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
266 ;; Constants to represent rounding modes in the ROUND instruction
275 ;; Constants to represent AVX512F embeded rounding
277 [(ROUND_NEAREST_INT 0)
285 ;; Constants to represent pcomtrue/pcomfalse variants
295 ;; Constants used in the XOP pperm instruction
297 [(PPERM_SRC 0x00) /* copy source */
298 (PPERM_INVERT 0x20) /* invert source */
299 (PPERM_REVERSE 0x40) /* bit reverse source */
300 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
301 (PPERM_ZERO 0x80) /* all 0's */
302 (PPERM_ONES 0xa0) /* all 1's */
303 (PPERM_SIGN 0xc0) /* propagate sign bit */
304 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
305 (PPERM_SRC1 0x00) /* use first source byte */
306 (PPERM_SRC2 0x10) /* use second source byte */
309 ;; Registers by name.
392 (FIRST_PSEUDO_REG 81)
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,v")
1648 (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1649 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1650 "* return output_fp_compare (insn, operands, true,
1651 <FPCMP:MODE>mode == CCFPUmode);"
1652 [(set_attr "type" "fcmp,ssecomi")
1653 (set_attr "prefix" "orig,maybe_vex")
1654 (set_attr "mode" "<MODEF:MODE>")
1655 (set_attr "prefix_rep" "*,0")
1656 (set (attr "prefix_data16")
1657 (cond [(eq_attr "alternative" "0")
1659 (eq_attr "mode" "DF")
1662 (const_string "0")))
1663 (set_attr "athlon_decode" "vector")
1664 (set_attr "amdfam10_decode" "direct")
1665 (set_attr "bdver1_decode" "double")
1666 (set (attr "enabled")
1667 (cond [(eq_attr "alternative" "0")
1668 (symbol_ref "TARGET_MIX_SSE_I387")
1670 (symbol_ref "true")))])
1672 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1673 [(set (reg:FPCMP FLAGS_REG)
1675 (match_operand:X87MODEF 0 "register_operand" "f")
1676 (match_operand:X87MODEF 1 "register_operand" "f")))]
1677 "TARGET_80387 && TARGET_CMOVE
1678 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1679 "* return output_fp_compare (insn, operands, true,
1680 <FPCMP:MODE>mode == CCFPUmode);"
1681 [(set_attr "type" "fcmp")
1682 (set_attr "mode" "<X87MODEF:MODE>")
1683 (set_attr "athlon_decode" "vector")
1684 (set_attr "amdfam10_decode" "direct")
1685 (set_attr "bdver1_decode" "double")])
1687 ;; Push/pop instructions.
1689 (define_insn "*push<mode>2"
1690 [(set (match_operand:DWI 0 "push_operand" "=<")
1691 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1694 [(set_attr "type" "multi")
1695 (set_attr "mode" "<MODE>")])
1698 [(set (match_operand:TI 0 "push_operand")
1699 (match_operand:TI 1 "general_operand"))]
1700 "TARGET_64BIT && reload_completed
1701 && !SSE_REG_P (operands[1])"
1703 "ix86_split_long_move (operands); DONE;")
1705 (define_insn "*pushdi2_rex64"
1706 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1707 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1712 [(set_attr "type" "push,multi")
1713 (set_attr "mode" "DI")])
1715 ;; Convert impossible pushes of immediate to existing instructions.
1716 ;; First try to get scratch register and go through it. In case this
1717 ;; fails, push sign extended lower part first and then overwrite
1718 ;; upper part by 32bit move.
1720 [(match_scratch:DI 2 "r")
1721 (set (match_operand:DI 0 "push_operand")
1722 (match_operand:DI 1 "immediate_operand"))]
1723 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1724 && !x86_64_immediate_operand (operands[1], DImode)"
1725 [(set (match_dup 2) (match_dup 1))
1726 (set (match_dup 0) (match_dup 2))])
1728 ;; We need to define this as both peepholer and splitter for case
1729 ;; peephole2 pass is not run.
1730 ;; "&& 1" is needed to keep it from matching the previous pattern.
1732 [(set (match_operand:DI 0 "push_operand")
1733 (match_operand:DI 1 "immediate_operand"))]
1734 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1735 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1736 [(set (match_dup 0) (match_dup 1))
1737 (set (match_dup 2) (match_dup 3))]
1739 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1741 operands[1] = gen_lowpart (DImode, operands[2]);
1742 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1747 [(set (match_operand:DI 0 "push_operand")
1748 (match_operand:DI 1 "immediate_operand"))]
1749 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1750 ? epilogue_completed : reload_completed)
1751 && !symbolic_operand (operands[1], DImode)
1752 && !x86_64_immediate_operand (operands[1], DImode)"
1753 [(set (match_dup 0) (match_dup 1))
1754 (set (match_dup 2) (match_dup 3))]
1756 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1758 operands[1] = gen_lowpart (DImode, operands[2]);
1759 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1764 [(set (match_operand:DI 0 "push_operand")
1765 (match_operand:DI 1 "general_operand"))]
1766 "!TARGET_64BIT && reload_completed
1767 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1769 "ix86_split_long_move (operands); DONE;")
1771 (define_insn "*pushsi2"
1772 [(set (match_operand:SI 0 "push_operand" "=<")
1773 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1776 [(set_attr "type" "push")
1777 (set_attr "mode" "SI")])
1779 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1780 ;; "push a byte/word". But actually we use pushl, which has the effect
1781 ;; of rounding the amount pushed up to a word.
1783 ;; For TARGET_64BIT we always round up to 8 bytes.
1784 (define_insn "*push<mode>2_rex64"
1785 [(set (match_operand:SWI124 0 "push_operand" "=X")
1786 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1789 [(set_attr "type" "push")
1790 (set_attr "mode" "DI")])
1792 (define_insn "*push<mode>2"
1793 [(set (match_operand:SWI12 0 "push_operand" "=X")
1794 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1797 [(set_attr "type" "push")
1798 (set_attr "mode" "SI")])
1800 (define_insn "*push<mode>2_prologue"
1801 [(set (match_operand:W 0 "push_operand" "=<")
1802 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1803 (clobber (mem:BLK (scratch)))]
1805 "push{<imodesuffix>}\t%1"
1806 [(set_attr "type" "push")
1807 (set_attr "mode" "<MODE>")])
1809 (define_insn "*pop<mode>1"
1810 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1811 (match_operand:W 1 "pop_operand" ">"))]
1813 "pop{<imodesuffix>}\t%0"
1814 [(set_attr "type" "pop")
1815 (set_attr "mode" "<MODE>")])
1817 (define_insn "*pop<mode>1_epilogue"
1818 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1819 (match_operand:W 1 "pop_operand" ">"))
1820 (clobber (mem:BLK (scratch)))]
1822 "pop{<imodesuffix>}\t%0"
1823 [(set_attr "type" "pop")
1824 (set_attr "mode" "<MODE>")])
1826 (define_insn "*pushfl<mode>2"
1827 [(set (match_operand:W 0 "push_operand" "=<")
1828 (match_operand:W 1 "flags_reg_operand"))]
1830 "pushf{<imodesuffix>}"
1831 [(set_attr "type" "push")
1832 (set_attr "mode" "<MODE>")])
1834 (define_insn "*popfl<mode>1"
1835 [(set (match_operand:W 0 "flags_reg_operand")
1836 (match_operand:W 1 "pop_operand" ">"))]
1838 "popf{<imodesuffix>}"
1839 [(set_attr "type" "pop")
1840 (set_attr "mode" "<MODE>")])
1843 ;; Move instructions.
1845 (define_expand "movxi"
1846 [(set (match_operand:XI 0 "nonimmediate_operand")
1847 (match_operand:XI 1 "general_operand"))]
1849 "ix86_expand_move (XImode, operands); DONE;")
1851 ;; Reload patterns to support multi-word load/store
1852 ;; with non-offsetable address.
1853 (define_expand "reload_noff_store"
1854 [(parallel [(match_operand 0 "memory_operand" "=m")
1855 (match_operand 1 "register_operand" "r")
1856 (match_operand:DI 2 "register_operand" "=&r")])]
1859 rtx mem = operands[0];
1860 rtx addr = XEXP (mem, 0);
1862 emit_move_insn (operands[2], addr);
1863 mem = replace_equiv_address_nv (mem, operands[2]);
1865 emit_insn (gen_rtx_SET (mem, operands[1]));
1869 (define_expand "reload_noff_load"
1870 [(parallel [(match_operand 0 "register_operand" "=r")
1871 (match_operand 1 "memory_operand" "m")
1872 (match_operand:DI 2 "register_operand" "=r")])]
1875 rtx mem = operands[1];
1876 rtx addr = XEXP (mem, 0);
1878 emit_move_insn (operands[2], addr);
1879 mem = replace_equiv_address_nv (mem, operands[2]);
1881 emit_insn (gen_rtx_SET (operands[0], mem));
1885 (define_expand "movoi"
1886 [(set (match_operand:OI 0 "nonimmediate_operand")
1887 (match_operand:OI 1 "general_operand"))]
1889 "ix86_expand_move (OImode, operands); DONE;")
1891 (define_expand "movti"
1892 [(set (match_operand:TI 0 "nonimmediate_operand")
1893 (match_operand:TI 1 "nonimmediate_operand"))]
1894 "TARGET_64BIT || TARGET_SSE"
1897 ix86_expand_move (TImode, operands);
1899 ix86_expand_vector_move (TImode, operands);
1903 ;; This expands to what emit_move_complex would generate if we didn't
1904 ;; have a movti pattern. Having this avoids problems with reload on
1905 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1906 ;; to have around all the time.
1907 (define_expand "movcdi"
1908 [(set (match_operand:CDI 0 "nonimmediate_operand")
1909 (match_operand:CDI 1 "general_operand"))]
1912 if (push_operand (operands[0], CDImode))
1913 emit_move_complex_push (CDImode, operands[0], operands[1]);
1915 emit_move_complex_parts (operands[0], operands[1]);
1919 (define_expand "mov<mode>"
1920 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1921 (match_operand:SWI1248x 1 "general_operand"))]
1923 "ix86_expand_move (<MODE>mode, operands); DONE;")
1925 (define_insn "*mov<mode>_xor"
1926 [(set (match_operand:SWI48 0 "register_operand" "=r")
1927 (match_operand:SWI48 1 "const0_operand"))
1928 (clobber (reg:CC FLAGS_REG))]
1931 [(set_attr "type" "alu1")
1932 (set_attr "mode" "SI")
1933 (set_attr "length_immediate" "0")])
1935 (define_insn "*mov<mode>_or"
1936 [(set (match_operand:SWI48 0 "register_operand" "=r")
1937 (match_operand:SWI48 1 "const_int_operand"))
1938 (clobber (reg:CC FLAGS_REG))]
1940 && operands[1] == constm1_rtx"
1941 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1942 [(set_attr "type" "alu1")
1943 (set_attr "mode" "<MODE>")
1944 (set_attr "length_immediate" "1")])
1946 (define_insn "*movxi_internal_avx512f"
1947 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1948 (match_operand:XI 1 "vector_move_operand" "C ,vm,v"))]
1949 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951 switch (which_alternative)
1954 return standard_sse_constant_opcode (insn, operands[1]);
1957 if (misaligned_operand (operands[0], XImode)
1958 || misaligned_operand (operands[1], XImode))
1959 return "vmovdqu32\t{%1, %0|%0, %1}";
1961 return "vmovdqa32\t{%1, %0|%0, %1}";
1966 [(set_attr "type" "sselog1,ssemov,ssemov")
1967 (set_attr "prefix" "evex")
1968 (set_attr "mode" "XI")])
1970 (define_insn "*movoi_internal_avx"
1971 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1972 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1973 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1975 switch (get_attr_type (insn))
1978 return standard_sse_constant_opcode (insn, operands[1]);
1981 if (misaligned_operand (operands[0], OImode)
1982 || misaligned_operand (operands[1], OImode))
1984 if (get_attr_mode (insn) == MODE_V8SF)
1985 return "vmovups\t{%1, %0|%0, %1}";
1986 else if (get_attr_mode (insn) == MODE_XI)
1987 return "vmovdqu32\t{%1, %0|%0, %1}";
1989 return "vmovdqu\t{%1, %0|%0, %1}";
1993 if (get_attr_mode (insn) == MODE_V8SF)
1994 return "vmovaps\t{%1, %0|%0, %1}";
1995 else if (get_attr_mode (insn) == MODE_XI)
1996 return "vmovdqa32\t{%1, %0|%0, %1}";
1998 return "vmovdqa\t{%1, %0|%0, %1}";
2005 [(set_attr "type" "sselog1,ssemov,ssemov")
2006 (set_attr "prefix" "vex")
2008 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2009 (match_operand 1 "ext_sse_reg_operand"))
2011 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2012 (const_string "V8SF")
2013 (and (eq_attr "alternative" "2")
2014 (match_test "TARGET_SSE_TYPELESS_STORES"))
2015 (const_string "V8SF")
2017 (const_string "OI")))])
2019 (define_insn "*movti_internal"
2020 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2021 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2022 "(TARGET_64BIT || TARGET_SSE)
2023 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2025 switch (get_attr_type (insn))
2031 return standard_sse_constant_opcode (insn, operands[1]);
2034 /* TDmode values are passed as TImode on the stack. Moving them
2035 to stack may result in unaligned memory access. */
2036 if (misaligned_operand (operands[0], TImode)
2037 || misaligned_operand (operands[1], TImode))
2039 if (get_attr_mode (insn) == MODE_V4SF)
2040 return "%vmovups\t{%1, %0|%0, %1}";
2041 else if (get_attr_mode (insn) == MODE_XI)
2042 return "vmovdqu32\t{%1, %0|%0, %1}";
2044 return "%vmovdqu\t{%1, %0|%0, %1}";
2048 if (get_attr_mode (insn) == MODE_V4SF)
2049 return "%vmovaps\t{%1, %0|%0, %1}";
2050 else if (get_attr_mode (insn) == MODE_XI)
2051 return "vmovdqa32\t{%1, %0|%0, %1}";
2053 return "%vmovdqa\t{%1, %0|%0, %1}";
2060 [(set_attr "isa" "x64,x64,*,*,*")
2061 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2062 (set (attr "prefix")
2063 (if_then_else (eq_attr "type" "sselog1,ssemov")
2064 (const_string "maybe_vex")
2065 (const_string "orig")))
2067 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2068 (match_operand 1 "ext_sse_reg_operand"))
2070 (eq_attr "alternative" "0,1")
2072 (ior (not (match_test "TARGET_SSE2"))
2073 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2074 (const_string "V4SF")
2075 (and (eq_attr "alternative" "4")
2076 (match_test "TARGET_SSE_TYPELESS_STORES"))
2077 (const_string "V4SF")
2078 (match_test "TARGET_AVX")
2080 (match_test "optimize_function_for_size_p (cfun)")
2081 (const_string "V4SF")
2083 (const_string "TI")))])
2086 [(set (match_operand:TI 0 "nonimmediate_operand")
2087 (match_operand:TI 1 "general_operand"))]
2089 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2091 "ix86_split_long_move (operands); DONE;")
2093 (define_insn "*movdi_internal"
2094 [(set (match_operand:DI 0 "nonimmediate_operand"
2095 "=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")
2096 (match_operand:DI 1 "general_operand"
2097 "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"))]
2098 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2100 switch (get_attr_type (insn))
2103 return "kmovq\t{%1, %0|%0, %1}";
2109 return "pxor\t%0, %0";
2112 /* Handle broken assemblers that require movd instead of movq. */
2113 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2114 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2115 return "movd\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2119 if (GENERAL_REG_P (operands[0]))
2120 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2122 return standard_sse_constant_opcode (insn, operands[1]);
2125 switch (get_attr_mode (insn))
2128 /* Handle broken assemblers that require movd instead of movq. */
2129 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2130 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2131 return "%vmovd\t{%1, %0|%0, %1}";
2132 return "%vmovq\t{%1, %0|%0, %1}";
2134 return "%vmovdqa\t{%1, %0|%0, %1}";
2136 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2139 gcc_assert (!TARGET_AVX);
2140 return "movlps\t{%1, %0|%0, %1}";
2142 return "%vmovaps\t{%1, %0|%0, %1}";
2149 if (SSE_REG_P (operands[0]))
2150 return "movq2dq\t{%1, %0|%0, %1}";
2152 return "movdq2q\t{%1, %0|%0, %1}";
2155 return "lea{q}\t{%E1, %0|%0, %E1}";
2158 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159 if (get_attr_mode (insn) == MODE_SI)
2160 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2161 else if (which_alternative == 4)
2162 return "movabs{q}\t{%1, %0|%0, %1}";
2163 else if (ix86_use_lea_for_mov (insn, operands))
2164 return "lea{q}\t{%E1, %0|%0, %E1}";
2166 return "mov{q}\t{%1, %0|%0, %1}";
2173 (cond [(eq_attr "alternative" "0,1")
2174 (const_string "nox64")
2175 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2176 (const_string "x64")
2177 (eq_attr "alternative" "17")
2178 (const_string "x64_sse4")
2180 (const_string "*")))
2182 (cond [(eq_attr "alternative" "0,1")
2183 (const_string "multi")
2184 (eq_attr "alternative" "6")
2185 (const_string "mmx")
2186 (eq_attr "alternative" "7,8,9,10,11")
2187 (const_string "mmxmov")
2188 (eq_attr "alternative" "12,17")
2189 (const_string "sselog1")
2190 (eq_attr "alternative" "13,14,15,16,18")
2191 (const_string "ssemov")
2192 (eq_attr "alternative" "19,20")
2193 (const_string "ssecvt")
2194 (eq_attr "alternative" "21,22,23,24")
2195 (const_string "mskmov")
2196 (and (match_operand 0 "register_operand")
2197 (match_operand 1 "pic_32bit_operand"))
2198 (const_string "lea")
2200 (const_string "imov")))
2203 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2205 (const_string "*")))
2206 (set (attr "length_immediate")
2207 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2209 (eq_attr "alternative" "17")
2212 (const_string "*")))
2213 (set (attr "prefix_rex")
2214 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2216 (const_string "*")))
2217 (set (attr "prefix_extra")
2218 (if_then_else (eq_attr "alternative" "17")
2220 (const_string "*")))
2221 (set (attr "prefix")
2222 (if_then_else (eq_attr "type" "sselog1,ssemov")
2223 (const_string "maybe_vex")
2224 (const_string "orig")))
2225 (set (attr "prefix_data16")
2226 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2228 (const_string "*")))
2230 (cond [(eq_attr "alternative" "2")
2232 (eq_attr "alternative" "12,13")
2233 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2234 (match_operand 1 "ext_sse_reg_operand"))
2236 (ior (not (match_test "TARGET_SSE2"))
2237 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2238 (const_string "V4SF")
2239 (match_test "TARGET_AVX")
2241 (match_test "optimize_function_for_size_p (cfun)")
2242 (const_string "V4SF")
2244 (const_string "TI"))
2246 (and (eq_attr "alternative" "14,15")
2247 (not (match_test "TARGET_SSE2")))
2248 (const_string "V2SF")
2249 (eq_attr "alternative" "17")
2252 (const_string "DI")))])
2255 [(set (match_operand:DI 0 "nonimmediate_operand")
2256 (match_operand:DI 1 "general_operand"))]
2257 "!TARGET_64BIT && reload_completed
2258 && !(MMX_REG_P (operands[0])
2259 || SSE_REG_P (operands[0])
2260 || MASK_REG_P (operands[0]))
2261 && !(MMX_REG_P (operands[1])
2262 || SSE_REG_P (operands[1])
2263 || MASK_REG_P (operands[1]))"
2265 "ix86_split_long_move (operands); DONE;")
2267 (define_insn "*movsi_internal"
2268 [(set (match_operand:SI 0 "nonimmediate_operand"
2269 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2270 (match_operand:SI 1 "general_operand"
2271 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2272 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2274 switch (get_attr_type (insn))
2277 if (GENERAL_REG_P (operands[0]))
2278 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2280 return standard_sse_constant_opcode (insn, operands[1]);
2283 return "kmovd\t{%1, %0|%0, %1}";
2286 switch (get_attr_mode (insn))
2289 return "%vmovd\t{%1, %0|%0, %1}";
2291 return "%vmovdqa\t{%1, %0|%0, %1}";
2293 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2296 return "%vmovaps\t{%1, %0|%0, %1}";
2299 gcc_assert (!TARGET_AVX);
2300 return "movss\t{%1, %0|%0, %1}";
2307 return "pxor\t%0, %0";
2310 switch (get_attr_mode (insn))
2313 return "movq\t{%1, %0|%0, %1}";
2315 return "movd\t{%1, %0|%0, %1}";
2322 return "lea{l}\t{%E1, %0|%0, %E1}";
2325 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2326 if (ix86_use_lea_for_mov (insn, operands))
2327 return "lea{l}\t{%E1, %0|%0, %E1}";
2329 return "mov{l}\t{%1, %0|%0, %1}";
2336 (if_then_else (eq_attr "alternative" "11")
2337 (const_string "sse4")
2338 (const_string "*")))
2340 (cond [(eq_attr "alternative" "2")
2341 (const_string "mmx")
2342 (eq_attr "alternative" "3,4,5")
2343 (const_string "mmxmov")
2344 (eq_attr "alternative" "6,11")
2345 (const_string "sselog1")
2346 (eq_attr "alternative" "7,8,9,10,12")
2347 (const_string "ssemov")
2348 (eq_attr "alternative" "13,14")
2349 (const_string "mskmov")
2350 (and (match_operand 0 "register_operand")
2351 (match_operand 1 "pic_32bit_operand"))
2352 (const_string "lea")
2354 (const_string "imov")))
2355 (set (attr "length_immediate")
2356 (if_then_else (eq_attr "alternative" "11")
2358 (const_string "*")))
2359 (set (attr "prefix_extra")
2360 (if_then_else (eq_attr "alternative" "11")
2362 (const_string "*")))
2363 (set (attr "prefix")
2364 (if_then_else (eq_attr "type" "sselog1,ssemov")
2365 (const_string "maybe_vex")
2366 (const_string "orig")))
2367 (set (attr "prefix_data16")
2368 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2370 (const_string "*")))
2372 (cond [(eq_attr "alternative" "2,3")
2374 (eq_attr "alternative" "6,7")
2375 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2376 (match_operand 1 "ext_sse_reg_operand"))
2378 (ior (not (match_test "TARGET_SSE2"))
2379 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2380 (const_string "V4SF")
2381 (match_test "TARGET_AVX")
2383 (match_test "optimize_function_for_size_p (cfun)")
2384 (const_string "V4SF")
2386 (const_string "TI"))
2388 (and (eq_attr "alternative" "8,9")
2389 (not (match_test "TARGET_SSE2")))
2391 (eq_attr "alternative" "11")
2394 (const_string "SI")))])
2396 (define_insn "kmovw"
2397 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2399 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2401 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2403 kmovw\t{%k1, %0|%0, %k1}
2404 kmovw\t{%1, %0|%0, %1}";
2405 [(set_attr "mode" "HI")
2406 (set_attr "type" "mskmov")
2407 (set_attr "prefix" "vex")])
2410 (define_insn "*movhi_internal"
2411 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2412 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2413 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 switch (get_attr_type (insn))
2418 /* movzwl is faster than movw on p2 due to partial word stalls,
2419 though not as fast as an aligned movl. */
2420 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2423 switch (which_alternative)
2425 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2426 case 5: return "kmovw\t{%1, %0|%0, %1}";
2427 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2428 default: gcc_unreachable ();
2432 if (get_attr_mode (insn) == MODE_SI)
2433 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2435 return "mov{w}\t{%1, %0|%0, %1}";
2439 (cond [(eq_attr "alternative" "4,5,6")
2440 (const_string "mskmov")
2441 (match_test "optimize_function_for_size_p (cfun)")
2442 (const_string "imov")
2443 (and (eq_attr "alternative" "0")
2444 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2445 (not (match_test "TARGET_HIMODE_MATH"))))
2446 (const_string "imov")
2447 (and (eq_attr "alternative" "1,2")
2448 (match_operand:HI 1 "aligned_operand"))
2449 (const_string "imov")
2450 (and (match_test "TARGET_MOVX")
2451 (eq_attr "alternative" "0,2"))
2452 (const_string "imovx")
2454 (const_string "imov")))
2455 (set (attr "prefix")
2456 (if_then_else (eq_attr "alternative" "4,5,6")
2457 (const_string "vex")
2458 (const_string "orig")))
2460 (cond [(eq_attr "type" "imovx")
2462 (and (eq_attr "alternative" "1,2")
2463 (match_operand:HI 1 "aligned_operand"))
2465 (and (eq_attr "alternative" "0")
2466 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2467 (not (match_test "TARGET_HIMODE_MATH"))))
2470 (const_string "HI")))])
2472 ;; Situation is quite tricky about when to choose full sized (SImode) move
2473 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2474 ;; partial register dependency machines (such as AMD Athlon), where QImode
2475 ;; moves issue extra dependency and for partial register stalls machines
2476 ;; that don't use QImode patterns (and QImode move cause stall on the next
2479 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2480 ;; register stall machines with, where we use QImode instructions, since
2481 ;; partial register stall can be caused there. Then we use movzx.
2483 (define_insn "*movqi_internal"
2484 [(set (match_operand:QI 0 "nonimmediate_operand"
2485 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2486 (match_operand:QI 1 "general_operand"
2487 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2488 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2490 switch (get_attr_type (insn))
2493 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2494 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2497 switch (which_alternative)
2499 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2500 : "kmovw\t{%k1, %0|%0, %k1}";
2501 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2502 : "kmovw\t{%1, %0|%0, %1}";
2503 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2504 : "kmovw\t{%1, %k0|%k0, %1}";
2507 gcc_assert (TARGET_AVX512DQ);
2508 return "kmovb\t{%1, %0|%0, %1}";
2509 default: gcc_unreachable ();
2513 if (get_attr_mode (insn) == MODE_SI)
2514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2516 return "mov{b}\t{%1, %0|%0, %1}";
2519 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2521 (cond [(eq_attr "alternative" "7,8,9,10,11")
2522 (const_string "mskmov")
2523 (and (eq_attr "alternative" "5")
2524 (not (match_operand:QI 1 "aligned_operand")))
2525 (const_string "imovx")
2526 (match_test "optimize_function_for_size_p (cfun)")
2527 (const_string "imov")
2528 (and (eq_attr "alternative" "3")
2529 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2530 (not (match_test "TARGET_QIMODE_MATH"))))
2531 (const_string "imov")
2532 (eq_attr "alternative" "3,5")
2533 (const_string "imovx")
2534 (and (match_test "TARGET_MOVX")
2535 (eq_attr "alternative" "2"))
2536 (const_string "imovx")
2538 (const_string "imov")))
2539 (set (attr "prefix")
2540 (if_then_else (eq_attr "alternative" "7,8,9")
2541 (const_string "vex")
2542 (const_string "orig")))
2544 (cond [(eq_attr "alternative" "3,4,5")
2546 (eq_attr "alternative" "6")
2548 (eq_attr "type" "imovx")
2550 (and (eq_attr "type" "imov")
2551 (and (eq_attr "alternative" "0,1")
2552 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2553 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2554 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2556 ;; Avoid partial register stalls when not using QImode arithmetic
2557 (and (eq_attr "type" "imov")
2558 (and (eq_attr "alternative" "0,1")
2559 (and (match_test "TARGET_PARTIAL_REG_STALL")
2560 (not (match_test "TARGET_QIMODE_MATH")))))
2563 (const_string "QI")))])
2565 ;; Stores and loads of ax to arbitrary constant address.
2566 ;; We fake an second form of instruction to force reload to load address
2567 ;; into register when rax is not available
2568 (define_insn "*movabs<mode>_1"
2569 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2570 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2571 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2573 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2574 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2575 [(set_attr "type" "imov")
2576 (set_attr "modrm" "0,*")
2577 (set_attr "length_address" "8,0")
2578 (set_attr "length_immediate" "0,*")
2579 (set_attr "memory" "store")
2580 (set_attr "mode" "<MODE>")])
2582 (define_insn "*movabs<mode>_2"
2583 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2584 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2585 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2587 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2588 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2589 [(set_attr "type" "imov")
2590 (set_attr "modrm" "0,*")
2591 (set_attr "length_address" "8,0")
2592 (set_attr "length_immediate" "0")
2593 (set_attr "memory" "load")
2594 (set_attr "mode" "<MODE>")])
2596 (define_insn "*swap<mode>"
2597 [(set (match_operand:SWI48 0 "register_operand" "+r")
2598 (match_operand:SWI48 1 "register_operand" "+r"))
2602 "xchg{<imodesuffix>}\t%1, %0"
2603 [(set_attr "type" "imov")
2604 (set_attr "mode" "<MODE>")
2605 (set_attr "pent_pair" "np")
2606 (set_attr "athlon_decode" "vector")
2607 (set_attr "amdfam10_decode" "double")
2608 (set_attr "bdver1_decode" "double")])
2610 (define_insn "*swap<mode>_1"
2611 [(set (match_operand:SWI12 0 "register_operand" "+r")
2612 (match_operand:SWI12 1 "register_operand" "+r"))
2615 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2617 [(set_attr "type" "imov")
2618 (set_attr "mode" "SI")
2619 (set_attr "pent_pair" "np")
2620 (set_attr "athlon_decode" "vector")
2621 (set_attr "amdfam10_decode" "double")
2622 (set_attr "bdver1_decode" "double")])
2624 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2625 ;; is disabled for AMDFAM10
2626 (define_insn "*swap<mode>_2"
2627 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2628 (match_operand:SWI12 1 "register_operand" "+<r>"))
2631 "TARGET_PARTIAL_REG_STALL"
2632 "xchg{<imodesuffix>}\t%1, %0"
2633 [(set_attr "type" "imov")
2634 (set_attr "mode" "<MODE>")
2635 (set_attr "pent_pair" "np")
2636 (set_attr "athlon_decode" "vector")])
2638 (define_expand "movstrict<mode>"
2639 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2640 (match_operand:SWI12 1 "general_operand"))]
2643 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2645 if (GET_CODE (operands[0]) == SUBREG
2646 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2648 /* Don't generate memory->memory moves, go through a register */
2649 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2650 operands[1] = force_reg (<MODE>mode, operands[1]);
2653 (define_insn "*movstrict<mode>_1"
2654 [(set (strict_low_part
2655 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2656 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2657 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2658 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2659 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2660 [(set_attr "type" "imov")
2661 (set_attr "mode" "<MODE>")])
2663 (define_insn "*movstrict<mode>_xor"
2664 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2665 (match_operand:SWI12 1 "const0_operand"))
2666 (clobber (reg:CC FLAGS_REG))]
2668 "xor{<imodesuffix>}\t%0, %0"
2669 [(set_attr "type" "alu1")
2670 (set_attr "mode" "<MODE>")
2671 (set_attr "length_immediate" "0")])
2673 (define_insn "*mov<mode>_extv_1"
2674 [(set (match_operand:SWI24 0 "register_operand" "=R")
2675 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2679 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2680 [(set_attr "type" "imovx")
2681 (set_attr "mode" "SI")])
2683 (define_insn "*movqi_extv_1"
2684 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2685 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2690 switch (get_attr_type (insn))
2693 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2695 return "mov{b}\t{%h1, %0|%0, %h1}";
2698 [(set_attr "isa" "*,*,nox64")
2700 (if_then_else (and (match_operand:QI 0 "register_operand")
2701 (ior (not (match_operand:QI 0 "QIreg_operand"))
2702 (match_test "TARGET_MOVX")))
2703 (const_string "imovx")
2704 (const_string "imov")))
2706 (if_then_else (eq_attr "type" "imovx")
2708 (const_string "QI")))])
2710 (define_insn "*mov<mode>_extzv_1"
2711 [(set (match_operand:SWI48 0 "register_operand" "=R")
2712 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2717 [(set_attr "type" "imovx")
2718 (set_attr "mode" "SI")])
2720 (define_insn "*movqi_extzv_2"
2721 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2723 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2728 switch (get_attr_type (insn))
2731 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2733 return "mov{b}\t{%h1, %0|%0, %h1}";
2736 [(set_attr "isa" "*,*,nox64")
2738 (if_then_else (and (match_operand:QI 0 "register_operand")
2739 (ior (not (match_operand:QI 0 "QIreg_operand"))
2740 (match_test "TARGET_MOVX")))
2741 (const_string "imovx")
2742 (const_string "imov")))
2744 (if_then_else (eq_attr "type" "imovx")
2746 (const_string "QI")))])
2748 (define_insn "mov<mode>_insv_1"
2749 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2752 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2755 if (CONST_INT_P (operands[1]))
2756 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2757 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2759 [(set_attr "isa" "*,nox64")
2760 (set_attr "type" "imov")
2761 (set_attr "mode" "QI")])
2763 (define_insn "*movqi_insv_2"
2764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2767 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2770 "mov{b}\t{%h1, %h0|%h0, %h1}"
2771 [(set_attr "type" "imov")
2772 (set_attr "mode" "QI")])
2774 ;; Floating point push instructions.
2776 (define_insn "*pushtf"
2777 [(set (match_operand:TF 0 "push_operand" "=<,<")
2778 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2779 "TARGET_64BIT || TARGET_SSE"
2781 /* This insn should be already split before reg-stack. */
2784 [(set_attr "isa" "*,x64")
2785 (set_attr "type" "multi")
2786 (set_attr "unit" "sse,*")
2787 (set_attr "mode" "TF,DI")])
2789 ;; %%% Kill this when call knows how to work this out.
2791 [(set (match_operand:TF 0 "push_operand")
2792 (match_operand:TF 1 "sse_reg_operand"))]
2793 "TARGET_SSE && reload_completed"
2794 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2795 (set (match_dup 0) (match_dup 1))]
2797 /* Preserve memory attributes. */
2798 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2801 (define_insn "*pushxf"
2802 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2803 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2806 /* This insn should be already split before reg-stack. */
2809 [(set_attr "type" "multi")
2810 (set_attr "unit" "i387,*,*,*")
2812 (cond [(eq_attr "alternative" "1,2,3")
2813 (if_then_else (match_test "TARGET_64BIT")
2815 (const_string "SI"))
2817 (const_string "XF")))
2818 (set (attr "preferred_for_size")
2819 (cond [(eq_attr "alternative" "1")
2820 (symbol_ref "false")]
2821 (symbol_ref "true")))])
2823 ;; %%% Kill this when call knows how to work this out.
2825 [(set (match_operand:XF 0 "push_operand")
2826 (match_operand:XF 1 "fp_register_operand"))]
2828 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2829 (set (match_dup 0) (match_dup 1))]
2831 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2832 /* Preserve memory attributes. */
2833 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2836 (define_insn "*pushdf"
2837 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2838 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2841 /* This insn should be already split before reg-stack. */
2844 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2845 (set_attr "type" "multi")
2846 (set_attr "unit" "i387,*,*,*,*,sse")
2847 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2848 (set (attr "preferred_for_size")
2849 (cond [(eq_attr "alternative" "1")
2850 (symbol_ref "false")]
2851 (symbol_ref "true")))
2852 (set (attr "preferred_for_speed")
2853 (cond [(eq_attr "alternative" "1")
2854 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2855 (symbol_ref "true")))])
2857 ;; %%% Kill this when call knows how to work this out.
2859 [(set (match_operand:DF 0 "push_operand")
2860 (match_operand:DF 1 "any_fp_register_operand"))]
2862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2863 (set (match_dup 0) (match_dup 1))]
2865 /* Preserve memory attributes. */
2866 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2869 (define_insn "*pushsf_rex64"
2870 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2871 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2874 /* Anything else should be already split before reg-stack. */
2875 gcc_assert (which_alternative == 1);
2876 return "push{q}\t%q1";
2878 [(set_attr "type" "multi,push,multi")
2879 (set_attr "unit" "i387,*,*")
2880 (set_attr "mode" "SF,DI,SF")])
2882 (define_insn "*pushsf"
2883 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2884 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2887 /* Anything else should be already split before reg-stack. */
2888 gcc_assert (which_alternative == 1);
2889 return "push{l}\t%1";
2891 [(set_attr "type" "multi,push,multi")
2892 (set_attr "unit" "i387,*,*")
2893 (set_attr "mode" "SF,SI,SF")])
2895 ;; %%% Kill this when call knows how to work this out.
2897 [(set (match_operand:SF 0 "push_operand")
2898 (match_operand:SF 1 "any_fp_register_operand"))]
2900 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2901 (set (match_dup 0) (match_dup 1))]
2903 rtx op = XEXP (operands[0], 0);
2904 if (GET_CODE (op) == PRE_DEC)
2906 gcc_assert (!TARGET_64BIT);
2911 op = XEXP (XEXP (op, 1), 1);
2912 gcc_assert (CONST_INT_P (op));
2915 /* Preserve memory attributes. */
2916 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2920 [(set (match_operand:SF 0 "push_operand")
2921 (match_operand:SF 1 "memory_operand"))]
2923 && (operands[2] = find_constant_src (insn))"
2924 [(set (match_dup 0) (match_dup 2))])
2927 [(set (match_operand 0 "push_operand")
2928 (match_operand 1 "general_operand"))]
2930 && (GET_MODE (operands[0]) == TFmode
2931 || GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == DFmode)
2933 && !ANY_FP_REG_P (operands[1])"
2935 "ix86_split_long_move (operands); DONE;")
2937 ;; Floating point move instructions.
2939 (define_expand "movtf"
2940 [(set (match_operand:TF 0 "nonimmediate_operand")
2941 (match_operand:TF 1 "nonimmediate_operand"))]
2942 "TARGET_64BIT || TARGET_SSE"
2943 "ix86_expand_move (TFmode, operands); DONE;")
2945 (define_expand "mov<mode>"
2946 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2947 (match_operand:X87MODEF 1 "general_operand"))]
2949 "ix86_expand_move (<MODE>mode, operands); DONE;")
2951 (define_insn "*movtf_internal"
2952 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2953 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2954 "(TARGET_64BIT || TARGET_SSE)
2955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2956 && (!can_create_pseudo_p ()
2957 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2958 || !CONST_DOUBLE_P (operands[1])
2959 || (optimize_function_for_size_p (cfun)
2960 && standard_sse_constant_p (operands[1])
2961 && !memory_operand (operands[0], TFmode))
2962 || (!TARGET_MEMORY_MISMATCH_STALL
2963 && memory_operand (operands[0], TFmode)))"
2965 switch (get_attr_type (insn))
2968 return standard_sse_constant_opcode (insn, operands[1]);
2971 /* Handle misaligned load/store since we
2972 don't have movmisaligntf pattern. */
2973 if (misaligned_operand (operands[0], TFmode)
2974 || misaligned_operand (operands[1], TFmode))
2976 if (get_attr_mode (insn) == MODE_V4SF)
2977 return "%vmovups\t{%1, %0|%0, %1}";
2979 return "%vmovdqu\t{%1, %0|%0, %1}";
2983 if (get_attr_mode (insn) == MODE_V4SF)
2984 return "%vmovaps\t{%1, %0|%0, %1}";
2986 return "%vmovdqa\t{%1, %0|%0, %1}";
2996 [(set_attr "isa" "*,*,*,x64,x64")
2997 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2998 (set (attr "prefix")
2999 (if_then_else (eq_attr "type" "sselog1,ssemov")
3000 (const_string "maybe_vex")
3001 (const_string "orig")))
3003 (cond [(eq_attr "alternative" "3,4")
3005 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3006 (const_string "V4SF")
3007 (and (eq_attr "alternative" "2")
3008 (match_test "TARGET_SSE_TYPELESS_STORES"))
3009 (const_string "V4SF")
3010 (match_test "TARGET_AVX")
3012 (ior (not (match_test "TARGET_SSE2"))
3013 (match_test "optimize_function_for_size_p (cfun)"))
3014 (const_string "V4SF")
3016 (const_string "TI")))])
3018 ;; Possible store forwarding (partial memory) stall
3019 ;; in alternatives 4, 6, 7 and 8.
3020 (define_insn "*movxf_internal"
3021 [(set (match_operand:XF 0 "nonimmediate_operand"
3022 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3023 (match_operand:XF 1 "general_operand"
3024 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3025 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026 && (!can_create_pseudo_p ()
3027 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3028 || !CONST_DOUBLE_P (operands[1])
3029 || (optimize_function_for_size_p (cfun)
3030 && standard_80387_constant_p (operands[1]) > 0
3031 && !memory_operand (operands[0], XFmode))
3032 || (!TARGET_MEMORY_MISMATCH_STALL
3033 && memory_operand (operands[0], XFmode)))"
3035 switch (get_attr_type (insn))
3038 if (which_alternative == 2)
3039 return standard_80387_constant_opcode (operands[1]);
3040 return output_387_reg_move (insn, operands);
3050 (cond [(eq_attr "alternative" "7")
3051 (const_string "nox64")
3052 (eq_attr "alternative" "8")
3053 (const_string "x64")
3055 (const_string "*")))
3057 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3058 (const_string "multi")
3060 (const_string "fmov")))
3062 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3063 (if_then_else (match_test "TARGET_64BIT")
3065 (const_string "SI"))
3067 (const_string "XF")))
3068 (set (attr "preferred_for_size")
3069 (cond [(eq_attr "alternative" "3,4")
3070 (symbol_ref "false")]
3071 (symbol_ref "true")))])
3073 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3074 (define_insn "*movdf_internal"
3075 [(set (match_operand:DF 0 "nonimmediate_operand"
3076 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3077 (match_operand:DF 1 "general_operand"
3078 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3079 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3080 && (!can_create_pseudo_p ()
3081 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3082 || !CONST_DOUBLE_P (operands[1])
3083 || (optimize_function_for_size_p (cfun)
3084 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3085 && standard_80387_constant_p (operands[1]) > 0)
3086 || (TARGET_SSE2 && TARGET_SSE_MATH
3087 && standard_sse_constant_p (operands[1])))
3088 && !memory_operand (operands[0], DFmode))
3089 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3090 && memory_operand (operands[0], DFmode)))"
3092 switch (get_attr_type (insn))
3095 if (which_alternative == 2)
3096 return standard_80387_constant_opcode (operands[1]);
3097 return output_387_reg_move (insn, operands);
3103 if (get_attr_mode (insn) == MODE_SI)
3104 return "mov{l}\t{%1, %k0|%k0, %1}";
3105 else if (which_alternative == 11)
3106 return "movabs{q}\t{%1, %0|%0, %1}";
3108 return "mov{q}\t{%1, %0|%0, %1}";
3111 return standard_sse_constant_opcode (insn, operands[1]);
3114 switch (get_attr_mode (insn))
3117 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3118 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3119 return "%vmovsd\t{%1, %0|%0, %1}";
3122 return "%vmovaps\t{%1, %0|%0, %1}";
3124 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3126 return "%vmovapd\t{%1, %0|%0, %1}";
3129 gcc_assert (!TARGET_AVX);
3130 return "movlps\t{%1, %0|%0, %1}";
3132 gcc_assert (!TARGET_AVX);
3133 return "movlpd\t{%1, %0|%0, %1}";
3136 /* Handle broken assemblers that require movd instead of movq. */
3137 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3138 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3139 return "%vmovd\t{%1, %0|%0, %1}";
3140 return "%vmovq\t{%1, %0|%0, %1}";
3151 (cond [(eq_attr "alternative" "3,4,5,6,7")
3152 (const_string "nox64")
3153 (eq_attr "alternative" "8,9,10,11,20,21")
3154 (const_string "x64")
3155 (eq_attr "alternative" "12,13,14,15")
3156 (const_string "sse2")
3158 (const_string "*")))
3160 (cond [(eq_attr "alternative" "0,1,2")
3161 (const_string "fmov")
3162 (eq_attr "alternative" "3,4,5,6,7")
3163 (const_string "multi")
3164 (eq_attr "alternative" "8,9,10,11")
3165 (const_string "imov")
3166 (eq_attr "alternative" "12,16")
3167 (const_string "sselog1")
3169 (const_string "ssemov")))
3171 (if_then_else (eq_attr "alternative" "11")
3173 (const_string "*")))
3174 (set (attr "length_immediate")
3175 (if_then_else (eq_attr "alternative" "11")
3177 (const_string "*")))
3178 (set (attr "prefix")
3179 (if_then_else (eq_attr "type" "sselog1,ssemov")
3180 (const_string "maybe_vex")
3181 (const_string "orig")))
3182 (set (attr "prefix_data16")
3184 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3185 (eq_attr "mode" "V1DF"))
3187 (const_string "*")))
3189 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3191 (eq_attr "alternative" "8,9,11,20,21")
3194 /* xorps is one byte shorter for non-AVX targets. */
3195 (eq_attr "alternative" "12,16")
3196 (cond [(not (match_test "TARGET_SSE2"))
3197 (const_string "V4SF")
3198 (match_test "TARGET_AVX512F")
3200 (match_test "TARGET_AVX")
3201 (const_string "V2DF")
3202 (match_test "optimize_function_for_size_p (cfun)")
3203 (const_string "V4SF")
3204 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3207 (const_string "V2DF"))
3209 /* For architectures resolving dependencies on
3210 whole SSE registers use movapd to break dependency
3211 chains, otherwise use short move to avoid extra work. */
3213 /* movaps is one byte shorter for non-AVX targets. */
3214 (eq_attr "alternative" "13,17")
3215 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3216 (match_operand 1 "ext_sse_reg_operand"))
3217 (const_string "V8DF")
3218 (ior (not (match_test "TARGET_SSE2"))
3219 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3220 (const_string "V4SF")
3221 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3222 (const_string "V2DF")
3223 (match_test "TARGET_AVX")
3225 (match_test "optimize_function_for_size_p (cfun)")
3226 (const_string "V4SF")
3228 (const_string "DF"))
3230 /* For architectures resolving dependencies on register
3231 parts we may avoid extra work to zero out upper part
3233 (eq_attr "alternative" "14,18")
3234 (cond [(not (match_test "TARGET_SSE2"))
3235 (const_string "V2SF")
3236 (match_test "TARGET_AVX")
3238 (match_test "TARGET_SSE_SPLIT_REGS")
3239 (const_string "V1DF")
3241 (const_string "DF"))
3243 (and (eq_attr "alternative" "15,19")
3244 (not (match_test "TARGET_SSE2")))
3245 (const_string "V2SF")
3247 (const_string "DF")))
3248 (set (attr "preferred_for_size")
3249 (cond [(eq_attr "alternative" "3,4")
3250 (symbol_ref "false")]
3251 (symbol_ref "true")))
3252 (set (attr "preferred_for_speed")
3253 (cond [(eq_attr "alternative" "3,4")
3254 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3255 (symbol_ref "true")))])
3257 (define_insn "*movsf_internal"
3258 [(set (match_operand:SF 0 "nonimmediate_operand"
3259 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3260 (match_operand:SF 1 "general_operand"
3261 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3262 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3263 && (!can_create_pseudo_p ()
3264 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3265 || !CONST_DOUBLE_P (operands[1])
3266 || (optimize_function_for_size_p (cfun)
3267 && ((!TARGET_SSE_MATH
3268 && standard_80387_constant_p (operands[1]) > 0)
3270 && standard_sse_constant_p (operands[1]))))
3271 || memory_operand (operands[0], SFmode))"
3273 switch (get_attr_type (insn))
3276 if (which_alternative == 2)
3277 return standard_80387_constant_opcode (operands[1]);
3278 return output_387_reg_move (insn, operands);
3281 return "mov{l}\t{%1, %0|%0, %1}";
3284 return standard_sse_constant_opcode (insn, operands[1]);
3287 switch (get_attr_mode (insn))
3290 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3291 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3292 return "%vmovss\t{%1, %0|%0, %1}";
3295 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3297 return "%vmovaps\t{%1, %0|%0, %1}";
3300 return "%vmovd\t{%1, %0|%0, %1}";
3307 switch (get_attr_mode (insn))
3310 return "movq\t{%1, %0|%0, %1}";
3312 return "movd\t{%1, %0|%0, %1}";
3323 (cond [(eq_attr "alternative" "0,1,2")
3324 (const_string "fmov")
3325 (eq_attr "alternative" "3,4")
3326 (const_string "imov")
3327 (eq_attr "alternative" "5")
3328 (const_string "sselog1")
3329 (eq_attr "alternative" "11,12,13,14,15")
3330 (const_string "mmxmov")
3332 (const_string "ssemov")))
3333 (set (attr "prefix")
3334 (if_then_else (eq_attr "type" "sselog1,ssemov")
3335 (const_string "maybe_vex")
3336 (const_string "orig")))
3337 (set (attr "prefix_data16")
3338 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3340 (const_string "*")))
3342 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3344 (eq_attr "alternative" "11")
3346 (eq_attr "alternative" "5")
3347 (cond [(not (match_test "TARGET_SSE2"))
3348 (const_string "V4SF")
3349 (match_test "TARGET_AVX512F")
3350 (const_string "V16SF")
3351 (match_test "TARGET_AVX")
3352 (const_string "V4SF")
3353 (match_test "optimize_function_for_size_p (cfun)")
3354 (const_string "V4SF")
3355 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3358 (const_string "V4SF"))
3360 /* For architectures resolving dependencies on
3361 whole SSE registers use APS move to break dependency
3362 chains, otherwise use short move to avoid extra work.
3364 Do the same for architectures resolving dependencies on
3365 the parts. While in DF mode it is better to always handle
3366 just register parts, the SF mode is different due to lack
3367 of instructions to load just part of the register. It is
3368 better to maintain the whole registers in single format
3369 to avoid problems on using packed logical operations. */
3370 (eq_attr "alternative" "6")
3371 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3372 (match_operand 1 "ext_sse_reg_operand"))
3373 (const_string "V16SF")
3374 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3375 (match_test "TARGET_SSE_SPLIT_REGS"))
3376 (const_string "V4SF")
3378 (const_string "SF"))
3380 (const_string "SF")))])
3383 [(set (match_operand 0 "any_fp_register_operand")
3384 (match_operand 1 "memory_operand"))]
3386 && (GET_MODE (operands[0]) == TFmode
3387 || GET_MODE (operands[0]) == XFmode
3388 || GET_MODE (operands[0]) == DFmode
3389 || GET_MODE (operands[0]) == SFmode)
3390 && (operands[2] = find_constant_src (insn))"
3391 [(set (match_dup 0) (match_dup 2))]
3393 rtx c = operands[2];
3394 int r = REGNO (operands[0]);
3396 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3397 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3402 [(set (match_operand 0 "any_fp_register_operand")
3403 (float_extend (match_operand 1 "memory_operand")))]
3405 && (GET_MODE (operands[0]) == TFmode
3406 || GET_MODE (operands[0]) == XFmode
3407 || GET_MODE (operands[0]) == DFmode)
3408 && (operands[2] = find_constant_src (insn))"
3409 [(set (match_dup 0) (match_dup 2))]
3411 rtx c = operands[2];
3412 int r = REGNO (operands[0]);
3414 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3415 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3419 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3421 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3422 (match_operand:X87MODEF 1 "immediate_operand"))]
3424 && (standard_80387_constant_p (operands[1]) == 8
3425 || standard_80387_constant_p (operands[1]) == 9)"
3426 [(set (match_dup 0)(match_dup 1))
3428 (neg:X87MODEF (match_dup 0)))]
3432 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3433 if (real_isnegzero (&r))
3434 operands[1] = CONST0_RTX (<MODE>mode);
3436 operands[1] = CONST1_RTX (<MODE>mode);
3440 [(set (match_operand 0 "nonimmediate_operand")
3441 (match_operand 1 "general_operand"))]
3443 && (GET_MODE (operands[0]) == TFmode
3444 || GET_MODE (operands[0]) == XFmode
3445 || GET_MODE (operands[0]) == DFmode)
3446 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3448 "ix86_split_long_move (operands); DONE;")
3450 (define_insn "swapxf"
3451 [(set (match_operand:XF 0 "register_operand" "+f")
3452 (match_operand:XF 1 "register_operand" "+f"))
3457 if (STACK_TOP_P (operands[0]))
3462 [(set_attr "type" "fxch")
3463 (set_attr "mode" "XF")])
3465 (define_insn "*swap<mode>"
3466 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3467 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3470 "TARGET_80387 || reload_completed"
3472 if (STACK_TOP_P (operands[0]))
3477 [(set_attr "type" "fxch")
3478 (set_attr "mode" "<MODE>")])
3480 ;; Zero extension instructions
3482 (define_expand "zero_extendsidi2"
3483 [(set (match_operand:DI 0 "nonimmediate_operand")
3484 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3486 (define_insn "*zero_extendsidi2"
3487 [(set (match_operand:DI 0 "nonimmediate_operand"
3488 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3490 (match_operand:SI 1 "x86_64_zext_operand"
3491 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3494 switch (get_attr_type (insn))
3497 if (ix86_use_lea_for_mov (insn, operands))
3498 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3500 return "mov{l}\t{%1, %k0|%k0, %1}";
3506 return "movd\t{%1, %0|%0, %1}";
3509 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3512 if (GENERAL_REG_P (operands[0]))
3513 return "%vmovd\t{%1, %k0|%k0, %1}";
3515 return "%vmovd\t{%1, %0|%0, %1}";
3522 (cond [(eq_attr "alternative" "0,1,2")
3523 (const_string "nox64")
3524 (eq_attr "alternative" "3,7")
3525 (const_string "x64")
3526 (eq_attr "alternative" "8")
3527 (const_string "x64_sse4")
3528 (eq_attr "alternative" "10")
3529 (const_string "sse2")
3531 (const_string "*")))
3533 (cond [(eq_attr "alternative" "0,1,2,4")
3534 (const_string "multi")
3535 (eq_attr "alternative" "5,6")
3536 (const_string "mmxmov")
3537 (eq_attr "alternative" "7,9,10")
3538 (const_string "ssemov")
3539 (eq_attr "alternative" "8")
3540 (const_string "sselog1")
3542 (const_string "imovx")))
3543 (set (attr "prefix_extra")
3544 (if_then_else (eq_attr "alternative" "8")
3546 (const_string "*")))
3547 (set (attr "length_immediate")
3548 (if_then_else (eq_attr "alternative" "8")
3550 (const_string "*")))
3551 (set (attr "prefix")
3552 (if_then_else (eq_attr "type" "ssemov,sselog1")
3553 (const_string "maybe_vex")
3554 (const_string "orig")))
3555 (set (attr "prefix_0f")
3556 (if_then_else (eq_attr "type" "imovx")
3558 (const_string "*")))
3560 (cond [(eq_attr "alternative" "5,6")
3562 (eq_attr "alternative" "7,8,9")
3565 (const_string "SI")))])
3568 [(set (match_operand:DI 0 "memory_operand")
3569 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3571 [(set (match_dup 4) (const_int 0))]
3572 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3575 [(set (match_operand:DI 0 "register_operand")
3576 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3577 "!TARGET_64BIT && reload_completed
3578 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3579 && true_regnum (operands[0]) == true_regnum (operands[1])"
3580 [(set (match_dup 4) (const_int 0))]
3581 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3584 [(set (match_operand:DI 0 "nonimmediate_operand")
3585 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3586 "!TARGET_64BIT && reload_completed
3587 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3588 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3589 [(set (match_dup 3) (match_dup 1))
3590 (set (match_dup 4) (const_int 0))]
3591 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3593 (define_insn "zero_extend<mode>di2"
3594 [(set (match_operand:DI 0 "register_operand" "=r")
3596 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3598 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3599 [(set_attr "type" "imovx")
3600 (set_attr "mode" "SI")])
3602 (define_expand "zero_extend<mode>si2"
3603 [(set (match_operand:SI 0 "register_operand")
3604 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3607 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3609 operands[1] = force_reg (<MODE>mode, operands[1]);
3610 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3615 (define_insn_and_split "zero_extend<mode>si2_and"
3616 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3618 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3619 (clobber (reg:CC FLAGS_REG))]
3620 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3622 "&& reload_completed"
3623 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3624 (clobber (reg:CC FLAGS_REG))])]
3626 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3628 ix86_expand_clear (operands[0]);
3630 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3631 emit_insn (gen_movstrict<mode>
3632 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3636 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3638 [(set_attr "type" "alu1")
3639 (set_attr "mode" "SI")])
3641 (define_insn "*zero_extend<mode>si2"
3642 [(set (match_operand:SI 0 "register_operand" "=r")
3644 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3645 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3646 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3647 [(set_attr "type" "imovx")
3648 (set_attr "mode" "SI")])
3650 (define_expand "zero_extendqihi2"
3651 [(set (match_operand:HI 0 "register_operand")
3652 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3655 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3657 operands[1] = force_reg (QImode, operands[1]);
3658 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3663 (define_insn_and_split "zero_extendqihi2_and"
3664 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3665 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3666 (clobber (reg:CC FLAGS_REG))]
3667 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3669 "&& reload_completed"
3670 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3671 (clobber (reg:CC FLAGS_REG))])]
3673 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3675 ix86_expand_clear (operands[0]);
3677 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3678 emit_insn (gen_movstrictqi
3679 (gen_lowpart (QImode, operands[0]), operands[1]));
3683 operands[0] = gen_lowpart (SImode, operands[0]);
3685 [(set_attr "type" "alu1")
3686 (set_attr "mode" "SI")])
3688 ; zero extend to SImode to avoid partial register stalls
3689 (define_insn "*zero_extendqihi2"
3690 [(set (match_operand:HI 0 "register_operand" "=r")
3691 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3692 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3693 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")])
3697 ;; Sign extension instructions
3699 (define_expand "extendsidi2"
3700 [(set (match_operand:DI 0 "register_operand")
3701 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3706 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3711 (define_insn "*extendsidi2_rex64"
3712 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3713 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3717 movs{lq|x}\t{%1, %0|%0, %1}"
3718 [(set_attr "type" "imovx")
3719 (set_attr "mode" "DI")
3720 (set_attr "prefix_0f" "0")
3721 (set_attr "modrm" "0,1")])
3723 (define_insn "extendsidi2_1"
3724 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3725 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3726 (clobber (reg:CC FLAGS_REG))
3727 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3731 ;; Split the memory case. If the source register doesn't die, it will stay
3732 ;; this way, if it does die, following peephole2s take care of it.
3734 [(set (match_operand:DI 0 "memory_operand")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_operand:SI 2 "register_operand"))]
3741 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3743 emit_move_insn (operands[3], operands[1]);
3745 /* Generate a cltd if possible and doing so it profitable. */
3746 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3747 && true_regnum (operands[1]) == AX_REG
3748 && true_regnum (operands[2]) == DX_REG)
3750 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3754 emit_move_insn (operands[2], operands[1]);
3755 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3757 emit_move_insn (operands[4], operands[2]);
3761 ;; Peepholes for the case where the source register does die, after
3762 ;; being split with the above splitter.
3764 [(set (match_operand:SI 0 "memory_operand")
3765 (match_operand:SI 1 "register_operand"))
3766 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3767 (parallel [(set (match_dup 2)
3768 (ashiftrt:SI (match_dup 2) (const_int 31)))
3769 (clobber (reg:CC FLAGS_REG))])
3770 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3771 "REGNO (operands[1]) != REGNO (operands[2])
3772 && peep2_reg_dead_p (2, operands[1])
3773 && peep2_reg_dead_p (4, operands[2])
3774 && !reg_mentioned_p (operands[2], operands[3])"
3775 [(set (match_dup 0) (match_dup 1))
3776 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3777 (clobber (reg:CC FLAGS_REG))])
3778 (set (match_dup 3) (match_dup 1))])
3781 [(set (match_operand:SI 0 "memory_operand")
3782 (match_operand:SI 1 "register_operand"))
3783 (parallel [(set (match_operand:SI 2 "register_operand")
3784 (ashiftrt:SI (match_dup 1) (const_int 31)))
3785 (clobber (reg:CC FLAGS_REG))])
3786 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3787 "/* cltd is shorter than sarl $31, %eax */
3788 !optimize_function_for_size_p (cfun)
3789 && true_regnum (operands[1]) == AX_REG
3790 && true_regnum (operands[2]) == DX_REG
3791 && peep2_reg_dead_p (2, operands[1])
3792 && peep2_reg_dead_p (3, operands[2])
3793 && !reg_mentioned_p (operands[2], operands[3])"
3794 [(set (match_dup 0) (match_dup 1))
3795 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3796 (clobber (reg:CC FLAGS_REG))])
3797 (set (match_dup 3) (match_dup 1))])
3799 ;; Extend to register case. Optimize case where source and destination
3800 ;; registers match and cases where we can use cltd.
3802 [(set (match_operand:DI 0 "register_operand")
3803 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3804 (clobber (reg:CC FLAGS_REG))
3805 (clobber (match_scratch:SI 2))]
3809 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3811 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3812 emit_move_insn (operands[3], operands[1]);
3814 /* Generate a cltd if possible and doing so it profitable. */
3815 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3816 && true_regnum (operands[3]) == AX_REG
3817 && true_regnum (operands[4]) == DX_REG)
3819 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3823 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3824 emit_move_insn (operands[4], operands[1]);
3826 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3830 (define_insn "extend<mode>di2"
3831 [(set (match_operand:DI 0 "register_operand" "=r")
3833 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3835 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "DI")])
3839 (define_insn "extendhisi2"
3840 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3844 switch (get_attr_prefix_0f (insn))
3847 return "{cwtl|cwde}";
3849 return "movs{wl|x}\t{%1, %0|%0, %1}";
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "SI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3859 (const_string "1")))
3861 (if_then_else (eq_attr "prefix_0f" "0")
3863 (const_string "1")))])
3865 (define_insn "*extendhisi2_zext"
3866 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3869 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3872 switch (get_attr_prefix_0f (insn))
3875 return "{cwtl|cwde}";
3877 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3880 [(set_attr "type" "imovx")
3881 (set_attr "mode" "SI")
3882 (set (attr "prefix_0f")
3883 ;; movsx is short decodable while cwtl is vector decoded.
3884 (if_then_else (and (eq_attr "cpu" "!k6")
3885 (eq_attr "alternative" "0"))
3887 (const_string "1")))
3889 (if_then_else (eq_attr "prefix_0f" "0")
3891 (const_string "1")))])
3893 (define_insn "extendqisi2"
3894 [(set (match_operand:SI 0 "register_operand" "=r")
3895 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3897 "movs{bl|x}\t{%1, %0|%0, %1}"
3898 [(set_attr "type" "imovx")
3899 (set_attr "mode" "SI")])
3901 (define_insn "*extendqisi2_zext"
3902 [(set (match_operand:DI 0 "register_operand" "=r")
3904 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3906 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3907 [(set_attr "type" "imovx")
3908 (set_attr "mode" "SI")])
3910 (define_insn "extendqihi2"
3911 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3912 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3915 switch (get_attr_prefix_0f (insn))
3918 return "{cbtw|cbw}";
3920 return "movs{bw|x}\t{%1, %0|%0, %1}";
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "HI")
3925 (set (attr "prefix_0f")
3926 ;; movsx is short decodable while cwtl is vector decoded.
3927 (if_then_else (and (eq_attr "cpu" "!k6")
3928 (eq_attr "alternative" "0"))
3930 (const_string "1")))
3932 (if_then_else (eq_attr "prefix_0f" "0")
3934 (const_string "1")))])
3936 ;; Conversions between float and double.
3938 ;; These are all no-ops in the model used for the 80387.
3939 ;; So just emit moves.
3941 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3943 [(set (match_operand:DF 0 "push_operand")
3944 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3946 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3947 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3950 [(set (match_operand:XF 0 "push_operand")
3951 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3953 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3954 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3955 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3957 (define_expand "extendsfdf2"
3958 [(set (match_operand:DF 0 "nonimmediate_operand")
3959 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3960 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3962 /* ??? Needed for compress_float_constant since all fp constants
3963 are TARGET_LEGITIMATE_CONSTANT_P. */
3964 if (CONST_DOUBLE_P (operands[1]))
3966 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3967 && standard_80387_constant_p (operands[1]) > 0)
3969 operands[1] = simplify_const_unary_operation
3970 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3971 emit_move_insn_1 (operands[0], operands[1]);
3974 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3978 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3980 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3982 We do the conversion post reload to avoid producing of 128bit spills
3983 that might lead to ICE on 32bit target. The sequence unlikely combine
3986 [(set (match_operand:DF 0 "register_operand")
3988 (match_operand:SF 1 "nonimmediate_operand")))]
3989 "TARGET_USE_VECTOR_FP_CONVERTS
3990 && optimize_insn_for_speed_p ()
3991 && reload_completed && SSE_REG_P (operands[0])
3992 && (!EXT_REX_SSE_REG_P (operands[0])
3993 || TARGET_AVX512VL)"
3998 (parallel [(const_int 0) (const_int 1)]))))]
4000 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4001 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4002 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4003 Try to avoid move when unpacking can be done in source. */
4004 if (REG_P (operands[1]))
4006 /* If it is unsafe to overwrite upper half of source, we need
4007 to move to destination and unpack there. */
4008 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4009 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4010 && true_regnum (operands[0]) != true_regnum (operands[1]))
4012 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4013 emit_move_insn (tmp, operands[1]);
4016 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4017 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4021 emit_insn (gen_vec_setv4sf_0 (operands[3],
4022 CONST0_RTX (V4SFmode), operands[1]));
4025 ;; It's more profitable to split and then extend in the same register.
4027 [(set (match_operand:DF 0 "register_operand")
4029 (match_operand:SF 1 "memory_operand")))]
4030 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4031 && optimize_insn_for_speed_p ()
4032 && SSE_REG_P (operands[0])"
4033 [(set (match_dup 2) (match_dup 1))
4034 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4035 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4037 (define_insn "*extendsfdf2_mixed"
4038 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4040 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4043 switch (which_alternative)
4047 return output_387_reg_move (insn, operands);
4050 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4056 [(set_attr "type" "fmov,fmov,ssecvt")
4057 (set_attr "prefix" "orig,orig,maybe_vex")
4058 (set_attr "mode" "SF,XF,DF")
4059 (set (attr "enabled")
4060 (cond [(eq_attr "alternative" "0,1")
4061 (symbol_ref "TARGET_MIX_SSE_I387")
4063 (symbol_ref "true")))])
4065 (define_insn "*extendsfdf2_i387"
4066 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4067 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4069 "* return output_387_reg_move (insn, operands);"
4070 [(set_attr "type" "fmov")
4071 (set_attr "mode" "SF,XF")])
4073 (define_expand "extend<mode>xf2"
4074 [(set (match_operand:XF 0 "nonimmediate_operand")
4075 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4078 /* ??? Needed for compress_float_constant since all fp constants
4079 are TARGET_LEGITIMATE_CONSTANT_P. */
4080 if (CONST_DOUBLE_P (operands[1]))
4082 if (standard_80387_constant_p (operands[1]) > 0)
4084 operands[1] = simplify_const_unary_operation
4085 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4086 emit_move_insn_1 (operands[0], operands[1]);
4089 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4093 (define_insn "*extend<mode>xf2_i387"
4094 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4096 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4098 "* return output_387_reg_move (insn, operands);"
4099 [(set_attr "type" "fmov")
4100 (set_attr "mode" "<MODE>,XF")])
4102 ;; %%% This seems bad bad news.
4103 ;; This cannot output into an f-reg because there is no way to be sure
4104 ;; of truncating in that case. Otherwise this is just like a simple move
4105 ;; insn. So we pretend we can output to a reg in order to get better
4106 ;; register preferencing, but we really use a stack slot.
4108 ;; Conversion from DFmode to SFmode.
4110 (define_expand "truncdfsf2"
4111 [(set (match_operand:SF 0 "nonimmediate_operand")
4113 (match_operand:DF 1 "nonimmediate_operand")))]
4114 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4116 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4118 else if (flag_unsafe_math_optimizations)
4122 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4123 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4128 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4130 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4132 We do the conversion post reload to avoid producing of 128bit spills
4133 that might lead to ICE on 32bit target. The sequence unlikely combine
4136 [(set (match_operand:SF 0 "register_operand")
4138 (match_operand:DF 1 "nonimmediate_operand")))]
4139 "TARGET_USE_VECTOR_FP_CONVERTS
4140 && optimize_insn_for_speed_p ()
4141 && reload_completed && SSE_REG_P (operands[0])
4142 && (!EXT_REX_SSE_REG_P (operands[0])
4143 || TARGET_AVX512VL)"
4146 (float_truncate:V2SF
4150 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4151 operands[3] = CONST0_RTX (V2SFmode);
4152 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4153 /* Use movsd for loading from memory, unpcklpd for registers.
4154 Try to avoid move when unpacking can be done in source, or SSE3
4155 movddup is available. */
4156 if (REG_P (operands[1]))
4159 && true_regnum (operands[0]) != true_regnum (operands[1])
4160 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4161 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4163 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4164 emit_move_insn (tmp, operands[1]);
4167 else if (!TARGET_SSE3)
4168 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4169 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4172 emit_insn (gen_sse2_loadlpd (operands[4],
4173 CONST0_RTX (V2DFmode), operands[1]));
4176 ;; It's more profitable to split and then extend in the same register.
4178 [(set (match_operand:SF 0 "register_operand")
4180 (match_operand:DF 1 "memory_operand")))]
4181 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4182 && optimize_insn_for_speed_p ()
4183 && SSE_REG_P (operands[0])"
4184 [(set (match_dup 2) (match_dup 1))
4185 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4186 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4188 (define_expand "truncdfsf2_with_temp"
4189 [(parallel [(set (match_operand:SF 0)
4190 (float_truncate:SF (match_operand:DF 1)))
4191 (clobber (match_operand:SF 2))])])
4193 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4194 ;; because nothing we do there is unsafe.
4195 (define_insn "*truncdfsf_fast_mixed"
4196 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4198 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4199 "TARGET_SSE2 && TARGET_SSE_MATH"
4201 switch (which_alternative)
4204 return output_387_reg_move (insn, operands);
4206 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4211 [(set_attr "type" "fmov,ssecvt")
4212 (set_attr "prefix" "orig,maybe_vex")
4213 (set_attr "mode" "SF")
4214 (set (attr "enabled")
4215 (cond [(eq_attr "alternative" "0")
4216 (symbol_ref "TARGET_MIX_SSE_I387
4217 && flag_unsafe_math_optimizations")
4219 (symbol_ref "true")))])
4221 (define_insn "*truncdfsf_fast_i387"
4222 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4224 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4225 "TARGET_80387 && flag_unsafe_math_optimizations"
4226 "* return output_387_reg_move (insn, operands);"
4227 [(set_attr "type" "fmov")
4228 (set_attr "mode" "SF")])
4230 (define_insn "*truncdfsf_mixed"
4231 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4233 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4234 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4235 "TARGET_MIX_SSE_I387"
4237 switch (which_alternative)
4240 return output_387_reg_move (insn, operands);
4242 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4248 [(set_attr "isa" "*,sse2,*,*,*")
4249 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4250 (set_attr "unit" "*,*,i387,i387,i387")
4251 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_i387"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4257 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4258 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4261 switch (which_alternative)
4264 return output_387_reg_move (insn, operands);
4270 [(set_attr "type" "fmov,multi,multi,multi")
4271 (set_attr "unit" "*,i387,i387,i387")
4272 (set_attr "mode" "SF")])
4274 (define_insn "*truncdfsf2_i387_1"
4275 [(set (match_operand:SF 0 "memory_operand" "=m")
4277 (match_operand:DF 1 "register_operand" "f")))]
4279 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4280 && !TARGET_MIX_SSE_I387"
4281 "* return output_387_reg_move (insn, operands);"
4282 [(set_attr "type" "fmov")
4283 (set_attr "mode" "SF")])
4286 [(set (match_operand:SF 0 "register_operand")
4288 (match_operand:DF 1 "fp_register_operand")))
4289 (clobber (match_operand 2))]
4291 [(set (match_dup 2) (match_dup 1))
4292 (set (match_dup 0) (match_dup 2))]
4293 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4295 ;; Conversion from XFmode to {SF,DF}mode
4297 (define_expand "truncxf<mode>2"
4298 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4299 (float_truncate:MODEF
4300 (match_operand:XF 1 "register_operand")))
4301 (clobber (match_dup 2))])]
4304 if (flag_unsafe_math_optimizations)
4306 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4307 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4308 if (reg != operands[0])
4309 emit_move_insn (operands[0], reg);
4313 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4316 (define_insn "*truncxfsf2_mixed"
4317 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4319 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4320 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4323 gcc_assert (!which_alternative);
4324 return output_387_reg_move (insn, operands);
4326 [(set_attr "type" "fmov,multi,multi,multi")
4327 (set_attr "unit" "*,i387,i387,i387")
4328 (set_attr "mode" "SF")])
4330 (define_insn "*truncxfdf2_mixed"
4331 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4333 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4334 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4337 gcc_assert (!which_alternative);
4338 return output_387_reg_move (insn, operands);
4340 [(set_attr "isa" "*,*,sse2,*")
4341 (set_attr "type" "fmov,multi,multi,multi")
4342 (set_attr "unit" "*,i387,i387,i387")
4343 (set_attr "mode" "DF")])
4345 (define_insn "truncxf<mode>2_i387_noop"
4346 [(set (match_operand:MODEF 0 "register_operand" "=f")
4347 (float_truncate:MODEF
4348 (match_operand:XF 1 "register_operand" "f")))]
4349 "TARGET_80387 && flag_unsafe_math_optimizations"
4350 "* return output_387_reg_move (insn, operands);"
4351 [(set_attr "type" "fmov")
4352 (set_attr "mode" "<MODE>")])
4354 (define_insn "*truncxf<mode>2_i387"
4355 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4356 (float_truncate:MODEF
4357 (match_operand:XF 1 "register_operand" "f")))]
4359 "* return output_387_reg_move (insn, operands);"
4360 [(set_attr "type" "fmov")
4361 (set_attr "mode" "<MODE>")])
4364 [(set (match_operand:MODEF 0 "register_operand")
4365 (float_truncate:MODEF
4366 (match_operand:XF 1 "register_operand")))
4367 (clobber (match_operand:MODEF 2 "memory_operand"))]
4368 "TARGET_80387 && reload_completed"
4369 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4370 (set (match_dup 0) (match_dup 2))])
4373 [(set (match_operand:MODEF 0 "memory_operand")
4374 (float_truncate:MODEF
4375 (match_operand:XF 1 "register_operand")))
4376 (clobber (match_operand:MODEF 2 "memory_operand"))]
4378 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4380 ;; Signed conversion to DImode.
4382 (define_expand "fix_truncxfdi2"
4383 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4384 (fix:DI (match_operand:XF 1 "register_operand")))
4385 (clobber (reg:CC FLAGS_REG))])]
4390 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4395 (define_expand "fix_trunc<mode>di2"
4396 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4397 (fix:DI (match_operand:MODEF 1 "register_operand")))
4398 (clobber (reg:CC FLAGS_REG))])]
4399 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4402 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4404 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4407 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4409 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4410 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4411 if (out != operands[0])
4412 emit_move_insn (operands[0], out);
4417 ;; Signed conversion to SImode.
4419 (define_expand "fix_truncxfsi2"
4420 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4421 (fix:SI (match_operand:XF 1 "register_operand")))
4422 (clobber (reg:CC FLAGS_REG))])]
4427 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4432 (define_expand "fix_trunc<mode>si2"
4433 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4434 (fix:SI (match_operand:MODEF 1 "register_operand")))
4435 (clobber (reg:CC FLAGS_REG))])]
4436 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4439 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4441 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4444 if (SSE_FLOAT_MODE_P (<MODE>mode))
4446 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4447 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4448 if (out != operands[0])
4449 emit_move_insn (operands[0], out);
4454 ;; Signed conversion to HImode.
4456 (define_expand "fix_trunc<mode>hi2"
4457 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4458 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4459 (clobber (reg:CC FLAGS_REG))])]
4461 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4465 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4470 ;; Unsigned conversion to SImode.
4472 (define_expand "fixuns_trunc<mode>si2"
4474 [(set (match_operand:SI 0 "register_operand")
4476 (match_operand:MODEF 1 "nonimmediate_operand")))
4478 (clobber (match_scratch:<ssevecmode> 3))
4479 (clobber (match_scratch:<ssevecmode> 4))])]
4480 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4482 machine_mode mode = <MODE>mode;
4483 machine_mode vecmode = <ssevecmode>mode;
4484 REAL_VALUE_TYPE TWO31r;
4487 if (optimize_insn_for_size_p ())
4490 real_ldexp (&TWO31r, &dconst1, 31);
4491 two31 = const_double_from_real_value (TWO31r, mode);
4492 two31 = ix86_build_const_vector (vecmode, true, two31);
4493 operands[2] = force_reg (vecmode, two31);
4496 (define_insn_and_split "*fixuns_trunc<mode>_1"
4497 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4499 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4500 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4501 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4502 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4503 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4504 && optimize_function_for_speed_p (cfun)"
4506 "&& reload_completed"
4509 ix86_split_convert_uns_si_sse (operands);
4513 ;; Unsigned conversion to HImode.
4514 ;; Without these patterns, we'll try the unsigned SI conversion which
4515 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4517 (define_expand "fixuns_trunc<mode>hi2"
4519 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4520 (set (match_operand:HI 0 "nonimmediate_operand")
4521 (subreg:HI (match_dup 2) 0))]
4522 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4523 "operands[2] = gen_reg_rtx (SImode);")
4525 ;; When SSE is available, it is always faster to use it!
4526 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4527 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4528 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4529 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4530 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4531 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4532 [(set_attr "type" "sseicvt")
4533 (set_attr "prefix" "maybe_vex")
4534 (set (attr "prefix_rex")
4536 (match_test "<SWI48:MODE>mode == DImode")
4538 (const_string "*")))
4539 (set_attr "mode" "<MODEF:MODE>")
4540 (set_attr "athlon_decode" "double,vector")
4541 (set_attr "amdfam10_decode" "double,double")
4542 (set_attr "bdver1_decode" "double,double")])
4544 ;; Avoid vector decoded forms of the instruction.
4546 [(match_scratch:MODEF 2 "x")
4547 (set (match_operand:SWI48 0 "register_operand")
4548 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4549 "TARGET_AVOID_VECTOR_DECODE
4550 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4551 && optimize_insn_for_speed_p ()"
4552 [(set (match_dup 2) (match_dup 1))
4553 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4555 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4556 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4557 (fix:SWI248x (match_operand 1 "register_operand")))]
4558 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4560 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561 && (TARGET_64BIT || <MODE>mode != DImode))
4563 && can_create_pseudo_p ()"
4568 if (memory_operand (operands[0], VOIDmode))
4569 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4572 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4573 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4579 [(set_attr "type" "fisttp")
4580 (set_attr "mode" "<MODE>")])
4582 (define_insn "fix_trunc<mode>_i387_fisttp"
4583 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4584 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4585 (clobber (match_scratch:XF 2 "=&1f"))]
4586 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4588 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4589 && (TARGET_64BIT || <MODE>mode != DImode))
4590 && TARGET_SSE_MATH)"
4591 "* return output_fix_trunc (insn, operands, true);"
4592 [(set_attr "type" "fisttp")
4593 (set_attr "mode" "<MODE>")])
4595 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4596 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4597 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4598 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4599 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && (TARGET_64BIT || <MODE>mode != DImode))
4604 && TARGET_SSE_MATH)"
4606 [(set_attr "type" "fisttp")
4607 (set_attr "mode" "<MODE>")])
4610 [(set (match_operand:SWI248x 0 "register_operand")
4611 (fix:SWI248x (match_operand 1 "register_operand")))
4612 (clobber (match_operand:SWI248x 2 "memory_operand"))
4613 (clobber (match_scratch 3))]
4615 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4616 (clobber (match_dup 3))])
4617 (set (match_dup 0) (match_dup 2))])
4620 [(set (match_operand:SWI248x 0 "memory_operand")
4621 (fix:SWI248x (match_operand 1 "register_operand")))
4622 (clobber (match_operand:SWI248x 2 "memory_operand"))
4623 (clobber (match_scratch 3))]
4625 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4626 (clobber (match_dup 3))])])
4628 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4629 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4630 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4631 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4632 ;; function in i386.c.
4633 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4634 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4635 (fix:SWI248x (match_operand 1 "register_operand")))
4636 (clobber (reg:CC FLAGS_REG))]
4637 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4640 && (TARGET_64BIT || <MODE>mode != DImode))
4641 && can_create_pseudo_p ()"
4646 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4648 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4649 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4650 if (memory_operand (operands[0], VOIDmode))
4651 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4652 operands[2], operands[3]));
4655 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4656 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4657 operands[2], operands[3],
4662 [(set_attr "type" "fistp")
4663 (set_attr "i387_cw" "trunc")
4664 (set_attr "mode" "<MODE>")])
4666 (define_insn "fix_truncdi_i387"
4667 [(set (match_operand:DI 0 "memory_operand" "=m")
4668 (fix:DI (match_operand 1 "register_operand" "f")))
4669 (use (match_operand:HI 2 "memory_operand" "m"))
4670 (use (match_operand:HI 3 "memory_operand" "m"))
4671 (clobber (match_scratch:XF 4 "=&1f"))]
4672 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4675 "* return output_fix_trunc (insn, operands, false);"
4676 [(set_attr "type" "fistp")
4677 (set_attr "i387_cw" "trunc")
4678 (set_attr "mode" "DI")])
4680 (define_insn "fix_truncdi_i387_with_temp"
4681 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4682 (fix:DI (match_operand 1 "register_operand" "f,f")))
4683 (use (match_operand:HI 2 "memory_operand" "m,m"))
4684 (use (match_operand:HI 3 "memory_operand" "m,m"))
4685 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4686 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4687 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4689 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4691 [(set_attr "type" "fistp")
4692 (set_attr "i387_cw" "trunc")
4693 (set_attr "mode" "DI")])
4696 [(set (match_operand:DI 0 "register_operand")
4697 (fix:DI (match_operand 1 "register_operand")))
4698 (use (match_operand:HI 2 "memory_operand"))
4699 (use (match_operand:HI 3 "memory_operand"))
4700 (clobber (match_operand:DI 4 "memory_operand"))
4701 (clobber (match_scratch 5))]
4703 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4706 (clobber (match_dup 5))])
4707 (set (match_dup 0) (match_dup 4))])
4710 [(set (match_operand:DI 0 "memory_operand")
4711 (fix:DI (match_operand 1 "register_operand")))
4712 (use (match_operand:HI 2 "memory_operand"))
4713 (use (match_operand:HI 3 "memory_operand"))
4714 (clobber (match_operand:DI 4 "memory_operand"))
4715 (clobber (match_scratch 5))]
4717 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4720 (clobber (match_dup 5))])])
4722 (define_insn "fix_trunc<mode>_i387"
4723 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4724 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4725 (use (match_operand:HI 2 "memory_operand" "m"))
4726 (use (match_operand:HI 3 "memory_operand" "m"))]
4727 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4729 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4730 "* return output_fix_trunc (insn, operands, false);"
4731 [(set_attr "type" "fistp")
4732 (set_attr "i387_cw" "trunc")
4733 (set_attr "mode" "<MODE>")])
4735 (define_insn "fix_trunc<mode>_i387_with_temp"
4736 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4737 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4738 (use (match_operand:HI 2 "memory_operand" "m,m"))
4739 (use (match_operand:HI 3 "memory_operand" "m,m"))
4740 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4741 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4743 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4745 [(set_attr "type" "fistp")
4746 (set_attr "i387_cw" "trunc")
4747 (set_attr "mode" "<MODE>")])
4750 [(set (match_operand:SWI24 0 "register_operand")
4751 (fix:SWI24 (match_operand 1 "register_operand")))
4752 (use (match_operand:HI 2 "memory_operand"))
4753 (use (match_operand:HI 3 "memory_operand"))
4754 (clobber (match_operand:SWI24 4 "memory_operand"))]
4756 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4758 (use (match_dup 3))])
4759 (set (match_dup 0) (match_dup 4))])
4762 [(set (match_operand:SWI24 0 "memory_operand")
4763 (fix:SWI24 (match_operand 1 "register_operand")))
4764 (use (match_operand:HI 2 "memory_operand"))
4765 (use (match_operand:HI 3 "memory_operand"))
4766 (clobber (match_operand:SWI24 4 "memory_operand"))]
4768 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4770 (use (match_dup 3))])])
4772 (define_insn "x86_fnstcw_1"
4773 [(set (match_operand:HI 0 "memory_operand" "=m")
4774 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4777 [(set (attr "length")
4778 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4779 (set_attr "mode" "HI")
4780 (set_attr "unit" "i387")
4781 (set_attr "bdver1_decode" "vector")])
4783 (define_insn "x86_fldcw_1"
4784 [(set (reg:HI FPCR_REG)
4785 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4788 [(set (attr "length")
4789 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4790 (set_attr "mode" "HI")
4791 (set_attr "unit" "i387")
4792 (set_attr "athlon_decode" "vector")
4793 (set_attr "amdfam10_decode" "vector")
4794 (set_attr "bdver1_decode" "vector")])
4796 ;; Conversion between fixed point and floating point.
4798 ;; Even though we only accept memory inputs, the backend _really_
4799 ;; wants to be able to do this between registers. Thankfully, LRA
4800 ;; will fix this up for us during register allocation.
4802 (define_insn "floathi<mode>2"
4803 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4804 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4807 || TARGET_MIX_SSE_I387)"
4809 [(set_attr "type" "fmov")
4810 (set_attr "mode" "<MODE>")
4811 (set_attr "fp_int_src" "true")])
4813 (define_insn "float<SWI48x:mode>xf2"
4814 [(set (match_operand:XF 0 "register_operand" "=f")
4815 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4818 [(set_attr "type" "fmov")
4819 (set_attr "mode" "XF")
4820 (set_attr "fp_int_src" "true")])
4822 (define_expand "float<SWI48:mode><MODEF:mode>2"
4823 [(set (match_operand:MODEF 0 "register_operand")
4824 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4825 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4827 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4828 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4830 rtx reg = gen_reg_rtx (XFmode);
4831 rtx (*insn)(rtx, rtx);
4833 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4835 if (<MODEF:MODE>mode == SFmode)
4836 insn = gen_truncxfsf2;
4837 else if (<MODEF:MODE>mode == DFmode)
4838 insn = gen_truncxfdf2;
4842 emit_insn (insn (operands[0], reg));
4847 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
4848 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4850 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4851 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4854 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4855 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4856 [(set_attr "type" "fmov,sseicvt,sseicvt")
4857 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4858 (set_attr "mode" "<MODEF:MODE>")
4859 (set (attr "prefix_rex")
4861 (and (eq_attr "prefix" "maybe_vex")
4862 (match_test "<SWI48:MODE>mode == DImode"))
4864 (const_string "*")))
4865 (set_attr "unit" "i387,*,*")
4866 (set_attr "athlon_decode" "*,double,direct")
4867 (set_attr "amdfam10_decode" "*,vector,double")
4868 (set_attr "bdver1_decode" "*,double,direct")
4869 (set_attr "fp_int_src" "true")
4870 (set (attr "enabled")
4871 (cond [(eq_attr "alternative" "0")
4872 (symbol_ref "TARGET_MIX_SSE_I387
4873 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4876 (symbol_ref "true")))
4877 (set (attr "preferred_for_speed")
4878 (cond [(eq_attr "alternative" "1")
4879 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4880 (symbol_ref "true")))])
4882 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4883 [(set (match_operand:MODEF 0 "register_operand" "=f")
4884 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4885 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4887 [(set_attr "type" "fmov")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set_attr "fp_int_src" "true")])
4891 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4892 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4893 ;; alternative in sse2_loadld.
4895 [(set (match_operand:MODEF 0 "register_operand")
4896 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4897 "TARGET_SSE2 && TARGET_SSE_MATH
4898 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4899 && reload_completed && SSE_REG_P (operands[0])
4900 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4901 && (!EXT_REX_SSE_REG_P (operands[0])
4902 || TARGET_AVX512VL)"
4905 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4907 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4909 emit_insn (gen_sse2_loadld (operands[4],
4910 CONST0_RTX (V4SImode), operands[1]));
4912 if (<ssevecmode>mode == V4SFmode)
4913 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4915 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4919 ;; Avoid partial SSE register dependency stalls
4921 [(set (match_operand:MODEF 0 "register_operand")
4922 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4923 "TARGET_SSE2 && TARGET_SSE_MATH
4924 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4925 && optimize_function_for_speed_p (cfun)
4926 && reload_completed && SSE_REG_P (operands[0])
4927 && (!EXT_REX_SSE_REG_P (operands[0])
4928 || TARGET_AVX512VL)"
4931 const machine_mode vmode = <MODEF:ssevecmode>mode;
4932 const machine_mode mode = <MODEF:MODE>mode;
4933 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4935 emit_move_insn (op0, CONST0_RTX (vmode));
4937 t = gen_rtx_FLOAT (mode, operands[1]);
4938 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4939 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4940 emit_insn (gen_rtx_SET (op0, t));
4944 ;; Break partial reg stall for cvtsd2ss.
4947 [(set (match_operand:SF 0 "register_operand")
4949 (match_operand:DF 1 "nonimmediate_operand")))]
4950 "TARGET_SSE2 && TARGET_SSE_MATH
4951 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4952 && optimize_function_for_speed_p (cfun)
4953 && SSE_REG_P (operands[0])
4954 && (!SSE_REG_P (operands[1])
4955 || REGNO (operands[0]) != REGNO (operands[1]))
4956 && (!EXT_REX_SSE_REG_P (operands[0])
4957 || TARGET_AVX512VL)"
4961 (float_truncate:V2SF
4966 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4968 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4970 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4973 ;; Break partial reg stall for cvtss2sd.
4976 [(set (match_operand:DF 0 "register_operand")
4978 (match_operand:SF 1 "nonimmediate_operand")))]
4979 "TARGET_SSE2 && TARGET_SSE_MATH
4980 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4981 && optimize_function_for_speed_p (cfun)
4982 && SSE_REG_P (operands[0])
4983 && (!SSE_REG_P (operands[1])
4984 || REGNO (operands[0]) != REGNO (operands[1]))
4985 && (!EXT_REX_SSE_REG_P (operands[0])
4986 || TARGET_AVX512VL)"
4992 (parallel [(const_int 0) (const_int 1)])))
4996 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4998 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5000 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5003 ;; Avoid store forwarding (partial memory) stall penalty
5004 ;; by passing DImode value through XMM registers. */
5006 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5007 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5009 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5010 (clobber (match_scratch:V4SI 3 "=X,x"))
5011 (clobber (match_scratch:V4SI 4 "=X,x"))
5012 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5013 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5014 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5015 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5017 [(set_attr "type" "multi")
5018 (set_attr "mode" "<X87MODEF:MODE>")
5019 (set_attr "unit" "i387")
5020 (set_attr "fp_int_src" "true")])
5023 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5024 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5025 (clobber (match_scratch:V4SI 3))
5026 (clobber (match_scratch:V4SI 4))
5027 (clobber (match_operand:DI 2 "memory_operand"))]
5028 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5029 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5030 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5031 && reload_completed"
5032 [(set (match_dup 2) (match_dup 3))
5033 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5035 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5036 Assemble the 64-bit DImode value in an xmm register. */
5037 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5038 gen_rtx_SUBREG (SImode, operands[1], 0)));
5039 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5040 gen_rtx_SUBREG (SImode, operands[1], 4)));
5041 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5044 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5048 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5049 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5050 (clobber (match_scratch:V4SI 3))
5051 (clobber (match_scratch:V4SI 4))
5052 (clobber (match_operand:DI 2 "memory_operand"))]
5053 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5054 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5055 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5056 && reload_completed"
5057 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5059 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5060 [(set (match_operand:MODEF 0 "register_operand")
5061 (unsigned_float:MODEF
5062 (match_operand:SWI12 1 "nonimmediate_operand")))]
5064 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5066 operands[1] = convert_to_mode (SImode, operands[1], 1);
5067 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5071 ;; Avoid store forwarding (partial memory) stall penalty by extending
5072 ;; SImode value to DImode through XMM register instead of pushing two
5073 ;; SImode values to stack. Also note that fild loads from memory only.
5075 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5076 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5077 (unsigned_float:X87MODEF
5078 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5079 (clobber (match_scratch:DI 3 "=x"))
5080 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5082 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5083 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5085 "&& reload_completed"
5086 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5087 (set (match_dup 2) (match_dup 3))
5089 (float:X87MODEF (match_dup 2)))]
5091 [(set_attr "type" "multi")
5092 (set_attr "mode" "<MODE>")])
5094 (define_expand "floatunssi<mode>2"
5096 [(set (match_operand:X87MODEF 0 "register_operand")
5097 (unsigned_float:X87MODEF
5098 (match_operand:SI 1 "nonimmediate_operand")))
5099 (clobber (match_scratch:DI 3))
5100 (clobber (match_dup 2))])]
5102 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5103 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5104 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5106 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5108 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5112 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5115 (define_expand "floatunsdisf2"
5116 [(use (match_operand:SF 0 "register_operand"))
5117 (use (match_operand:DI 1 "nonimmediate_operand"))]
5118 "TARGET_64BIT && TARGET_SSE_MATH"
5119 "x86_emit_floatuns (operands); DONE;")
5121 (define_expand "floatunsdidf2"
5122 [(use (match_operand:DF 0 "register_operand"))
5123 (use (match_operand:DI 1 "nonimmediate_operand"))]
5124 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5125 && TARGET_SSE2 && TARGET_SSE_MATH"
5128 x86_emit_floatuns (operands);
5130 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5134 ;; Load effective address instructions
5136 (define_insn_and_split "*lea<mode>"
5137 [(set (match_operand:SWI48 0 "register_operand" "=r")
5138 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5141 if (SImode_address_operand (operands[1], VOIDmode))
5143 gcc_assert (TARGET_64BIT);
5144 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5147 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5149 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5152 machine_mode mode = <MODE>mode;
5155 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5156 change operands[] array behind our back. */
5157 pat = PATTERN (curr_insn);
5159 operands[0] = SET_DEST (pat);
5160 operands[1] = SET_SRC (pat);
5162 /* Emit all operations in SImode for zero-extended addresses. */
5163 if (SImode_address_operand (operands[1], VOIDmode))
5166 ix86_split_lea_for_addr (curr_insn, operands, mode);
5168 /* Zero-extend return register to DImode for zero-extended addresses. */
5169 if (mode != <MODE>mode)
5170 emit_insn (gen_zero_extendsidi2
5171 (operands[0], gen_lowpart (mode, operands[0])));
5175 [(set_attr "type" "lea")
5178 (match_operand 1 "SImode_address_operand")
5180 (const_string "<MODE>")))])
5184 (define_expand "add<mode>3"
5185 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5186 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5187 (match_operand:SDWIM 2 "<general_operand>")))]
5189 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5191 (define_insn_and_split "*add<dwi>3_doubleword"
5192 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5194 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5195 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5196 (clobber (reg:CC FLAGS_REG))]
5197 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5200 [(parallel [(set (reg:CC FLAGS_REG)
5201 (unspec:CC [(match_dup 1) (match_dup 2)]
5204 (plus:DWIH (match_dup 1) (match_dup 2)))])
5205 (parallel [(set (match_dup 3)
5209 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5211 (clobber (reg:CC FLAGS_REG))])]
5212 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5214 (define_insn "*add<mode>3_cc"
5215 [(set (reg:CC FLAGS_REG)
5217 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5218 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5220 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5221 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5222 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5223 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5224 [(set_attr "type" "alu")
5225 (set_attr "mode" "<MODE>")])
5227 (define_insn "addqi3_cc"
5228 [(set (reg:CC FLAGS_REG)
5230 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5231 (match_operand:QI 2 "general_operand" "qn,qm")]
5233 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5234 (plus:QI (match_dup 1) (match_dup 2)))]
5235 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5236 "add{b}\t{%2, %0|%0, %2}"
5237 [(set_attr "type" "alu")
5238 (set_attr "mode" "QI")])
5240 (define_insn "*add<mode>_1"
5241 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5243 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5244 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5245 (clobber (reg:CC FLAGS_REG))]
5246 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5248 switch (get_attr_type (insn))
5254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5255 if (operands[2] == const1_rtx)
5256 return "inc{<imodesuffix>}\t%0";
5259 gcc_assert (operands[2] == constm1_rtx);
5260 return "dec{<imodesuffix>}\t%0";
5264 /* For most processors, ADD is faster than LEA. This alternative
5265 was added to use ADD as much as possible. */
5266 if (which_alternative == 2)
5267 std::swap (operands[1], operands[2]);
5269 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5270 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5271 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5273 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5277 (cond [(eq_attr "alternative" "3")
5278 (const_string "lea")
5279 (match_operand:SWI48 2 "incdec_operand")
5280 (const_string "incdec")
5282 (const_string "alu")))
5283 (set (attr "length_immediate")
5285 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5287 (const_string "*")))
5288 (set_attr "mode" "<MODE>")])
5290 ;; It may seem that nonimmediate operand is proper one for operand 1.
5291 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5292 ;; we take care in ix86_binary_operator_ok to not allow two memory
5293 ;; operands so proper swapping will be done in reload. This allow
5294 ;; patterns constructed from addsi_1 to match.
5296 (define_insn "addsi_1_zext"
5297 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5299 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5300 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5301 (clobber (reg:CC FLAGS_REG))]
5302 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5304 switch (get_attr_type (insn))
5310 if (operands[2] == const1_rtx)
5311 return "inc{l}\t%k0";
5314 gcc_assert (operands[2] == constm1_rtx);
5315 return "dec{l}\t%k0";
5319 /* For most processors, ADD is faster than LEA. This alternative
5320 was added to use ADD as much as possible. */
5321 if (which_alternative == 1)
5322 std::swap (operands[1], operands[2]);
5324 if (x86_maybe_negate_const_int (&operands[2], SImode))
5325 return "sub{l}\t{%2, %k0|%k0, %2}";
5327 return "add{l}\t{%2, %k0|%k0, %2}";
5331 (cond [(eq_attr "alternative" "2")
5332 (const_string "lea")
5333 (match_operand:SI 2 "incdec_operand")
5334 (const_string "incdec")
5336 (const_string "alu")))
5337 (set (attr "length_immediate")
5339 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5341 (const_string "*")))
5342 (set_attr "mode" "SI")])
5344 (define_insn "*addhi_1"
5345 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5346 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5347 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5348 (clobber (reg:CC FLAGS_REG))]
5349 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5351 switch (get_attr_type (insn))
5357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5358 if (operands[2] == const1_rtx)
5359 return "inc{w}\t%0";
5362 gcc_assert (operands[2] == constm1_rtx);
5363 return "dec{w}\t%0";
5367 /* For most processors, ADD is faster than LEA. This alternative
5368 was added to use ADD as much as possible. */
5369 if (which_alternative == 2)
5370 std::swap (operands[1], operands[2]);
5372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373 if (x86_maybe_negate_const_int (&operands[2], HImode))
5374 return "sub{w}\t{%2, %0|%0, %2}";
5376 return "add{w}\t{%2, %0|%0, %2}";
5380 (cond [(eq_attr "alternative" "3")
5381 (const_string "lea")
5382 (match_operand:HI 2 "incdec_operand")
5383 (const_string "incdec")
5385 (const_string "alu")))
5386 (set (attr "length_immediate")
5388 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5390 (const_string "*")))
5391 (set_attr "mode" "HI,HI,HI,SI")])
5393 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5394 (define_insn "*addqi_1"
5395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5396 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5397 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5398 (clobber (reg:CC FLAGS_REG))]
5399 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5401 bool widen = (which_alternative == 3 || which_alternative == 4);
5403 switch (get_attr_type (insn))
5409 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410 if (operands[2] == const1_rtx)
5411 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5414 gcc_assert (operands[2] == constm1_rtx);
5415 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5419 /* For most processors, ADD is faster than LEA. These alternatives
5420 were added to use ADD as much as possible. */
5421 if (which_alternative == 2 || which_alternative == 4)
5422 std::swap (operands[1], operands[2]);
5424 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5425 if (x86_maybe_negate_const_int (&operands[2], QImode))
5428 return "sub{l}\t{%2, %k0|%k0, %2}";
5430 return "sub{b}\t{%2, %0|%0, %2}";
5433 return "add{l}\t{%k2, %k0|%k0, %k2}";
5435 return "add{b}\t{%2, %0|%0, %2}";
5439 (cond [(eq_attr "alternative" "5")
5440 (const_string "lea")
5441 (match_operand:QI 2 "incdec_operand")
5442 (const_string "incdec")
5444 (const_string "alu")))
5445 (set (attr "length_immediate")
5447 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5449 (const_string "*")))
5450 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5452 (define_insn "*addqi_1_slp"
5453 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5454 (plus:QI (match_dup 0)
5455 (match_operand:QI 1 "general_operand" "qn,qm")))
5456 (clobber (reg:CC FLAGS_REG))]
5457 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5458 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5460 switch (get_attr_type (insn))
5463 if (operands[1] == const1_rtx)
5464 return "inc{b}\t%0";
5467 gcc_assert (operands[1] == constm1_rtx);
5468 return "dec{b}\t%0";
5472 if (x86_maybe_negate_const_int (&operands[1], QImode))
5473 return "sub{b}\t{%1, %0|%0, %1}";
5475 return "add{b}\t{%1, %0|%0, %1}";
5479 (if_then_else (match_operand:QI 1 "incdec_operand")
5480 (const_string "incdec")
5481 (const_string "alu1")))
5482 (set (attr "memory")
5483 (if_then_else (match_operand 1 "memory_operand")
5484 (const_string "load")
5485 (const_string "none")))
5486 (set_attr "mode" "QI")])
5488 ;; Split non destructive adds if we cannot use lea.
5490 [(set (match_operand:SWI48 0 "register_operand")
5491 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5492 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5493 (clobber (reg:CC FLAGS_REG))]
5494 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5495 [(set (match_dup 0) (match_dup 1))
5496 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5497 (clobber (reg:CC FLAGS_REG))])])
5499 ;; Convert add to the lea pattern to avoid flags dependency.
5501 [(set (match_operand:SWI 0 "register_operand")
5502 (plus:SWI (match_operand:SWI 1 "register_operand")
5503 (match_operand:SWI 2 "<nonmemory_operand>")))
5504 (clobber (reg:CC FLAGS_REG))]
5505 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5508 machine_mode mode = <MODE>mode;
5511 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5514 operands[0] = gen_lowpart (mode, operands[0]);
5515 operands[1] = gen_lowpart (mode, operands[1]);
5516 operands[2] = gen_lowpart (mode, operands[2]);
5519 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5521 emit_insn (gen_rtx_SET (operands[0], pat));
5525 ;; Split non destructive adds if we cannot use lea.
5527 [(set (match_operand:DI 0 "register_operand")
5529 (plus:SI (match_operand:SI 1 "register_operand")
5530 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5531 (clobber (reg:CC FLAGS_REG))]
5533 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5534 [(set (match_dup 3) (match_dup 1))
5535 (parallel [(set (match_dup 0)
5536 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5537 (clobber (reg:CC FLAGS_REG))])]
5538 "operands[3] = gen_lowpart (SImode, operands[0]);")
5540 ;; Convert add to the lea pattern to avoid flags dependency.
5542 [(set (match_operand:DI 0 "register_operand")
5544 (plus:SI (match_operand:SI 1 "register_operand")
5545 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5549 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5551 (define_insn "*add<mode>_2"
5552 [(set (reg FLAGS_REG)
5555 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5556 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5559 (plus:SWI (match_dup 1) (match_dup 2)))]
5560 "ix86_match_ccmode (insn, CCGOCmode)
5561 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5563 switch (get_attr_type (insn))
5566 if (operands[2] == const1_rtx)
5567 return "inc{<imodesuffix>}\t%0";
5570 gcc_assert (operands[2] == constm1_rtx);
5571 return "dec{<imodesuffix>}\t%0";
5575 if (which_alternative == 2)
5576 std::swap (operands[1], operands[2]);
5578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5580 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5582 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5586 (if_then_else (match_operand:SWI 2 "incdec_operand")
5587 (const_string "incdec")
5588 (const_string "alu")))
5589 (set (attr "length_immediate")
5591 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5593 (const_string "*")))
5594 (set_attr "mode" "<MODE>")])
5596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5597 (define_insn "*addsi_2_zext"
5598 [(set (reg FLAGS_REG)
5600 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5601 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5603 (set (match_operand:DI 0 "register_operand" "=r,r")
5604 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5605 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5606 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5608 switch (get_attr_type (insn))
5611 if (operands[2] == const1_rtx)
5612 return "inc{l}\t%k0";
5615 gcc_assert (operands[2] == constm1_rtx);
5616 return "dec{l}\t%k0";
5620 if (which_alternative == 1)
5621 std::swap (operands[1], operands[2]);
5623 if (x86_maybe_negate_const_int (&operands[2], SImode))
5624 return "sub{l}\t{%2, %k0|%k0, %2}";
5626 return "add{l}\t{%2, %k0|%k0, %2}";
5630 (if_then_else (match_operand:SI 2 "incdec_operand")
5631 (const_string "incdec")
5632 (const_string "alu")))
5633 (set (attr "length_immediate")
5635 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5637 (const_string "*")))
5638 (set_attr "mode" "SI")])
5640 (define_insn "*add<mode>_3"
5641 [(set (reg FLAGS_REG)
5643 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5644 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5645 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5646 "ix86_match_ccmode (insn, CCZmode)
5647 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5649 switch (get_attr_type (insn))
5652 if (operands[2] == const1_rtx)
5653 return "inc{<imodesuffix>}\t%0";
5656 gcc_assert (operands[2] == constm1_rtx);
5657 return "dec{<imodesuffix>}\t%0";
5661 if (which_alternative == 1)
5662 std::swap (operands[1], operands[2]);
5664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5672 (if_then_else (match_operand:SWI 2 "incdec_operand")
5673 (const_string "incdec")
5674 (const_string "alu")))
5675 (set (attr "length_immediate")
5677 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5679 (const_string "*")))
5680 (set_attr "mode" "<MODE>")])
5682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5683 (define_insn "*addsi_3_zext"
5684 [(set (reg FLAGS_REG)
5686 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5687 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5688 (set (match_operand:DI 0 "register_operand" "=r,r")
5689 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5690 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5691 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5693 switch (get_attr_type (insn))
5696 if (operands[2] == const1_rtx)
5697 return "inc{l}\t%k0";
5700 gcc_assert (operands[2] == constm1_rtx);
5701 return "dec{l}\t%k0";
5705 if (which_alternative == 1)
5706 std::swap (operands[1], operands[2]);
5708 if (x86_maybe_negate_const_int (&operands[2], SImode))
5709 return "sub{l}\t{%2, %k0|%k0, %2}";
5711 return "add{l}\t{%2, %k0|%k0, %2}";
5715 (if_then_else (match_operand:SI 2 "incdec_operand")
5716 (const_string "incdec")
5717 (const_string "alu")))
5718 (set (attr "length_immediate")
5720 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5722 (const_string "*")))
5723 (set_attr "mode" "SI")])
5725 ; For comparisons against 1, -1 and 128, we may generate better code
5726 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5727 ; is matched then. We can't accept general immediate, because for
5728 ; case of overflows, the result is messed up.
5729 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5730 ; only for comparisons not depending on it.
5732 (define_insn "*adddi_4"
5733 [(set (reg FLAGS_REG)
5735 (match_operand:DI 1 "nonimmediate_operand" "0")
5736 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5737 (clobber (match_scratch:DI 0 "=rm"))]
5739 && ix86_match_ccmode (insn, CCGCmode)"
5741 switch (get_attr_type (insn))
5744 if (operands[2] == constm1_rtx)
5745 return "inc{q}\t%0";
5748 gcc_assert (operands[2] == const1_rtx);
5749 return "dec{q}\t%0";
5753 if (x86_maybe_negate_const_int (&operands[2], DImode))
5754 return "add{q}\t{%2, %0|%0, %2}";
5756 return "sub{q}\t{%2, %0|%0, %2}";
5760 (if_then_else (match_operand:DI 2 "incdec_operand")
5761 (const_string "incdec")
5762 (const_string "alu")))
5763 (set (attr "length_immediate")
5765 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5767 (const_string "*")))
5768 (set_attr "mode" "DI")])
5770 ; For comparisons against 1, -1 and 128, we may generate better code
5771 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5772 ; is matched then. We can't accept general immediate, because for
5773 ; case of overflows, the result is messed up.
5774 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5775 ; only for comparisons not depending on it.
5777 (define_insn "*add<mode>_4"
5778 [(set (reg FLAGS_REG)
5780 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5781 (match_operand:SWI124 2 "const_int_operand" "n")))
5782 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5783 "ix86_match_ccmode (insn, CCGCmode)"
5785 switch (get_attr_type (insn))
5788 if (operands[2] == constm1_rtx)
5789 return "inc{<imodesuffix>}\t%0";
5792 gcc_assert (operands[2] == const1_rtx);
5793 return "dec{<imodesuffix>}\t%0";
5797 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5798 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5800 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5804 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5805 (const_string "incdec")
5806 (const_string "alu")))
5807 (set (attr "length_immediate")
5809 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5811 (const_string "*")))
5812 (set_attr "mode" "<MODE>")])
5814 (define_insn "*add<mode>_5"
5815 [(set (reg FLAGS_REG)
5818 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5819 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5821 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5822 "ix86_match_ccmode (insn, CCGOCmode)
5823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5825 switch (get_attr_type (insn))
5828 if (operands[2] == const1_rtx)
5829 return "inc{<imodesuffix>}\t%0";
5832 gcc_assert (operands[2] == constm1_rtx);
5833 return "dec{<imodesuffix>}\t%0";
5837 if (which_alternative == 1)
5838 std::swap (operands[1], operands[2]);
5840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5842 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5844 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5848 (if_then_else (match_operand:SWI 2 "incdec_operand")
5849 (const_string "incdec")
5850 (const_string "alu")))
5851 (set (attr "length_immediate")
5853 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5855 (const_string "*")))
5856 (set_attr "mode" "<MODE>")])
5858 (define_insn "addqi_ext_1"
5859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5864 (match_operand 1 "ext_register_operand" "0,0")
5867 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5868 (clobber (reg:CC FLAGS_REG))]
5871 switch (get_attr_type (insn))
5874 if (operands[2] == const1_rtx)
5875 return "inc{b}\t%h0";
5878 gcc_assert (operands[2] == constm1_rtx);
5879 return "dec{b}\t%h0";
5883 return "add{b}\t{%2, %h0|%h0, %2}";
5886 [(set_attr "isa" "*,nox64")
5888 (if_then_else (match_operand:QI 2 "incdec_operand")
5889 (const_string "incdec")
5890 (const_string "alu")))
5891 (set_attr "modrm" "1")
5892 (set_attr "mode" "QI")])
5894 (define_insn "*addqi_ext_2"
5895 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5900 (match_operand 1 "ext_register_operand" "%0")
5904 (match_operand 2 "ext_register_operand" "Q")
5907 (clobber (reg:CC FLAGS_REG))]
5909 "add{b}\t{%h2, %h0|%h0, %h2}"
5910 [(set_attr "type" "alu")
5911 (set_attr "mode" "QI")])
5913 ;; Add with jump on overflow.
5914 (define_expand "addv<mode>4"
5915 [(parallel [(set (reg:CCO FLAGS_REG)
5918 (match_operand:SWI 1 "nonimmediate_operand"))
5921 (plus:SWI (match_dup 1)
5922 (match_operand:SWI 2
5923 "<general_operand>")))))
5924 (set (match_operand:SWI 0 "register_operand")
5925 (plus:SWI (match_dup 1) (match_dup 2)))])
5926 (set (pc) (if_then_else
5927 (eq (reg:CCO FLAGS_REG) (const_int 0))
5928 (label_ref (match_operand 3))
5932 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5933 if (CONST_INT_P (operands[2]))
5934 operands[4] = operands[2];
5936 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5939 (define_insn "*addv<mode>4"
5940 [(set (reg:CCO FLAGS_REG)
5943 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5945 (match_operand:SWI 2 "<general_sext_operand>"
5948 (plus:SWI (match_dup 1) (match_dup 2)))))
5949 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5950 (plus:SWI (match_dup 1) (match_dup 2)))]
5951 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5952 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5953 [(set_attr "type" "alu")
5954 (set_attr "mode" "<MODE>")])
5956 (define_insn "*addv<mode>4_1"
5957 [(set (reg:CCO FLAGS_REG)
5960 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5961 (match_operand:<DWI> 3 "const_int_operand" "i"))
5963 (plus:SWI (match_dup 1)
5964 (match_operand:SWI 2 "x86_64_immediate_operand"
5966 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5967 (plus:SWI (match_dup 1) (match_dup 2)))]
5968 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5969 && CONST_INT_P (operands[2])
5970 && INTVAL (operands[2]) == INTVAL (operands[3])"
5971 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5972 [(set_attr "type" "alu")
5973 (set_attr "mode" "<MODE>")
5974 (set (attr "length_immediate")
5975 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5977 (match_test "<MODE_SIZE> == 8")
5979 (const_string "<MODE_SIZE>")))])
5981 ;; The lea patterns for modes less than 32 bits need to be matched by
5982 ;; several insns converted to real lea by splitters.
5984 (define_insn_and_split "*lea_general_1"
5985 [(set (match_operand 0 "register_operand" "=r")
5986 (plus (plus (match_operand 1 "index_register_operand" "l")
5987 (match_operand 2 "register_operand" "r"))
5988 (match_operand 3 "immediate_operand" "i")))]
5989 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5993 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5994 || GET_MODE (operands[3]) == VOIDmode)"
5996 "&& reload_completed"
5999 machine_mode mode = SImode;
6002 operands[0] = gen_lowpart (mode, operands[0]);
6003 operands[1] = gen_lowpart (mode, operands[1]);
6004 operands[2] = gen_lowpart (mode, operands[2]);
6005 operands[3] = gen_lowpart (mode, operands[3]);
6007 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6010 emit_insn (gen_rtx_SET (operands[0], pat));
6013 [(set_attr "type" "lea")
6014 (set_attr "mode" "SI")])
6016 (define_insn_and_split "*lea_general_2"
6017 [(set (match_operand 0 "register_operand" "=r")
6018 (plus (mult (match_operand 1 "index_register_operand" "l")
6019 (match_operand 2 "const248_operand" "n"))
6020 (match_operand 3 "nonmemory_operand" "ri")))]
6021 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6022 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6023 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6024 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6025 || GET_MODE (operands[3]) == VOIDmode)"
6027 "&& reload_completed"
6030 machine_mode mode = SImode;
6033 operands[0] = gen_lowpart (mode, operands[0]);
6034 operands[1] = gen_lowpart (mode, operands[1]);
6035 operands[3] = gen_lowpart (mode, operands[3]);
6037 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6040 emit_insn (gen_rtx_SET (operands[0], pat));
6043 [(set_attr "type" "lea")
6044 (set_attr "mode" "SI")])
6046 (define_insn_and_split "*lea_general_3"
6047 [(set (match_operand 0 "register_operand" "=r")
6048 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6049 (match_operand 2 "const248_operand" "n"))
6050 (match_operand 3 "register_operand" "r"))
6051 (match_operand 4 "immediate_operand" "i")))]
6052 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6053 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6055 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6057 "&& reload_completed"
6060 machine_mode mode = SImode;
6063 operands[0] = gen_lowpart (mode, operands[0]);
6064 operands[1] = gen_lowpart (mode, operands[1]);
6065 operands[3] = gen_lowpart (mode, operands[3]);
6066 operands[4] = gen_lowpart (mode, operands[4]);
6068 pat = gen_rtx_PLUS (mode,
6070 gen_rtx_MULT (mode, operands[1],
6075 emit_insn (gen_rtx_SET (operands[0], pat));
6078 [(set_attr "type" "lea")
6079 (set_attr "mode" "SI")])
6081 (define_insn_and_split "*lea_general_4"
6082 [(set (match_operand 0 "register_operand" "=r")
6084 (match_operand 1 "index_register_operand" "l")
6085 (match_operand 2 "const_int_operand" "n"))
6086 (match_operand 3 "const_int_operand" "n")))]
6087 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6088 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6089 || GET_MODE (operands[0]) == SImode
6090 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6091 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6092 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6093 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6094 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6096 "&& reload_completed"
6099 machine_mode mode = GET_MODE (operands[0]);
6102 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6105 operands[0] = gen_lowpart (mode, operands[0]);
6106 operands[1] = gen_lowpart (mode, operands[1]);
6109 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6111 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6112 INTVAL (operands[3]));
6114 emit_insn (gen_rtx_SET (operands[0], pat));
6117 [(set_attr "type" "lea")
6119 (if_then_else (match_operand:DI 0)
6121 (const_string "SI")))])
6123 ;; Subtract instructions
6125 (define_expand "sub<mode>3"
6126 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6127 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6128 (match_operand:SDWIM 2 "<general_operand>")))]
6130 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6132 (define_insn_and_split "*sub<dwi>3_doubleword"
6133 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6135 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6136 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6137 (clobber (reg:CC FLAGS_REG))]
6138 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6141 [(parallel [(set (reg:CC FLAGS_REG)
6142 (compare:CC (match_dup 1) (match_dup 2)))
6144 (minus:DWIH (match_dup 1) (match_dup 2)))])
6145 (parallel [(set (match_dup 3)
6149 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6151 (clobber (reg:CC FLAGS_REG))])]
6152 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6154 (define_insn "*sub<mode>_1"
6155 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6157 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6158 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6159 (clobber (reg:CC FLAGS_REG))]
6160 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6161 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6162 [(set_attr "type" "alu")
6163 (set_attr "mode" "<MODE>")])
6165 (define_insn "*subsi_1_zext"
6166 [(set (match_operand:DI 0 "register_operand" "=r")
6168 (minus:SI (match_operand:SI 1 "register_operand" "0")
6169 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6170 (clobber (reg:CC FLAGS_REG))]
6171 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6172 "sub{l}\t{%2, %k0|%k0, %2}"
6173 [(set_attr "type" "alu")
6174 (set_attr "mode" "SI")])
6176 (define_insn "*subqi_1_slp"
6177 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6178 (minus:QI (match_dup 0)
6179 (match_operand:QI 1 "general_operand" "qn,qm")))
6180 (clobber (reg:CC FLAGS_REG))]
6181 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6182 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6183 "sub{b}\t{%1, %0|%0, %1}"
6184 [(set_attr "type" "alu1")
6185 (set_attr "mode" "QI")])
6187 (define_insn "*sub<mode>_2"
6188 [(set (reg FLAGS_REG)
6191 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6192 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6194 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6195 (minus:SWI (match_dup 1) (match_dup 2)))]
6196 "ix86_match_ccmode (insn, CCGOCmode)
6197 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6198 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6199 [(set_attr "type" "alu")
6200 (set_attr "mode" "<MODE>")])
6202 (define_insn "*subsi_2_zext"
6203 [(set (reg FLAGS_REG)
6205 (minus:SI (match_operand:SI 1 "register_operand" "0")
6206 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6208 (set (match_operand:DI 0 "register_operand" "=r")
6210 (minus:SI (match_dup 1)
6212 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6213 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6214 "sub{l}\t{%2, %k0|%k0, %2}"
6215 [(set_attr "type" "alu")
6216 (set_attr "mode" "SI")])
6218 ;; Subtract with jump on overflow.
6219 (define_expand "subv<mode>4"
6220 [(parallel [(set (reg:CCO FLAGS_REG)
6221 (eq:CCO (minus:<DWI>
6223 (match_operand:SWI 1 "nonimmediate_operand"))
6226 (minus:SWI (match_dup 1)
6227 (match_operand:SWI 2
6228 "<general_operand>")))))
6229 (set (match_operand:SWI 0 "register_operand")
6230 (minus:SWI (match_dup 1) (match_dup 2)))])
6231 (set (pc) (if_then_else
6232 (eq (reg:CCO FLAGS_REG) (const_int 0))
6233 (label_ref (match_operand 3))
6237 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6238 if (CONST_INT_P (operands[2]))
6239 operands[4] = operands[2];
6241 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6244 (define_insn "*subv<mode>4"
6245 [(set (reg:CCO FLAGS_REG)
6246 (eq:CCO (minus:<DWI>
6248 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6250 (match_operand:SWI 2 "<general_sext_operand>"
6253 (minus:SWI (match_dup 1) (match_dup 2)))))
6254 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6255 (minus:SWI (match_dup 1) (match_dup 2)))]
6256 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6257 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6258 [(set_attr "type" "alu")
6259 (set_attr "mode" "<MODE>")])
6261 (define_insn "*subv<mode>4_1"
6262 [(set (reg:CCO FLAGS_REG)
6263 (eq:CCO (minus:<DWI>
6265 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6266 (match_operand:<DWI> 3 "const_int_operand" "i"))
6268 (minus:SWI (match_dup 1)
6269 (match_operand:SWI 2 "x86_64_immediate_operand"
6271 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6272 (minus:SWI (match_dup 1) (match_dup 2)))]
6273 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6274 && CONST_INT_P (operands[2])
6275 && INTVAL (operands[2]) == INTVAL (operands[3])"
6276 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6277 [(set_attr "type" "alu")
6278 (set_attr "mode" "<MODE>")
6279 (set (attr "length_immediate")
6280 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6282 (match_test "<MODE_SIZE> == 8")
6284 (const_string "<MODE_SIZE>")))])
6286 (define_insn "*sub<mode>_3"
6287 [(set (reg FLAGS_REG)
6288 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6289 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6290 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6291 (minus:SWI (match_dup 1) (match_dup 2)))]
6292 "ix86_match_ccmode (insn, CCmode)
6293 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6294 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6295 [(set_attr "type" "alu")
6296 (set_attr "mode" "<MODE>")])
6298 (define_insn "*subsi_3_zext"
6299 [(set (reg FLAGS_REG)
6300 (compare (match_operand:SI 1 "register_operand" "0")
6301 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6302 (set (match_operand:DI 0 "register_operand" "=r")
6304 (minus:SI (match_dup 1)
6306 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6307 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6308 "sub{l}\t{%2, %1|%1, %2}"
6309 [(set_attr "type" "alu")
6310 (set_attr "mode" "SI")])
6312 ;; Add with carry and subtract with borrow
6314 (define_expand "<plusminus_insn><mode>3_carry"
6316 [(set (match_operand:SWI 0 "nonimmediate_operand")
6318 (match_operand:SWI 1 "nonimmediate_operand")
6319 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6320 [(match_operand 3 "flags_reg_operand")
6322 (match_operand:SWI 2 "<general_operand>"))))
6323 (clobber (reg:CC FLAGS_REG))])]
6324 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6326 (define_insn "*<plusminus_insn><mode>3_carry"
6327 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6329 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6331 (match_operator 3 "ix86_carry_flag_operator"
6332 [(reg FLAGS_REG) (const_int 0)])
6333 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6334 (clobber (reg:CC FLAGS_REG))]
6335 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6336 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6337 [(set_attr "type" "alu")
6338 (set_attr "use_carry" "1")
6339 (set_attr "pent_pair" "pu")
6340 (set_attr "mode" "<MODE>")])
6342 (define_insn "*addsi3_carry_zext"
6343 [(set (match_operand:DI 0 "register_operand" "=r")
6345 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6346 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6347 [(reg FLAGS_REG) (const_int 0)])
6348 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6349 (clobber (reg:CC FLAGS_REG))]
6350 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6351 "adc{l}\t{%2, %k0|%k0, %2}"
6352 [(set_attr "type" "alu")
6353 (set_attr "use_carry" "1")
6354 (set_attr "pent_pair" "pu")
6355 (set_attr "mode" "SI")])
6357 (define_insn "*subsi3_carry_zext"
6358 [(set (match_operand:DI 0 "register_operand" "=r")
6360 (minus:SI (match_operand:SI 1 "register_operand" "0")
6361 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6362 [(reg FLAGS_REG) (const_int 0)])
6363 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6366 "sbb{l}\t{%2, %k0|%k0, %2}"
6367 [(set_attr "type" "alu")
6368 (set_attr "pent_pair" "pu")
6369 (set_attr "mode" "SI")])
6373 (define_insn "adcx<mode>3"
6374 [(set (reg:CCC FLAGS_REG)
6377 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6379 (match_operator 4 "ix86_carry_flag_operator"
6380 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6381 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6383 (set (match_operand:SWI48 0 "register_operand" "=r")
6384 (plus:SWI48 (match_dup 1)
6385 (plus:SWI48 (match_op_dup 4
6386 [(match_dup 3) (const_int 0)])
6388 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6389 "adcx\t{%2, %0|%0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "use_carry" "1")
6392 (set_attr "mode" "<MODE>")])
6394 ;; Overflow setting add instructions
6396 (define_insn "*add<mode>3_cconly_overflow"
6397 [(set (reg:CCC FLAGS_REG)
6400 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6401 (match_operand:SWI 2 "<general_operand>" "<g>"))
6403 (clobber (match_scratch:SWI 0 "=<r>"))]
6404 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6405 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6409 (define_insn "*add<mode>3_cc_overflow"
6410 [(set (reg:CCC FLAGS_REG)
6413 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6414 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6416 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6417 (plus:SWI (match_dup 1) (match_dup 2)))]
6418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6419 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6420 [(set_attr "type" "alu")
6421 (set_attr "mode" "<MODE>")])
6423 (define_insn "*addsi3_zext_cc_overflow"
6424 [(set (reg:CCC FLAGS_REG)
6427 (match_operand:SI 1 "nonimmediate_operand" "%0")
6428 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6430 (set (match_operand:DI 0 "register_operand" "=r")
6431 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6432 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6433 "add{l}\t{%2, %k0|%k0, %2}"
6434 [(set_attr "type" "alu")
6435 (set_attr "mode" "SI")])
6437 ;; The patterns that match these are at the end of this file.
6439 (define_expand "<plusminus_insn>xf3"
6440 [(set (match_operand:XF 0 "register_operand")
6442 (match_operand:XF 1 "register_operand")
6443 (match_operand:XF 2 "register_operand")))]
6446 (define_expand "<plusminus_insn><mode>3"
6447 [(set (match_operand:MODEF 0 "register_operand")
6449 (match_operand:MODEF 1 "register_operand")
6450 (match_operand:MODEF 2 "nonimmediate_operand")))]
6451 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6452 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6454 ;; Multiply instructions
6456 (define_expand "mul<mode>3"
6457 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6459 (match_operand:SWIM248 1 "register_operand")
6460 (match_operand:SWIM248 2 "<general_operand>")))
6461 (clobber (reg:CC FLAGS_REG))])])
6463 (define_expand "mulqi3"
6464 [(parallel [(set (match_operand:QI 0 "register_operand")
6466 (match_operand:QI 1 "register_operand")
6467 (match_operand:QI 2 "nonimmediate_operand")))
6468 (clobber (reg:CC FLAGS_REG))])]
6469 "TARGET_QIMODE_MATH")
6472 ;; IMUL reg32/64, reg32/64, imm8 Direct
6473 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6474 ;; IMUL reg32/64, reg32/64, imm32 Direct
6475 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6476 ;; IMUL reg32/64, reg32/64 Direct
6477 ;; IMUL reg32/64, mem32/64 Direct
6479 ;; On BDVER1, all above IMULs use DirectPath
6481 (define_insn "*mul<mode>3_1"
6482 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6484 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6485 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6489 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6490 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6491 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "imul")
6493 (set_attr "prefix_0f" "0,0,1")
6494 (set (attr "athlon_decode")
6495 (cond [(eq_attr "cpu" "athlon")
6496 (const_string "vector")
6497 (eq_attr "alternative" "1")
6498 (const_string "vector")
6499 (and (eq_attr "alternative" "2")
6500 (match_operand 1 "memory_operand"))
6501 (const_string "vector")]
6502 (const_string "direct")))
6503 (set (attr "amdfam10_decode")
6504 (cond [(and (eq_attr "alternative" "0,1")
6505 (match_operand 1 "memory_operand"))
6506 (const_string "vector")]
6507 (const_string "direct")))
6508 (set_attr "bdver1_decode" "direct")
6509 (set_attr "mode" "<MODE>")])
6511 (define_insn "*mulsi3_1_zext"
6512 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6514 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6515 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6516 (clobber (reg:CC FLAGS_REG))]
6518 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6520 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6521 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6522 imul{l}\t{%2, %k0|%k0, %2}"
6523 [(set_attr "type" "imul")
6524 (set_attr "prefix_0f" "0,0,1")
6525 (set (attr "athlon_decode")
6526 (cond [(eq_attr "cpu" "athlon")
6527 (const_string "vector")
6528 (eq_attr "alternative" "1")
6529 (const_string "vector")
6530 (and (eq_attr "alternative" "2")
6531 (match_operand 1 "memory_operand"))
6532 (const_string "vector")]
6533 (const_string "direct")))
6534 (set (attr "amdfam10_decode")
6535 (cond [(and (eq_attr "alternative" "0,1")
6536 (match_operand 1 "memory_operand"))
6537 (const_string "vector")]
6538 (const_string "direct")))
6539 (set_attr "bdver1_decode" "direct")
6540 (set_attr "mode" "SI")])
6543 ;; IMUL reg16, reg16, imm8 VectorPath
6544 ;; IMUL reg16, mem16, imm8 VectorPath
6545 ;; IMUL reg16, reg16, imm16 VectorPath
6546 ;; IMUL reg16, mem16, imm16 VectorPath
6547 ;; IMUL reg16, reg16 Direct
6548 ;; IMUL reg16, mem16 Direct
6550 ;; On BDVER1, all HI MULs use DoublePath
6552 (define_insn "*mulhi3_1"
6553 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6554 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6555 (match_operand:HI 2 "general_operand" "K,n,mr")))
6556 (clobber (reg:CC FLAGS_REG))]
6558 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6560 imul{w}\t{%2, %1, %0|%0, %1, %2}
6561 imul{w}\t{%2, %1, %0|%0, %1, %2}
6562 imul{w}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "imul")
6564 (set_attr "prefix_0f" "0,0,1")
6565 (set (attr "athlon_decode")
6566 (cond [(eq_attr "cpu" "athlon")
6567 (const_string "vector")
6568 (eq_attr "alternative" "1,2")
6569 (const_string "vector")]
6570 (const_string "direct")))
6571 (set (attr "amdfam10_decode")
6572 (cond [(eq_attr "alternative" "0,1")
6573 (const_string "vector")]
6574 (const_string "direct")))
6575 (set_attr "bdver1_decode" "double")
6576 (set_attr "mode" "HI")])
6578 ;;On AMDFAM10 and BDVER1
6582 (define_insn "*mulqi3_1"
6583 [(set (match_operand:QI 0 "register_operand" "=a")
6584 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6585 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6586 (clobber (reg:CC FLAGS_REG))]
6588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6590 [(set_attr "type" "imul")
6591 (set_attr "length_immediate" "0")
6592 (set (attr "athlon_decode")
6593 (if_then_else (eq_attr "cpu" "athlon")
6594 (const_string "vector")
6595 (const_string "direct")))
6596 (set_attr "amdfam10_decode" "direct")
6597 (set_attr "bdver1_decode" "direct")
6598 (set_attr "mode" "QI")])
6600 ;; Multiply with jump on overflow.
6601 (define_expand "mulv<mode>4"
6602 [(parallel [(set (reg:CCO FLAGS_REG)
6605 (match_operand:SWI48 1 "register_operand"))
6608 (mult:SWI48 (match_dup 1)
6609 (match_operand:SWI48 2
6610 "<general_operand>")))))
6611 (set (match_operand:SWI48 0 "register_operand")
6612 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6613 (set (pc) (if_then_else
6614 (eq (reg:CCO FLAGS_REG) (const_int 0))
6615 (label_ref (match_operand 3))
6619 if (CONST_INT_P (operands[2]))
6620 operands[4] = operands[2];
6622 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6625 (define_insn "*mulv<mode>4"
6626 [(set (reg:CCO FLAGS_REG)
6629 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6631 (match_operand:SWI48 2 "<general_sext_operand>"
6634 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6635 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6636 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6637 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6639 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6640 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "imul")
6642 (set_attr "prefix_0f" "0,1")
6643 (set (attr "athlon_decode")
6644 (cond [(eq_attr "cpu" "athlon")
6645 (const_string "vector")
6646 (eq_attr "alternative" "0")
6647 (const_string "vector")
6648 (and (eq_attr "alternative" "1")
6649 (match_operand 1 "memory_operand"))
6650 (const_string "vector")]
6651 (const_string "direct")))
6652 (set (attr "amdfam10_decode")
6653 (cond [(and (eq_attr "alternative" "1")
6654 (match_operand 1 "memory_operand"))
6655 (const_string "vector")]
6656 (const_string "direct")))
6657 (set_attr "bdver1_decode" "direct")
6658 (set_attr "mode" "<MODE>")])
6660 (define_insn "*mulv<mode>4_1"
6661 [(set (reg:CCO FLAGS_REG)
6664 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6665 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6667 (mult:SWI48 (match_dup 1)
6668 (match_operand:SWI 2 "x86_64_immediate_operand"
6670 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6671 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6672 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6673 && CONST_INT_P (operands[2])
6674 && INTVAL (operands[2]) == INTVAL (operands[3])"
6676 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6677 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6678 [(set_attr "type" "imul")
6679 (set (attr "athlon_decode")
6680 (cond [(eq_attr "cpu" "athlon")
6681 (const_string "vector")
6682 (eq_attr "alternative" "1")
6683 (const_string "vector")]
6684 (const_string "direct")))
6685 (set (attr "amdfam10_decode")
6686 (cond [(match_operand 1 "memory_operand")
6687 (const_string "vector")]
6688 (const_string "direct")))
6689 (set_attr "bdver1_decode" "direct")
6690 (set_attr "mode" "<MODE>")
6691 (set (attr "length_immediate")
6692 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6694 (match_test "<MODE_SIZE> == 8")
6696 (const_string "<MODE_SIZE>")))])
6698 (define_expand "umulv<mode>4"
6699 [(parallel [(set (reg:CCO FLAGS_REG)
6702 (match_operand:SWI48 1
6703 "nonimmediate_operand"))
6705 (match_operand:SWI48 2
6706 "nonimmediate_operand")))
6708 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6709 (set (match_operand:SWI48 0 "register_operand")
6710 (mult:SWI48 (match_dup 1) (match_dup 2)))
6711 (clobber (match_scratch:SWI48 4))])
6712 (set (pc) (if_then_else
6713 (eq (reg:CCO FLAGS_REG) (const_int 0))
6714 (label_ref (match_operand 3))
6718 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6719 operands[1] = force_reg (<MODE>mode, operands[1]);
6722 (define_insn "*umulv<mode>4"
6723 [(set (reg:CCO FLAGS_REG)
6726 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6728 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6730 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6731 (set (match_operand:SWI48 0 "register_operand" "=a")
6732 (mult:SWI48 (match_dup 1) (match_dup 2)))
6733 (clobber (match_scratch:SWI48 3 "=d"))]
6734 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 "mul{<imodesuffix>}\t%2"
6736 [(set_attr "type" "imul")
6737 (set_attr "length_immediate" "0")
6738 (set (attr "athlon_decode")
6739 (if_then_else (eq_attr "cpu" "athlon")
6740 (const_string "vector")
6741 (const_string "double")))
6742 (set_attr "amdfam10_decode" "double")
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "<MODE>")])
6746 (define_expand "<u>mulvqi4"
6747 [(parallel [(set (reg:CCO FLAGS_REG)
6750 (match_operand:QI 1 "nonimmediate_operand"))
6752 (match_operand:QI 2 "nonimmediate_operand")))
6754 (mult:QI (match_dup 1) (match_dup 2)))))
6755 (set (match_operand:QI 0 "register_operand")
6756 (mult:QI (match_dup 1) (match_dup 2)))])
6757 (set (pc) (if_then_else
6758 (eq (reg:CCO FLAGS_REG) (const_int 0))
6759 (label_ref (match_operand 3))
6761 "TARGET_QIMODE_MATH"
6763 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6764 operands[1] = force_reg (QImode, operands[1]);
6767 (define_insn "*<u>mulvqi4"
6768 [(set (reg:CCO FLAGS_REG)
6771 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6773 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6775 (mult:QI (match_dup 1) (match_dup 2)))))
6776 (set (match_operand:QI 0 "register_operand" "=a")
6777 (mult:QI (match_dup 1) (match_dup 2)))]
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780 "<sgnprefix>mul{b}\t%2"
6781 [(set_attr "type" "imul")
6782 (set_attr "length_immediate" "0")
6783 (set (attr "athlon_decode")
6784 (if_then_else (eq_attr "cpu" "athlon")
6785 (const_string "vector")
6786 (const_string "direct")))
6787 (set_attr "amdfam10_decode" "direct")
6788 (set_attr "bdver1_decode" "direct")
6789 (set_attr "mode" "QI")])
6791 (define_expand "<u>mul<mode><dwi>3"
6792 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6795 (match_operand:DWIH 1 "nonimmediate_operand"))
6797 (match_operand:DWIH 2 "register_operand"))))
6798 (clobber (reg:CC FLAGS_REG))])])
6800 (define_expand "<u>mulqihi3"
6801 [(parallel [(set (match_operand:HI 0 "register_operand")
6804 (match_operand:QI 1 "nonimmediate_operand"))
6806 (match_operand:QI 2 "register_operand"))))
6807 (clobber (reg:CC FLAGS_REG))])]
6808 "TARGET_QIMODE_MATH")
6810 (define_insn "*bmi2_umul<mode><dwi>3_1"
6811 [(set (match_operand:DWIH 0 "register_operand" "=r")
6813 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6814 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6815 (set (match_operand:DWIH 1 "register_operand" "=r")
6818 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6819 (zero_extend:<DWI> (match_dup 3)))
6820 (match_operand:QI 4 "const_int_operand" "n"))))]
6821 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823 "mulx\t{%3, %0, %1|%1, %0, %3}"
6824 [(set_attr "type" "imulx")
6825 (set_attr "prefix" "vex")
6826 (set_attr "mode" "<MODE>")])
6828 (define_insn "*umul<mode><dwi>3_1"
6829 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6832 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6834 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6835 (clobber (reg:CC FLAGS_REG))]
6836 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839 mul{<imodesuffix>}\t%2"
6840 [(set_attr "isa" "bmi2,*")
6841 (set_attr "type" "imulx,imul")
6842 (set_attr "length_immediate" "*,0")
6843 (set (attr "athlon_decode")
6844 (cond [(eq_attr "alternative" "1")
6845 (if_then_else (eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (const_string "double"))]
6848 (const_string "*")))
6849 (set_attr "amdfam10_decode" "*,double")
6850 (set_attr "bdver1_decode" "*,direct")
6851 (set_attr "prefix" "vex,orig")
6852 (set_attr "mode" "<MODE>")])
6854 ;; Convert mul to the mulx pattern to avoid flags dependency.
6856 [(set (match_operand:<DWI> 0 "register_operand")
6859 (match_operand:DWIH 1 "register_operand"))
6861 (match_operand:DWIH 2 "nonimmediate_operand"))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "TARGET_BMI2 && reload_completed
6864 && true_regnum (operands[1]) == DX_REG"
6865 [(parallel [(set (match_dup 3)
6866 (mult:DWIH (match_dup 1) (match_dup 2)))
6870 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6871 (zero_extend:<DWI> (match_dup 2)))
6874 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6879 (define_insn "*mul<mode><dwi>3_1"
6880 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6883 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6885 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 "imul{<imodesuffix>}\t%2"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "double")))
6895 (set_attr "amdfam10_decode" "double")
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "<MODE>")])
6899 (define_insn "*<u>mulqihi3_1"
6900 [(set (match_operand:HI 0 "register_operand" "=a")
6903 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6905 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6909 "<sgnprefix>mul{b}\t%2"
6910 [(set_attr "type" "imul")
6911 (set_attr "length_immediate" "0")
6912 (set (attr "athlon_decode")
6913 (if_then_else (eq_attr "cpu" "athlon")
6914 (const_string "vector")
6915 (const_string "direct")))
6916 (set_attr "amdfam10_decode" "direct")
6917 (set_attr "bdver1_decode" "direct")
6918 (set_attr "mode" "QI")])
6920 (define_expand "<s>mul<mode>3_highpart"
6921 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6926 (match_operand:SWI48 1 "nonimmediate_operand"))
6928 (match_operand:SWI48 2 "register_operand")))
6930 (clobber (match_scratch:SWI48 3))
6931 (clobber (reg:CC FLAGS_REG))])]
6933 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935 (define_insn "*<s>muldi3_highpart_1"
6936 [(set (match_operand:DI 0 "register_operand" "=d")
6941 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6943 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6945 (clobber (match_scratch:DI 3 "=1"))
6946 (clobber (reg:CC FLAGS_REG))]
6948 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949 "<sgnprefix>mul{q}\t%2"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "amdfam10_decode" "double")
6957 (set_attr "bdver1_decode" "direct")
6958 (set_attr "mode" "DI")])
6960 (define_insn "*<s>mulsi3_highpart_1"
6961 [(set (match_operand:SI 0 "register_operand" "=d")
6966 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6968 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6970 (clobber (match_scratch:SI 3 "=1"))
6971 (clobber (reg:CC FLAGS_REG))]
6972 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{l}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "double")))
6980 (set_attr "amdfam10_decode" "double")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "SI")])
6984 (define_insn "*<s>mulsi3_highpart_zext"
6985 [(set (match_operand:DI 0 "register_operand" "=d")
6986 (zero_extend:DI (truncate:SI
6988 (mult:DI (any_extend:DI
6989 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6991 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6993 (clobber (match_scratch:SI 3 "=1"))
6994 (clobber (reg:CC FLAGS_REG))]
6996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997 "<sgnprefix>mul{l}\t%2"
6998 [(set_attr "type" "imul")
6999 (set_attr "length_immediate" "0")
7000 (set (attr "athlon_decode")
7001 (if_then_else (eq_attr "cpu" "athlon")
7002 (const_string "vector")
7003 (const_string "double")))
7004 (set_attr "amdfam10_decode" "double")
7005 (set_attr "bdver1_decode" "direct")
7006 (set_attr "mode" "SI")])
7008 ;; The patterns that match these are at the end of this file.
7010 (define_expand "mulxf3"
7011 [(set (match_operand:XF 0 "register_operand")
7012 (mult:XF (match_operand:XF 1 "register_operand")
7013 (match_operand:XF 2 "register_operand")))]
7016 (define_expand "mul<mode>3"
7017 [(set (match_operand:MODEF 0 "register_operand")
7018 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7019 (match_operand:MODEF 2 "nonimmediate_operand")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7021 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023 ;; Divide instructions
7025 ;; The patterns that match these are at the end of this file.
7027 (define_expand "divxf3"
7028 [(set (match_operand:XF 0 "register_operand")
7029 (div:XF (match_operand:XF 1 "register_operand")
7030 (match_operand:XF 2 "register_operand")))]
7033 (define_expand "divdf3"
7034 [(set (match_operand:DF 0 "register_operand")
7035 (div:DF (match_operand:DF 1 "register_operand")
7036 (match_operand:DF 2 "nonimmediate_operand")))]
7037 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7038 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040 (define_expand "divsf3"
7041 [(set (match_operand:SF 0 "register_operand")
7042 (div:SF (match_operand:SF 1 "register_operand")
7043 (match_operand:SF 2 "nonimmediate_operand")))]
7044 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7049 && optimize_insn_for_speed_p ()
7050 && flag_finite_math_only && !flag_trapping_math
7051 && flag_unsafe_math_optimizations)
7053 ix86_emit_swdivsf (operands[0], operands[1],
7054 operands[2], SFmode);
7059 ;; Divmod instructions.
7061 (define_expand "divmod<mode>4"
7062 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7064 (match_operand:SWIM248 1 "register_operand")
7065 (match_operand:SWIM248 2 "nonimmediate_operand")))
7066 (set (match_operand:SWIM248 3 "register_operand")
7067 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7068 (clobber (reg:CC FLAGS_REG))])])
7070 ;; Split with 8bit unsigned divide:
7071 ;; if (dividend an divisor are in [0-255])
7072 ;; use 8bit unsigned integer divide
7074 ;; use original integer divide
7076 [(set (match_operand:SWI48 0 "register_operand")
7077 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7078 (match_operand:SWI48 3 "nonimmediate_operand")))
7079 (set (match_operand:SWI48 1 "register_operand")
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7081 (clobber (reg:CC FLAGS_REG))]
7082 "TARGET_USE_8BIT_IDIV
7083 && TARGET_QIMODE_MATH
7084 && can_create_pseudo_p ()
7085 && !optimize_insn_for_size_p ()"
7087 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089 (define_insn_and_split "divmod<mode>4_1"
7090 [(set (match_operand:SWI48 0 "register_operand" "=a")
7091 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7092 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7093 (set (match_operand:SWI48 1 "register_operand" "=&d")
7094 (mod:SWI48 (match_dup 2) (match_dup 3)))
7095 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7096 (clobber (reg:CC FLAGS_REG))]
7100 [(parallel [(set (match_dup 1)
7101 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7102 (clobber (reg:CC FLAGS_REG))])
7103 (parallel [(set (match_dup 0)
7104 (div:SWI48 (match_dup 2) (match_dup 3)))
7106 (mod:SWI48 (match_dup 2) (match_dup 3)))
7108 (clobber (reg:CC FLAGS_REG))])]
7110 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7113 operands[4] = operands[2];
7116 /* Avoid use of cltd in favor of a mov+shift. */
7117 emit_move_insn (operands[1], operands[2]);
7118 operands[4] = operands[1];
7121 [(set_attr "type" "multi")
7122 (set_attr "mode" "<MODE>")])
7124 (define_insn_and_split "*divmod<mode>4"
7125 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7126 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7127 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7128 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7129 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130 (clobber (reg:CC FLAGS_REG))]
7134 [(parallel [(set (match_dup 1)
7135 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7136 (clobber (reg:CC FLAGS_REG))])
7137 (parallel [(set (match_dup 0)
7138 (div:SWIM248 (match_dup 2) (match_dup 3)))
7140 (mod:SWIM248 (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 (<MODE>mode != HImode
7147 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7148 operands[4] = operands[2];
7151 /* Avoid use of cltd in favor of a mov+shift. */
7152 emit_move_insn (operands[1], operands[2]);
7153 operands[4] = operands[1];
7156 [(set_attr "type" "multi")
7157 (set_attr "mode" "<MODE>")])
7159 (define_insn "*divmod<mode>4_noext"
7160 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7161 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7162 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7163 (set (match_operand:SWIM248 1 "register_operand" "=d")
7164 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7165 (use (match_operand:SWIM248 4 "register_operand" "1"))
7166 (clobber (reg:CC FLAGS_REG))]
7168 "idiv{<imodesuffix>}\t%3"
7169 [(set_attr "type" "idiv")
7170 (set_attr "mode" "<MODE>")])
7172 (define_expand "divmodqi4"
7173 [(parallel [(set (match_operand:QI 0 "register_operand")
7175 (match_operand:QI 1 "register_operand")
7176 (match_operand:QI 2 "nonimmediate_operand")))
7177 (set (match_operand:QI 3 "register_operand")
7178 (mod:QI (match_dup 1) (match_dup 2)))
7179 (clobber (reg:CC FLAGS_REG))])]
7180 "TARGET_QIMODE_MATH"
7185 tmp0 = gen_reg_rtx (HImode);
7186 tmp1 = gen_reg_rtx (HImode);
7188 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7190 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193 /* Extract remainder from AH. */
7194 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195 insn = emit_move_insn (operands[3], tmp1);
7197 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198 set_unique_reg_note (insn, REG_EQUAL, mod);
7200 /* Extract quotient from AL. */
7201 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204 set_unique_reg_note (insn, REG_EQUAL, div);
7209 ;; Divide AX by r/m8, with result stored in
7212 ;; Change div/mod to HImode and extend the second argument to HImode
7213 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7214 ;; combine may fail.
7215 (define_insn "divmodhiqi3"
7216 [(set (match_operand:HI 0 "register_operand" "=a")
7221 (mod:HI (match_operand:HI 1 "register_operand" "0")
7223 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7227 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_QIMODE_MATH"
7231 [(set_attr "type" "idiv")
7232 (set_attr "mode" "QI")])
7234 (define_expand "udivmod<mode>4"
7235 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7237 (match_operand:SWIM248 1 "register_operand")
7238 (match_operand:SWIM248 2 "nonimmediate_operand")))
7239 (set (match_operand:SWIM248 3 "register_operand")
7240 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7241 (clobber (reg:CC FLAGS_REG))])])
7243 ;; Split with 8bit unsigned divide:
7244 ;; if (dividend an divisor are in [0-255])
7245 ;; use 8bit unsigned integer divide
7247 ;; use original integer divide
7249 [(set (match_operand:SWI48 0 "register_operand")
7250 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7251 (match_operand:SWI48 3 "nonimmediate_operand")))
7252 (set (match_operand:SWI48 1 "register_operand")
7253 (umod:SWI48 (match_dup 2) (match_dup 3)))
7254 (clobber (reg:CC FLAGS_REG))]
7255 "TARGET_USE_8BIT_IDIV
7256 && TARGET_QIMODE_MATH
7257 && can_create_pseudo_p ()
7258 && !optimize_insn_for_size_p ()"
7260 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262 (define_insn_and_split "udivmod<mode>4_1"
7263 [(set (match_operand:SWI48 0 "register_operand" "=a")
7264 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7265 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7266 (set (match_operand:SWI48 1 "register_operand" "=&d")
7267 (umod:SWI48 (match_dup 2) (match_dup 3)))
7268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7269 (clobber (reg:CC FLAGS_REG))]
7273 [(set (match_dup 1) (const_int 0))
7274 (parallel [(set (match_dup 0)
7275 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7277 (umod:SWI48 (match_dup 2) (match_dup 3)))
7279 (clobber (reg:CC FLAGS_REG))])]
7281 [(set_attr "type" "multi")
7282 (set_attr "mode" "<MODE>")])
7284 (define_insn_and_split "*udivmod<mode>4"
7285 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7286 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7287 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7288 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7289 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290 (clobber (reg:CC FLAGS_REG))]
7294 [(set (match_dup 1) (const_int 0))
7295 (parallel [(set (match_dup 0)
7296 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7298 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7300 (clobber (reg:CC FLAGS_REG))])]
7302 [(set_attr "type" "multi")
7303 (set_attr "mode" "<MODE>")])
7305 ;; Optimize division or modulo by constant power of 2, if the constant
7306 ;; materializes only after expansion.
7307 (define_insn_and_split "*udivmod<mode>4_pow2"
7308 [(set (match_operand:SWI48 0 "register_operand" "=r")
7309 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7310 (match_operand:SWI48 3 "const_int_operand" "n")))
7311 (set (match_operand:SWI48 1 "register_operand" "=r")
7312 (umod:SWI48 (match_dup 2) (match_dup 3)))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7315 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7318 [(set (match_dup 1) (match_dup 2))
7319 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7320 (clobber (reg:CC FLAGS_REG))])
7321 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7322 (clobber (reg:CC FLAGS_REG))])]
7324 int v = exact_log2 (UINTVAL (operands[3]));
7325 operands[4] = GEN_INT (v);
7326 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7328 [(set_attr "type" "multi")
7329 (set_attr "mode" "<MODE>")])
7331 (define_insn "*udivmod<mode>4_noext"
7332 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7333 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7334 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7335 (set (match_operand:SWIM248 1 "register_operand" "=d")
7336 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7337 (use (match_operand:SWIM248 4 "register_operand" "1"))
7338 (clobber (reg:CC FLAGS_REG))]
7340 "div{<imodesuffix>}\t%3"
7341 [(set_attr "type" "idiv")
7342 (set_attr "mode" "<MODE>")])
7344 (define_expand "udivmodqi4"
7345 [(parallel [(set (match_operand:QI 0 "register_operand")
7347 (match_operand:QI 1 "register_operand")
7348 (match_operand:QI 2 "nonimmediate_operand")))
7349 (set (match_operand:QI 3 "register_operand")
7350 (umod:QI (match_dup 1) (match_dup 2)))
7351 (clobber (reg:CC FLAGS_REG))])]
7352 "TARGET_QIMODE_MATH"
7357 tmp0 = gen_reg_rtx (HImode);
7358 tmp1 = gen_reg_rtx (HImode);
7360 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7362 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7363 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7365 /* Extract remainder from AH. */
7366 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7367 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7368 insn = emit_move_insn (operands[3], tmp1);
7370 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7371 set_unique_reg_note (insn, REG_EQUAL, mod);
7373 /* Extract quotient from AL. */
7374 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7376 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7377 set_unique_reg_note (insn, REG_EQUAL, div);
7382 (define_insn "udivmodhiqi3"
7383 [(set (match_operand:HI 0 "register_operand" "=a")
7388 (mod:HI (match_operand:HI 1 "register_operand" "0")
7390 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7394 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "TARGET_QIMODE_MATH"
7398 [(set_attr "type" "idiv")
7399 (set_attr "mode" "QI")])
7401 ;; We cannot use div/idiv for double division, because it causes
7402 ;; "division by zero" on the overflow and that's not what we expect
7403 ;; from truncate. Because true (non truncating) double division is
7404 ;; never generated, we can't create this insn anyway.
7407 ; [(set (match_operand:SI 0 "register_operand" "=a")
7409 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7411 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7412 ; (set (match_operand:SI 3 "register_operand" "=d")
7414 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7415 ; (clobber (reg:CC FLAGS_REG))]
7417 ; "div{l}\t{%2, %0|%0, %2}"
7418 ; [(set_attr "type" "idiv")])
7420 ;;- Logical AND instructions
7422 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7423 ;; Note that this excludes ah.
7425 (define_expand "testsi_ccno_1"
7426 [(set (reg:CCNO FLAGS_REG)
7428 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7429 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7432 (define_expand "testqi_ccz_1"
7433 [(set (reg:CCZ FLAGS_REG)
7434 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7435 (match_operand:QI 1 "nonmemory_operand"))
7438 (define_expand "testdi_ccno_1"
7439 [(set (reg:CCNO FLAGS_REG)
7441 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7442 (match_operand:DI 1 "x86_64_szext_general_operand"))
7444 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7446 (define_insn "*testdi_1"
7447 [(set (reg FLAGS_REG)
7450 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7451 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7456 test{l}\t{%k1, %k0|%k0, %k1}
7457 test{l}\t{%k1, %k0|%k0, %k1}
7458 test{q}\t{%1, %0|%0, %1}
7459 test{q}\t{%1, %0|%0, %1}
7460 test{q}\t{%1, %0|%0, %1}"
7461 [(set_attr "type" "test")
7462 (set_attr "modrm" "0,1,0,1,1")
7463 (set_attr "mode" "SI,SI,DI,DI,DI")])
7465 (define_insn "*testqi_1_maybe_si"
7466 [(set (reg FLAGS_REG)
7469 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7470 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7472 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7473 && ix86_match_ccmode (insn,
7474 CONST_INT_P (operands[1])
7475 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7477 if (which_alternative == 3)
7479 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7480 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7481 return "test{l}\t{%1, %k0|%k0, %1}";
7483 return "test{b}\t{%1, %0|%0, %1}";
7485 [(set_attr "type" "test")
7486 (set_attr "modrm" "0,1,1,1")
7487 (set_attr "mode" "QI,QI,QI,SI")
7488 (set_attr "pent_pair" "uv,np,uv,np")])
7490 (define_insn "*test<mode>_1"
7491 [(set (reg FLAGS_REG)
7494 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7495 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7497 "ix86_match_ccmode (insn, CCNOmode)
7498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7499 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7500 [(set_attr "type" "test")
7501 (set_attr "modrm" "0,1,1")
7502 (set_attr "mode" "<MODE>")
7503 (set_attr "pent_pair" "uv,np,uv")])
7505 (define_expand "testqi_ext_ccno_0"
7506 [(set (reg:CCNO FLAGS_REG)
7510 (match_operand 0 "ext_register_operand")
7513 (match_operand 1 "const_int_operand"))
7516 (define_insn "*testqi_ext_0"
7517 [(set (reg FLAGS_REG)
7521 (match_operand 0 "ext_register_operand" "Q")
7524 (match_operand 1 "const_int_operand" "n"))
7526 "ix86_match_ccmode (insn, CCNOmode)"
7527 "test{b}\t{%1, %h0|%h0, %1}"
7528 [(set_attr "type" "test")
7529 (set_attr "mode" "QI")
7530 (set_attr "length_immediate" "1")
7531 (set_attr "modrm" "1")
7532 (set_attr "pent_pair" "np")])
7534 (define_insn "*testqi_ext_1"
7535 [(set (reg FLAGS_REG)
7539 (match_operand 0 "ext_register_operand" "Q,Q")
7543 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7545 "ix86_match_ccmode (insn, CCNOmode)"
7546 "test{b}\t{%1, %h0|%h0, %1}"
7547 [(set_attr "isa" "*,nox64")
7548 (set_attr "type" "test")
7549 (set_attr "mode" "QI")])
7551 (define_insn "*testqi_ext_2"
7552 [(set (reg FLAGS_REG)
7556 (match_operand 0 "ext_register_operand" "Q")
7560 (match_operand 1 "ext_register_operand" "Q")
7564 "ix86_match_ccmode (insn, CCNOmode)"
7565 "test{b}\t{%h1, %h0|%h0, %h1}"
7566 [(set_attr "type" "test")
7567 (set_attr "mode" "QI")])
7569 ;; Combine likes to form bit extractions for some tests. Humor it.
7570 (define_insn "*testqi_ext_3"
7571 [(set (reg FLAGS_REG)
7572 (compare (zero_extract:SWI48
7573 (match_operand 0 "nonimmediate_operand" "rm")
7574 (match_operand:SWI48 1 "const_int_operand")
7575 (match_operand:SWI48 2 "const_int_operand"))
7577 "ix86_match_ccmode (insn, CCNOmode)
7578 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7579 || GET_MODE (operands[0]) == SImode
7580 || GET_MODE (operands[0]) == HImode
7581 || GET_MODE (operands[0]) == QImode)
7582 /* Ensure that resulting mask is zero or sign extended operand. */
7583 && INTVAL (operands[2]) >= 0
7584 && ((INTVAL (operands[1]) > 0
7585 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7586 || (<MODE>mode == DImode
7587 && INTVAL (operands[1]) > 32
7588 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7592 [(set (match_operand 0 "flags_reg_operand")
7593 (match_operator 1 "compare_operator"
7595 (match_operand 2 "nonimmediate_operand")
7596 (match_operand 3 "const_int_operand")
7597 (match_operand 4 "const_int_operand"))
7599 "ix86_match_ccmode (insn, CCNOmode)"
7600 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7602 rtx val = operands[2];
7603 HOST_WIDE_INT len = INTVAL (operands[3]);
7604 HOST_WIDE_INT pos = INTVAL (operands[4]);
7606 machine_mode mode, submode;
7608 mode = GET_MODE (val);
7611 /* ??? Combine likes to put non-volatile mem extractions in QImode
7612 no matter the size of the test. So find a mode that works. */
7613 if (! MEM_VOLATILE_P (val))
7615 mode = smallest_mode_for_size (pos + len, MODE_INT);
7616 val = adjust_address (val, mode, 0);
7619 else if (GET_CODE (val) == SUBREG
7620 && (submode = GET_MODE (SUBREG_REG (val)),
7621 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7622 && pos + len <= GET_MODE_BITSIZE (submode)
7623 && GET_MODE_CLASS (submode) == MODE_INT)
7625 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7627 val = SUBREG_REG (val);
7629 else if (mode == HImode && pos + len <= 8)
7631 /* Small HImode tests can be converted to QImode. */
7633 val = gen_lowpart (QImode, val);
7636 if (len == HOST_BITS_PER_WIDE_INT)
7639 mask = ((HOST_WIDE_INT)1 << len) - 1;
7642 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7645 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7646 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7647 ;; this is relatively important trick.
7648 ;; Do the conversion only post-reload to avoid limiting of the register class
7651 [(set (match_operand 0 "flags_reg_operand")
7652 (match_operator 1 "compare_operator"
7653 [(and (match_operand 2 "QIreg_operand")
7654 (match_operand 3 "const_int_operand"))
7657 && GET_MODE (operands[2]) != QImode
7658 && ((ix86_match_ccmode (insn, CCZmode)
7659 && !(INTVAL (operands[3]) & ~(255 << 8)))
7660 || (ix86_match_ccmode (insn, CCNOmode)
7661 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7664 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7668 operands[2] = gen_lowpart (SImode, operands[2]);
7669 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7673 [(set (match_operand 0 "flags_reg_operand")
7674 (match_operator 1 "compare_operator"
7675 [(and (match_operand 2 "nonimmediate_operand")
7676 (match_operand 3 "const_int_operand"))
7679 && GET_MODE (operands[2]) != QImode
7680 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7681 && ((ix86_match_ccmode (insn, CCZmode)
7682 && !(INTVAL (operands[3]) & ~255))
7683 || (ix86_match_ccmode (insn, CCNOmode)
7684 && !(INTVAL (operands[3]) & ~127)))"
7686 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7689 operands[2] = gen_lowpart (QImode, operands[2]);
7690 operands[3] = gen_lowpart (QImode, operands[3]);
7694 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7695 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7696 (match_operand:SWI1248x 2 "mask_reg_operand")))
7697 (clobber (reg:CC FLAGS_REG))]
7698 "TARGET_AVX512F && reload_completed"
7700 (any_logic:SWI1248x (match_dup 1)
7703 (define_insn "*k<logic><mode>"
7704 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7705 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7706 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7709 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7710 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7712 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7714 [(set_attr "mode" "<MODE>")
7715 (set_attr "type" "msklog")
7716 (set_attr "prefix" "vex")])
7718 ;; %%% This used to optimize known byte-wide and operations to memory,
7719 ;; and sometimes to QImode registers. If this is considered useful,
7720 ;; it should be done with splitters.
7722 (define_expand "and<mode>3"
7723 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7724 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7725 (match_operand:SWIM 2 "<general_szext_operand>")))]
7728 machine_mode mode = <MODE>mode;
7729 rtx (*insn) (rtx, rtx);
7731 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7733 HOST_WIDE_INT ival = INTVAL (operands[2]);
7735 if (ival == (HOST_WIDE_INT) 0xffffffff)
7737 else if (ival == 0xffff)
7739 else if (ival == 0xff)
7743 if (mode == <MODE>mode)
7745 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7749 if (<MODE>mode == DImode)
7750 insn = (mode == SImode)
7751 ? gen_zero_extendsidi2
7753 ? gen_zero_extendhidi2
7754 : gen_zero_extendqidi2;
7755 else if (<MODE>mode == SImode)
7756 insn = (mode == HImode)
7757 ? gen_zero_extendhisi2
7758 : gen_zero_extendqisi2;
7759 else if (<MODE>mode == HImode)
7760 insn = gen_zero_extendqihi2;
7764 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7768 (define_insn "*anddi_1"
7769 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7771 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7772 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7776 switch (get_attr_type (insn))
7782 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7785 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7786 if (get_attr_mode (insn) == MODE_SI)
7787 return "and{l}\t{%k2, %k0|%k0, %k2}";
7789 return "and{q}\t{%2, %0|%0, %2}";
7792 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7793 (set_attr "length_immediate" "*,*,*,0,0")
7794 (set (attr "prefix_rex")
7796 (and (eq_attr "type" "imovx")
7797 (and (match_test "INTVAL (operands[2]) == 0xff")
7798 (match_operand 1 "ext_QIreg_operand")))
7800 (const_string "*")))
7801 (set_attr "mode" "SI,DI,DI,SI,DI")])
7803 (define_insn "*andsi_1"
7804 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7805 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7806 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "ix86_binary_operator_ok (AND, SImode, operands)"
7810 switch (get_attr_type (insn))
7816 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7819 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7820 return "and{l}\t{%2, %0|%0, %2}";
7823 [(set_attr "type" "alu,alu,imovx,msklog")
7824 (set (attr "prefix_rex")
7826 (and (eq_attr "type" "imovx")
7827 (and (match_test "INTVAL (operands[2]) == 0xff")
7828 (match_operand 1 "ext_QIreg_operand")))
7830 (const_string "*")))
7831 (set_attr "length_immediate" "*,*,0,0")
7832 (set_attr "mode" "SI")])
7834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7835 (define_insn "*andsi_1_zext"
7836 [(set (match_operand:DI 0 "register_operand" "=r")
7838 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7839 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7840 (clobber (reg:CC FLAGS_REG))]
7841 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7842 "and{l}\t{%2, %k0|%k0, %2}"
7843 [(set_attr "type" "alu")
7844 (set_attr "mode" "SI")])
7846 (define_insn "*andhi_1"
7847 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7848 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7849 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7850 (clobber (reg:CC FLAGS_REG))]
7851 "ix86_binary_operator_ok (AND, HImode, operands)"
7853 switch (get_attr_type (insn))
7859 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7863 return "and{w}\t{%2, %0|%0, %2}";
7866 [(set_attr "type" "alu,alu,imovx,msklog")
7867 (set_attr "length_immediate" "*,*,0,*")
7868 (set (attr "prefix_rex")
7870 (and (eq_attr "type" "imovx")
7871 (match_operand 1 "ext_QIreg_operand"))
7873 (const_string "*")))
7874 (set_attr "mode" "HI,HI,SI,HI")])
7876 ;; %%% Potential partial reg stall on alternative 2. What to do?
7877 (define_insn "*andqi_1"
7878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7879 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7880 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7881 (clobber (reg:CC FLAGS_REG))]
7882 "ix86_binary_operator_ok (AND, QImode, operands)"
7884 switch (which_alternative)
7888 return "and{b}\t{%2, %0|%0, %2}";
7890 return "and{l}\t{%k2, %k0|%k0, %k2}";
7892 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7893 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7898 [(set_attr "type" "alu,alu,alu,msklog")
7899 (set_attr "mode" "QI,QI,SI,HI")])
7901 (define_insn "*andqi_1_slp"
7902 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7903 (and:QI (match_dup 0)
7904 (match_operand:QI 1 "general_operand" "qn,qmn")))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7907 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908 "and{b}\t{%1, %0|%0, %1}"
7909 [(set_attr "type" "alu1")
7910 (set_attr "mode" "QI")])
7912 (define_insn "kandn<mode>"
7913 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7916 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7917 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7918 (clobber (reg:CC FLAGS_REG))]
7921 switch (which_alternative)
7924 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7928 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7929 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7931 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7936 [(set_attr "isa" "bmi,*,avx512f")
7937 (set_attr "type" "bitmanip,*,msklog")
7938 (set_attr "prefix" "*,*,vex")
7939 (set_attr "btver2_decode" "direct,*,*")
7940 (set_attr "mode" "<MODE>")])
7943 [(set (match_operand:SWI12 0 "general_reg_operand")
7947 (match_operand:SWI12 1 "general_reg_operand")))
7948 (clobber (reg:CC FLAGS_REG))]
7949 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7951 (not:HI (match_dup 0)))
7952 (parallel [(set (match_dup 0)
7953 (and:HI (match_dup 0)
7955 (clobber (reg:CC FLAGS_REG))])])
7957 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7959 [(set (match_operand:DI 0 "register_operand")
7960 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7961 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7962 (clobber (reg:CC FLAGS_REG))]
7964 [(parallel [(set (match_dup 0)
7965 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7966 (clobber (reg:CC FLAGS_REG))])]
7967 "operands[2] = gen_lowpart (SImode, operands[2]);")
7970 [(set (match_operand:SWI248 0 "register_operand")
7971 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7972 (match_operand:SWI248 2 "const_int_operand")))
7973 (clobber (reg:CC FLAGS_REG))]
7975 && true_regnum (operands[0]) != true_regnum (operands[1])"
7978 HOST_WIDE_INT ival = INTVAL (operands[2]);
7980 rtx (*insn) (rtx, rtx);
7982 if (ival == (HOST_WIDE_INT) 0xffffffff)
7984 else if (ival == 0xffff)
7988 gcc_assert (ival == 0xff);
7992 if (<MODE>mode == DImode)
7993 insn = (mode == SImode)
7994 ? gen_zero_extendsidi2
7996 ? gen_zero_extendhidi2
7997 : gen_zero_extendqidi2;
8000 if (<MODE>mode != SImode)
8001 /* Zero extend to SImode to avoid partial register stalls. */
8002 operands[0] = gen_lowpart (SImode, operands[0]);
8004 insn = (mode == HImode)
8005 ? gen_zero_extendhisi2
8006 : gen_zero_extendqisi2;
8008 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8013 [(set (match_operand:SWI48 0 "register_operand")
8014 (and:SWI48 (match_dup 0)
8015 (const_int -65536)))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8018 || optimize_function_for_size_p (cfun)"
8019 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8020 "operands[1] = gen_lowpart (HImode, operands[0]);")
8023 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8024 (and:SWI248 (match_dup 0)
8026 (clobber (reg:CC FLAGS_REG))]
8027 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8028 && reload_completed"
8029 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8030 "operands[1] = gen_lowpart (QImode, operands[0]);")
8033 [(set (match_operand:SWI248 0 "QIreg_operand")
8034 (and:SWI248 (match_dup 0)
8035 (const_int -65281)))
8036 (clobber (reg:CC FLAGS_REG))]
8037 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8038 && reload_completed"
8039 [(parallel [(set (zero_extract:SI (match_dup 0)
8043 (zero_extract:SI (match_dup 0)
8046 (zero_extract:SI (match_dup 0)
8049 (clobber (reg:CC FLAGS_REG))])]
8050 "operands[0] = gen_lowpart (SImode, operands[0]);")
8052 (define_insn "*anddi_2"
8053 [(set (reg FLAGS_REG)
8056 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8057 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8059 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8060 (and:DI (match_dup 1) (match_dup 2)))]
8062 && ix86_match_ccmode
8064 /* If we are going to emit andl instead of andq, and the operands[2]
8065 constant might have the SImode sign bit set, make sure the sign
8066 flag isn't tested, because the instruction will set the sign flag
8067 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8068 conservatively assume it might have bit 31 set. */
8069 (satisfies_constraint_Z (operands[2])
8070 && (!CONST_INT_P (operands[2])
8071 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8072 ? CCZmode : CCNOmode)
8073 && ix86_binary_operator_ok (AND, DImode, operands)"
8075 and{l}\t{%k2, %k0|%k0, %k2}
8076 and{q}\t{%2, %0|%0, %2}
8077 and{q}\t{%2, %0|%0, %2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "mode" "SI,DI,DI")])
8081 (define_insn "*andqi_2_maybe_si"
8082 [(set (reg FLAGS_REG)
8084 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8085 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8087 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8088 (and:QI (match_dup 1) (match_dup 2)))]
8089 "ix86_binary_operator_ok (AND, QImode, operands)
8090 && ix86_match_ccmode (insn,
8091 CONST_INT_P (operands[2])
8092 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8094 if (which_alternative == 2)
8096 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8097 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8098 return "and{l}\t{%2, %k0|%k0, %2}";
8100 return "and{b}\t{%2, %0|%0, %2}";
8102 [(set_attr "type" "alu")
8103 (set_attr "mode" "QI,QI,SI")])
8105 (define_insn "*and<mode>_2"
8106 [(set (reg FLAGS_REG)
8107 (compare (and:SWI124
8108 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8109 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8111 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8112 (and:SWI124 (match_dup 1) (match_dup 2)))]
8113 "ix86_match_ccmode (insn, CCNOmode)
8114 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8115 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8116 [(set_attr "type" "alu")
8117 (set_attr "mode" "<MODE>")])
8119 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8120 (define_insn "*andsi_2_zext"
8121 [(set (reg FLAGS_REG)
8123 (match_operand:SI 1 "nonimmediate_operand" "%0")
8124 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8126 (set (match_operand:DI 0 "register_operand" "=r")
8127 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8128 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8129 && ix86_binary_operator_ok (AND, SImode, operands)"
8130 "and{l}\t{%2, %k0|%k0, %2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "SI")])
8134 (define_insn "*andqi_2_slp"
8135 [(set (reg FLAGS_REG)
8137 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8138 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8140 (set (strict_low_part (match_dup 0))
8141 (and:QI (match_dup 0) (match_dup 1)))]
8142 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8143 && ix86_match_ccmode (insn, CCNOmode)
8144 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8145 "and{b}\t{%1, %0|%0, %1}"
8146 [(set_attr "type" "alu1")
8147 (set_attr "mode" "QI")])
8149 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8150 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8151 ;; for a QImode operand, which of course failed.
8152 (define_insn "andqi_ext_0"
8153 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8158 (match_operand 1 "ext_register_operand" "0")
8161 (match_operand 2 "const_int_operand" "n")))
8162 (clobber (reg:CC FLAGS_REG))]
8164 "and{b}\t{%2, %h0|%h0, %2}"
8165 [(set_attr "type" "alu")
8166 (set_attr "length_immediate" "1")
8167 (set_attr "modrm" "1")
8168 (set_attr "mode" "QI")])
8170 ;; Generated by peephole translating test to and. This shows up
8171 ;; often in fp comparisons.
8172 (define_insn "*andqi_ext_0_cc"
8173 [(set (reg FLAGS_REG)
8177 (match_operand 1 "ext_register_operand" "0")
8180 (match_operand 2 "const_int_operand" "n"))
8182 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8191 "ix86_match_ccmode (insn, CCNOmode)"
8192 "and{b}\t{%2, %h0|%h0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "length_immediate" "1")
8195 (set_attr "modrm" "1")
8196 (set_attr "mode" "QI")])
8198 (define_insn "*andqi_ext_1"
8199 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8204 (match_operand 1 "ext_register_operand" "0,0")
8208 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8209 (clobber (reg:CC FLAGS_REG))]
8211 "and{b}\t{%2, %h0|%h0, %2}"
8212 [(set_attr "isa" "*,nox64")
8213 (set_attr "type" "alu")
8214 (set_attr "length_immediate" "0")
8215 (set_attr "mode" "QI")])
8217 (define_insn "*andqi_ext_2"
8218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223 (match_operand 1 "ext_register_operand" "%0")
8227 (match_operand 2 "ext_register_operand" "Q")
8230 (clobber (reg:CC FLAGS_REG))]
8232 "and{b}\t{%h2, %h0|%h0, %h2}"
8233 [(set_attr "type" "alu")
8234 (set_attr "length_immediate" "0")
8235 (set_attr "mode" "QI")])
8237 ;; Convert wide AND instructions with immediate operand to shorter QImode
8238 ;; equivalents when possible.
8239 ;; Don't do the splitting with memory operands, since it introduces risk
8240 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8241 ;; for size, but that can (should?) be handled by generic code instead.
8243 [(set (match_operand 0 "QIreg_operand")
8244 (and (match_operand 1 "register_operand")
8245 (match_operand 2 "const_int_operand")))
8246 (clobber (reg:CC FLAGS_REG))]
8248 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8249 && !(~INTVAL (operands[2]) & ~(255 << 8))
8250 && GET_MODE (operands[0]) != QImode"
8251 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8252 (and:SI (zero_extract:SI (match_dup 1)
8253 (const_int 8) (const_int 8))
8255 (clobber (reg:CC FLAGS_REG))])]
8257 operands[0] = gen_lowpart (SImode, operands[0]);
8258 operands[1] = gen_lowpart (SImode, operands[1]);
8259 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8262 ;; Since AND can be encoded with sign extended immediate, this is only
8263 ;; profitable when 7th bit is not set.
8265 [(set (match_operand 0 "any_QIreg_operand")
8266 (and (match_operand 1 "general_operand")
8267 (match_operand 2 "const_int_operand")))
8268 (clobber (reg:CC FLAGS_REG))]
8270 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271 && !(~INTVAL (operands[2]) & ~255)
8272 && !(INTVAL (operands[2]) & 128)
8273 && GET_MODE (operands[0]) != QImode"
8274 [(parallel [(set (strict_low_part (match_dup 0))
8275 (and:QI (match_dup 1)
8277 (clobber (reg:CC FLAGS_REG))])]
8279 operands[0] = gen_lowpart (QImode, operands[0]);
8280 operands[1] = gen_lowpart (QImode, operands[1]);
8281 operands[2] = gen_lowpart (QImode, operands[2]);
8284 ;; Logical inclusive and exclusive OR instructions
8286 ;; %%% This used to optimize known byte-wide and operations to memory.
8287 ;; If this is considered useful, it should be done with splitters.
8289 (define_expand "<code><mode>3"
8290 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8291 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8292 (match_operand:SWIM 2 "<general_operand>")))]
8294 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8296 (define_insn "*<code><mode>_1"
8297 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8299 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8300 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8304 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8305 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8306 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8307 [(set_attr "type" "alu,alu,msklog")
8308 (set_attr "mode" "<MODE>")])
8310 (define_insn "*<code>hi_1"
8311 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8313 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8314 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8318 <logic>{w}\t{%2, %0|%0, %2}
8319 <logic>{w}\t{%2, %0|%0, %2}
8320 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8321 [(set_attr "type" "alu,alu,msklog")
8322 (set_attr "mode" "HI")])
8324 ;; %%% Potential partial reg stall on alternative 2. What to do?
8325 (define_insn "*<code>qi_1"
8326 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8327 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8328 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8332 <logic>{b}\t{%2, %0|%0, %2}
8333 <logic>{b}\t{%2, %0|%0, %2}
8334 <logic>{l}\t{%k2, %k0|%k0, %k2}
8335 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8336 [(set_attr "type" "alu,alu,alu,msklog")
8337 (set_attr "mode" "QI,QI,SI,HI")])
8339 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8340 (define_insn "*<code>si_1_zext"
8341 [(set (match_operand:DI 0 "register_operand" "=r")
8343 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8344 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8347 "<logic>{l}\t{%2, %k0|%k0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "mode" "SI")])
8351 (define_insn "*<code>si_1_zext_imm"
8352 [(set (match_operand:DI 0 "register_operand" "=r")
8354 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8355 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8356 (clobber (reg:CC FLAGS_REG))]
8357 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8358 "<logic>{l}\t{%2, %k0|%k0, %2}"
8359 [(set_attr "type" "alu")
8360 (set_attr "mode" "SI")])
8362 (define_insn "*<code>qi_1_slp"
8363 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8364 (any_or:QI (match_dup 0)
8365 (match_operand:QI 1 "general_operand" "qmn,qn")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8369 "<logic>{b}\t{%1, %0|%0, %1}"
8370 [(set_attr "type" "alu1")
8371 (set_attr "mode" "QI")])
8373 (define_insn "*<code><mode>_2"
8374 [(set (reg FLAGS_REG)
8375 (compare (any_or:SWI
8376 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8377 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8379 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8380 (any_or:SWI (match_dup 1) (match_dup 2)))]
8381 "ix86_match_ccmode (insn, CCNOmode)
8382 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8383 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "mode" "<MODE>")])
8387 (define_insn "kxnor<mode>"
8388 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8391 (match_operand:SWI12 1 "register_operand" "0,k")
8392 (match_operand:SWI12 2 "register_operand" "r,k"))))
8393 (clobber (reg:CC FLAGS_REG))]
8396 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8397 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8398 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8400 [(set_attr "type" "*,msklog")
8401 (set_attr "prefix" "*,vex")
8402 (set_attr "mode" "<MODE>")])
8404 (define_insn "kxnor<mode>"
8405 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8408 (match_operand:SWI48x 1 "register_operand" "0,k")
8409 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8410 (clobber (reg:CC FLAGS_REG))]
8414 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8415 [(set_attr "type" "*,msklog")
8416 (set_attr "prefix" "*,vex")
8417 (set_attr "mode" "<MODE>")])
8420 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8424 (match_operand:SWI1248x 1 "general_reg_operand"))))
8425 (clobber (reg:CC FLAGS_REG))]
8426 "TARGET_AVX512F && reload_completed"
8427 [(parallel [(set (match_dup 0)
8428 (xor:HI (match_dup 0)
8430 (clobber (reg:CC FLAGS_REG))])
8432 (not:HI (match_dup 0)))])
8434 ;;There are kortrest[bdq] but no intrinsics for them.
8435 ;;We probably don't need to implement them.
8436 (define_insn "kortestzhi"
8437 [(set (reg:CCZ FLAGS_REG)
8440 (match_operand:HI 0 "register_operand" "k")
8441 (match_operand:HI 1 "register_operand" "k"))
8443 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8444 "kortestw\t{%1, %0|%0, %1}"
8445 [(set_attr "mode" "HI")
8446 (set_attr "type" "msklog")
8447 (set_attr "prefix" "vex")])
8449 (define_insn "kortestchi"
8450 [(set (reg:CCC FLAGS_REG)
8453 (match_operand:HI 0 "register_operand" "k")
8454 (match_operand:HI 1 "register_operand" "k"))
8456 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8457 "kortestw\t{%1, %0|%0, %1}"
8458 [(set_attr "mode" "HI")
8459 (set_attr "type" "msklog")
8460 (set_attr "prefix" "vex")])
8462 (define_insn "kunpckhi"
8463 [(set (match_operand:HI 0 "register_operand" "=k")
8466 (match_operand:HI 1 "register_operand" "k")
8468 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8470 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8471 [(set_attr "mode" "HI")
8472 (set_attr "type" "msklog")
8473 (set_attr "prefix" "vex")])
8475 (define_insn "kunpcksi"
8476 [(set (match_operand:SI 0 "register_operand" "=k")
8479 (match_operand:SI 1 "register_operand" "k")
8481 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8483 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8484 [(set_attr "mode" "SI")])
8486 (define_insn "kunpckdi"
8487 [(set (match_operand:DI 0 "register_operand" "=k")
8490 (match_operand:DI 1 "register_operand" "k")
8492 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8494 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8495 [(set_attr "mode" "DI")])
8497 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8498 ;; ??? Special case for immediate operand is missing - it is tricky.
8499 (define_insn "*<code>si_2_zext"
8500 [(set (reg FLAGS_REG)
8501 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8502 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8504 (set (match_operand:DI 0 "register_operand" "=r")
8505 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8506 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8507 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8508 "<logic>{l}\t{%2, %k0|%k0, %2}"
8509 [(set_attr "type" "alu")
8510 (set_attr "mode" "SI")])
8512 (define_insn "*<code>si_2_zext_imm"
8513 [(set (reg FLAGS_REG)
8515 (match_operand:SI 1 "nonimmediate_operand" "%0")
8516 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8518 (set (match_operand:DI 0 "register_operand" "=r")
8519 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8520 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8521 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8522 "<logic>{l}\t{%2, %k0|%k0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "mode" "SI")])
8526 (define_insn "*<code>qi_2_slp"
8527 [(set (reg FLAGS_REG)
8528 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8529 (match_operand:QI 1 "general_operand" "qmn,qn"))
8531 (set (strict_low_part (match_dup 0))
8532 (any_or:QI (match_dup 0) (match_dup 1)))]
8533 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8534 && ix86_match_ccmode (insn, CCNOmode)
8535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8536 "<logic>{b}\t{%1, %0|%0, %1}"
8537 [(set_attr "type" "alu1")
8538 (set_attr "mode" "QI")])
8540 (define_insn "*<code><mode>_3"
8541 [(set (reg FLAGS_REG)
8542 (compare (any_or:SWI
8543 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8544 (match_operand:SWI 2 "<general_operand>" "<g>"))
8546 (clobber (match_scratch:SWI 0 "=<r>"))]
8547 "ix86_match_ccmode (insn, CCNOmode)
8548 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8549 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8550 [(set_attr "type" "alu")
8551 (set_attr "mode" "<MODE>")])
8553 (define_insn "*<code>qi_ext_0"
8554 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8559 (match_operand 1 "ext_register_operand" "0")
8562 (match_operand 2 "const_int_operand" "n")))
8563 (clobber (reg:CC FLAGS_REG))]
8564 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8565 "<logic>{b}\t{%2, %h0|%h0, %2}"
8566 [(set_attr "type" "alu")
8567 (set_attr "length_immediate" "1")
8568 (set_attr "modrm" "1")
8569 (set_attr "mode" "QI")])
8571 (define_insn "*<code>qi_ext_1"
8572 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8577 (match_operand 1 "ext_register_operand" "0,0")
8581 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8584 "<logic>{b}\t{%2, %h0|%h0, %2}"
8585 [(set_attr "isa" "*,nox64")
8586 (set_attr "type" "alu")
8587 (set_attr "length_immediate" "0")
8588 (set_attr "mode" "QI")])
8590 (define_insn "*<code>qi_ext_2"
8591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8595 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8598 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8601 (clobber (reg:CC FLAGS_REG))]
8602 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8603 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "length_immediate" "0")
8606 (set_attr "mode" "QI")])
8609 [(set (match_operand 0 "QIreg_operand")
8610 (any_or (match_operand 1 "register_operand")
8611 (match_operand 2 "const_int_operand")))
8612 (clobber (reg:CC FLAGS_REG))]
8614 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8615 && !(INTVAL (operands[2]) & ~(255 << 8))
8616 && GET_MODE (operands[0]) != QImode"
8617 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8618 (any_or:SI (zero_extract:SI (match_dup 1)
8619 (const_int 8) (const_int 8))
8621 (clobber (reg:CC FLAGS_REG))])]
8623 operands[0] = gen_lowpart (SImode, operands[0]);
8624 operands[1] = gen_lowpart (SImode, operands[1]);
8625 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8628 ;; Since OR can be encoded with sign extended immediate, this is only
8629 ;; profitable when 7th bit is set.
8631 [(set (match_operand 0 "any_QIreg_operand")
8632 (any_or (match_operand 1 "general_operand")
8633 (match_operand 2 "const_int_operand")))
8634 (clobber (reg:CC FLAGS_REG))]
8636 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8637 && !(INTVAL (operands[2]) & ~255)
8638 && (INTVAL (operands[2]) & 128)
8639 && GET_MODE (operands[0]) != QImode"
8640 [(parallel [(set (strict_low_part (match_dup 0))
8641 (any_or:QI (match_dup 1)
8643 (clobber (reg:CC FLAGS_REG))])]
8645 operands[0] = gen_lowpart (QImode, operands[0]);
8646 operands[1] = gen_lowpart (QImode, operands[1]);
8647 operands[2] = gen_lowpart (QImode, operands[2]);
8650 (define_expand "xorqi_cc_ext_1"
8652 (set (reg:CCNO FLAGS_REG)
8656 (match_operand 1 "ext_register_operand")
8659 (match_operand:QI 2 "const_int_operand"))
8661 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8671 (define_insn "*xorqi_cc_ext_1"
8672 [(set (reg FLAGS_REG)
8676 (match_operand 1 "ext_register_operand" "0,0")
8679 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8681 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8690 "ix86_match_ccmode (insn, CCNOmode)"
8691 "xor{b}\t{%2, %h0|%h0, %2}"
8692 [(set_attr "isa" "*,nox64")
8693 (set_attr "type" "alu")
8694 (set_attr "modrm" "1")
8695 (set_attr "mode" "QI")])
8697 ;; Negation instructions
8699 (define_expand "neg<mode>2"
8700 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8701 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8703 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8705 (define_insn_and_split "*neg<dwi>2_doubleword"
8706 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8707 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8713 [(set (reg:CCZ FLAGS_REG)
8714 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8715 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8718 (plus:DWIH (match_dup 3)
8719 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8721 (clobber (reg:CC FLAGS_REG))])
8724 (neg:DWIH (match_dup 2)))
8725 (clobber (reg:CC FLAGS_REG))])]
8726 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8728 (define_insn "*neg<mode>2_1"
8729 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8730 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8731 (clobber (reg:CC FLAGS_REG))]
8732 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8733 "neg{<imodesuffix>}\t%0"
8734 [(set_attr "type" "negnot")
8735 (set_attr "mode" "<MODE>")])
8737 ;; Combine is quite creative about this pattern.
8738 (define_insn "*negsi2_1_zext"
8739 [(set (match_operand:DI 0 "register_operand" "=r")
8741 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8744 (clobber (reg:CC FLAGS_REG))]
8745 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8747 [(set_attr "type" "negnot")
8748 (set_attr "mode" "SI")])
8750 ;; The problem with neg is that it does not perform (compare x 0),
8751 ;; it really performs (compare 0 x), which leaves us with the zero
8752 ;; flag being the only useful item.
8754 (define_insn "*neg<mode>2_cmpz"
8755 [(set (reg:CCZ FLAGS_REG)
8757 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8759 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8760 (neg:SWI (match_dup 1)))]
8761 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8762 "neg{<imodesuffix>}\t%0"
8763 [(set_attr "type" "negnot")
8764 (set_attr "mode" "<MODE>")])
8766 (define_insn "*negsi2_cmpz_zext"
8767 [(set (reg:CCZ FLAGS_REG)
8771 (match_operand:DI 1 "register_operand" "0")
8775 (set (match_operand:DI 0 "register_operand" "=r")
8776 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8779 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8781 [(set_attr "type" "negnot")
8782 (set_attr "mode" "SI")])
8784 ;; Negate with jump on overflow.
8785 (define_expand "negv<mode>3"
8786 [(parallel [(set (reg:CCO FLAGS_REG)
8787 (ne:CCO (match_operand:SWI 1 "register_operand")
8789 (set (match_operand:SWI 0 "register_operand")
8790 (neg:SWI (match_dup 1)))])
8791 (set (pc) (if_then_else
8792 (eq (reg:CCO FLAGS_REG) (const_int 0))
8793 (label_ref (match_operand 2))
8798 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8802 (define_insn "*negv<mode>3"
8803 [(set (reg:CCO FLAGS_REG)
8804 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8805 (match_operand:SWI 2 "const_int_operand")))
8806 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8807 (neg:SWI (match_dup 1)))]
8808 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8809 && mode_signbit_p (<MODE>mode, operands[2])"
8810 "neg{<imodesuffix>}\t%0"
8811 [(set_attr "type" "negnot")
8812 (set_attr "mode" "<MODE>")])
8814 ;; Changing of sign for FP values is doable using integer unit too.
8816 (define_expand "<code><mode>2"
8817 [(set (match_operand:X87MODEF 0 "register_operand")
8818 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8819 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8820 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8822 (define_insn "*absneg<mode>2_mixed"
8823 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8824 (match_operator:MODEF 3 "absneg_operator"
8825 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8826 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8827 (clobber (reg:CC FLAGS_REG))]
8828 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8830 [(set (attr "enabled")
8831 (cond [(eq_attr "alternative" "2")
8832 (symbol_ref "TARGET_MIX_SSE_I387")
8834 (symbol_ref "true")))])
8836 (define_insn "*absneg<mode>2_i387"
8837 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8838 (match_operator:X87MODEF 3 "absneg_operator"
8839 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8840 (use (match_operand 2))
8841 (clobber (reg:CC FLAGS_REG))]
8842 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8845 (define_expand "<code>tf2"
8846 [(set (match_operand:TF 0 "register_operand")
8847 (absneg:TF (match_operand:TF 1 "register_operand")))]
8849 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8851 (define_insn "*absnegtf2_sse"
8852 [(set (match_operand:TF 0 "register_operand" "=x,x")
8853 (match_operator:TF 3 "absneg_operator"
8854 [(match_operand:TF 1 "register_operand" "0,x")]))
8855 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8856 (clobber (reg:CC FLAGS_REG))]
8860 ;; Splitters for fp abs and neg.
8863 [(set (match_operand 0 "fp_register_operand")
8864 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8865 (use (match_operand 2))
8866 (clobber (reg:CC FLAGS_REG))]
8868 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8871 [(set (match_operand 0 "register_operand")
8872 (match_operator 3 "absneg_operator"
8873 [(match_operand 1 "register_operand")]))
8874 (use (match_operand 2 "nonimmediate_operand"))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "reload_completed && SSE_REG_P (operands[0])"
8877 [(set (match_dup 0) (match_dup 3))]
8879 machine_mode mode = GET_MODE (operands[0]);
8880 machine_mode vmode = GET_MODE (operands[2]);
8883 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8884 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8885 if (operands_match_p (operands[0], operands[2]))
8886 std::swap (operands[1], operands[2]);
8887 if (GET_CODE (operands[3]) == ABS)
8888 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8890 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8895 [(set (match_operand:SF 0 "register_operand")
8896 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8897 (use (match_operand:V4SF 2))
8898 (clobber (reg:CC FLAGS_REG))]
8900 [(parallel [(set (match_dup 0) (match_dup 1))
8901 (clobber (reg:CC FLAGS_REG))])]
8904 operands[0] = gen_lowpart (SImode, operands[0]);
8905 if (GET_CODE (operands[1]) == ABS)
8907 tmp = gen_int_mode (0x7fffffff, SImode);
8908 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8912 tmp = gen_int_mode (0x80000000, SImode);
8913 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8919 [(set (match_operand:DF 0 "register_operand")
8920 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8921 (use (match_operand 2))
8922 (clobber (reg:CC FLAGS_REG))]
8924 [(parallel [(set (match_dup 0) (match_dup 1))
8925 (clobber (reg:CC FLAGS_REG))])]
8930 tmp = gen_lowpart (DImode, operands[0]);
8931 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8934 if (GET_CODE (operands[1]) == ABS)
8937 tmp = gen_rtx_NOT (DImode, tmp);
8941 operands[0] = gen_highpart (SImode, operands[0]);
8942 if (GET_CODE (operands[1]) == ABS)
8944 tmp = gen_int_mode (0x7fffffff, SImode);
8945 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8949 tmp = gen_int_mode (0x80000000, SImode);
8950 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8957 [(set (match_operand:XF 0 "register_operand")
8958 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8959 (use (match_operand 2))
8960 (clobber (reg:CC FLAGS_REG))]
8962 [(parallel [(set (match_dup 0) (match_dup 1))
8963 (clobber (reg:CC FLAGS_REG))])]
8966 operands[0] = gen_rtx_REG (SImode,
8967 true_regnum (operands[0])
8968 + (TARGET_64BIT ? 1 : 2));
8969 if (GET_CODE (operands[1]) == ABS)
8971 tmp = GEN_INT (0x7fff);
8972 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8976 tmp = GEN_INT (0x8000);
8977 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8982 ;; Conditionalize these after reload. If they match before reload, we
8983 ;; lose the clobber and ability to use integer instructions.
8985 (define_insn "*<code><mode>2_1"
8986 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8987 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8989 && (reload_completed
8990 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8991 "f<absneg_mnemonic>"
8992 [(set_attr "type" "fsgn")
8993 (set_attr "mode" "<MODE>")])
8995 (define_insn "*<code>extendsfdf2"
8996 [(set (match_operand:DF 0 "register_operand" "=f")
8997 (absneg:DF (float_extend:DF
8998 (match_operand:SF 1 "register_operand" "0"))))]
8999 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9000 "f<absneg_mnemonic>"
9001 [(set_attr "type" "fsgn")
9002 (set_attr "mode" "DF")])
9004 (define_insn "*<code>extendsfxf2"
9005 [(set (match_operand:XF 0 "register_operand" "=f")
9006 (absneg:XF (float_extend:XF
9007 (match_operand:SF 1 "register_operand" "0"))))]
9009 "f<absneg_mnemonic>"
9010 [(set_attr "type" "fsgn")
9011 (set_attr "mode" "XF")])
9013 (define_insn "*<code>extenddfxf2"
9014 [(set (match_operand:XF 0 "register_operand" "=f")
9015 (absneg:XF (float_extend:XF
9016 (match_operand:DF 1 "register_operand" "0"))))]
9018 "f<absneg_mnemonic>"
9019 [(set_attr "type" "fsgn")
9020 (set_attr "mode" "XF")])
9022 ;; Copysign instructions
9024 (define_mode_iterator CSGNMODE [SF DF TF])
9025 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9027 (define_expand "copysign<mode>3"
9028 [(match_operand:CSGNMODE 0 "register_operand")
9029 (match_operand:CSGNMODE 1 "nonmemory_operand")
9030 (match_operand:CSGNMODE 2 "register_operand")]
9031 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032 || (TARGET_SSE && (<MODE>mode == TFmode))"
9033 "ix86_expand_copysign (operands); DONE;")
9035 (define_insn_and_split "copysign<mode>3_const"
9036 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9038 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9039 (match_operand:CSGNMODE 2 "register_operand" "0")
9040 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9042 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9043 || (TARGET_SSE && (<MODE>mode == TFmode))"
9045 "&& reload_completed"
9047 "ix86_split_copysign_const (operands); DONE;")
9049 (define_insn "copysign<mode>3_var"
9050 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9052 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9053 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9054 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9055 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9057 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9058 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9059 || (TARGET_SSE && (<MODE>mode == TFmode))"
9063 [(set (match_operand:CSGNMODE 0 "register_operand")
9065 [(match_operand:CSGNMODE 2 "register_operand")
9066 (match_operand:CSGNMODE 3 "register_operand")
9067 (match_operand:<CSGNVMODE> 4)
9068 (match_operand:<CSGNVMODE> 5)]
9070 (clobber (match_scratch:<CSGNVMODE> 1))]
9071 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9072 || (TARGET_SSE && (<MODE>mode == TFmode)))
9073 && reload_completed"
9075 "ix86_split_copysign_var (operands); DONE;")
9077 ;; One complement instructions
9079 (define_expand "one_cmpl<mode>2"
9080 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9081 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9083 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9085 (define_insn "*one_cmpl<mode>2_1"
9086 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9087 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9088 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9090 not{<imodesuffix>}\t%0
9091 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9092 [(set_attr "isa" "*,avx512bw")
9093 (set_attr "type" "negnot,msklog")
9094 (set_attr "prefix" "*,vex")
9095 (set_attr "mode" "<MODE>")])
9097 (define_insn "*one_cmplhi2_1"
9098 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9099 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9100 "ix86_unary_operator_ok (NOT, HImode, operands)"
9103 knotw\t{%1, %0|%0, %1}"
9104 [(set_attr "isa" "*,avx512f")
9105 (set_attr "type" "negnot,msklog")
9106 (set_attr "prefix" "*,vex")
9107 (set_attr "mode" "HI")])
9109 ;; %%% Potential partial reg stall on alternative 1. What to do?
9110 (define_insn "*one_cmplqi2_1"
9111 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9112 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9113 "ix86_unary_operator_ok (NOT, QImode, operands)"
9115 switch (which_alternative)
9118 return "not{b}\t%0";
9120 return "not{l}\t%k0";
9122 if (TARGET_AVX512DQ)
9123 return "knotb\t{%1, %0|%0, %1}";
9124 return "knotw\t{%1, %0|%0, %1}";
9129 [(set_attr "isa" "*,*,avx512f")
9130 (set_attr "type" "negnot,negnot,msklog")
9131 (set_attr "prefix" "*,*,vex")
9132 (set_attr "mode" "QI,SI,QI")])
9134 ;; ??? Currently never generated - xor is used instead.
9135 (define_insn "*one_cmplsi2_1_zext"
9136 [(set (match_operand:DI 0 "register_operand" "=r")
9138 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9139 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9141 [(set_attr "type" "negnot")
9142 (set_attr "mode" "SI")])
9144 (define_insn "*one_cmpl<mode>2_2"
9145 [(set (reg FLAGS_REG)
9146 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9148 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9149 (not:SWI (match_dup 1)))]
9150 "ix86_match_ccmode (insn, CCNOmode)
9151 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9153 [(set_attr "type" "alu1")
9154 (set_attr "mode" "<MODE>")])
9157 [(set (match_operand 0 "flags_reg_operand")
9158 (match_operator 2 "compare_operator"
9159 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9161 (set (match_operand:SWI 1 "nonimmediate_operand")
9162 (not:SWI (match_dup 3)))]
9163 "ix86_match_ccmode (insn, CCNOmode)"
9164 [(parallel [(set (match_dup 0)
9165 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9168 (xor:SWI (match_dup 3) (const_int -1)))])])
9170 ;; ??? Currently never generated - xor is used instead.
9171 (define_insn "*one_cmplsi2_2_zext"
9172 [(set (reg FLAGS_REG)
9173 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9175 (set (match_operand:DI 0 "register_operand" "=r")
9176 (zero_extend:DI (not:SI (match_dup 1))))]
9177 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9178 && ix86_unary_operator_ok (NOT, SImode, operands)"
9180 [(set_attr "type" "alu1")
9181 (set_attr "mode" "SI")])
9184 [(set (match_operand 0 "flags_reg_operand")
9185 (match_operator 2 "compare_operator"
9186 [(not:SI (match_operand:SI 3 "register_operand"))
9188 (set (match_operand:DI 1 "register_operand")
9189 (zero_extend:DI (not:SI (match_dup 3))))]
9190 "ix86_match_ccmode (insn, CCNOmode)"
9191 [(parallel [(set (match_dup 0)
9192 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9195 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9197 ;; Shift instructions
9199 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9200 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9201 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9202 ;; from the assembler input.
9204 ;; This instruction shifts the target reg/mem as usual, but instead of
9205 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9206 ;; is a left shift double, bits are taken from the high order bits of
9207 ;; reg, else if the insn is a shift right double, bits are taken from the
9208 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9209 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9211 ;; Since sh[lr]d does not change the `reg' operand, that is done
9212 ;; separately, making all shifts emit pairs of shift double and normal
9213 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9214 ;; support a 63 bit shift, each shift where the count is in a reg expands
9215 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9217 ;; If the shift count is a constant, we need never emit more than one
9218 ;; shift pair, instead using moves and sign extension for counts greater
9221 (define_expand "ashl<mode>3"
9222 [(set (match_operand:SDWIM 0 "<shift_operand>")
9223 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9224 (match_operand:QI 2 "nonmemory_operand")))]
9226 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9228 (define_insn "*ashl<mode>3_doubleword"
9229 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9230 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9231 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9232 (clobber (reg:CC FLAGS_REG))]
9235 [(set_attr "type" "multi")])
9238 [(set (match_operand:DWI 0 "register_operand")
9239 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9240 (match_operand:QI 2 "nonmemory_operand")))
9241 (clobber (reg:CC FLAGS_REG))]
9242 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9244 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9246 ;; By default we don't ask for a scratch register, because when DWImode
9247 ;; values are manipulated, registers are already at a premium. But if
9248 ;; we have one handy, we won't turn it away.
9251 [(match_scratch:DWIH 3 "r")
9252 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9254 (match_operand:<DWI> 1 "nonmemory_operand")
9255 (match_operand:QI 2 "nonmemory_operand")))
9256 (clobber (reg:CC FLAGS_REG))])
9260 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9262 (define_insn "x86_64_shld"
9263 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9264 (ior:DI (ashift:DI (match_dup 0)
9265 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9266 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9267 (minus:QI (const_int 64) (match_dup 2)))))
9268 (clobber (reg:CC FLAGS_REG))]
9270 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9271 [(set_attr "type" "ishift")
9272 (set_attr "prefix_0f" "1")
9273 (set_attr "mode" "DI")
9274 (set_attr "athlon_decode" "vector")
9275 (set_attr "amdfam10_decode" "vector")
9276 (set_attr "bdver1_decode" "vector")])
9278 (define_insn "x86_shld"
9279 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9280 (ior:SI (ashift:SI (match_dup 0)
9281 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9282 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9283 (minus:QI (const_int 32) (match_dup 2)))))
9284 (clobber (reg:CC FLAGS_REG))]
9286 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9287 [(set_attr "type" "ishift")
9288 (set_attr "prefix_0f" "1")
9289 (set_attr "mode" "SI")
9290 (set_attr "pent_pair" "np")
9291 (set_attr "athlon_decode" "vector")
9292 (set_attr "amdfam10_decode" "vector")
9293 (set_attr "bdver1_decode" "vector")])
9295 (define_expand "x86_shift<mode>_adj_1"
9296 [(set (reg:CCZ FLAGS_REG)
9297 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9300 (set (match_operand:SWI48 0 "register_operand")
9301 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9302 (match_operand:SWI48 1 "register_operand")
9305 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9306 (match_operand:SWI48 3 "register_operand")
9309 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9311 (define_expand "x86_shift<mode>_adj_2"
9312 [(use (match_operand:SWI48 0 "register_operand"))
9313 (use (match_operand:SWI48 1 "register_operand"))
9314 (use (match_operand:QI 2 "register_operand"))]
9317 rtx_code_label *label = gen_label_rtx ();
9320 emit_insn (gen_testqi_ccz_1 (operands[2],
9321 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9323 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9324 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9325 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9326 gen_rtx_LABEL_REF (VOIDmode, label),
9328 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9329 JUMP_LABEL (tmp) = label;
9331 emit_move_insn (operands[0], operands[1]);
9332 ix86_expand_clear (operands[1]);
9335 LABEL_NUSES (label) = 1;
9340 ;; Avoid useless masking of count operand.
9341 (define_insn "*ashl<mode>3_mask"
9342 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9344 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9347 (match_operand:SI 2 "register_operand" "c")
9348 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9349 (clobber (reg:CC FLAGS_REG))]
9350 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9351 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9352 == GET_MODE_BITSIZE (<MODE>mode)-1"
9354 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9356 [(set_attr "type" "ishift")
9357 (set_attr "mode" "<MODE>")])
9359 (define_insn "*bmi2_ashl<mode>3_1"
9360 [(set (match_operand:SWI48 0 "register_operand" "=r")
9361 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9362 (match_operand:SWI48 2 "register_operand" "r")))]
9364 "shlx\t{%2, %1, %0|%0, %1, %2}"
9365 [(set_attr "type" "ishiftx")
9366 (set_attr "mode" "<MODE>")])
9368 (define_insn "*ashl<mode>3_1"
9369 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9370 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9371 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9372 (clobber (reg:CC FLAGS_REG))]
9373 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9375 switch (get_attr_type (insn))
9382 gcc_assert (operands[2] == const1_rtx);
9383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9384 return "add{<imodesuffix>}\t%0, %0";
9387 if (operands[2] == const1_rtx
9388 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9389 return "sal{<imodesuffix>}\t%0";
9391 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9394 [(set_attr "isa" "*,*,bmi2")
9396 (cond [(eq_attr "alternative" "1")
9397 (const_string "lea")
9398 (eq_attr "alternative" "2")
9399 (const_string "ishiftx")
9400 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9401 (match_operand 0 "register_operand"))
9402 (match_operand 2 "const1_operand"))
9403 (const_string "alu")
9405 (const_string "ishift")))
9406 (set (attr "length_immediate")
9408 (ior (eq_attr "type" "alu")
9409 (and (eq_attr "type" "ishift")
9410 (and (match_operand 2 "const1_operand")
9411 (ior (match_test "TARGET_SHIFT1")
9412 (match_test "optimize_function_for_size_p (cfun)")))))
9414 (const_string "*")))
9415 (set_attr "mode" "<MODE>")])
9417 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9419 [(set (match_operand:SWI48 0 "register_operand")
9420 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9421 (match_operand:QI 2 "register_operand")))
9422 (clobber (reg:CC FLAGS_REG))]
9423 "TARGET_BMI2 && reload_completed"
9425 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9426 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9428 (define_insn "*bmi2_ashlsi3_1_zext"
9429 [(set (match_operand:DI 0 "register_operand" "=r")
9431 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9432 (match_operand:SI 2 "register_operand" "r"))))]
9433 "TARGET_64BIT && TARGET_BMI2"
9434 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9435 [(set_attr "type" "ishiftx")
9436 (set_attr "mode" "SI")])
9438 (define_insn "*ashlsi3_1_zext"
9439 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9441 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9442 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9443 (clobber (reg:CC FLAGS_REG))]
9444 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9446 switch (get_attr_type (insn))
9453 gcc_assert (operands[2] == const1_rtx);
9454 return "add{l}\t%k0, %k0";
9457 if (operands[2] == const1_rtx
9458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9459 return "sal{l}\t%k0";
9461 return "sal{l}\t{%2, %k0|%k0, %2}";
9464 [(set_attr "isa" "*,*,bmi2")
9466 (cond [(eq_attr "alternative" "1")
9467 (const_string "lea")
9468 (eq_attr "alternative" "2")
9469 (const_string "ishiftx")
9470 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 2 "const1_operand"))
9472 (const_string "alu")
9474 (const_string "ishift")))
9475 (set (attr "length_immediate")
9477 (ior (eq_attr "type" "alu")
9478 (and (eq_attr "type" "ishift")
9479 (and (match_operand 2 "const1_operand")
9480 (ior (match_test "TARGET_SHIFT1")
9481 (match_test "optimize_function_for_size_p (cfun)")))))
9483 (const_string "*")))
9484 (set_attr "mode" "SI")])
9486 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9488 [(set (match_operand:DI 0 "register_operand")
9490 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9491 (match_operand:QI 2 "register_operand"))))
9492 (clobber (reg:CC FLAGS_REG))]
9493 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9495 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496 "operands[2] = gen_lowpart (SImode, operands[2]);")
9498 (define_insn "*ashlhi3_1"
9499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9500 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9501 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9505 switch (get_attr_type (insn))
9511 gcc_assert (operands[2] == const1_rtx);
9512 return "add{w}\t%0, %0";
9515 if (operands[2] == const1_rtx
9516 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9517 return "sal{w}\t%0";
9519 return "sal{w}\t{%2, %0|%0, %2}";
9523 (cond [(eq_attr "alternative" "1")
9524 (const_string "lea")
9525 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9526 (match_operand 0 "register_operand"))
9527 (match_operand 2 "const1_operand"))
9528 (const_string "alu")
9530 (const_string "ishift")))
9531 (set (attr "length_immediate")
9533 (ior (eq_attr "type" "alu")
9534 (and (eq_attr "type" "ishift")
9535 (and (match_operand 2 "const1_operand")
9536 (ior (match_test "TARGET_SHIFT1")
9537 (match_test "optimize_function_for_size_p (cfun)")))))
9539 (const_string "*")))
9540 (set_attr "mode" "HI,SI")])
9542 ;; %%% Potential partial reg stall on alternative 1. What to do?
9543 (define_insn "*ashlqi3_1"
9544 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9545 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9546 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9547 (clobber (reg:CC FLAGS_REG))]
9548 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9550 switch (get_attr_type (insn))
9556 gcc_assert (operands[2] == const1_rtx);
9557 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9558 return "add{l}\t%k0, %k0";
9560 return "add{b}\t%0, %0";
9563 if (operands[2] == const1_rtx
9564 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 if (get_attr_mode (insn) == MODE_SI)
9567 return "sal{l}\t%k0";
9569 return "sal{b}\t%0";
9573 if (get_attr_mode (insn) == MODE_SI)
9574 return "sal{l}\t{%2, %k0|%k0, %2}";
9576 return "sal{b}\t{%2, %0|%0, %2}";
9581 (cond [(eq_attr "alternative" "2")
9582 (const_string "lea")
9583 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584 (match_operand 0 "register_operand"))
9585 (match_operand 2 "const1_operand"))
9586 (const_string "alu")
9588 (const_string "ishift")))
9589 (set (attr "length_immediate")
9591 (ior (eq_attr "type" "alu")
9592 (and (eq_attr "type" "ishift")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "*")))
9598 (set_attr "mode" "QI,SI,SI")])
9600 (define_insn "*ashlqi3_1_slp"
9601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9602 (ashift:QI (match_dup 0)
9603 (match_operand:QI 1 "nonmemory_operand" "cI")))
9604 (clobber (reg:CC FLAGS_REG))]
9605 "(optimize_function_for_size_p (cfun)
9606 || !TARGET_PARTIAL_FLAG_REG_STALL
9607 || (operands[1] == const1_rtx
9609 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9611 switch (get_attr_type (insn))
9614 gcc_assert (operands[1] == const1_rtx);
9615 return "add{b}\t%0, %0";
9618 if (operands[1] == const1_rtx
9619 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9620 return "sal{b}\t%0";
9622 return "sal{b}\t{%1, %0|%0, %1}";
9626 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9627 (match_operand 0 "register_operand"))
9628 (match_operand 1 "const1_operand"))
9629 (const_string "alu")
9631 (const_string "ishift1")))
9632 (set (attr "length_immediate")
9634 (ior (eq_attr "type" "alu")
9635 (and (eq_attr "type" "ishift1")
9636 (and (match_operand 1 "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")])
9643 ;; Convert ashift to the lea pattern to avoid flags dependency.
9645 [(set (match_operand 0 "register_operand")
9646 (ashift (match_operand 1 "index_register_operand")
9647 (match_operand:QI 2 "const_int_operand")))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9651 && true_regnum (operands[0]) != true_regnum (operands[1])"
9654 machine_mode mode = GET_MODE (operands[0]);
9657 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9660 operands[0] = gen_lowpart (mode, operands[0]);
9661 operands[1] = gen_lowpart (mode, operands[1]);
9664 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9666 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9668 emit_insn (gen_rtx_SET (operands[0], pat));
9672 ;; Convert ashift to the lea pattern to avoid flags dependency.
9674 [(set (match_operand:DI 0 "register_operand")
9676 (ashift:SI (match_operand:SI 1 "index_register_operand")
9677 (match_operand:QI 2 "const_int_operand"))))
9678 (clobber (reg:CC FLAGS_REG))]
9679 "TARGET_64BIT && reload_completed
9680 && true_regnum (operands[0]) != true_regnum (operands[1])"
9682 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9684 operands[1] = gen_lowpart (SImode, operands[1]);
9685 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9688 ;; This pattern can't accept a variable shift count, since shifts by
9689 ;; zero don't affect the flags. We assume that shifts by constant
9690 ;; zero are optimized away.
9691 (define_insn "*ashl<mode>3_cmp"
9692 [(set (reg FLAGS_REG)
9694 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9695 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9697 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9698 (ashift:SWI (match_dup 1) (match_dup 2)))]
9699 "(optimize_function_for_size_p (cfun)
9700 || !TARGET_PARTIAL_FLAG_REG_STALL
9701 || (operands[2] == const1_rtx
9703 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9704 && ix86_match_ccmode (insn, CCGOCmode)
9705 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9707 switch (get_attr_type (insn))
9710 gcc_assert (operands[2] == const1_rtx);
9711 return "add{<imodesuffix>}\t%0, %0";
9714 if (operands[2] == const1_rtx
9715 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9716 return "sal{<imodesuffix>}\t%0";
9718 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9722 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9723 (match_operand 0 "register_operand"))
9724 (match_operand 2 "const1_operand"))
9725 (const_string "alu")
9727 (const_string "ishift")))
9728 (set (attr "length_immediate")
9730 (ior (eq_attr "type" "alu")
9731 (and (eq_attr "type" "ishift")
9732 (and (match_operand 2 "const1_operand")
9733 (ior (match_test "TARGET_SHIFT1")
9734 (match_test "optimize_function_for_size_p (cfun)")))))
9736 (const_string "*")))
9737 (set_attr "mode" "<MODE>")])
9739 (define_insn "*ashlsi3_cmp_zext"
9740 [(set (reg FLAGS_REG)
9742 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9743 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9745 (set (match_operand:DI 0 "register_operand" "=r")
9746 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9748 && (optimize_function_for_size_p (cfun)
9749 || !TARGET_PARTIAL_FLAG_REG_STALL
9750 || (operands[2] == const1_rtx
9752 || TARGET_DOUBLE_WITH_ADD)))
9753 && ix86_match_ccmode (insn, CCGOCmode)
9754 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9756 switch (get_attr_type (insn))
9759 gcc_assert (operands[2] == const1_rtx);
9760 return "add{l}\t%k0, %k0";
9763 if (operands[2] == const1_rtx
9764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765 return "sal{l}\t%k0";
9767 return "sal{l}\t{%2, %k0|%k0, %2}";
9771 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9772 (match_operand 2 "const1_operand"))
9773 (const_string "alu")
9775 (const_string "ishift")))
9776 (set (attr "length_immediate")
9778 (ior (eq_attr "type" "alu")
9779 (and (eq_attr "type" "ishift")
9780 (and (match_operand 2 "const1_operand")
9781 (ior (match_test "TARGET_SHIFT1")
9782 (match_test "optimize_function_for_size_p (cfun)")))))
9784 (const_string "*")))
9785 (set_attr "mode" "SI")])
9787 (define_insn "*ashl<mode>3_cconly"
9788 [(set (reg FLAGS_REG)
9790 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9791 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9793 (clobber (match_scratch:SWI 0 "=<r>"))]
9794 "(optimize_function_for_size_p (cfun)
9795 || !TARGET_PARTIAL_FLAG_REG_STALL
9796 || (operands[2] == const1_rtx
9798 || TARGET_DOUBLE_WITH_ADD)))
9799 && ix86_match_ccmode (insn, CCGOCmode)"
9801 switch (get_attr_type (insn))
9804 gcc_assert (operands[2] == const1_rtx);
9805 return "add{<imodesuffix>}\t%0, %0";
9808 if (operands[2] == const1_rtx
9809 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9810 return "sal{<imodesuffix>}\t%0";
9812 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9816 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9817 (match_operand 0 "register_operand"))
9818 (match_operand 2 "const1_operand"))
9819 (const_string "alu")
9821 (const_string "ishift")))
9822 (set (attr "length_immediate")
9824 (ior (eq_attr "type" "alu")
9825 (and (eq_attr "type" "ishift")
9826 (and (match_operand 2 "const1_operand")
9827 (ior (match_test "TARGET_SHIFT1")
9828 (match_test "optimize_function_for_size_p (cfun)")))))
9830 (const_string "*")))
9831 (set_attr "mode" "<MODE>")])
9833 ;; See comment above `ashl<mode>3' about how this works.
9835 (define_expand "<shift_insn><mode>3"
9836 [(set (match_operand:SDWIM 0 "<shift_operand>")
9837 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9838 (match_operand:QI 2 "nonmemory_operand")))]
9840 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9842 ;; Avoid useless masking of count operand.
9843 (define_insn "*<shift_insn><mode>3_mask"
9844 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9846 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9849 (match_operand:SI 2 "register_operand" "c")
9850 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9851 (clobber (reg:CC FLAGS_REG))]
9852 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9853 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9854 == GET_MODE_BITSIZE (<MODE>mode)-1"
9856 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9858 [(set_attr "type" "ishift")
9859 (set_attr "mode" "<MODE>")])
9861 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9862 [(set (match_operand:DWI 0 "register_operand" "=r")
9863 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9864 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9865 (clobber (reg:CC FLAGS_REG))]
9868 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9870 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9871 [(set_attr "type" "multi")])
9873 ;; By default we don't ask for a scratch register, because when DWImode
9874 ;; values are manipulated, registers are already at a premium. But if
9875 ;; we have one handy, we won't turn it away.
9878 [(match_scratch:DWIH 3 "r")
9879 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9881 (match_operand:<DWI> 1 "register_operand")
9882 (match_operand:QI 2 "nonmemory_operand")))
9883 (clobber (reg:CC FLAGS_REG))])
9887 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9889 (define_insn "x86_64_shrd"
9890 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9891 (ior:DI (lshiftrt:DI (match_dup 0)
9892 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9893 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9894 (minus:QI (const_int 64) (match_dup 2)))))
9895 (clobber (reg:CC FLAGS_REG))]
9897 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9898 [(set_attr "type" "ishift")
9899 (set_attr "prefix_0f" "1")
9900 (set_attr "mode" "DI")
9901 (set_attr "athlon_decode" "vector")
9902 (set_attr "amdfam10_decode" "vector")
9903 (set_attr "bdver1_decode" "vector")])
9905 (define_insn "x86_shrd"
9906 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9907 (ior:SI (lshiftrt:SI (match_dup 0)
9908 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9909 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9910 (minus:QI (const_int 32) (match_dup 2)))))
9911 (clobber (reg:CC FLAGS_REG))]
9913 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9914 [(set_attr "type" "ishift")
9915 (set_attr "prefix_0f" "1")
9916 (set_attr "mode" "SI")
9917 (set_attr "pent_pair" "np")
9918 (set_attr "athlon_decode" "vector")
9919 (set_attr "amdfam10_decode" "vector")
9920 (set_attr "bdver1_decode" "vector")])
9922 (define_insn "ashrdi3_cvt"
9923 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9924 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9925 (match_operand:QI 2 "const_int_operand")))
9926 (clobber (reg:CC FLAGS_REG))]
9927 "TARGET_64BIT && INTVAL (operands[2]) == 63
9928 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9929 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9932 sar{q}\t{%2, %0|%0, %2}"
9933 [(set_attr "type" "imovx,ishift")
9934 (set_attr "prefix_0f" "0,*")
9935 (set_attr "length_immediate" "0,*")
9936 (set_attr "modrm" "0,1")
9937 (set_attr "mode" "DI")])
9939 (define_insn "ashrsi3_cvt"
9940 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9941 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9942 (match_operand:QI 2 "const_int_operand")))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "INTVAL (operands[2]) == 31
9945 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9946 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9949 sar{l}\t{%2, %0|%0, %2}"
9950 [(set_attr "type" "imovx,ishift")
9951 (set_attr "prefix_0f" "0,*")
9952 (set_attr "length_immediate" "0,*")
9953 (set_attr "modrm" "0,1")
9954 (set_attr "mode" "SI")])
9956 (define_insn "*ashrsi3_cvt_zext"
9957 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9959 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9960 (match_operand:QI 2 "const_int_operand"))))
9961 (clobber (reg:CC FLAGS_REG))]
9962 "TARGET_64BIT && INTVAL (operands[2]) == 31
9963 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9964 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9967 sar{l}\t{%2, %k0|%k0, %2}"
9968 [(set_attr "type" "imovx,ishift")
9969 (set_attr "prefix_0f" "0,*")
9970 (set_attr "length_immediate" "0,*")
9971 (set_attr "modrm" "0,1")
9972 (set_attr "mode" "SI")])
9974 (define_expand "x86_shift<mode>_adj_3"
9975 [(use (match_operand:SWI48 0 "register_operand"))
9976 (use (match_operand:SWI48 1 "register_operand"))
9977 (use (match_operand:QI 2 "register_operand"))]
9980 rtx_code_label *label = gen_label_rtx ();
9983 emit_insn (gen_testqi_ccz_1 (operands[2],
9984 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9986 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9987 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9988 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9989 gen_rtx_LABEL_REF (VOIDmode, label),
9991 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9992 JUMP_LABEL (tmp) = label;
9994 emit_move_insn (operands[0], operands[1]);
9995 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9996 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9998 LABEL_NUSES (label) = 1;
10003 (define_insn "*bmi2_<shift_insn><mode>3_1"
10004 [(set (match_operand:SWI48 0 "register_operand" "=r")
10005 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10006 (match_operand:SWI48 2 "register_operand" "r")))]
10008 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10009 [(set_attr "type" "ishiftx")
10010 (set_attr "mode" "<MODE>")])
10012 (define_insn "*<shift_insn><mode>3_1"
10013 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10015 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10016 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10017 (clobber (reg:CC FLAGS_REG))]
10018 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10020 switch (get_attr_type (insn))
10026 if (operands[2] == const1_rtx
10027 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028 return "<shift>{<imodesuffix>}\t%0";
10030 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10033 [(set_attr "isa" "*,bmi2")
10034 (set_attr "type" "ishift,ishiftx")
10035 (set (attr "length_immediate")
10037 (and (match_operand 2 "const1_operand")
10038 (ior (match_test "TARGET_SHIFT1")
10039 (match_test "optimize_function_for_size_p (cfun)")))
10041 (const_string "*")))
10042 (set_attr "mode" "<MODE>")])
10044 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10046 [(set (match_operand:SWI48 0 "register_operand")
10047 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10048 (match_operand:QI 2 "register_operand")))
10049 (clobber (reg:CC FLAGS_REG))]
10050 "TARGET_BMI2 && reload_completed"
10051 [(set (match_dup 0)
10052 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10053 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10055 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10056 [(set (match_operand:DI 0 "register_operand" "=r")
10058 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10059 (match_operand:SI 2 "register_operand" "r"))))]
10060 "TARGET_64BIT && TARGET_BMI2"
10061 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10062 [(set_attr "type" "ishiftx")
10063 (set_attr "mode" "SI")])
10065 (define_insn "*<shift_insn>si3_1_zext"
10066 [(set (match_operand:DI 0 "register_operand" "=r,r")
10068 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10069 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10073 switch (get_attr_type (insn))
10079 if (operands[2] == const1_rtx
10080 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10081 return "<shift>{l}\t%k0";
10083 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10086 [(set_attr "isa" "*,bmi2")
10087 (set_attr "type" "ishift,ishiftx")
10088 (set (attr "length_immediate")
10090 (and (match_operand 2 "const1_operand")
10091 (ior (match_test "TARGET_SHIFT1")
10092 (match_test "optimize_function_for_size_p (cfun)")))
10094 (const_string "*")))
10095 (set_attr "mode" "SI")])
10097 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10099 [(set (match_operand:DI 0 "register_operand")
10101 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10102 (match_operand:QI 2 "register_operand"))))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10105 [(set (match_dup 0)
10106 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10107 "operands[2] = gen_lowpart (SImode, operands[2]);")
10109 (define_insn "*<shift_insn><mode>3_1"
10110 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10112 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10113 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10114 (clobber (reg:CC FLAGS_REG))]
10115 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10117 if (operands[2] == const1_rtx
10118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119 return "<shift>{<imodesuffix>}\t%0";
10121 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10123 [(set_attr "type" "ishift")
10124 (set (attr "length_immediate")
10126 (and (match_operand 2 "const1_operand")
10127 (ior (match_test "TARGET_SHIFT1")
10128 (match_test "optimize_function_for_size_p (cfun)")))
10130 (const_string "*")))
10131 (set_attr "mode" "<MODE>")])
10133 (define_insn "*<shift_insn>qi3_1_slp"
10134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10135 (any_shiftrt:QI (match_dup 0)
10136 (match_operand:QI 1 "nonmemory_operand" "cI")))
10137 (clobber (reg:CC FLAGS_REG))]
10138 "(optimize_function_for_size_p (cfun)
10139 || !TARGET_PARTIAL_REG_STALL
10140 || (operands[1] == const1_rtx
10141 && TARGET_SHIFT1))"
10143 if (operands[1] == const1_rtx
10144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145 return "<shift>{b}\t%0";
10147 return "<shift>{b}\t{%1, %0|%0, %1}";
10149 [(set_attr "type" "ishift1")
10150 (set (attr "length_immediate")
10152 (and (match_operand 1 "const1_operand")
10153 (ior (match_test "TARGET_SHIFT1")
10154 (match_test "optimize_function_for_size_p (cfun)")))
10156 (const_string "*")))
10157 (set_attr "mode" "QI")])
10159 ;; This pattern can't accept a variable shift count, since shifts by
10160 ;; zero don't affect the flags. We assume that shifts by constant
10161 ;; zero are optimized away.
10162 (define_insn "*<shift_insn><mode>3_cmp"
10163 [(set (reg FLAGS_REG)
10166 (match_operand:SWI 1 "nonimmediate_operand" "0")
10167 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10169 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10170 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10171 "(optimize_function_for_size_p (cfun)
10172 || !TARGET_PARTIAL_FLAG_REG_STALL
10173 || (operands[2] == const1_rtx
10175 && ix86_match_ccmode (insn, CCGOCmode)
10176 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10178 if (operands[2] == const1_rtx
10179 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10180 return "<shift>{<imodesuffix>}\t%0";
10182 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10184 [(set_attr "type" "ishift")
10185 (set (attr "length_immediate")
10187 (and (match_operand 2 "const1_operand")
10188 (ior (match_test "TARGET_SHIFT1")
10189 (match_test "optimize_function_for_size_p (cfun)")))
10191 (const_string "*")))
10192 (set_attr "mode" "<MODE>")])
10194 (define_insn "*<shift_insn>si3_cmp_zext"
10195 [(set (reg FLAGS_REG)
10197 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10198 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10200 (set (match_operand:DI 0 "register_operand" "=r")
10201 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10203 && (optimize_function_for_size_p (cfun)
10204 || !TARGET_PARTIAL_FLAG_REG_STALL
10205 || (operands[2] == const1_rtx
10207 && ix86_match_ccmode (insn, CCGOCmode)
10208 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10210 if (operands[2] == const1_rtx
10211 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10212 return "<shift>{l}\t%k0";
10214 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10216 [(set_attr "type" "ishift")
10217 (set (attr "length_immediate")
10219 (and (match_operand 2 "const1_operand")
10220 (ior (match_test "TARGET_SHIFT1")
10221 (match_test "optimize_function_for_size_p (cfun)")))
10223 (const_string "*")))
10224 (set_attr "mode" "SI")])
10226 (define_insn "*<shift_insn><mode>3_cconly"
10227 [(set (reg FLAGS_REG)
10230 (match_operand:SWI 1 "register_operand" "0")
10231 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10233 (clobber (match_scratch:SWI 0 "=<r>"))]
10234 "(optimize_function_for_size_p (cfun)
10235 || !TARGET_PARTIAL_FLAG_REG_STALL
10236 || (operands[2] == const1_rtx
10238 && ix86_match_ccmode (insn, CCGOCmode)"
10240 if (operands[2] == const1_rtx
10241 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10242 return "<shift>{<imodesuffix>}\t%0";
10244 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10246 [(set_attr "type" "ishift")
10247 (set (attr "length_immediate")
10249 (and (match_operand 2 "const1_operand")
10250 (ior (match_test "TARGET_SHIFT1")
10251 (match_test "optimize_function_for_size_p (cfun)")))
10253 (const_string "*")))
10254 (set_attr "mode" "<MODE>")])
10256 ;; Rotate instructions
10258 (define_expand "<rotate_insn>ti3"
10259 [(set (match_operand:TI 0 "register_operand")
10260 (any_rotate:TI (match_operand:TI 1 "register_operand")
10261 (match_operand:QI 2 "nonmemory_operand")))]
10264 if (const_1_to_63_operand (operands[2], VOIDmode))
10265 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10266 (operands[0], operands[1], operands[2]));
10273 (define_expand "<rotate_insn>di3"
10274 [(set (match_operand:DI 0 "shiftdi_operand")
10275 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10276 (match_operand:QI 2 "nonmemory_operand")))]
10280 ix86_expand_binary_operator (<CODE>, DImode, operands);
10281 else if (const_1_to_31_operand (operands[2], VOIDmode))
10282 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10283 (operands[0], operands[1], operands[2]));
10290 (define_expand "<rotate_insn><mode>3"
10291 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10292 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10293 (match_operand:QI 2 "nonmemory_operand")))]
10295 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10297 ;; Avoid useless masking of count operand.
10298 (define_insn "*<rotate_insn><mode>3_mask"
10299 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10301 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10304 (match_operand:SI 2 "register_operand" "c")
10305 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10308 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10309 == GET_MODE_BITSIZE (<MODE>mode)-1"
10311 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10313 [(set_attr "type" "rotate")
10314 (set_attr "mode" "<MODE>")])
10316 ;; Implement rotation using two double-precision
10317 ;; shift instructions and a scratch register.
10319 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10320 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10321 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10322 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10323 (clobber (reg:CC FLAGS_REG))
10324 (clobber (match_scratch:DWIH 3 "=&r"))]
10328 [(set (match_dup 3) (match_dup 4))
10330 [(set (match_dup 4)
10331 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10332 (lshiftrt:DWIH (match_dup 5)
10333 (minus:QI (match_dup 6) (match_dup 2)))))
10334 (clobber (reg:CC FLAGS_REG))])
10336 [(set (match_dup 5)
10337 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10338 (lshiftrt:DWIH (match_dup 3)
10339 (minus:QI (match_dup 6) (match_dup 2)))))
10340 (clobber (reg:CC FLAGS_REG))])]
10342 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10344 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10347 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10348 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10349 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10350 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10351 (clobber (reg:CC FLAGS_REG))
10352 (clobber (match_scratch:DWIH 3 "=&r"))]
10356 [(set (match_dup 3) (match_dup 4))
10358 [(set (match_dup 4)
10359 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10360 (ashift:DWIH (match_dup 5)
10361 (minus:QI (match_dup 6) (match_dup 2)))))
10362 (clobber (reg:CC FLAGS_REG))])
10364 [(set (match_dup 5)
10365 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10366 (ashift:DWIH (match_dup 3)
10367 (minus:QI (match_dup 6) (match_dup 2)))))
10368 (clobber (reg:CC FLAGS_REG))])]
10370 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10372 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10375 (define_insn "*bmi2_rorx<mode>3_1"
10376 [(set (match_operand:SWI48 0 "register_operand" "=r")
10377 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10378 (match_operand:QI 2 "immediate_operand" "<S>")))]
10380 "rorx\t{%2, %1, %0|%0, %1, %2}"
10381 [(set_attr "type" "rotatex")
10382 (set_attr "mode" "<MODE>")])
10384 (define_insn "*<rotate_insn><mode>3_1"
10385 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10387 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10388 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392 switch (get_attr_type (insn))
10398 if (operands[2] == const1_rtx
10399 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10400 return "<rotate>{<imodesuffix>}\t%0";
10402 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10405 [(set_attr "isa" "*,bmi2")
10406 (set_attr "type" "rotate,rotatex")
10407 (set (attr "length_immediate")
10409 (and (eq_attr "type" "rotate")
10410 (and (match_operand 2 "const1_operand")
10411 (ior (match_test "TARGET_SHIFT1")
10412 (match_test "optimize_function_for_size_p (cfun)"))))
10414 (const_string "*")))
10415 (set_attr "mode" "<MODE>")])
10417 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10419 [(set (match_operand:SWI48 0 "register_operand")
10420 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10421 (match_operand:QI 2 "immediate_operand")))
10422 (clobber (reg:CC FLAGS_REG))]
10423 "TARGET_BMI2 && reload_completed"
10424 [(set (match_dup 0)
10425 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10428 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10432 [(set (match_operand:SWI48 0 "register_operand")
10433 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10434 (match_operand:QI 2 "immediate_operand")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_BMI2 && reload_completed"
10437 [(set (match_dup 0)
10438 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10440 (define_insn "*bmi2_rorxsi3_1_zext"
10441 [(set (match_operand:DI 0 "register_operand" "=r")
10443 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10444 (match_operand:QI 2 "immediate_operand" "I"))))]
10445 "TARGET_64BIT && TARGET_BMI2"
10446 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10447 [(set_attr "type" "rotatex")
10448 (set_attr "mode" "SI")])
10450 (define_insn "*<rotate_insn>si3_1_zext"
10451 [(set (match_operand:DI 0 "register_operand" "=r,r")
10453 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10454 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10455 (clobber (reg:CC FLAGS_REG))]
10456 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10458 switch (get_attr_type (insn))
10464 if (operands[2] == const1_rtx
10465 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10466 return "<rotate>{l}\t%k0";
10468 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10471 [(set_attr "isa" "*,bmi2")
10472 (set_attr "type" "rotate,rotatex")
10473 (set (attr "length_immediate")
10475 (and (eq_attr "type" "rotate")
10476 (and (match_operand 2 "const1_operand")
10477 (ior (match_test "TARGET_SHIFT1")
10478 (match_test "optimize_function_for_size_p (cfun)"))))
10480 (const_string "*")))
10481 (set_attr "mode" "SI")])
10483 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10485 [(set (match_operand:DI 0 "register_operand")
10487 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10488 (match_operand:QI 2 "immediate_operand"))))
10489 (clobber (reg:CC FLAGS_REG))]
10490 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10491 [(set (match_dup 0)
10492 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10495 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10499 [(set (match_operand:DI 0 "register_operand")
10501 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10502 (match_operand:QI 2 "immediate_operand"))))
10503 (clobber (reg:CC FLAGS_REG))]
10504 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10505 [(set (match_dup 0)
10506 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10508 (define_insn "*<rotate_insn><mode>3_1"
10509 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10510 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10511 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10512 (clobber (reg:CC FLAGS_REG))]
10513 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10515 if (operands[2] == const1_rtx
10516 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10517 return "<rotate>{<imodesuffix>}\t%0";
10519 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10521 [(set_attr "type" "rotate")
10522 (set (attr "length_immediate")
10524 (and (match_operand 2 "const1_operand")
10525 (ior (match_test "TARGET_SHIFT1")
10526 (match_test "optimize_function_for_size_p (cfun)")))
10528 (const_string "*")))
10529 (set_attr "mode" "<MODE>")])
10531 (define_insn "*<rotate_insn>qi3_1_slp"
10532 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10533 (any_rotate:QI (match_dup 0)
10534 (match_operand:QI 1 "nonmemory_operand" "cI")))
10535 (clobber (reg:CC FLAGS_REG))]
10536 "(optimize_function_for_size_p (cfun)
10537 || !TARGET_PARTIAL_REG_STALL
10538 || (operands[1] == const1_rtx
10539 && TARGET_SHIFT1))"
10541 if (operands[1] == const1_rtx
10542 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10543 return "<rotate>{b}\t%0";
10545 return "<rotate>{b}\t{%1, %0|%0, %1}";
10547 [(set_attr "type" "rotate1")
10548 (set (attr "length_immediate")
10550 (and (match_operand 1 "const1_operand")
10551 (ior (match_test "TARGET_SHIFT1")
10552 (match_test "optimize_function_for_size_p (cfun)")))
10554 (const_string "*")))
10555 (set_attr "mode" "QI")])
10558 [(set (match_operand:HI 0 "register_operand")
10559 (any_rotate:HI (match_dup 0) (const_int 8)))
10560 (clobber (reg:CC FLAGS_REG))]
10562 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10563 [(parallel [(set (strict_low_part (match_dup 0))
10564 (bswap:HI (match_dup 0)))
10565 (clobber (reg:CC FLAGS_REG))])])
10567 ;; Bit set / bit test instructions
10569 (define_expand "extv"
10570 [(set (match_operand:SI 0 "register_operand")
10571 (sign_extract:SI (match_operand:SI 1 "register_operand")
10572 (match_operand:SI 2 "const8_operand")
10573 (match_operand:SI 3 "const8_operand")))]
10576 /* Handle extractions from %ah et al. */
10577 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10580 /* From mips.md: extract_bit_field doesn't verify that our source
10581 matches the predicate, so check it again here. */
10582 if (! ext_register_operand (operands[1], VOIDmode))
10586 (define_expand "extzv"
10587 [(set (match_operand:SI 0 "register_operand")
10588 (zero_extract:SI (match_operand 1 "ext_register_operand")
10589 (match_operand:SI 2 "const8_operand")
10590 (match_operand:SI 3 "const8_operand")))]
10593 /* Handle extractions from %ah et al. */
10594 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10597 /* From mips.md: extract_bit_field doesn't verify that our source
10598 matches the predicate, so check it again here. */
10599 if (! ext_register_operand (operands[1], VOIDmode))
10603 (define_expand "insv"
10604 [(set (zero_extract (match_operand 0 "register_operand")
10605 (match_operand 1 "const_int_operand")
10606 (match_operand 2 "const_int_operand"))
10607 (match_operand 3 "register_operand"))]
10610 rtx (*gen_mov_insv_1) (rtx, rtx);
10612 if (ix86_expand_pinsr (operands))
10615 /* Handle insertions to %ah et al. */
10616 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10619 /* From mips.md: insert_bit_field doesn't verify that our source
10620 matches the predicate, so check it again here. */
10621 if (! ext_register_operand (operands[0], VOIDmode))
10624 gen_mov_insv_1 = (TARGET_64BIT
10625 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10627 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10631 ;; %%% bts, btr, btc, bt.
10632 ;; In general these instructions are *slow* when applied to memory,
10633 ;; since they enforce atomic operation. When applied to registers,
10634 ;; it depends on the cpu implementation. They're never faster than
10635 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10636 ;; no point. But in 64-bit, we can't hold the relevant immediates
10637 ;; within the instruction itself, so operating on bits in the high
10638 ;; 32-bits of a register becomes easier.
10640 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10641 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10642 ;; negdf respectively, so they can never be disabled entirely.
10644 (define_insn "*btsq"
10645 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10647 (match_operand:DI 1 "const_0_to_63_operand"))
10649 (clobber (reg:CC FLAGS_REG))]
10650 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10651 "bts{q}\t{%1, %0|%0, %1}"
10652 [(set_attr "type" "alu1")
10653 (set_attr "prefix_0f" "1")
10654 (set_attr "mode" "DI")])
10656 (define_insn "*btrq"
10657 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10659 (match_operand:DI 1 "const_0_to_63_operand"))
10661 (clobber (reg:CC FLAGS_REG))]
10662 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10663 "btr{q}\t{%1, %0|%0, %1}"
10664 [(set_attr "type" "alu1")
10665 (set_attr "prefix_0f" "1")
10666 (set_attr "mode" "DI")])
10668 (define_insn "*btcq"
10669 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10671 (match_operand:DI 1 "const_0_to_63_operand"))
10672 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10673 (clobber (reg:CC FLAGS_REG))]
10674 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10675 "btc{q}\t{%1, %0|%0, %1}"
10676 [(set_attr "type" "alu1")
10677 (set_attr "prefix_0f" "1")
10678 (set_attr "mode" "DI")])
10680 ;; Allow Nocona to avoid these instructions if a register is available.
10683 [(match_scratch:DI 2 "r")
10684 (parallel [(set (zero_extract:DI
10685 (match_operand:DI 0 "register_operand")
10687 (match_operand:DI 1 "const_0_to_63_operand"))
10689 (clobber (reg:CC FLAGS_REG))])]
10690 "TARGET_64BIT && !TARGET_USE_BT"
10693 int i = INTVAL (operands[1]);
10695 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10699 emit_move_insn (operands[2], op1);
10703 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10708 [(match_scratch:DI 2 "r")
10709 (parallel [(set (zero_extract:DI
10710 (match_operand:DI 0 "register_operand")
10712 (match_operand:DI 1 "const_0_to_63_operand"))
10714 (clobber (reg:CC FLAGS_REG))])]
10715 "TARGET_64BIT && !TARGET_USE_BT"
10718 int i = INTVAL (operands[1]);
10720 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10724 emit_move_insn (operands[2], op1);
10728 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10733 [(match_scratch:DI 2 "r")
10734 (parallel [(set (zero_extract:DI
10735 (match_operand:DI 0 "register_operand")
10737 (match_operand:DI 1 "const_0_to_63_operand"))
10738 (not:DI (zero_extract:DI
10739 (match_dup 0) (const_int 1) (match_dup 1))))
10740 (clobber (reg:CC FLAGS_REG))])]
10741 "TARGET_64BIT && !TARGET_USE_BT"
10744 int i = INTVAL (operands[1]);
10746 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10750 emit_move_insn (operands[2], op1);
10754 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10758 (define_insn "*bt<mode>"
10759 [(set (reg:CCC FLAGS_REG)
10761 (zero_extract:SWI48
10762 (match_operand:SWI48 0 "register_operand" "r")
10764 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10766 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10767 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10768 [(set_attr "type" "alu1")
10769 (set_attr "prefix_0f" "1")
10770 (set_attr "mode" "<MODE>")])
10772 ;; Store-flag instructions.
10774 ;; For all sCOND expanders, also expand the compare or test insn that
10775 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10777 (define_insn_and_split "*setcc_di_1"
10778 [(set (match_operand:DI 0 "register_operand" "=q")
10779 (match_operator:DI 1 "ix86_comparison_operator"
10780 [(reg FLAGS_REG) (const_int 0)]))]
10781 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10783 "&& reload_completed"
10784 [(set (match_dup 2) (match_dup 1))
10785 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10787 PUT_MODE (operands[1], QImode);
10788 operands[2] = gen_lowpart (QImode, operands[0]);
10791 (define_insn_and_split "*setcc_si_1_and"
10792 [(set (match_operand:SI 0 "register_operand" "=q")
10793 (match_operator:SI 1 "ix86_comparison_operator"
10794 [(reg FLAGS_REG) (const_int 0)]))
10795 (clobber (reg:CC FLAGS_REG))]
10796 "!TARGET_PARTIAL_REG_STALL
10797 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10799 "&& reload_completed"
10800 [(set (match_dup 2) (match_dup 1))
10801 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10802 (clobber (reg:CC FLAGS_REG))])]
10804 PUT_MODE (operands[1], QImode);
10805 operands[2] = gen_lowpart (QImode, operands[0]);
10808 (define_insn_and_split "*setcc_si_1_movzbl"
10809 [(set (match_operand:SI 0 "register_operand" "=q")
10810 (match_operator:SI 1 "ix86_comparison_operator"
10811 [(reg FLAGS_REG) (const_int 0)]))]
10812 "!TARGET_PARTIAL_REG_STALL
10813 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10815 "&& reload_completed"
10816 [(set (match_dup 2) (match_dup 1))
10817 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10819 PUT_MODE (operands[1], QImode);
10820 operands[2] = gen_lowpart (QImode, operands[0]);
10823 (define_insn "*setcc_qi"
10824 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10825 (match_operator:QI 1 "ix86_comparison_operator"
10826 [(reg FLAGS_REG) (const_int 0)]))]
10829 [(set_attr "type" "setcc")
10830 (set_attr "mode" "QI")])
10832 (define_insn "*setcc_qi_slp"
10833 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10834 (match_operator:QI 1 "ix86_comparison_operator"
10835 [(reg FLAGS_REG) (const_int 0)]))]
10838 [(set_attr "type" "setcc")
10839 (set_attr "mode" "QI")])
10841 ;; In general it is not safe to assume too much about CCmode registers,
10842 ;; so simplify-rtx stops when it sees a second one. Under certain
10843 ;; conditions this is safe on x86, so help combine not create
10850 [(set (match_operand:QI 0 "nonimmediate_operand")
10851 (ne:QI (match_operator 1 "ix86_comparison_operator"
10852 [(reg FLAGS_REG) (const_int 0)])
10855 [(set (match_dup 0) (match_dup 1))]
10856 "PUT_MODE (operands[1], QImode);")
10859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10860 (ne:QI (match_operator 1 "ix86_comparison_operator"
10861 [(reg FLAGS_REG) (const_int 0)])
10864 [(set (match_dup 0) (match_dup 1))]
10865 "PUT_MODE (operands[1], QImode);")
10868 [(set (match_operand:QI 0 "nonimmediate_operand")
10869 (eq:QI (match_operator 1 "ix86_comparison_operator"
10870 [(reg FLAGS_REG) (const_int 0)])
10873 [(set (match_dup 0) (match_dup 1))]
10875 rtx new_op1 = copy_rtx (operands[1]);
10876 operands[1] = new_op1;
10877 PUT_MODE (new_op1, QImode);
10878 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10879 GET_MODE (XEXP (new_op1, 0))));
10881 /* Make sure that (a) the CCmode we have for the flags is strong
10882 enough for the reversed compare or (b) we have a valid FP compare. */
10883 if (! ix86_comparison_operator (new_op1, VOIDmode))
10888 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10889 (eq:QI (match_operator 1 "ix86_comparison_operator"
10890 [(reg FLAGS_REG) (const_int 0)])
10893 [(set (match_dup 0) (match_dup 1))]
10895 rtx new_op1 = copy_rtx (operands[1]);
10896 operands[1] = new_op1;
10897 PUT_MODE (new_op1, QImode);
10898 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10899 GET_MODE (XEXP (new_op1, 0))));
10901 /* Make sure that (a) the CCmode we have for the flags is strong
10902 enough for the reversed compare or (b) we have a valid FP compare. */
10903 if (! ix86_comparison_operator (new_op1, VOIDmode))
10907 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10908 ;; subsequent logical operations are used to imitate conditional moves.
10909 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10912 (define_insn "setcc_<mode>_sse"
10913 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10914 (match_operator:MODEF 3 "sse_comparison_operator"
10915 [(match_operand:MODEF 1 "register_operand" "0,x")
10916 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10917 "SSE_FLOAT_MODE_P (<MODE>mode)"
10919 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10920 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10921 [(set_attr "isa" "noavx,avx")
10922 (set_attr "type" "ssecmp")
10923 (set_attr "length_immediate" "1")
10924 (set_attr "prefix" "orig,vex")
10925 (set_attr "mode" "<MODE>")])
10927 ;; Basic conditional jump instructions.
10928 ;; We ignore the overflow flag for signed branch instructions.
10930 (define_insn "*jcc_1_bnd"
10932 (if_then_else (match_operator 1 "ix86_comparison_operator"
10933 [(reg FLAGS_REG) (const_int 0)])
10934 (label_ref (match_operand 0))
10936 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10938 [(set_attr "type" "ibr")
10939 (set_attr "modrm" "0")
10940 (set (attr "length")
10941 (if_then_else (and (ge (minus (match_dup 0) (pc))
10943 (lt (minus (match_dup 0) (pc))
10948 (define_insn "*jcc_1"
10950 (if_then_else (match_operator 1 "ix86_comparison_operator"
10951 [(reg FLAGS_REG) (const_int 0)])
10952 (label_ref (match_operand 0))
10956 [(set_attr "type" "ibr")
10957 (set_attr "modrm" "0")
10958 (set (attr "length")
10959 (if_then_else (and (ge (minus (match_dup 0) (pc))
10961 (lt (minus (match_dup 0) (pc))
10966 (define_insn "*jcc_2_bnd"
10968 (if_then_else (match_operator 1 "ix86_comparison_operator"
10969 [(reg FLAGS_REG) (const_int 0)])
10971 (label_ref (match_operand 0))))]
10972 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10974 [(set_attr "type" "ibr")
10975 (set_attr "modrm" "0")
10976 (set (attr "length")
10977 (if_then_else (and (ge (minus (match_dup 0) (pc))
10979 (lt (minus (match_dup 0) (pc))
10984 (define_insn "*jcc_2"
10986 (if_then_else (match_operator 1 "ix86_comparison_operator"
10987 [(reg FLAGS_REG) (const_int 0)])
10989 (label_ref (match_operand 0))))]
10992 [(set_attr "type" "ibr")
10993 (set_attr "modrm" "0")
10994 (set (attr "length")
10995 (if_then_else (and (ge (minus (match_dup 0) (pc))
10997 (lt (minus (match_dup 0) (pc))
11002 ;; In general it is not safe to assume too much about CCmode registers,
11003 ;; so simplify-rtx stops when it sees a second one. Under certain
11004 ;; conditions this is safe on x86, so help combine not create
11012 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11013 [(reg FLAGS_REG) (const_int 0)])
11015 (label_ref (match_operand 1))
11019 (if_then_else (match_dup 0)
11020 (label_ref (match_dup 1))
11022 "PUT_MODE (operands[0], VOIDmode);")
11026 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11027 [(reg FLAGS_REG) (const_int 0)])
11029 (label_ref (match_operand 1))
11033 (if_then_else (match_dup 0)
11034 (label_ref (match_dup 1))
11037 rtx new_op0 = copy_rtx (operands[0]);
11038 operands[0] = new_op0;
11039 PUT_MODE (new_op0, VOIDmode);
11040 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11041 GET_MODE (XEXP (new_op0, 0))));
11043 /* Make sure that (a) the CCmode we have for the flags is strong
11044 enough for the reversed compare or (b) we have a valid FP compare. */
11045 if (! ix86_comparison_operator (new_op0, VOIDmode))
11049 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11050 ;; pass generates from shift insn with QImode operand. Actually, the mode
11051 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11052 ;; appropriate modulo of the bit offset value.
11054 (define_insn_and_split "*jcc_bt<mode>"
11056 (if_then_else (match_operator 0 "bt_comparison_operator"
11057 [(zero_extract:SWI48
11058 (match_operand:SWI48 1 "register_operand" "r")
11061 (match_operand:QI 2 "register_operand" "r")))
11063 (label_ref (match_operand 3))
11065 (clobber (reg:CC FLAGS_REG))]
11066 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11069 [(set (reg:CCC FLAGS_REG)
11071 (zero_extract:SWI48
11077 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11078 (label_ref (match_dup 3))
11081 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11083 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11086 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11087 ;; zero extended to SImode.
11088 (define_insn_and_split "*jcc_bt<mode>_1"
11090 (if_then_else (match_operator 0 "bt_comparison_operator"
11091 [(zero_extract:SWI48
11092 (match_operand:SWI48 1 "register_operand" "r")
11094 (match_operand:SI 2 "register_operand" "r"))
11096 (label_ref (match_operand 3))
11098 (clobber (reg:CC FLAGS_REG))]
11099 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11102 [(set (reg:CCC FLAGS_REG)
11104 (zero_extract:SWI48
11110 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11111 (label_ref (match_dup 3))
11114 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11116 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11119 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11120 ;; also for DImode, this is what combine produces.
11121 (define_insn_and_split "*jcc_bt<mode>_mask"
11123 (if_then_else (match_operator 0 "bt_comparison_operator"
11124 [(zero_extract:SWI48
11125 (match_operand:SWI48 1 "register_operand" "r")
11128 (match_operand:SI 2 "register_operand" "r")
11129 (match_operand:SI 3 "const_int_operand" "n")))])
11130 (label_ref (match_operand 4))
11132 (clobber (reg:CC FLAGS_REG))]
11133 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11134 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11135 == GET_MODE_BITSIZE (<MODE>mode)-1"
11138 [(set (reg:CCC FLAGS_REG)
11140 (zero_extract:SWI48
11146 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11147 (label_ref (match_dup 4))
11150 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11152 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11155 (define_insn_and_split "*jcc_btsi_1"
11157 (if_then_else (match_operator 0 "bt_comparison_operator"
11160 (match_operand:SI 1 "register_operand" "r")
11161 (match_operand:QI 2 "register_operand" "r"))
11164 (label_ref (match_operand 3))
11166 (clobber (reg:CC FLAGS_REG))]
11167 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11170 [(set (reg:CCC FLAGS_REG)
11178 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11179 (label_ref (match_dup 3))
11182 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11184 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11187 ;; avoid useless masking of bit offset operand
11188 (define_insn_and_split "*jcc_btsi_mask_1"
11191 (match_operator 0 "bt_comparison_operator"
11194 (match_operand:SI 1 "register_operand" "r")
11197 (match_operand:SI 2 "register_operand" "r")
11198 (match_operand:SI 3 "const_int_operand" "n")) 0))
11201 (label_ref (match_operand 4))
11203 (clobber (reg:CC FLAGS_REG))]
11204 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11205 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11208 [(set (reg:CCC FLAGS_REG)
11216 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11217 (label_ref (match_dup 4))
11219 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11221 ;; Define combination compare-and-branch fp compare instructions to help
11224 (define_insn "*jcc<mode>_0_i387"
11226 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11227 [(match_operand:X87MODEF 1 "register_operand" "f")
11228 (match_operand:X87MODEF 2 "const0_operand")])
11229 (label_ref (match_operand 3))
11231 (clobber (reg:CCFP FPSR_REG))
11232 (clobber (reg:CCFP FLAGS_REG))
11233 (clobber (match_scratch:HI 4 "=a"))]
11234 "TARGET_80387 && !TARGET_CMOVE"
11237 (define_insn "*jcc<mode>_0_r_i387"
11239 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11240 [(match_operand:X87MODEF 1 "register_operand" "f")
11241 (match_operand:X87MODEF 2 "const0_operand")])
11243 (label_ref (match_operand 3))))
11244 (clobber (reg:CCFP FPSR_REG))
11245 (clobber (reg:CCFP FLAGS_REG))
11246 (clobber (match_scratch:HI 4 "=a"))]
11247 "TARGET_80387 && !TARGET_CMOVE"
11250 (define_insn "*jccxf_i387"
11252 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11253 [(match_operand:XF 1 "register_operand" "f")
11254 (match_operand:XF 2 "register_operand" "f")])
11255 (label_ref (match_operand 3))
11257 (clobber (reg:CCFP FPSR_REG))
11258 (clobber (reg:CCFP FLAGS_REG))
11259 (clobber (match_scratch:HI 4 "=a"))]
11260 "TARGET_80387 && !TARGET_CMOVE"
11263 (define_insn "*jccxf_r_i387"
11265 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11266 [(match_operand:XF 1 "register_operand" "f")
11267 (match_operand:XF 2 "register_operand" "f")])
11269 (label_ref (match_operand 3))))
11270 (clobber (reg:CCFP FPSR_REG))
11271 (clobber (reg:CCFP FLAGS_REG))
11272 (clobber (match_scratch:HI 4 "=a"))]
11273 "TARGET_80387 && !TARGET_CMOVE"
11276 (define_insn "*jcc<mode>_i387"
11278 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11279 [(match_operand:MODEF 1 "register_operand" "f")
11280 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11281 (label_ref (match_operand 3))
11283 (clobber (reg:CCFP FPSR_REG))
11284 (clobber (reg:CCFP FLAGS_REG))
11285 (clobber (match_scratch:HI 4 "=a"))]
11286 "TARGET_80387 && !TARGET_CMOVE"
11289 (define_insn "*jcc<mode>_r_i387"
11291 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11292 [(match_operand:MODEF 1 "register_operand" "f")
11293 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11295 (label_ref (match_operand 3))))
11296 (clobber (reg:CCFP FPSR_REG))
11297 (clobber (reg:CCFP FLAGS_REG))
11298 (clobber (match_scratch:HI 4 "=a"))]
11299 "TARGET_80387 && !TARGET_CMOVE"
11302 (define_insn "*jccu<mode>_i387"
11304 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11305 [(match_operand:X87MODEF 1 "register_operand" "f")
11306 (match_operand:X87MODEF 2 "register_operand" "f")])
11307 (label_ref (match_operand 3))
11309 (clobber (reg:CCFP FPSR_REG))
11310 (clobber (reg:CCFP FLAGS_REG))
11311 (clobber (match_scratch:HI 4 "=a"))]
11312 "TARGET_80387 && !TARGET_CMOVE"
11315 (define_insn "*jccu<mode>_r_i387"
11317 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11318 [(match_operand:X87MODEF 1 "register_operand" "f")
11319 (match_operand:X87MODEF 2 "register_operand" "f")])
11321 (label_ref (match_operand 3))))
11322 (clobber (reg:CCFP FPSR_REG))
11323 (clobber (reg:CCFP FLAGS_REG))
11324 (clobber (match_scratch:HI 4 "=a"))]
11325 "TARGET_80387 && !TARGET_CMOVE"
11330 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11331 [(match_operand:X87MODEF 1 "register_operand")
11332 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11334 (match_operand 4)))
11335 (clobber (reg:CCFP FPSR_REG))
11336 (clobber (reg:CCFP FLAGS_REG))]
11337 "TARGET_80387 && !TARGET_CMOVE
11338 && reload_completed"
11341 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11342 operands[3], operands[4], NULL_RTX);
11348 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11349 [(match_operand:X87MODEF 1 "register_operand")
11350 (match_operand:X87MODEF 2 "general_operand")])
11352 (match_operand 4)))
11353 (clobber (reg:CCFP FPSR_REG))
11354 (clobber (reg:CCFP FLAGS_REG))
11355 (clobber (match_scratch:HI 5))]
11356 "TARGET_80387 && !TARGET_CMOVE
11357 && reload_completed"
11360 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11361 operands[3], operands[4], operands[5]);
11365 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11366 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11367 ;; with a precedence over other operators and is always put in the first
11368 ;; place. Swap condition and operands to match ficom instruction.
11370 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11373 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11374 [(match_operator:X87MODEF 1 "float_operator"
11375 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11376 (match_operand:X87MODEF 3 "register_operand" "f")])
11377 (label_ref (match_operand 4))
11379 (clobber (reg:CCFP FPSR_REG))
11380 (clobber (reg:CCFP FLAGS_REG))
11381 (clobber (match_scratch:HI 5 "=a"))]
11382 "TARGET_80387 && !TARGET_CMOVE
11383 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11384 || optimize_function_for_size_p (cfun))"
11387 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11390 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11391 [(match_operator:X87MODEF 1 "float_operator"
11392 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11393 (match_operand:X87MODEF 3 "register_operand" "f")])
11395 (label_ref (match_operand 4))))
11396 (clobber (reg:CCFP FPSR_REG))
11397 (clobber (reg:CCFP FLAGS_REG))
11398 (clobber (match_scratch:HI 5 "=a"))]
11399 "TARGET_80387 && !TARGET_CMOVE
11400 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11401 || optimize_function_for_size_p (cfun))"
11407 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11408 [(match_operator:X87MODEF 1 "float_operator"
11409 [(match_operand:SWI24 2 "memory_operand")])
11410 (match_operand:X87MODEF 3 "register_operand")])
11412 (match_operand 5)))
11413 (clobber (reg:CCFP FPSR_REG))
11414 (clobber (reg:CCFP FLAGS_REG))
11415 (clobber (match_scratch:HI 6))]
11416 "TARGET_80387 && !TARGET_CMOVE
11417 && reload_completed"
11420 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11421 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11422 operands[4], operands[5], operands[6]);
11426 ;; Unconditional and other jump instructions
11428 (define_insn "jump_bnd"
11430 (label_ref (match_operand 0)))]
11431 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11433 [(set_attr "type" "ibr")
11434 (set (attr "length")
11435 (if_then_else (and (ge (minus (match_dup 0) (pc))
11437 (lt (minus (match_dup 0) (pc))
11441 (set_attr "modrm" "0")])
11443 (define_insn "jump"
11445 (label_ref (match_operand 0)))]
11448 [(set_attr "type" "ibr")
11449 (set (attr "length")
11450 (if_then_else (and (ge (minus (match_dup 0) (pc))
11452 (lt (minus (match_dup 0) (pc))
11456 (set_attr "modrm" "0")])
11458 (define_expand "indirect_jump"
11459 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11463 operands[0] = convert_memory_address (word_mode, operands[0]);
11466 (define_insn "*indirect_jump"
11467 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11470 [(set_attr "type" "ibr")
11471 (set_attr "length_immediate" "0")])
11473 (define_expand "tablejump"
11474 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11475 (use (label_ref (match_operand 1)))])]
11478 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11479 relative. Convert the relative address to an absolute address. */
11483 enum rtx_code code;
11485 /* We can't use @GOTOFF for text labels on VxWorks;
11486 see gotoff_operand. */
11487 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11491 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11493 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11497 op1 = pic_offset_table_rtx;
11502 op0 = pic_offset_table_rtx;
11506 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11511 operands[0] = convert_memory_address (word_mode, operands[0]);
11514 (define_insn "*tablejump_1"
11515 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11516 (use (label_ref (match_operand 1)))]
11519 [(set_attr "type" "ibr")
11520 (set_attr "length_immediate" "0")])
11522 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11525 [(set (reg FLAGS_REG) (match_operand 0))
11526 (set (match_operand:QI 1 "register_operand")
11527 (match_operator:QI 2 "ix86_comparison_operator"
11528 [(reg FLAGS_REG) (const_int 0)]))
11529 (set (match_operand 3 "any_QIreg_operand")
11530 (zero_extend (match_dup 1)))]
11531 "(peep2_reg_dead_p (3, operands[1])
11532 || operands_match_p (operands[1], operands[3]))
11533 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11534 [(set (match_dup 4) (match_dup 0))
11535 (set (strict_low_part (match_dup 5))
11538 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11539 operands[5] = gen_lowpart (QImode, operands[3]);
11540 ix86_expand_clear (operands[3]);
11544 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11545 (match_operand 4)])
11546 (set (match_operand:QI 1 "register_operand")
11547 (match_operator:QI 2 "ix86_comparison_operator"
11548 [(reg FLAGS_REG) (const_int 0)]))
11549 (set (match_operand 3 "any_QIreg_operand")
11550 (zero_extend (match_dup 1)))]
11551 "(peep2_reg_dead_p (3, operands[1])
11552 || operands_match_p (operands[1], operands[3]))
11553 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11554 && ! (GET_CODE (operands[4]) == CLOBBER
11555 && reg_mentioned_p (operands[3], operands[4]))"
11556 [(parallel [(set (match_dup 5) (match_dup 0))
11558 (set (strict_low_part (match_dup 6))
11561 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11562 operands[6] = gen_lowpart (QImode, operands[3]);
11563 ix86_expand_clear (operands[3]);
11566 ;; Similar, but match zero extend with andsi3.
11569 [(set (reg FLAGS_REG) (match_operand 0))
11570 (set (match_operand:QI 1 "register_operand")
11571 (match_operator:QI 2 "ix86_comparison_operator"
11572 [(reg FLAGS_REG) (const_int 0)]))
11573 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11574 (and:SI (match_dup 3) (const_int 255)))
11575 (clobber (reg:CC FLAGS_REG))])]
11576 "REGNO (operands[1]) == REGNO (operands[3])
11577 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11578 [(set (match_dup 4) (match_dup 0))
11579 (set (strict_low_part (match_dup 5))
11582 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11583 operands[5] = gen_lowpart (QImode, operands[3]);
11584 ix86_expand_clear (operands[3]);
11588 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11589 (match_operand 4)])
11590 (set (match_operand:QI 1 "register_operand")
11591 (match_operator:QI 2 "ix86_comparison_operator"
11592 [(reg FLAGS_REG) (const_int 0)]))
11593 (parallel [(set (match_operand 3 "any_QIreg_operand")
11594 (zero_extend (match_dup 1)))
11595 (clobber (reg:CC FLAGS_REG))])]
11596 "(peep2_reg_dead_p (3, operands[1])
11597 || operands_match_p (operands[1], operands[3]))
11598 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11599 && ! (GET_CODE (operands[4]) == CLOBBER
11600 && reg_mentioned_p (operands[3], operands[4]))"
11601 [(parallel [(set (match_dup 5) (match_dup 0))
11603 (set (strict_low_part (match_dup 6))
11606 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11607 operands[6] = gen_lowpart (QImode, operands[3]);
11608 ix86_expand_clear (operands[3]);
11611 ;; Call instructions.
11613 ;; The predicates normally associated with named expanders are not properly
11614 ;; checked for calls. This is a bug in the generic code, but it isn't that
11615 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11617 ;; P6 processors will jump to the address after the decrement when %esp
11618 ;; is used as a call operand, so they will execute return address as a code.
11619 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11621 ;; Register constraint for call instruction.
11622 (define_mode_attr c [(SI "l") (DI "r")])
11624 ;; Call subroutine returning no value.
11626 (define_expand "call"
11627 [(call (match_operand:QI 0)
11629 (use (match_operand 2))]
11632 ix86_expand_call (NULL, operands[0], operands[1],
11633 operands[2], NULL, false);
11637 (define_expand "sibcall"
11638 [(call (match_operand:QI 0)
11640 (use (match_operand 2))]
11643 ix86_expand_call (NULL, operands[0], operands[1],
11644 operands[2], NULL, true);
11648 (define_insn "*call"
11649 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11650 (match_operand 1))]
11651 "!SIBLING_CALL_P (insn)"
11652 "* return ix86_output_call_insn (insn, operands[0]);"
11653 [(set_attr "type" "call")])
11655 (define_insn "*sibcall"
11656 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11657 (match_operand 1))]
11658 "SIBLING_CALL_P (insn)"
11659 "* return ix86_output_call_insn (insn, operands[0]);"
11660 [(set_attr "type" "call")])
11662 (define_insn "*sibcall_memory"
11663 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11665 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11667 "* return ix86_output_call_insn (insn, operands[0]);"
11668 [(set_attr "type" "call")])
11671 [(set (match_operand:W 0 "register_operand")
11672 (match_operand:W 1 "memory_operand"))
11673 (call (mem:QI (match_dup 0))
11674 (match_operand 3))]
11675 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11676 && peep2_reg_dead_p (2, operands[0])"
11677 [(parallel [(call (mem:QI (match_dup 1))
11679 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11682 [(set (match_operand:W 0 "register_operand")
11683 (match_operand:W 1 "memory_operand"))
11684 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11685 (call (mem:QI (match_dup 0))
11686 (match_operand 3))]
11687 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11688 && peep2_reg_dead_p (3, operands[0])"
11689 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11690 (parallel [(call (mem:QI (match_dup 1))
11692 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11694 (define_expand "call_pop"
11695 [(parallel [(call (match_operand:QI 0)
11696 (match_operand:SI 1))
11697 (set (reg:SI SP_REG)
11698 (plus:SI (reg:SI SP_REG)
11699 (match_operand:SI 3)))])]
11702 ix86_expand_call (NULL, operands[0], operands[1],
11703 operands[2], operands[3], false);
11707 (define_insn "*call_pop"
11708 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_operand:SI 2 "immediate_operand" "i")))]
11713 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11714 "* return ix86_output_call_insn (insn, operands[0]);"
11715 [(set_attr "type" "call")])
11717 (define_insn "*sibcall_pop"
11718 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11720 (set (reg:SI SP_REG)
11721 (plus:SI (reg:SI SP_REG)
11722 (match_operand:SI 2 "immediate_operand" "i")))]
11723 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11724 "* return ix86_output_call_insn (insn, operands[0]);"
11725 [(set_attr "type" "call")])
11727 (define_insn "*sibcall_pop_memory"
11728 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11730 (set (reg:SI SP_REG)
11731 (plus:SI (reg:SI SP_REG)
11732 (match_operand:SI 2 "immediate_operand" "i")))
11733 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11735 "* return ix86_output_call_insn (insn, operands[0]);"
11736 [(set_attr "type" "call")])
11739 [(set (match_operand:SI 0 "register_operand")
11740 (match_operand:SI 1 "memory_operand"))
11741 (parallel [(call (mem:QI (match_dup 0))
11743 (set (reg:SI SP_REG)
11744 (plus:SI (reg:SI SP_REG)
11745 (match_operand:SI 4 "immediate_operand")))])]
11746 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11747 && peep2_reg_dead_p (2, operands[0])"
11748 [(parallel [(call (mem:QI (match_dup 1))
11750 (set (reg:SI SP_REG)
11751 (plus:SI (reg:SI SP_REG)
11753 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11756 [(set (match_operand:SI 0 "register_operand")
11757 (match_operand:SI 1 "memory_operand"))
11758 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11759 (parallel [(call (mem:QI (match_dup 0))
11761 (set (reg:SI SP_REG)
11762 (plus:SI (reg:SI SP_REG)
11763 (match_operand:SI 4 "immediate_operand")))])]
11764 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11765 && peep2_reg_dead_p (3, operands[0])"
11766 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11767 (parallel [(call (mem:QI (match_dup 1))
11769 (set (reg:SI SP_REG)
11770 (plus:SI (reg:SI SP_REG)
11772 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11774 ;; Combining simple memory jump instruction
11777 [(set (match_operand:W 0 "register_operand")
11778 (match_operand:W 1 "memory_operand"))
11779 (set (pc) (match_dup 0))]
11780 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11781 [(set (pc) (match_dup 1))])
11783 ;; Call subroutine, returning value in operand 0
11785 (define_expand "call_value"
11786 [(set (match_operand 0)
11787 (call (match_operand:QI 1)
11788 (match_operand 2)))
11789 (use (match_operand 3))]
11792 ix86_expand_call (operands[0], operands[1], operands[2],
11793 operands[3], NULL, false);
11797 (define_expand "sibcall_value"
11798 [(set (match_operand 0)
11799 (call (match_operand:QI 1)
11800 (match_operand 2)))
11801 (use (match_operand 3))]
11804 ix86_expand_call (operands[0], operands[1], operands[2],
11805 operands[3], NULL, true);
11809 (define_insn "*call_value"
11810 [(set (match_operand 0)
11811 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11812 (match_operand 2)))]
11813 "!SIBLING_CALL_P (insn)"
11814 "* return ix86_output_call_insn (insn, operands[1]);"
11815 [(set_attr "type" "callv")])
11817 (define_insn "*sibcall_value"
11818 [(set (match_operand 0)
11819 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11820 (match_operand 2)))]
11821 "SIBLING_CALL_P (insn)"
11822 "* return ix86_output_call_insn (insn, operands[1]);"
11823 [(set_attr "type" "callv")])
11825 (define_insn "*sibcall_value_memory"
11826 [(set (match_operand 0)
11827 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11828 (match_operand 2)))
11829 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11831 "* return ix86_output_call_insn (insn, operands[1]);"
11832 [(set_attr "type" "callv")])
11835 [(set (match_operand:W 0 "register_operand")
11836 (match_operand:W 1 "memory_operand"))
11837 (set (match_operand 2)
11838 (call (mem:QI (match_dup 0))
11839 (match_operand 3)))]
11840 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11841 && peep2_reg_dead_p (2, operands[0])"
11842 [(parallel [(set (match_dup 2)
11843 (call (mem:QI (match_dup 1))
11845 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11848 [(set (match_operand:W 0 "register_operand")
11849 (match_operand:W 1 "memory_operand"))
11850 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11851 (set (match_operand 2)
11852 (call (mem:QI (match_dup 0))
11853 (match_operand 3)))]
11854 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11855 && peep2_reg_dead_p (3, operands[0])"
11856 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11857 (parallel [(set (match_dup 2)
11858 (call (mem:QI (match_dup 1))
11860 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11862 (define_expand "call_value_pop"
11863 [(parallel [(set (match_operand 0)
11864 (call (match_operand:QI 1)
11865 (match_operand:SI 2)))
11866 (set (reg:SI SP_REG)
11867 (plus:SI (reg:SI SP_REG)
11868 (match_operand:SI 4)))])]
11871 ix86_expand_call (operands[0], operands[1], operands[2],
11872 operands[3], operands[4], false);
11876 (define_insn "*call_value_pop"
11877 [(set (match_operand 0)
11878 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11879 (match_operand 2)))
11880 (set (reg:SI SP_REG)
11881 (plus:SI (reg:SI SP_REG)
11882 (match_operand:SI 3 "immediate_operand" "i")))]
11883 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11884 "* return ix86_output_call_insn (insn, operands[1]);"
11885 [(set_attr "type" "callv")])
11887 (define_insn "*sibcall_value_pop"
11888 [(set (match_operand 0)
11889 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11890 (match_operand 2)))
11891 (set (reg:SI SP_REG)
11892 (plus:SI (reg:SI SP_REG)
11893 (match_operand:SI 3 "immediate_operand" "i")))]
11894 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11895 "* return ix86_output_call_insn (insn, operands[1]);"
11896 [(set_attr "type" "callv")])
11898 (define_insn "*sibcall_value_pop_memory"
11899 [(set (match_operand 0)
11900 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11901 (match_operand 2)))
11902 (set (reg:SI SP_REG)
11903 (plus:SI (reg:SI SP_REG)
11904 (match_operand:SI 3 "immediate_operand" "i")))
11905 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11907 "* return ix86_output_call_insn (insn, operands[1]);"
11908 [(set_attr "type" "callv")])
11911 [(set (match_operand:SI 0 "register_operand")
11912 (match_operand:SI 1 "memory_operand"))
11913 (parallel [(set (match_operand 2)
11914 (call (mem:QI (match_dup 0))
11915 (match_operand 3)))
11916 (set (reg:SI SP_REG)
11917 (plus:SI (reg:SI SP_REG)
11918 (match_operand:SI 4 "immediate_operand")))])]
11919 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11920 && peep2_reg_dead_p (2, operands[0])"
11921 [(parallel [(set (match_dup 2)
11922 (call (mem:QI (match_dup 1))
11924 (set (reg:SI SP_REG)
11925 (plus:SI (reg:SI SP_REG)
11927 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11930 [(set (match_operand:SI 0 "register_operand")
11931 (match_operand:SI 1 "memory_operand"))
11932 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11933 (parallel [(set (match_operand 2)
11934 (call (mem:QI (match_dup 0))
11935 (match_operand 3)))
11936 (set (reg:SI SP_REG)
11937 (plus:SI (reg:SI SP_REG)
11938 (match_operand:SI 4 "immediate_operand")))])]
11939 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11940 && peep2_reg_dead_p (3, operands[0])"
11941 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11942 (parallel [(set (match_dup 2)
11943 (call (mem:QI (match_dup 1))
11945 (set (reg:SI SP_REG)
11946 (plus:SI (reg:SI SP_REG)
11948 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11950 ;; Call subroutine returning any type.
11952 (define_expand "untyped_call"
11953 [(parallel [(call (match_operand 0)
11956 (match_operand 2)])]
11961 /* In order to give reg-stack an easier job in validating two
11962 coprocessor registers as containing a possible return value,
11963 simply pretend the untyped call returns a complex long double
11966 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11967 and should have the default ABI. */
11969 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11970 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11971 operands[0], const0_rtx,
11972 GEN_INT ((TARGET_64BIT
11973 ? (ix86_abi == SYSV_ABI
11974 ? X86_64_SSE_REGPARM_MAX
11975 : X86_64_MS_SSE_REGPARM_MAX)
11976 : X86_32_SSE_REGPARM_MAX)
11980 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11982 rtx set = XVECEXP (operands[2], 0, i);
11983 emit_move_insn (SET_DEST (set), SET_SRC (set));
11986 /* The optimizer does not know that the call sets the function value
11987 registers we stored in the result block. We avoid problems by
11988 claiming that all hard registers are used and clobbered at this
11990 emit_insn (gen_blockage ());
11995 ;; Prologue and epilogue instructions
11997 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11998 ;; all of memory. This blocks insns from being moved across this point.
12000 (define_insn "blockage"
12001 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12004 [(set_attr "length" "0")])
12006 ;; Do not schedule instructions accessing memory across this point.
12008 (define_expand "memory_blockage"
12009 [(set (match_dup 0)
12010 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12013 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12014 MEM_VOLATILE_P (operands[0]) = 1;
12017 (define_insn "*memory_blockage"
12018 [(set (match_operand:BLK 0)
12019 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12022 [(set_attr "length" "0")])
12024 ;; As USE insns aren't meaningful after reload, this is used instead
12025 ;; to prevent deleting instructions setting registers for PIC code
12026 (define_insn "prologue_use"
12027 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12030 [(set_attr "length" "0")])
12032 ;; Insn emitted into the body of a function to return from a function.
12033 ;; This is only done if the function's epilogue is known to be simple.
12034 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12036 (define_expand "return"
12038 "ix86_can_use_return_insn_p ()"
12040 if (crtl->args.pops_args)
12042 rtx popc = GEN_INT (crtl->args.pops_args);
12043 emit_jump_insn (gen_simple_return_pop_internal (popc));
12048 ;; We need to disable this for TARGET_SEH, as otherwise
12049 ;; shrink-wrapped prologue gets enabled too. This might exceed
12050 ;; the maximum size of prologue in unwind information.
12052 (define_expand "simple_return"
12056 if (crtl->args.pops_args)
12058 rtx popc = GEN_INT (crtl->args.pops_args);
12059 emit_jump_insn (gen_simple_return_pop_internal (popc));
12064 (define_insn "simple_return_internal"
12068 [(set_attr "length_nobnd" "1")
12069 (set_attr "atom_unit" "jeu")
12070 (set_attr "length_immediate" "0")
12071 (set_attr "modrm" "0")])
12073 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12074 ;; instruction Athlon and K8 have.
12076 (define_insn "simple_return_internal_long"
12078 (unspec [(const_int 0)] UNSPEC_REP)]
12081 if (ix86_bnd_prefixed_insn_p (insn))
12084 return "rep%; ret";
12086 [(set_attr "length" "2")
12087 (set_attr "atom_unit" "jeu")
12088 (set_attr "length_immediate" "0")
12089 (set_attr "prefix_rep" "1")
12090 (set_attr "modrm" "0")])
12092 (define_insn "simple_return_pop_internal"
12094 (use (match_operand:SI 0 "const_int_operand"))]
12097 [(set_attr "length_nobnd" "3")
12098 (set_attr "atom_unit" "jeu")
12099 (set_attr "length_immediate" "2")
12100 (set_attr "modrm" "0")])
12102 (define_insn "simple_return_indirect_internal"
12104 (use (match_operand:SI 0 "register_operand" "r"))]
12107 [(set_attr "type" "ibr")
12108 (set_attr "length_immediate" "0")])
12114 [(set_attr "length" "1")
12115 (set_attr "length_immediate" "0")
12116 (set_attr "modrm" "0")])
12118 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12119 (define_insn "nops"
12120 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12124 int num = INTVAL (operands[0]);
12126 gcc_assert (IN_RANGE (num, 1, 8));
12129 fputs ("\tnop\n", asm_out_file);
12133 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12134 (set_attr "length_immediate" "0")
12135 (set_attr "modrm" "0")])
12137 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12138 ;; branch prediction penalty for the third jump in a 16-byte
12142 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12145 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12146 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12148 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12149 The align insn is used to avoid 3 jump instructions in the row to improve
12150 branch prediction and the benefits hardly outweigh the cost of extra 8
12151 nops on the average inserted by full alignment pseudo operation. */
12155 [(set_attr "length" "16")])
12157 (define_expand "prologue"
12160 "ix86_expand_prologue (); DONE;")
12162 (define_insn "set_got"
12163 [(set (match_operand:SI 0 "register_operand" "=r")
12164 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12165 (clobber (reg:CC FLAGS_REG))]
12167 "* return output_set_got (operands[0], NULL_RTX);"
12168 [(set_attr "type" "multi")
12169 (set_attr "length" "12")])
12171 (define_insn "set_got_labelled"
12172 [(set (match_operand:SI 0 "register_operand" "=r")
12173 (unspec:SI [(label_ref (match_operand 1))]
12175 (clobber (reg:CC FLAGS_REG))]
12177 "* return output_set_got (operands[0], operands[1]);"
12178 [(set_attr "type" "multi")
12179 (set_attr "length" "12")])
12181 (define_insn "set_got_rex64"
12182 [(set (match_operand:DI 0 "register_operand" "=r")
12183 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12185 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12186 [(set_attr "type" "lea")
12187 (set_attr "length_address" "4")
12188 (set_attr "mode" "DI")])
12190 (define_insn "set_rip_rex64"
12191 [(set (match_operand:DI 0 "register_operand" "=r")
12192 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12194 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12195 [(set_attr "type" "lea")
12196 (set_attr "length_address" "4")
12197 (set_attr "mode" "DI")])
12199 (define_insn "set_got_offset_rex64"
12200 [(set (match_operand:DI 0 "register_operand" "=r")
12202 [(label_ref (match_operand 1))]
12203 UNSPEC_SET_GOT_OFFSET))]
12205 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12206 [(set_attr "type" "imov")
12207 (set_attr "length_immediate" "0")
12208 (set_attr "length_address" "8")
12209 (set_attr "mode" "DI")])
12211 (define_expand "epilogue"
12214 "ix86_expand_epilogue (1); DONE;")
12216 (define_expand "sibcall_epilogue"
12219 "ix86_expand_epilogue (0); DONE;")
12221 (define_expand "eh_return"
12222 [(use (match_operand 0 "register_operand"))]
12225 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12227 /* Tricky bit: we write the address of the handler to which we will
12228 be returning into someone else's stack frame, one word below the
12229 stack address we wish to restore. */
12230 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12231 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12232 tmp = gen_rtx_MEM (Pmode, tmp);
12233 emit_move_insn (tmp, ra);
12235 emit_jump_insn (gen_eh_return_internal ());
12240 (define_insn_and_split "eh_return_internal"
12244 "epilogue_completed"
12246 "ix86_expand_epilogue (2); DONE;")
12248 (define_insn "leave"
12249 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12250 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12251 (clobber (mem:BLK (scratch)))]
12254 [(set_attr "type" "leave")])
12256 (define_insn "leave_rex64"
12257 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12258 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12259 (clobber (mem:BLK (scratch)))]
12262 [(set_attr "type" "leave")])
12264 ;; Handle -fsplit-stack.
12266 (define_expand "split_stack_prologue"
12270 ix86_expand_split_stack_prologue ();
12274 ;; In order to support the call/return predictor, we use a return
12275 ;; instruction which the middle-end doesn't see.
12276 (define_insn "split_stack_return"
12277 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12278 UNSPECV_SPLIT_STACK_RETURN)]
12281 if (operands[0] == const0_rtx)
12286 [(set_attr "atom_unit" "jeu")
12287 (set_attr "modrm" "0")
12288 (set (attr "length")
12289 (if_then_else (match_operand:SI 0 "const0_operand")
12292 (set (attr "length_immediate")
12293 (if_then_else (match_operand:SI 0 "const0_operand")
12297 ;; If there are operand 0 bytes available on the stack, jump to
12300 (define_expand "split_stack_space_check"
12301 [(set (pc) (if_then_else
12302 (ltu (minus (reg SP_REG)
12303 (match_operand 0 "register_operand"))
12304 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12305 (label_ref (match_operand 1))
12309 rtx reg, size, limit;
12311 reg = gen_reg_rtx (Pmode);
12312 size = force_reg (Pmode, operands[0]);
12313 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12314 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12315 UNSPEC_STACK_CHECK);
12316 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12317 ix86_expand_branch (GEU, reg, limit, operands[1]);
12322 ;; Bit manipulation instructions.
12324 (define_expand "ffs<mode>2"
12325 [(set (match_dup 2) (const_int -1))
12326 (parallel [(set (match_dup 3) (match_dup 4))
12327 (set (match_operand:SWI48 0 "register_operand")
12329 (match_operand:SWI48 1 "nonimmediate_operand")))])
12330 (set (match_dup 0) (if_then_else:SWI48
12331 (eq (match_dup 3) (const_int 0))
12334 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12335 (clobber (reg:CC FLAGS_REG))])]
12338 machine_mode flags_mode;
12340 if (<MODE>mode == SImode && !TARGET_CMOVE)
12342 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12347 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12349 operands[2] = gen_reg_rtx (<MODE>mode);
12350 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12351 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12354 (define_insn_and_split "ffssi2_no_cmove"
12355 [(set (match_operand:SI 0 "register_operand" "=r")
12356 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12357 (clobber (match_scratch:SI 2 "=&q"))
12358 (clobber (reg:CC FLAGS_REG))]
12361 "&& reload_completed"
12362 [(parallel [(set (match_dup 4) (match_dup 5))
12363 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12364 (set (strict_low_part (match_dup 3))
12365 (eq:QI (match_dup 4) (const_int 0)))
12366 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12367 (clobber (reg:CC FLAGS_REG))])
12368 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12369 (clobber (reg:CC FLAGS_REG))])
12370 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12371 (clobber (reg:CC FLAGS_REG))])]
12373 machine_mode flags_mode
12374 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12376 operands[3] = gen_lowpart (QImode, operands[2]);
12377 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12378 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12380 ix86_expand_clear (operands[2]);
12383 (define_insn "*tzcnt<mode>_1"
12384 [(set (reg:CCC FLAGS_REG)
12385 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12387 (set (match_operand:SWI48 0 "register_operand" "=r")
12388 (ctz:SWI48 (match_dup 1)))]
12389 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12390 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12391 [(set_attr "type" "alu1")
12392 (set_attr "prefix_0f" "1")
12393 (set_attr "prefix_rep" "1")
12394 (set_attr "btver2_decode" "double")
12395 (set_attr "mode" "<MODE>")])
12397 (define_insn "*bsf<mode>_1"
12398 [(set (reg:CCZ FLAGS_REG)
12399 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12401 (set (match_operand:SWI48 0 "register_operand" "=r")
12402 (ctz:SWI48 (match_dup 1)))]
12404 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12405 [(set_attr "type" "alu1")
12406 (set_attr "prefix_0f" "1")
12407 (set_attr "btver2_decode" "double")
12408 (set_attr "mode" "<MODE>")])
12410 (define_expand "ctz<mode>2"
12412 [(set (match_operand:SWI248 0 "register_operand")
12414 (match_operand:SWI248 1 "nonimmediate_operand")))
12415 (clobber (reg:CC FLAGS_REG))])])
12417 ; False dependency happens when destination is only updated by tzcnt,
12418 ; lzcnt or popcnt. There is no false dependency when destination is
12419 ; also used in source.
12420 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12421 [(set (match_operand:SWI48 0 "register_operand" "=r")
12423 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12424 (clobber (reg:CC FLAGS_REG))]
12425 "(TARGET_BMI || TARGET_GENERIC)
12426 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12428 "&& reload_completed"
12430 [(set (match_dup 0)
12431 (ctz:SWI48 (match_dup 1)))
12432 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12433 (clobber (reg:CC FLAGS_REG))])]
12435 if (!reg_mentioned_p (operands[0], operands[1]))
12436 ix86_expand_clear (operands[0]);
12439 (define_insn "*ctz<mode>2_falsedep"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12443 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12444 UNSPEC_INSN_FALSE_DEP)
12445 (clobber (reg:CC FLAGS_REG))]
12449 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12450 else if (TARGET_GENERIC)
12451 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12452 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12454 gcc_unreachable ();
12456 [(set_attr "type" "alu1")
12457 (set_attr "prefix_0f" "1")
12458 (set_attr "prefix_rep" "1")
12459 (set_attr "mode" "<MODE>")])
12461 (define_insn "*ctz<mode>2"
12462 [(set (match_operand:SWI248 0 "register_operand" "=r")
12463 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12464 (clobber (reg:CC FLAGS_REG))]
12468 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12469 else if (optimize_function_for_size_p (cfun))
12471 else if (TARGET_GENERIC)
12472 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12473 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12475 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12477 [(set_attr "type" "alu1")
12478 (set_attr "prefix_0f" "1")
12479 (set (attr "prefix_rep")
12481 (ior (match_test "TARGET_BMI")
12482 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12483 (match_test "TARGET_GENERIC")))
12485 (const_string "0")))
12486 (set_attr "mode" "<MODE>")])
12488 (define_expand "clz<mode>2"
12490 [(set (match_operand:SWI248 0 "register_operand")
12493 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12494 (clobber (reg:CC FLAGS_REG))])
12496 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12497 (clobber (reg:CC FLAGS_REG))])]
12502 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12505 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12508 (define_expand "clz<mode>2_lzcnt"
12510 [(set (match_operand:SWI248 0 "register_operand")
12512 (match_operand:SWI248 1 "nonimmediate_operand")))
12513 (clobber (reg:CC FLAGS_REG))])]
12516 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12517 [(set (match_operand:SWI48 0 "register_operand" "=r")
12519 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12520 (clobber (reg:CC FLAGS_REG))]
12522 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12524 "&& reload_completed"
12526 [(set (match_dup 0)
12527 (clz:SWI48 (match_dup 1)))
12528 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12529 (clobber (reg:CC FLAGS_REG))])]
12531 if (!reg_mentioned_p (operands[0], operands[1]))
12532 ix86_expand_clear (operands[0]);
12535 (define_insn "*clz<mode>2_lzcnt_falsedep"
12536 [(set (match_operand:SWI48 0 "register_operand" "=r")
12538 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12539 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12540 UNSPEC_INSN_FALSE_DEP)
12541 (clobber (reg:CC FLAGS_REG))]
12543 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12544 [(set_attr "prefix_rep" "1")
12545 (set_attr "type" "bitmanip")
12546 (set_attr "mode" "<MODE>")])
12548 (define_insn "*clz<mode>2_lzcnt"
12549 [(set (match_operand:SWI248 0 "register_operand" "=r")
12550 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12551 (clobber (reg:CC FLAGS_REG))]
12553 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12554 [(set_attr "prefix_rep" "1")
12555 (set_attr "type" "bitmanip")
12556 (set_attr "mode" "<MODE>")])
12558 ;; BMI instructions.
12559 (define_insn "*bmi_andn_<mode>"
12560 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12562 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12563 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 "andn\t{%2, %1, %0|%0, %1, %2}"
12567 [(set_attr "type" "bitmanip")
12568 (set_attr "btver2_decode" "direct, double")
12569 (set_attr "mode" "<MODE>")])
12571 (define_insn "*bmi_andn_<mode>_ccno"
12572 [(set (reg FLAGS_REG)
12575 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12576 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12578 (clobber (match_scratch:SWI48 0 "=r,r"))]
12579 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12580 "andn\t{%2, %1, %0|%0, %1, %2}"
12581 [(set_attr "type" "bitmanip")
12582 (set_attr "btver2_decode" "direct, double")
12583 (set_attr "mode" "<MODE>")])
12585 (define_insn "bmi_bextr_<mode>"
12586 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12587 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12588 (match_operand:SWI48 2 "register_operand" "r,r")]
12590 (clobber (reg:CC FLAGS_REG))]
12592 "bextr\t{%2, %1, %0|%0, %1, %2}"
12593 [(set_attr "type" "bitmanip")
12594 (set_attr "btver2_decode" "direct, double")
12595 (set_attr "mode" "<MODE>")])
12597 (define_insn "*bmi_bextr_<mode>_ccz"
12598 [(set (reg:CCZ FLAGS_REG)
12600 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12601 (match_operand:SWI48 2 "register_operand" "r,r")]
12604 (clobber (match_scratch:SWI48 0 "=r,r"))]
12606 "bextr\t{%2, %1, %0|%0, %1, %2}"
12607 [(set_attr "type" "bitmanip")
12608 (set_attr "btver2_decode" "direct, double")
12609 (set_attr "mode" "<MODE>")])
12611 (define_insn "*bmi_blsi_<mode>"
12612 [(set (match_operand:SWI48 0 "register_operand" "=r")
12615 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12617 (clobber (reg:CC FLAGS_REG))]
12619 "blsi\t{%1, %0|%0, %1}"
12620 [(set_attr "type" "bitmanip")
12621 (set_attr "btver2_decode" "double")
12622 (set_attr "mode" "<MODE>")])
12624 (define_insn "*bmi_blsmsk_<mode>"
12625 [(set (match_operand:SWI48 0 "register_operand" "=r")
12628 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12631 (clobber (reg:CC FLAGS_REG))]
12633 "blsmsk\t{%1, %0|%0, %1}"
12634 [(set_attr "type" "bitmanip")
12635 (set_attr "btver2_decode" "double")
12636 (set_attr "mode" "<MODE>")])
12638 (define_insn "*bmi_blsr_<mode>"
12639 [(set (match_operand:SWI48 0 "register_operand" "=r")
12642 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12645 (clobber (reg:CC FLAGS_REG))]
12647 "blsr\t{%1, %0|%0, %1}"
12648 [(set_attr "type" "bitmanip")
12649 (set_attr "btver2_decode" "double")
12650 (set_attr "mode" "<MODE>")])
12652 ;; BMI2 instructions.
12653 (define_expand "bmi2_bzhi_<mode>3"
12655 [(set (match_operand:SWI48 0 "register_operand")
12656 (zero_extract:SWI48
12657 (match_operand:SWI48 1 "nonimmediate_operand")
12659 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12663 (clobber (reg:CC FLAGS_REG))])]
12665 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12667 (define_insn "*bmi2_bzhi_<mode>3"
12668 [(set (match_operand:SWI48 0 "register_operand" "=r")
12669 (zero_extract:SWI48
12670 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12672 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12674 (match_operand:SWI48 3 "const_int_operand" "n"))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12678 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12679 [(set_attr "type" "bitmanip")
12680 (set_attr "prefix" "vex")
12681 (set_attr "mode" "<MODE>")])
12683 (define_mode_attr k [(SI "k") (DI "q")])
12685 (define_insn "*bmi2_bzhi_<mode>3_1"
12686 [(set (match_operand:SWI48 0 "register_operand" "=r")
12687 (zero_extract:SWI48
12688 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12690 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12691 (match_operand:SWI48 3 "const_int_operand" "n"))
12693 (clobber (reg:CC FLAGS_REG))]
12694 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12695 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12696 [(set_attr "type" "bitmanip")
12697 (set_attr "prefix" "vex")
12698 (set_attr "mode" "<MODE>")])
12700 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12701 [(set (reg:CCZ FLAGS_REG)
12703 (zero_extract:SWI48
12704 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12706 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12707 (match_operand:SWI48 3 "const_int_operand" "n"))
12710 (clobber (match_scratch:SWI48 0 "=r"))]
12711 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12712 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12713 [(set_attr "type" "bitmanip")
12714 (set_attr "prefix" "vex")
12715 (set_attr "mode" "<MODE>")])
12717 (define_insn "bmi2_pdep_<mode>3"
12718 [(set (match_operand:SWI48 0 "register_operand" "=r")
12719 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12720 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12723 "pdep\t{%2, %1, %0|%0, %1, %2}"
12724 [(set_attr "type" "bitmanip")
12725 (set_attr "prefix" "vex")
12726 (set_attr "mode" "<MODE>")])
12728 (define_insn "bmi2_pext_<mode>3"
12729 [(set (match_operand:SWI48 0 "register_operand" "=r")
12730 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12731 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12734 "pext\t{%2, %1, %0|%0, %1, %2}"
12735 [(set_attr "type" "bitmanip")
12736 (set_attr "prefix" "vex")
12737 (set_attr "mode" "<MODE>")])
12739 ;; TBM instructions.
12740 (define_insn "tbm_bextri_<mode>"
12741 [(set (match_operand:SWI48 0 "register_operand" "=r")
12742 (zero_extract:SWI48
12743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12744 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12745 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12746 (clobber (reg:CC FLAGS_REG))]
12749 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12750 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12752 [(set_attr "type" "bitmanip")
12753 (set_attr "mode" "<MODE>")])
12755 (define_insn "*tbm_blcfill_<mode>"
12756 [(set (match_operand:SWI48 0 "register_operand" "=r")
12759 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12762 (clobber (reg:CC FLAGS_REG))]
12764 "blcfill\t{%1, %0|%0, %1}"
12765 [(set_attr "type" "bitmanip")
12766 (set_attr "mode" "<MODE>")])
12768 (define_insn "*tbm_blci_<mode>"
12769 [(set (match_operand:SWI48 0 "register_operand" "=r")
12773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12776 (clobber (reg:CC FLAGS_REG))]
12778 "blci\t{%1, %0|%0, %1}"
12779 [(set_attr "type" "bitmanip")
12780 (set_attr "mode" "<MODE>")])
12782 (define_insn "*tbm_blcic_<mode>"
12783 [(set (match_operand:SWI48 0 "register_operand" "=r")
12786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12790 (clobber (reg:CC FLAGS_REG))]
12792 "blcic\t{%1, %0|%0, %1}"
12793 [(set_attr "type" "bitmanip")
12794 (set_attr "mode" "<MODE>")])
12796 (define_insn "*tbm_blcmsk_<mode>"
12797 [(set (match_operand:SWI48 0 "register_operand" "=r")
12800 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12803 (clobber (reg:CC FLAGS_REG))]
12805 "blcmsk\t{%1, %0|%0, %1}"
12806 [(set_attr "type" "bitmanip")
12807 (set_attr "mode" "<MODE>")])
12809 (define_insn "*tbm_blcs_<mode>"
12810 [(set (match_operand:SWI48 0 "register_operand" "=r")
12813 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12816 (clobber (reg:CC FLAGS_REG))]
12818 "blcs\t{%1, %0|%0, %1}"
12819 [(set_attr "type" "bitmanip")
12820 (set_attr "mode" "<MODE>")])
12822 (define_insn "*tbm_blsfill_<mode>"
12823 [(set (match_operand:SWI48 0 "register_operand" "=r")
12826 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12829 (clobber (reg:CC FLAGS_REG))]
12831 "blsfill\t{%1, %0|%0, %1}"
12832 [(set_attr "type" "bitmanip")
12833 (set_attr "mode" "<MODE>")])
12835 (define_insn "*tbm_blsic_<mode>"
12836 [(set (match_operand:SWI48 0 "register_operand" "=r")
12839 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12843 (clobber (reg:CC FLAGS_REG))]
12845 "blsic\t{%1, %0|%0, %1}"
12846 [(set_attr "type" "bitmanip")
12847 (set_attr "mode" "<MODE>")])
12849 (define_insn "*tbm_t1mskc_<mode>"
12850 [(set (match_operand:SWI48 0 "register_operand" "=r")
12853 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12857 (clobber (reg:CC FLAGS_REG))]
12859 "t1mskc\t{%1, %0|%0, %1}"
12860 [(set_attr "type" "bitmanip")
12861 (set_attr "mode" "<MODE>")])
12863 (define_insn "*tbm_tzmsk_<mode>"
12864 [(set (match_operand:SWI48 0 "register_operand" "=r")
12867 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12871 (clobber (reg:CC FLAGS_REG))]
12873 "tzmsk\t{%1, %0|%0, %1}"
12874 [(set_attr "type" "bitmanip")
12875 (set_attr "mode" "<MODE>")])
12877 (define_insn "bsr_rex64"
12878 [(set (match_operand:DI 0 "register_operand" "=r")
12879 (minus:DI (const_int 63)
12880 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12881 (clobber (reg:CC FLAGS_REG))]
12883 "bsr{q}\t{%1, %0|%0, %1}"
12884 [(set_attr "type" "alu1")
12885 (set_attr "prefix_0f" "1")
12886 (set_attr "mode" "DI")])
12889 [(set (match_operand:SI 0 "register_operand" "=r")
12890 (minus:SI (const_int 31)
12891 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12892 (clobber (reg:CC FLAGS_REG))]
12894 "bsr{l}\t{%1, %0|%0, %1}"
12895 [(set_attr "type" "alu1")
12896 (set_attr "prefix_0f" "1")
12897 (set_attr "mode" "SI")])
12899 (define_insn "*bsrhi"
12900 [(set (match_operand:HI 0 "register_operand" "=r")
12901 (minus:HI (const_int 15)
12902 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12903 (clobber (reg:CC FLAGS_REG))]
12905 "bsr{w}\t{%1, %0|%0, %1}"
12906 [(set_attr "type" "alu1")
12907 (set_attr "prefix_0f" "1")
12908 (set_attr "mode" "HI")])
12910 (define_expand "popcount<mode>2"
12912 [(set (match_operand:SWI248 0 "register_operand")
12914 (match_operand:SWI248 1 "nonimmediate_operand")))
12915 (clobber (reg:CC FLAGS_REG))])]
12918 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12919 [(set (match_operand:SWI48 0 "register_operand" "=r")
12921 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12922 (clobber (reg:CC FLAGS_REG))]
12924 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12926 "&& reload_completed"
12928 [(set (match_dup 0)
12929 (popcount:SWI48 (match_dup 1)))
12930 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12931 (clobber (reg:CC FLAGS_REG))])]
12933 if (!reg_mentioned_p (operands[0], operands[1]))
12934 ix86_expand_clear (operands[0]);
12937 (define_insn "*popcount<mode>2_falsedep"
12938 [(set (match_operand:SWI48 0 "register_operand" "=r")
12940 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12941 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12942 UNSPEC_INSN_FALSE_DEP)
12943 (clobber (reg:CC FLAGS_REG))]
12947 return "popcnt\t{%1, %0|%0, %1}";
12949 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12952 [(set_attr "prefix_rep" "1")
12953 (set_attr "type" "bitmanip")
12954 (set_attr "mode" "<MODE>")])
12956 (define_insn "*popcount<mode>2"
12957 [(set (match_operand:SWI248 0 "register_operand" "=r")
12959 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12960 (clobber (reg:CC FLAGS_REG))]
12964 return "popcnt\t{%1, %0|%0, %1}";
12966 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12969 [(set_attr "prefix_rep" "1")
12970 (set_attr "type" "bitmanip")
12971 (set_attr "mode" "<MODE>")])
12973 (define_expand "bswapdi2"
12974 [(set (match_operand:DI 0 "register_operand")
12975 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12979 operands[1] = force_reg (DImode, operands[1]);
12982 (define_expand "bswapsi2"
12983 [(set (match_operand:SI 0 "register_operand")
12984 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12989 else if (TARGET_BSWAP)
12990 operands[1] = force_reg (SImode, operands[1]);
12993 rtx x = operands[0];
12995 emit_move_insn (x, operands[1]);
12996 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12997 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12998 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13003 (define_insn "*bswap<mode>2_movbe"
13004 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13005 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13010 movbe\t{%1, %0|%0, %1}
13011 movbe\t{%1, %0|%0, %1}"
13012 [(set_attr "type" "bitmanip,imov,imov")
13013 (set_attr "modrm" "0,1,1")
13014 (set_attr "prefix_0f" "*,1,1")
13015 (set_attr "prefix_extra" "*,1,1")
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*bswap<mode>2"
13019 [(set (match_operand:SWI48 0 "register_operand" "=r")
13020 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13023 [(set_attr "type" "bitmanip")
13024 (set_attr "modrm" "0")
13025 (set_attr "mode" "<MODE>")])
13027 (define_insn "*bswaphi_lowpart_1"
13028 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13029 (bswap:HI (match_dup 0)))
13030 (clobber (reg:CC FLAGS_REG))]
13031 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13033 xchg{b}\t{%h0, %b0|%b0, %h0}
13034 rol{w}\t{$8, %0|%0, 8}"
13035 [(set_attr "length" "2,4")
13036 (set_attr "mode" "QI,HI")])
13038 (define_insn "bswaphi_lowpart"
13039 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13040 (bswap:HI (match_dup 0)))
13041 (clobber (reg:CC FLAGS_REG))]
13043 "rol{w}\t{$8, %0|%0, 8}"
13044 [(set_attr "length" "4")
13045 (set_attr "mode" "HI")])
13047 (define_expand "paritydi2"
13048 [(set (match_operand:DI 0 "register_operand")
13049 (parity:DI (match_operand:DI 1 "register_operand")))]
13052 rtx scratch = gen_reg_rtx (QImode);
13055 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13056 NULL_RTX, operands[1]));
13058 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13059 gen_rtx_REG (CCmode, FLAGS_REG),
13061 emit_insn (gen_rtx_SET (scratch, cond));
13064 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13067 rtx tmp = gen_reg_rtx (SImode);
13069 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13070 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13075 (define_expand "paritysi2"
13076 [(set (match_operand:SI 0 "register_operand")
13077 (parity:SI (match_operand:SI 1 "register_operand")))]
13080 rtx scratch = gen_reg_rtx (QImode);
13083 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13085 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13086 gen_rtx_REG (CCmode, FLAGS_REG),
13088 emit_insn (gen_rtx_SET (scratch, cond));
13090 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13094 (define_insn_and_split "paritydi2_cmp"
13095 [(set (reg:CC FLAGS_REG)
13096 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13098 (clobber (match_scratch:DI 0 "=r"))
13099 (clobber (match_scratch:SI 1 "=&r"))
13100 (clobber (match_scratch:HI 2 "=Q"))]
13103 "&& reload_completed"
13105 [(set (match_dup 1)
13106 (xor:SI (match_dup 1) (match_dup 4)))
13107 (clobber (reg:CC FLAGS_REG))])
13109 [(set (reg:CC FLAGS_REG)
13110 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13111 (clobber (match_dup 1))
13112 (clobber (match_dup 2))])]
13114 operands[4] = gen_lowpart (SImode, operands[3]);
13118 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13119 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13122 operands[1] = gen_highpart (SImode, operands[3]);
13125 (define_insn_and_split "paritysi2_cmp"
13126 [(set (reg:CC FLAGS_REG)
13127 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13129 (clobber (match_scratch:SI 0 "=r"))
13130 (clobber (match_scratch:HI 1 "=&Q"))]
13133 "&& reload_completed"
13135 [(set (match_dup 1)
13136 (xor:HI (match_dup 1) (match_dup 3)))
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))])]
13143 operands[3] = gen_lowpart (HImode, operands[2]);
13145 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13146 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13149 (define_insn "*parityhi2_cmp"
13150 [(set (reg:CC FLAGS_REG)
13151 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13153 (clobber (match_scratch:HI 0 "=Q"))]
13155 "xor{b}\t{%h0, %b0|%b0, %h0}"
13156 [(set_attr "length" "2")
13157 (set_attr "mode" "HI")])
13160 ;; Thread-local storage patterns for ELF.
13162 ;; Note that these code sequences must appear exactly as shown
13163 ;; in order to allow linker relaxation.
13165 (define_insn "*tls_global_dynamic_32_gnu"
13166 [(set (match_operand:SI 0 "register_operand" "=a")
13168 [(match_operand:SI 1 "register_operand" "b")
13169 (match_operand 2 "tls_symbolic_operand")
13170 (match_operand 3 "constant_call_address_operand" "Bz")
13173 (clobber (match_scratch:SI 4 "=d"))
13174 (clobber (match_scratch:SI 5 "=c"))
13175 (clobber (reg:CC FLAGS_REG))]
13176 "!TARGET_64BIT && TARGET_GNU_TLS"
13179 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13180 if (TARGET_SUN_TLS)
13181 #ifdef HAVE_AS_IX86_TLSGDPLT
13182 return "call\t%a2@tlsgdplt";
13184 return "call\t%p3@plt";
13186 return "call\t%P3";
13188 [(set_attr "type" "multi")
13189 (set_attr "length" "12")])
13191 (define_expand "tls_global_dynamic_32"
13193 [(set (match_operand:SI 0 "register_operand")
13194 (unspec:SI [(match_operand:SI 2 "register_operand")
13195 (match_operand 1 "tls_symbolic_operand")
13196 (match_operand 3 "constant_call_address_operand")
13199 (clobber (match_scratch:SI 4))
13200 (clobber (match_scratch:SI 5))
13201 (clobber (reg:CC FLAGS_REG))])]
13203 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13205 (define_insn "*tls_global_dynamic_64_<mode>"
13206 [(set (match_operand:P 0 "register_operand" "=a")
13208 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13209 (match_operand 3)))
13210 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13215 fputs (ASM_BYTE "0x66\n", asm_out_file);
13217 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13218 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13219 fputs ("\trex64\n", asm_out_file);
13220 if (TARGET_SUN_TLS)
13221 return "call\t%p2@plt";
13222 return "call\t%P2";
13224 [(set_attr "type" "multi")
13225 (set (attr "length")
13226 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13228 (define_insn "*tls_global_dynamic_64_largepic"
13229 [(set (match_operand:DI 0 "register_operand" "=a")
13231 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13232 (match_operand:DI 3 "immediate_operand" "i")))
13233 (match_operand 4)))
13234 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13236 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13237 && GET_CODE (operands[3]) == CONST
13238 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13239 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13242 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13243 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13244 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13245 return "call\t{*%%rax|rax}";
13247 [(set_attr "type" "multi")
13248 (set_attr "length" "22")])
13250 (define_expand "tls_global_dynamic_64_<mode>"
13252 [(set (match_operand:P 0 "register_operand")
13254 (mem:QI (match_operand 2))
13256 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13259 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13261 (define_insn "*tls_local_dynamic_base_32_gnu"
13262 [(set (match_operand:SI 0 "register_operand" "=a")
13264 [(match_operand:SI 1 "register_operand" "b")
13265 (match_operand 2 "constant_call_address_operand" "Bz")
13267 UNSPEC_TLS_LD_BASE))
13268 (clobber (match_scratch:SI 3 "=d"))
13269 (clobber (match_scratch:SI 4 "=c"))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "!TARGET_64BIT && TARGET_GNU_TLS"
13274 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13275 if (TARGET_SUN_TLS)
13277 if (HAVE_AS_IX86_TLSLDMPLT)
13278 return "call\t%&@tlsldmplt";
13280 return "call\t%p2@plt";
13282 return "call\t%P2";
13284 [(set_attr "type" "multi")
13285 (set_attr "length" "11")])
13287 (define_expand "tls_local_dynamic_base_32"
13289 [(set (match_operand:SI 0 "register_operand")
13291 [(match_operand:SI 1 "register_operand")
13292 (match_operand 2 "constant_call_address_operand")
13294 UNSPEC_TLS_LD_BASE))
13295 (clobber (match_scratch:SI 3))
13296 (clobber (match_scratch:SI 4))
13297 (clobber (reg:CC FLAGS_REG))])]
13299 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13301 (define_insn "*tls_local_dynamic_base_64_<mode>"
13302 [(set (match_operand:P 0 "register_operand" "=a")
13304 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13305 (match_operand 2)))
13306 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13310 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13311 if (TARGET_SUN_TLS)
13312 return "call\t%p1@plt";
13313 return "call\t%P1";
13315 [(set_attr "type" "multi")
13316 (set_attr "length" "12")])
13318 (define_insn "*tls_local_dynamic_base_64_largepic"
13319 [(set (match_operand:DI 0 "register_operand" "=a")
13321 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13322 (match_operand:DI 2 "immediate_operand" "i")))
13323 (match_operand 3)))
13324 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13325 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13326 && GET_CODE (operands[2]) == CONST
13327 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13328 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13331 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13332 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13333 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13334 return "call\t{*%%rax|rax}";
13336 [(set_attr "type" "multi")
13337 (set_attr "length" "22")])
13339 (define_expand "tls_local_dynamic_base_64_<mode>"
13341 [(set (match_operand:P 0 "register_operand")
13343 (mem:QI (match_operand 1))
13345 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13347 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13349 ;; Local dynamic of a single variable is a lose. Show combine how
13350 ;; to convert that back to global dynamic.
13352 (define_insn_and_split "*tls_local_dynamic_32_once"
13353 [(set (match_operand:SI 0 "register_operand" "=a")
13355 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13356 (match_operand 2 "constant_call_address_operand" "Bz")
13358 UNSPEC_TLS_LD_BASE)
13359 (const:SI (unspec:SI
13360 [(match_operand 3 "tls_symbolic_operand")]
13362 (clobber (match_scratch:SI 4 "=d"))
13363 (clobber (match_scratch:SI 5 "=c"))
13364 (clobber (reg:CC FLAGS_REG))]
13369 [(set (match_dup 0)
13370 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13373 (clobber (match_dup 4))
13374 (clobber (match_dup 5))
13375 (clobber (reg:CC FLAGS_REG))])])
13377 ;; Segment register for the thread base ptr load
13378 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13380 ;; Load and add the thread base pointer from %<tp_seg>:0.
13381 (define_insn "*load_tp_x32"
13382 [(set (match_operand:SI 0 "register_operand" "=r")
13383 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13385 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13386 [(set_attr "type" "imov")
13387 (set_attr "modrm" "0")
13388 (set_attr "length" "7")
13389 (set_attr "memory" "load")
13390 (set_attr "imm_disp" "false")])
13392 (define_insn "*load_tp_x32_zext"
13393 [(set (match_operand:DI 0 "register_operand" "=r")
13394 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13396 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13397 [(set_attr "type" "imov")
13398 (set_attr "modrm" "0")
13399 (set_attr "length" "7")
13400 (set_attr "memory" "load")
13401 (set_attr "imm_disp" "false")])
13403 (define_insn "*load_tp_<mode>"
13404 [(set (match_operand:P 0 "register_operand" "=r")
13405 (unspec:P [(const_int 0)] UNSPEC_TP))]
13407 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13408 [(set_attr "type" "imov")
13409 (set_attr "modrm" "0")
13410 (set_attr "length" "7")
13411 (set_attr "memory" "load")
13412 (set_attr "imm_disp" "false")])
13414 (define_insn "*add_tp_x32"
13415 [(set (match_operand:SI 0 "register_operand" "=r")
13416 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13417 (match_operand:SI 1 "register_operand" "0")))
13418 (clobber (reg:CC FLAGS_REG))]
13420 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13421 [(set_attr "type" "alu")
13422 (set_attr "modrm" "0")
13423 (set_attr "length" "7")
13424 (set_attr "memory" "load")
13425 (set_attr "imm_disp" "false")])
13427 (define_insn "*add_tp_x32_zext"
13428 [(set (match_operand:DI 0 "register_operand" "=r")
13430 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13431 (match_operand:SI 1 "register_operand" "0"))))
13432 (clobber (reg:CC FLAGS_REG))]
13434 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13435 [(set_attr "type" "alu")
13436 (set_attr "modrm" "0")
13437 (set_attr "length" "7")
13438 (set_attr "memory" "load")
13439 (set_attr "imm_disp" "false")])
13441 (define_insn "*add_tp_<mode>"
13442 [(set (match_operand:P 0 "register_operand" "=r")
13443 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13444 (match_operand:P 1 "register_operand" "0")))
13445 (clobber (reg:CC FLAGS_REG))]
13447 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13448 [(set_attr "type" "alu")
13449 (set_attr "modrm" "0")
13450 (set_attr "length" "7")
13451 (set_attr "memory" "load")
13452 (set_attr "imm_disp" "false")])
13454 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13455 ;; %rax as destination of the initial executable code sequence.
13456 (define_insn "tls_initial_exec_64_sun"
13457 [(set (match_operand:DI 0 "register_operand" "=a")
13459 [(match_operand 1 "tls_symbolic_operand")]
13460 UNSPEC_TLS_IE_SUN))
13461 (clobber (reg:CC FLAGS_REG))]
13462 "TARGET_64BIT && TARGET_SUN_TLS"
13465 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13466 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13468 [(set_attr "type" "multi")])
13470 ;; GNU2 TLS patterns can be split.
13472 (define_expand "tls_dynamic_gnu2_32"
13473 [(set (match_dup 3)
13474 (plus:SI (match_operand:SI 2 "register_operand")
13476 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13479 [(set (match_operand:SI 0 "register_operand")
13480 (unspec:SI [(match_dup 1) (match_dup 3)
13481 (match_dup 2) (reg:SI SP_REG)]
13483 (clobber (reg:CC FLAGS_REG))])]
13484 "!TARGET_64BIT && TARGET_GNU2_TLS"
13486 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13487 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13490 (define_insn "*tls_dynamic_gnu2_lea_32"
13491 [(set (match_operand:SI 0 "register_operand" "=r")
13492 (plus:SI (match_operand:SI 1 "register_operand" "b")
13494 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13495 UNSPEC_TLSDESC))))]
13496 "!TARGET_64BIT && TARGET_GNU2_TLS"
13497 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13498 [(set_attr "type" "lea")
13499 (set_attr "mode" "SI")
13500 (set_attr "length" "6")
13501 (set_attr "length_address" "4")])
13503 (define_insn "*tls_dynamic_gnu2_call_32"
13504 [(set (match_operand:SI 0 "register_operand" "=a")
13505 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13506 (match_operand:SI 2 "register_operand" "0")
13507 ;; we have to make sure %ebx still points to the GOT
13508 (match_operand:SI 3 "register_operand" "b")
13511 (clobber (reg:CC FLAGS_REG))]
13512 "!TARGET_64BIT && TARGET_GNU2_TLS"
13513 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13514 [(set_attr "type" "call")
13515 (set_attr "length" "2")
13516 (set_attr "length_address" "0")])
13518 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13519 [(set (match_operand:SI 0 "register_operand" "=&a")
13521 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13522 (match_operand:SI 4)
13523 (match_operand:SI 2 "register_operand" "b")
13526 (const:SI (unspec:SI
13527 [(match_operand 1 "tls_symbolic_operand")]
13529 (clobber (reg:CC FLAGS_REG))]
13530 "!TARGET_64BIT && TARGET_GNU2_TLS"
13533 [(set (match_dup 0) (match_dup 5))]
13535 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13536 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13539 (define_expand "tls_dynamic_gnu2_64"
13540 [(set (match_dup 2)
13541 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13544 [(set (match_operand:DI 0 "register_operand")
13545 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13547 (clobber (reg:CC FLAGS_REG))])]
13548 "TARGET_64BIT && TARGET_GNU2_TLS"
13550 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13551 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13554 (define_insn "*tls_dynamic_gnu2_lea_64"
13555 [(set (match_operand:DI 0 "register_operand" "=r")
13556 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13558 "TARGET_64BIT && TARGET_GNU2_TLS"
13559 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13560 [(set_attr "type" "lea")
13561 (set_attr "mode" "DI")
13562 (set_attr "length" "7")
13563 (set_attr "length_address" "4")])
13565 (define_insn "*tls_dynamic_gnu2_call_64"
13566 [(set (match_operand:DI 0 "register_operand" "=a")
13567 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13568 (match_operand:DI 2 "register_operand" "0")
13571 (clobber (reg:CC FLAGS_REG))]
13572 "TARGET_64BIT && TARGET_GNU2_TLS"
13573 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13574 [(set_attr "type" "call")
13575 (set_attr "length" "2")
13576 (set_attr "length_address" "0")])
13578 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13579 [(set (match_operand:DI 0 "register_operand" "=&a")
13581 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13582 (match_operand:DI 3)
13585 (const:DI (unspec:DI
13586 [(match_operand 1 "tls_symbolic_operand")]
13588 (clobber (reg:CC FLAGS_REG))]
13589 "TARGET_64BIT && TARGET_GNU2_TLS"
13592 [(set (match_dup 0) (match_dup 4))]
13594 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13595 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13598 ;; These patterns match the binary 387 instructions for addM3, subM3,
13599 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13600 ;; SFmode. The first is the normal insn, the second the same insn but
13601 ;; with one operand a conversion, and the third the same insn but with
13602 ;; the other operand a conversion. The conversion may be SFmode or
13603 ;; SImode if the target mode DFmode, but only SImode if the target mode
13606 ;; Gcc is slightly more smart about handling normal two address instructions
13607 ;; so use special patterns for add and mull.
13609 (define_insn "*fop_<mode>_comm_mixed"
13610 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13611 (match_operator:MODEF 3 "binary_fp_operator"
13612 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13613 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13614 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13615 && COMMUTATIVE_ARITH_P (operands[3])
13616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13617 "* return output_387_binary_op (insn, operands);"
13618 [(set (attr "type")
13619 (if_then_else (eq_attr "alternative" "1,2")
13620 (if_then_else (match_operand:MODEF 3 "mult_operator")
13621 (const_string "ssemul")
13622 (const_string "sseadd"))
13623 (if_then_else (match_operand:MODEF 3 "mult_operator")
13624 (const_string "fmul")
13625 (const_string "fop"))))
13626 (set_attr "isa" "*,noavx,avx")
13627 (set_attr "prefix" "orig,orig,vex")
13628 (set_attr "mode" "<MODE>")
13629 (set (attr "enabled")
13630 (cond [(eq_attr "alternative" "0")
13631 (symbol_ref "TARGET_MIX_SSE_I387")
13633 (const_string "*")))])
13635 (define_insn "*fop_<mode>_comm_i387"
13636 [(set (match_operand:MODEF 0 "register_operand" "=f")
13637 (match_operator:MODEF 3 "binary_fp_operator"
13638 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13639 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13640 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13641 && COMMUTATIVE_ARITH_P (operands[3])
13642 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13643 "* return output_387_binary_op (insn, operands);"
13644 [(set (attr "type")
13645 (if_then_else (match_operand:MODEF 3 "mult_operator")
13646 (const_string "fmul")
13647 (const_string "fop")))
13648 (set_attr "mode" "<MODE>")])
13650 (define_insn "*rcpsf2_sse"
13651 [(set (match_operand:SF 0 "register_operand" "=x")
13652 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13655 "%vrcpss\t{%1, %d0|%d0, %1}"
13656 [(set_attr "type" "sse")
13657 (set_attr "atom_sse_attr" "rcp")
13658 (set_attr "btver2_sse_attr" "rcp")
13659 (set_attr "prefix" "maybe_vex")
13660 (set_attr "mode" "SF")])
13662 (define_insn "*fop_<mode>_1_mixed"
13663 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13664 (match_operator:MODEF 3 "binary_fp_operator"
13665 [(match_operand:MODEF 1
13666 "register_mixssei387nonimm_operand" "0,fm,0,v")
13667 (match_operand:MODEF 2
13668 "nonimmediate_operand" "fm,0,xm,vm")]))]
13669 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13670 && !COMMUTATIVE_ARITH_P (operands[3])
13671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13672 "* return output_387_binary_op (insn, operands);"
13673 [(set (attr "type")
13674 (cond [(and (eq_attr "alternative" "2,3")
13675 (match_operand:MODEF 3 "mult_operator"))
13676 (const_string "ssemul")
13677 (and (eq_attr "alternative" "2,3")
13678 (match_operand:MODEF 3 "div_operator"))
13679 (const_string "ssediv")
13680 (eq_attr "alternative" "2,3")
13681 (const_string "sseadd")
13682 (match_operand:MODEF 3 "mult_operator")
13683 (const_string "fmul")
13684 (match_operand:MODEF 3 "div_operator")
13685 (const_string "fdiv")
13687 (const_string "fop")))
13688 (set_attr "isa" "*,*,noavx,avx")
13689 (set_attr "prefix" "orig,orig,orig,vex")
13690 (set_attr "mode" "<MODE>")
13691 (set (attr "enabled")
13692 (cond [(eq_attr "alternative" "0,1")
13693 (symbol_ref "TARGET_MIX_SSE_I387")
13695 (const_string "*")))])
13697 ;; This pattern is not fully shadowed by the pattern above.
13698 (define_insn "*fop_<mode>_1_i387"
13699 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13700 (match_operator:MODEF 3 "binary_fp_operator"
13701 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13702 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13703 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13704 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13705 && !COMMUTATIVE_ARITH_P (operands[3])
13706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set (attr "type")
13709 (cond [(match_operand:MODEF 3 "mult_operator")
13710 (const_string "fmul")
13711 (match_operand:MODEF 3 "div_operator")
13712 (const_string "fdiv")
13714 (const_string "fop")))
13715 (set_attr "mode" "<MODE>")])
13717 ;; ??? Add SSE splitters for these!
13718 (define_insn "*fop_<MODEF:mode>_2_i387"
13719 [(set (match_operand:MODEF 0 "register_operand" "=f")
13720 (match_operator:MODEF 3 "binary_fp_operator"
13722 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13723 (match_operand:MODEF 2 "register_operand" "0")]))]
13724 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13725 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13726 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13727 || optimize_function_for_size_p (cfun))"
13728 { return output_387_binary_op (insn, operands); }
13729 [(set (attr "type")
13730 (cond [(match_operand:MODEF 3 "mult_operator")
13731 (const_string "fmul")
13732 (match_operand:MODEF 3 "div_operator")
13733 (const_string "fdiv")
13735 (const_string "fop")))
13736 (set_attr "fp_int_src" "true")
13737 (set_attr "mode" "<SWI24:MODE>")])
13739 (define_insn "*fop_<MODEF:mode>_3_i387"
13740 [(set (match_operand:MODEF 0 "register_operand" "=f")
13741 (match_operator:MODEF 3 "binary_fp_operator"
13742 [(match_operand:MODEF 1 "register_operand" "0")
13744 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13745 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13746 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13747 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13748 || optimize_function_for_size_p (cfun))"
13749 { return output_387_binary_op (insn, operands); }
13750 [(set (attr "type")
13751 (cond [(match_operand:MODEF 3 "mult_operator")
13752 (const_string "fmul")
13753 (match_operand:MODEF 3 "div_operator")
13754 (const_string "fdiv")
13756 (const_string "fop")))
13757 (set_attr "fp_int_src" "true")
13758 (set_attr "mode" "<MODE>")])
13760 (define_insn "*fop_df_4_i387"
13761 [(set (match_operand:DF 0 "register_operand" "=f,f")
13762 (match_operator:DF 3 "binary_fp_operator"
13764 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13765 (match_operand:DF 2 "register_operand" "0,f")]))]
13766 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13767 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13769 "* return output_387_binary_op (insn, operands);"
13770 [(set (attr "type")
13771 (cond [(match_operand:DF 3 "mult_operator")
13772 (const_string "fmul")
13773 (match_operand:DF 3 "div_operator")
13774 (const_string "fdiv")
13776 (const_string "fop")))
13777 (set_attr "mode" "SF")])
13779 (define_insn "*fop_df_5_i387"
13780 [(set (match_operand:DF 0 "register_operand" "=f,f")
13781 (match_operator:DF 3 "binary_fp_operator"
13782 [(match_operand:DF 1 "register_operand" "0,f")
13784 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13785 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13786 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13787 "* return output_387_binary_op (insn, operands);"
13788 [(set (attr "type")
13789 (cond [(match_operand:DF 3 "mult_operator")
13790 (const_string "fmul")
13791 (match_operand:DF 3 "div_operator")
13792 (const_string "fdiv")
13794 (const_string "fop")))
13795 (set_attr "mode" "SF")])
13797 (define_insn "*fop_df_6_i387"
13798 [(set (match_operand:DF 0 "register_operand" "=f,f")
13799 (match_operator:DF 3 "binary_fp_operator"
13801 (match_operand:SF 1 "register_operand" "0,f"))
13803 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13804 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13805 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13806 "* return output_387_binary_op (insn, operands);"
13807 [(set (attr "type")
13808 (cond [(match_operand:DF 3 "mult_operator")
13809 (const_string "fmul")
13810 (match_operand:DF 3 "div_operator")
13811 (const_string "fdiv")
13813 (const_string "fop")))
13814 (set_attr "mode" "SF")])
13816 (define_insn "*fop_xf_comm_i387"
13817 [(set (match_operand:XF 0 "register_operand" "=f")
13818 (match_operator:XF 3 "binary_fp_operator"
13819 [(match_operand:XF 1 "register_operand" "%0")
13820 (match_operand:XF 2 "register_operand" "f")]))]
13822 && COMMUTATIVE_ARITH_P (operands[3])"
13823 "* return output_387_binary_op (insn, operands);"
13824 [(set (attr "type")
13825 (if_then_else (match_operand:XF 3 "mult_operator")
13826 (const_string "fmul")
13827 (const_string "fop")))
13828 (set_attr "mode" "XF")])
13830 (define_insn "*fop_xf_1_i387"
13831 [(set (match_operand:XF 0 "register_operand" "=f,f")
13832 (match_operator:XF 3 "binary_fp_operator"
13833 [(match_operand:XF 1 "register_operand" "0,f")
13834 (match_operand:XF 2 "register_operand" "f,0")]))]
13836 && !COMMUTATIVE_ARITH_P (operands[3])"
13837 "* return output_387_binary_op (insn, operands);"
13838 [(set (attr "type")
13839 (cond [(match_operand:XF 3 "mult_operator")
13840 (const_string "fmul")
13841 (match_operand:XF 3 "div_operator")
13842 (const_string "fdiv")
13844 (const_string "fop")))
13845 (set_attr "mode" "XF")])
13847 (define_insn "*fop_xf_2_i387"
13848 [(set (match_operand:XF 0 "register_operand" "=f")
13849 (match_operator:XF 3 "binary_fp_operator"
13851 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13852 (match_operand:XF 2 "register_operand" "0")]))]
13854 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13855 { return output_387_binary_op (insn, operands); }
13856 [(set (attr "type")
13857 (cond [(match_operand:XF 3 "mult_operator")
13858 (const_string "fmul")
13859 (match_operand:XF 3 "div_operator")
13860 (const_string "fdiv")
13862 (const_string "fop")))
13863 (set_attr "fp_int_src" "true")
13864 (set_attr "mode" "<MODE>")])
13866 (define_insn "*fop_xf_3_i387"
13867 [(set (match_operand:XF 0 "register_operand" "=f")
13868 (match_operator:XF 3 "binary_fp_operator"
13869 [(match_operand:XF 1 "register_operand" "0")
13871 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13873 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13874 { return output_387_binary_op (insn, operands); }
13875 [(set (attr "type")
13876 (cond [(match_operand:XF 3 "mult_operator")
13877 (const_string "fmul")
13878 (match_operand:XF 3 "div_operator")
13879 (const_string "fdiv")
13881 (const_string "fop")))
13882 (set_attr "fp_int_src" "true")
13883 (set_attr "mode" "<MODE>")])
13885 (define_insn "*fop_xf_4_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f,f")
13887 (match_operator:XF 3 "binary_fp_operator"
13889 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13890 (match_operand:XF 2 "register_operand" "0,f")]))]
13892 "* return output_387_binary_op (insn, operands);"
13893 [(set (attr "type")
13894 (cond [(match_operand:XF 3 "mult_operator")
13895 (const_string "fmul")
13896 (match_operand:XF 3 "div_operator")
13897 (const_string "fdiv")
13899 (const_string "fop")))
13900 (set_attr "mode" "<MODE>")])
13902 (define_insn "*fop_xf_5_i387"
13903 [(set (match_operand:XF 0 "register_operand" "=f,f")
13904 (match_operator:XF 3 "binary_fp_operator"
13905 [(match_operand:XF 1 "register_operand" "0,f")
13907 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
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 "mode" "<MODE>")])
13919 (define_insn "*fop_xf_6_i387"
13920 [(set (match_operand:XF 0 "register_operand" "=f,f")
13921 (match_operator:XF 3 "binary_fp_operator"
13923 (match_operand:MODEF 1 "register_operand" "0,f"))
13925 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13927 "* return output_387_binary_op (insn, operands);"
13928 [(set (attr "type")
13929 (cond [(match_operand:XF 3 "mult_operator")
13930 (const_string "fmul")
13931 (match_operand:XF 3 "div_operator")
13932 (const_string "fdiv")
13934 (const_string "fop")))
13935 (set_attr "mode" "<MODE>")])
13937 ;; FPU special functions.
13939 ;; This pattern implements a no-op XFmode truncation for
13940 ;; all fancy i386 XFmode math functions.
13942 (define_insn "truncxf<mode>2_i387_noop_unspec"
13943 [(set (match_operand:MODEF 0 "register_operand" "=f")
13944 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13945 UNSPEC_TRUNC_NOOP))]
13946 "TARGET_USE_FANCY_MATH_387"
13947 "* return output_387_reg_move (insn, operands);"
13948 [(set_attr "type" "fmov")
13949 (set_attr "mode" "<MODE>")])
13951 (define_insn "sqrtxf2"
13952 [(set (match_operand:XF 0 "register_operand" "=f")
13953 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13954 "TARGET_USE_FANCY_MATH_387"
13956 [(set_attr "type" "fpspc")
13957 (set_attr "mode" "XF")
13958 (set_attr "athlon_decode" "direct")
13959 (set_attr "amdfam10_decode" "direct")
13960 (set_attr "bdver1_decode" "direct")])
13962 (define_insn "sqrt_extend<mode>xf2_i387"
13963 [(set (match_operand:XF 0 "register_operand" "=f")
13966 (match_operand:MODEF 1 "register_operand" "0"))))]
13967 "TARGET_USE_FANCY_MATH_387"
13969 [(set_attr "type" "fpspc")
13970 (set_attr "mode" "XF")
13971 (set_attr "athlon_decode" "direct")
13972 (set_attr "amdfam10_decode" "direct")
13973 (set_attr "bdver1_decode" "direct")])
13975 (define_insn "*rsqrtsf2_sse"
13976 [(set (match_operand:SF 0 "register_operand" "=x")
13977 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13980 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13981 [(set_attr "type" "sse")
13982 (set_attr "atom_sse_attr" "rcp")
13983 (set_attr "btver2_sse_attr" "rcp")
13984 (set_attr "prefix" "maybe_vex")
13985 (set_attr "mode" "SF")])
13987 (define_expand "rsqrtsf2"
13988 [(set (match_operand:SF 0 "register_operand")
13989 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13993 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13997 (define_insn "*sqrt<mode>2_sse"
13998 [(set (match_operand:MODEF 0 "register_operand" "=v")
14000 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14001 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14002 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14003 [(set_attr "type" "sse")
14004 (set_attr "atom_sse_attr" "sqrt")
14005 (set_attr "btver2_sse_attr" "sqrt")
14006 (set_attr "prefix" "maybe_vex")
14007 (set_attr "mode" "<MODE>")
14008 (set_attr "athlon_decode" "*")
14009 (set_attr "amdfam10_decode" "*")
14010 (set_attr "bdver1_decode" "*")])
14012 (define_expand "sqrt<mode>2"
14013 [(set (match_operand:MODEF 0 "register_operand")
14015 (match_operand:MODEF 1 "nonimmediate_operand")))]
14016 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14017 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14019 if (<MODE>mode == SFmode
14021 && TARGET_RECIP_SQRT
14022 && !optimize_function_for_size_p (cfun)
14023 && flag_finite_math_only && !flag_trapping_math
14024 && flag_unsafe_math_optimizations)
14026 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14030 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14032 rtx op0 = gen_reg_rtx (XFmode);
14033 rtx op1 = force_reg (<MODE>mode, operands[1]);
14035 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14036 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14041 (define_insn "fpremxf4_i387"
14042 [(set (match_operand:XF 0 "register_operand" "=f")
14043 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14044 (match_operand:XF 3 "register_operand" "1")]
14046 (set (match_operand:XF 1 "register_operand" "=u")
14047 (unspec:XF [(match_dup 2) (match_dup 3)]
14049 (set (reg:CCFP FPSR_REG)
14050 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14052 "TARGET_USE_FANCY_MATH_387
14053 && flag_finite_math_only"
14055 [(set_attr "type" "fpspc")
14056 (set_attr "mode" "XF")])
14058 (define_expand "fmodxf3"
14059 [(use (match_operand:XF 0 "register_operand"))
14060 (use (match_operand:XF 1 "general_operand"))
14061 (use (match_operand:XF 2 "general_operand"))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && flag_finite_math_only"
14065 rtx_code_label *label = gen_label_rtx ();
14067 rtx op1 = gen_reg_rtx (XFmode);
14068 rtx op2 = gen_reg_rtx (XFmode);
14070 emit_move_insn (op2, operands[2]);
14071 emit_move_insn (op1, operands[1]);
14073 emit_label (label);
14074 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14075 ix86_emit_fp_unordered_jump (label);
14076 LABEL_NUSES (label) = 1;
14078 emit_move_insn (operands[0], op1);
14082 (define_expand "fmod<mode>3"
14083 [(use (match_operand:MODEF 0 "register_operand"))
14084 (use (match_operand:MODEF 1 "general_operand"))
14085 (use (match_operand:MODEF 2 "general_operand"))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_finite_math_only"
14089 rtx (*gen_truncxf) (rtx, rtx);
14091 rtx_code_label *label = gen_label_rtx ();
14093 rtx op1 = gen_reg_rtx (XFmode);
14094 rtx op2 = gen_reg_rtx (XFmode);
14096 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14097 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14099 emit_label (label);
14100 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14101 ix86_emit_fp_unordered_jump (label);
14102 LABEL_NUSES (label) = 1;
14104 /* Truncate the result properly for strict SSE math. */
14105 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14106 && !TARGET_MIX_SSE_I387)
14107 gen_truncxf = gen_truncxf<mode>2;
14109 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14111 emit_insn (gen_truncxf (operands[0], op1));
14115 (define_insn "fprem1xf4_i387"
14116 [(set (match_operand:XF 0 "register_operand" "=f")
14117 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14118 (match_operand:XF 3 "register_operand" "1")]
14120 (set (match_operand:XF 1 "register_operand" "=u")
14121 (unspec:XF [(match_dup 2) (match_dup 3)]
14123 (set (reg:CCFP FPSR_REG)
14124 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14126 "TARGET_USE_FANCY_MATH_387
14127 && flag_finite_math_only"
14129 [(set_attr "type" "fpspc")
14130 (set_attr "mode" "XF")])
14132 (define_expand "remainderxf3"
14133 [(use (match_operand:XF 0 "register_operand"))
14134 (use (match_operand:XF 1 "general_operand"))
14135 (use (match_operand:XF 2 "general_operand"))]
14136 "TARGET_USE_FANCY_MATH_387
14137 && flag_finite_math_only"
14139 rtx_code_label *label = gen_label_rtx ();
14141 rtx op1 = gen_reg_rtx (XFmode);
14142 rtx op2 = gen_reg_rtx (XFmode);
14144 emit_move_insn (op2, operands[2]);
14145 emit_move_insn (op1, operands[1]);
14147 emit_label (label);
14148 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14149 ix86_emit_fp_unordered_jump (label);
14150 LABEL_NUSES (label) = 1;
14152 emit_move_insn (operands[0], op1);
14156 (define_expand "remainder<mode>3"
14157 [(use (match_operand:MODEF 0 "register_operand"))
14158 (use (match_operand:MODEF 1 "general_operand"))
14159 (use (match_operand:MODEF 2 "general_operand"))]
14160 "TARGET_USE_FANCY_MATH_387
14161 && flag_finite_math_only"
14163 rtx (*gen_truncxf) (rtx, rtx);
14165 rtx_code_label *label = gen_label_rtx ();
14167 rtx op1 = gen_reg_rtx (XFmode);
14168 rtx op2 = gen_reg_rtx (XFmode);
14170 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14171 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173 emit_label (label);
14175 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14176 ix86_emit_fp_unordered_jump (label);
14177 LABEL_NUSES (label) = 1;
14179 /* Truncate the result properly for strict SSE math. */
14180 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14181 && !TARGET_MIX_SSE_I387)
14182 gen_truncxf = gen_truncxf<mode>2;
14184 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14186 emit_insn (gen_truncxf (operands[0], op1));
14190 (define_int_iterator SINCOS
14194 (define_int_attr sincos
14195 [(UNSPEC_SIN "sin")
14196 (UNSPEC_COS "cos")])
14198 (define_insn "*<sincos>xf2_i387"
14199 [(set (match_operand:XF 0 "register_operand" "=f")
14200 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_unsafe_math_optimizations"
14205 [(set_attr "type" "fpspc")
14206 (set_attr "mode" "XF")])
14208 (define_insn "*<sincos>_extend<mode>xf2_i387"
14209 [(set (match_operand:XF 0 "register_operand" "=f")
14210 (unspec:XF [(float_extend:XF
14211 (match_operand:MODEF 1 "register_operand" "0"))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations"
14218 [(set_attr "type" "fpspc")
14219 (set_attr "mode" "XF")])
14221 ;; When sincos pattern is defined, sin and cos builtin functions will be
14222 ;; expanded to sincos pattern with one of its outputs left unused.
14223 ;; CSE pass will figure out if two sincos patterns can be combined,
14224 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14225 ;; depending on the unused output.
14227 (define_insn "sincosxf3"
14228 [(set (match_operand:XF 0 "register_operand" "=f")
14229 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14230 UNSPEC_SINCOS_COS))
14231 (set (match_operand:XF 1 "register_operand" "=u")
14232 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14236 [(set_attr "type" "fpspc")
14237 (set_attr "mode" "XF")])
14240 [(set (match_operand:XF 0 "register_operand")
14241 (unspec:XF [(match_operand:XF 2 "register_operand")]
14242 UNSPEC_SINCOS_COS))
14243 (set (match_operand:XF 1 "register_operand")
14244 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14245 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14246 && can_create_pseudo_p ()"
14247 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14250 [(set (match_operand:XF 0 "register_operand")
14251 (unspec:XF [(match_operand:XF 2 "register_operand")]
14252 UNSPEC_SINCOS_COS))
14253 (set (match_operand:XF 1 "register_operand")
14254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14256 && can_create_pseudo_p ()"
14257 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14259 (define_insn "sincos_extend<mode>xf3_i387"
14260 [(set (match_operand:XF 0 "register_operand" "=f")
14261 (unspec:XF [(float_extend:XF
14262 (match_operand:MODEF 2 "register_operand" "0"))]
14263 UNSPEC_SINCOS_COS))
14264 (set (match_operand:XF 1 "register_operand" "=u")
14265 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14266 "TARGET_USE_FANCY_MATH_387
14267 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14268 || TARGET_MIX_SSE_I387)
14269 && flag_unsafe_math_optimizations"
14271 [(set_attr "type" "fpspc")
14272 (set_attr "mode" "XF")])
14275 [(set (match_operand:XF 0 "register_operand")
14276 (unspec:XF [(float_extend:XF
14277 (match_operand:MODEF 2 "register_operand"))]
14278 UNSPEC_SINCOS_COS))
14279 (set (match_operand:XF 1 "register_operand")
14280 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14281 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14282 && can_create_pseudo_p ()"
14283 [(set (match_dup 1)
14284 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14287 [(set (match_operand:XF 0 "register_operand")
14288 (unspec:XF [(float_extend:XF
14289 (match_operand:MODEF 2 "register_operand"))]
14290 UNSPEC_SINCOS_COS))
14291 (set (match_operand:XF 1 "register_operand")
14292 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14293 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14294 && can_create_pseudo_p ()"
14295 [(set (match_dup 0)
14296 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14298 (define_expand "sincos<mode>3"
14299 [(use (match_operand:MODEF 0 "register_operand"))
14300 (use (match_operand:MODEF 1 "register_operand"))
14301 (use (match_operand:MODEF 2 "register_operand"))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14307 rtx op0 = gen_reg_rtx (XFmode);
14308 rtx op1 = gen_reg_rtx (XFmode);
14310 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14316 (define_insn "fptanxf4_i387"
14317 [(set (match_operand:XF 0 "register_operand" "=f")
14318 (match_operand:XF 3 "const_double_operand" "F"))
14319 (set (match_operand:XF 1 "register_operand" "=u")
14320 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations
14324 && standard_80387_constant_p (operands[3]) == 2"
14326 [(set_attr "type" "fpspc")
14327 (set_attr "mode" "XF")])
14329 (define_insn "fptan_extend<mode>xf4_i387"
14330 [(set (match_operand:MODEF 0 "register_operand" "=f")
14331 (match_operand:MODEF 3 "const_double_operand" "F"))
14332 (set (match_operand:XF 1 "register_operand" "=u")
14333 (unspec:XF [(float_extend:XF
14334 (match_operand:MODEF 2 "register_operand" "0"))]
14336 "TARGET_USE_FANCY_MATH_387
14337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14338 || TARGET_MIX_SSE_I387)
14339 && flag_unsafe_math_optimizations
14340 && standard_80387_constant_p (operands[3]) == 2"
14342 [(set_attr "type" "fpspc")
14343 (set_attr "mode" "XF")])
14345 (define_expand "tanxf2"
14346 [(use (match_operand:XF 0 "register_operand"))
14347 (use (match_operand:XF 1 "register_operand"))]
14348 "TARGET_USE_FANCY_MATH_387
14349 && flag_unsafe_math_optimizations"
14351 rtx one = gen_reg_rtx (XFmode);
14352 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14354 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14358 (define_expand "tan<mode>2"
14359 [(use (match_operand:MODEF 0 "register_operand"))
14360 (use (match_operand:MODEF 1 "register_operand"))]
14361 "TARGET_USE_FANCY_MATH_387
14362 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14363 || TARGET_MIX_SSE_I387)
14364 && flag_unsafe_math_optimizations"
14366 rtx op0 = gen_reg_rtx (XFmode);
14368 rtx one = gen_reg_rtx (<MODE>mode);
14369 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14371 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14372 operands[1], op2));
14373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14377 (define_insn "*fpatanxf3_i387"
14378 [(set (match_operand:XF 0 "register_operand" "=f")
14379 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14380 (match_operand:XF 2 "register_operand" "u")]
14382 (clobber (match_scratch:XF 3 "=2"))]
14383 "TARGET_USE_FANCY_MATH_387
14384 && flag_unsafe_math_optimizations"
14386 [(set_attr "type" "fpspc")
14387 (set_attr "mode" "XF")])
14389 (define_insn "fpatan_extend<mode>xf3_i387"
14390 [(set (match_operand:XF 0 "register_operand" "=f")
14391 (unspec:XF [(float_extend:XF
14392 (match_operand:MODEF 1 "register_operand" "0"))
14394 (match_operand:MODEF 2 "register_operand" "u"))]
14396 (clobber (match_scratch:XF 3 "=2"))]
14397 "TARGET_USE_FANCY_MATH_387
14398 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14399 || TARGET_MIX_SSE_I387)
14400 && flag_unsafe_math_optimizations"
14402 [(set_attr "type" "fpspc")
14403 (set_attr "mode" "XF")])
14405 (define_expand "atan2xf3"
14406 [(parallel [(set (match_operand:XF 0 "register_operand")
14407 (unspec:XF [(match_operand:XF 2 "register_operand")
14408 (match_operand:XF 1 "register_operand")]
14410 (clobber (match_scratch:XF 3))])]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations")
14414 (define_expand "atan2<mode>3"
14415 [(use (match_operand:MODEF 0 "register_operand"))
14416 (use (match_operand:MODEF 1 "register_operand"))
14417 (use (match_operand:MODEF 2 "register_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14423 rtx op0 = gen_reg_rtx (XFmode);
14425 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14426 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14430 (define_expand "atanxf2"
14431 [(parallel [(set (match_operand:XF 0 "register_operand")
14432 (unspec:XF [(match_dup 2)
14433 (match_operand:XF 1 "register_operand")]
14435 (clobber (match_scratch:XF 3))])]
14436 "TARGET_USE_FANCY_MATH_387
14437 && flag_unsafe_math_optimizations"
14439 operands[2] = gen_reg_rtx (XFmode);
14440 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14443 (define_expand "atan<mode>2"
14444 [(use (match_operand:MODEF 0 "register_operand"))
14445 (use (match_operand:MODEF 1 "register_operand"))]
14446 "TARGET_USE_FANCY_MATH_387
14447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14448 || TARGET_MIX_SSE_I387)
14449 && flag_unsafe_math_optimizations"
14451 rtx op0 = gen_reg_rtx (XFmode);
14453 rtx op2 = gen_reg_rtx (<MODE>mode);
14454 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14456 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14457 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14461 (define_expand "asinxf2"
14462 [(set (match_dup 2)
14463 (mult:XF (match_operand:XF 1 "register_operand")
14465 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14466 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14467 (parallel [(set (match_operand:XF 0 "register_operand")
14468 (unspec:XF [(match_dup 5) (match_dup 1)]
14470 (clobber (match_scratch:XF 6))])]
14471 "TARGET_USE_FANCY_MATH_387
14472 && flag_unsafe_math_optimizations"
14476 if (optimize_insn_for_size_p ())
14479 for (i = 2; i < 6; i++)
14480 operands[i] = gen_reg_rtx (XFmode);
14482 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14485 (define_expand "asin<mode>2"
14486 [(use (match_operand:MODEF 0 "register_operand"))
14487 (use (match_operand:MODEF 1 "general_operand"))]
14488 "TARGET_USE_FANCY_MATH_387
14489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14490 || TARGET_MIX_SSE_I387)
14491 && flag_unsafe_math_optimizations"
14493 rtx op0 = gen_reg_rtx (XFmode);
14494 rtx op1 = gen_reg_rtx (XFmode);
14496 if (optimize_insn_for_size_p ())
14499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14500 emit_insn (gen_asinxf2 (op0, op1));
14501 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14505 (define_expand "acosxf2"
14506 [(set (match_dup 2)
14507 (mult:XF (match_operand:XF 1 "register_operand")
14509 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14510 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14511 (parallel [(set (match_operand:XF 0 "register_operand")
14512 (unspec:XF [(match_dup 1) (match_dup 5)]
14514 (clobber (match_scratch:XF 6))])]
14515 "TARGET_USE_FANCY_MATH_387
14516 && flag_unsafe_math_optimizations"
14520 if (optimize_insn_for_size_p ())
14523 for (i = 2; i < 6; i++)
14524 operands[i] = gen_reg_rtx (XFmode);
14526 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14529 (define_expand "acos<mode>2"
14530 [(use (match_operand:MODEF 0 "register_operand"))
14531 (use (match_operand:MODEF 1 "general_operand"))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534 || TARGET_MIX_SSE_I387)
14535 && flag_unsafe_math_optimizations"
14537 rtx op0 = gen_reg_rtx (XFmode);
14538 rtx op1 = gen_reg_rtx (XFmode);
14540 if (optimize_insn_for_size_p ())
14543 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14544 emit_insn (gen_acosxf2 (op0, op1));
14545 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14549 (define_insn "fyl2xxf3_i387"
14550 [(set (match_operand:XF 0 "register_operand" "=f")
14551 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14552 (match_operand:XF 2 "register_operand" "u")]
14554 (clobber (match_scratch:XF 3 "=2"))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && flag_unsafe_math_optimizations"
14558 [(set_attr "type" "fpspc")
14559 (set_attr "mode" "XF")])
14561 (define_insn "fyl2x_extend<mode>xf3_i387"
14562 [(set (match_operand:XF 0 "register_operand" "=f")
14563 (unspec:XF [(float_extend:XF
14564 (match_operand:MODEF 1 "register_operand" "0"))
14565 (match_operand:XF 2 "register_operand" "u")]
14567 (clobber (match_scratch:XF 3 "=2"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14570 || TARGET_MIX_SSE_I387)
14571 && flag_unsafe_math_optimizations"
14573 [(set_attr "type" "fpspc")
14574 (set_attr "mode" "XF")])
14576 (define_expand "logxf2"
14577 [(parallel [(set (match_operand:XF 0 "register_operand")
14578 (unspec:XF [(match_operand:XF 1 "register_operand")
14579 (match_dup 2)] UNSPEC_FYL2X))
14580 (clobber (match_scratch:XF 3))])]
14581 "TARGET_USE_FANCY_MATH_387
14582 && flag_unsafe_math_optimizations"
14584 operands[2] = gen_reg_rtx (XFmode);
14585 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14588 (define_expand "log<mode>2"
14589 [(use (match_operand:MODEF 0 "register_operand"))
14590 (use (match_operand:MODEF 1 "register_operand"))]
14591 "TARGET_USE_FANCY_MATH_387
14592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14593 || TARGET_MIX_SSE_I387)
14594 && flag_unsafe_math_optimizations"
14596 rtx op0 = gen_reg_rtx (XFmode);
14598 rtx op2 = gen_reg_rtx (XFmode);
14599 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14601 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14606 (define_expand "log10xf2"
14607 [(parallel [(set (match_operand:XF 0 "register_operand")
14608 (unspec:XF [(match_operand:XF 1 "register_operand")
14609 (match_dup 2)] UNSPEC_FYL2X))
14610 (clobber (match_scratch:XF 3))])]
14611 "TARGET_USE_FANCY_MATH_387
14612 && flag_unsafe_math_optimizations"
14614 operands[2] = gen_reg_rtx (XFmode);
14615 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14618 (define_expand "log10<mode>2"
14619 [(use (match_operand:MODEF 0 "register_operand"))
14620 (use (match_operand:MODEF 1 "register_operand"))]
14621 "TARGET_USE_FANCY_MATH_387
14622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14623 || TARGET_MIX_SSE_I387)
14624 && flag_unsafe_math_optimizations"
14626 rtx op0 = gen_reg_rtx (XFmode);
14628 rtx op2 = gen_reg_rtx (XFmode);
14629 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14631 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14632 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14636 (define_expand "log2xf2"
14637 [(parallel [(set (match_operand:XF 0 "register_operand")
14638 (unspec:XF [(match_operand:XF 1 "register_operand")
14639 (match_dup 2)] UNSPEC_FYL2X))
14640 (clobber (match_scratch:XF 3))])]
14641 "TARGET_USE_FANCY_MATH_387
14642 && flag_unsafe_math_optimizations"
14644 operands[2] = gen_reg_rtx (XFmode);
14645 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14648 (define_expand "log2<mode>2"
14649 [(use (match_operand:MODEF 0 "register_operand"))
14650 (use (match_operand:MODEF 1 "register_operand"))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14653 || TARGET_MIX_SSE_I387)
14654 && flag_unsafe_math_optimizations"
14656 rtx op0 = gen_reg_rtx (XFmode);
14658 rtx op2 = gen_reg_rtx (XFmode);
14659 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14661 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14666 (define_insn "fyl2xp1xf3_i387"
14667 [(set (match_operand:XF 0 "register_operand" "=f")
14668 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14669 (match_operand:XF 2 "register_operand" "u")]
14671 (clobber (match_scratch:XF 3 "=2"))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "XF")])
14678 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14679 [(set (match_operand:XF 0 "register_operand" "=f")
14680 (unspec:XF [(float_extend:XF
14681 (match_operand:MODEF 1 "register_operand" "0"))
14682 (match_operand:XF 2 "register_operand" "u")]
14684 (clobber (match_scratch:XF 3 "=2"))]
14685 "TARGET_USE_FANCY_MATH_387
14686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14687 || TARGET_MIX_SSE_I387)
14688 && flag_unsafe_math_optimizations"
14690 [(set_attr "type" "fpspc")
14691 (set_attr "mode" "XF")])
14693 (define_expand "log1pxf2"
14694 [(use (match_operand:XF 0 "register_operand"))
14695 (use (match_operand:XF 1 "register_operand"))]
14696 "TARGET_USE_FANCY_MATH_387
14697 && flag_unsafe_math_optimizations"
14699 if (optimize_insn_for_size_p ())
14702 ix86_emit_i387_log1p (operands[0], operands[1]);
14706 (define_expand "log1p<mode>2"
14707 [(use (match_operand:MODEF 0 "register_operand"))
14708 (use (match_operand:MODEF 1 "register_operand"))]
14709 "TARGET_USE_FANCY_MATH_387
14710 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14711 || TARGET_MIX_SSE_I387)
14712 && flag_unsafe_math_optimizations"
14716 if (optimize_insn_for_size_p ())
14719 op0 = gen_reg_rtx (XFmode);
14721 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14723 ix86_emit_i387_log1p (op0, operands[1]);
14724 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14728 (define_insn "fxtractxf3_i387"
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14731 UNSPEC_XTRACT_FRACT))
14732 (set (match_operand:XF 1 "register_operand" "=u")
14733 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14734 "TARGET_USE_FANCY_MATH_387
14735 && flag_unsafe_math_optimizations"
14737 [(set_attr "type" "fpspc")
14738 (set_attr "mode" "XF")])
14740 (define_insn "fxtract_extend<mode>xf3_i387"
14741 [(set (match_operand:XF 0 "register_operand" "=f")
14742 (unspec:XF [(float_extend:XF
14743 (match_operand:MODEF 2 "register_operand" "0"))]
14744 UNSPEC_XTRACT_FRACT))
14745 (set (match_operand:XF 1 "register_operand" "=u")
14746 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14747 "TARGET_USE_FANCY_MATH_387
14748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14749 || TARGET_MIX_SSE_I387)
14750 && flag_unsafe_math_optimizations"
14752 [(set_attr "type" "fpspc")
14753 (set_attr "mode" "XF")])
14755 (define_expand "logbxf2"
14756 [(parallel [(set (match_dup 2)
14757 (unspec:XF [(match_operand:XF 1 "register_operand")]
14758 UNSPEC_XTRACT_FRACT))
14759 (set (match_operand:XF 0 "register_operand")
14760 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14761 "TARGET_USE_FANCY_MATH_387
14762 && flag_unsafe_math_optimizations"
14763 "operands[2] = gen_reg_rtx (XFmode);")
14765 (define_expand "logb<mode>2"
14766 [(use (match_operand:MODEF 0 "register_operand"))
14767 (use (match_operand:MODEF 1 "register_operand"))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14770 || TARGET_MIX_SSE_I387)
14771 && flag_unsafe_math_optimizations"
14773 rtx op0 = gen_reg_rtx (XFmode);
14774 rtx op1 = gen_reg_rtx (XFmode);
14776 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14777 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14781 (define_expand "ilogbxf2"
14782 [(use (match_operand:SI 0 "register_operand"))
14783 (use (match_operand:XF 1 "register_operand"))]
14784 "TARGET_USE_FANCY_MATH_387
14785 && flag_unsafe_math_optimizations"
14789 if (optimize_insn_for_size_p ())
14792 op0 = gen_reg_rtx (XFmode);
14793 op1 = gen_reg_rtx (XFmode);
14795 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14796 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14800 (define_expand "ilogb<mode>2"
14801 [(use (match_operand:SI 0 "register_operand"))
14802 (use (match_operand:MODEF 1 "register_operand"))]
14803 "TARGET_USE_FANCY_MATH_387
14804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14805 || TARGET_MIX_SSE_I387)
14806 && flag_unsafe_math_optimizations"
14810 if (optimize_insn_for_size_p ())
14813 op0 = gen_reg_rtx (XFmode);
14814 op1 = gen_reg_rtx (XFmode);
14816 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14817 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14821 (define_insn "*f2xm1xf2_i387"
14822 [(set (match_operand:XF 0 "register_operand" "=f")
14823 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14825 "TARGET_USE_FANCY_MATH_387
14826 && flag_unsafe_math_optimizations"
14828 [(set_attr "type" "fpspc")
14829 (set_attr "mode" "XF")])
14831 (define_insn "fscalexf4_i387"
14832 [(set (match_operand:XF 0 "register_operand" "=f")
14833 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14834 (match_operand:XF 3 "register_operand" "1")]
14835 UNSPEC_FSCALE_FRACT))
14836 (set (match_operand:XF 1 "register_operand" "=u")
14837 (unspec:XF [(match_dup 2) (match_dup 3)]
14838 UNSPEC_FSCALE_EXP))]
14839 "TARGET_USE_FANCY_MATH_387
14840 && flag_unsafe_math_optimizations"
14842 [(set_attr "type" "fpspc")
14843 (set_attr "mode" "XF")])
14845 (define_expand "expNcorexf3"
14846 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14847 (match_operand:XF 2 "register_operand")))
14848 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14849 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14850 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14851 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14852 (parallel [(set (match_operand:XF 0 "register_operand")
14853 (unspec:XF [(match_dup 8) (match_dup 4)]
14854 UNSPEC_FSCALE_FRACT))
14856 (unspec:XF [(match_dup 8) (match_dup 4)]
14857 UNSPEC_FSCALE_EXP))])]
14858 "TARGET_USE_FANCY_MATH_387
14859 && flag_unsafe_math_optimizations"
14863 if (optimize_insn_for_size_p ())
14866 for (i = 3; i < 10; i++)
14867 operands[i] = gen_reg_rtx (XFmode);
14869 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14872 (define_expand "expxf2"
14873 [(use (match_operand:XF 0 "register_operand"))
14874 (use (match_operand:XF 1 "register_operand"))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14880 if (optimize_insn_for_size_p ())
14883 op2 = gen_reg_rtx (XFmode);
14884 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14886 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14890 (define_expand "exp<mode>2"
14891 [(use (match_operand:MODEF 0 "register_operand"))
14892 (use (match_operand:MODEF 1 "general_operand"))]
14893 "TARGET_USE_FANCY_MATH_387
14894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14895 || TARGET_MIX_SSE_I387)
14896 && flag_unsafe_math_optimizations"
14900 if (optimize_insn_for_size_p ())
14903 op0 = gen_reg_rtx (XFmode);
14904 op1 = gen_reg_rtx (XFmode);
14906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907 emit_insn (gen_expxf2 (op0, op1));
14908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14912 (define_expand "exp10xf2"
14913 [(use (match_operand:XF 0 "register_operand"))
14914 (use (match_operand:XF 1 "register_operand"))]
14915 "TARGET_USE_FANCY_MATH_387
14916 && flag_unsafe_math_optimizations"
14920 if (optimize_insn_for_size_p ())
14923 op2 = gen_reg_rtx (XFmode);
14924 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14926 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14930 (define_expand "exp10<mode>2"
14931 [(use (match_operand:MODEF 0 "register_operand"))
14932 (use (match_operand:MODEF 1 "general_operand"))]
14933 "TARGET_USE_FANCY_MATH_387
14934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14935 || TARGET_MIX_SSE_I387)
14936 && flag_unsafe_math_optimizations"
14940 if (optimize_insn_for_size_p ())
14943 op0 = gen_reg_rtx (XFmode);
14944 op1 = gen_reg_rtx (XFmode);
14946 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14947 emit_insn (gen_exp10xf2 (op0, op1));
14948 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14952 (define_expand "exp2xf2"
14953 [(use (match_operand:XF 0 "register_operand"))
14954 (use (match_operand:XF 1 "register_operand"))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations"
14960 if (optimize_insn_for_size_p ())
14963 op2 = gen_reg_rtx (XFmode);
14964 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14966 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14970 (define_expand "exp2<mode>2"
14971 [(use (match_operand:MODEF 0 "register_operand"))
14972 (use (match_operand:MODEF 1 "general_operand"))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14975 || TARGET_MIX_SSE_I387)
14976 && flag_unsafe_math_optimizations"
14980 if (optimize_insn_for_size_p ())
14983 op0 = gen_reg_rtx (XFmode);
14984 op1 = gen_reg_rtx (XFmode);
14986 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14987 emit_insn (gen_exp2xf2 (op0, op1));
14988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14992 (define_expand "expm1xf2"
14993 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14995 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14996 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14997 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14998 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14999 (parallel [(set (match_dup 7)
15000 (unspec:XF [(match_dup 6) (match_dup 4)]
15001 UNSPEC_FSCALE_FRACT))
15003 (unspec:XF [(match_dup 6) (match_dup 4)]
15004 UNSPEC_FSCALE_EXP))])
15005 (parallel [(set (match_dup 10)
15006 (unspec:XF [(match_dup 9) (match_dup 8)]
15007 UNSPEC_FSCALE_FRACT))
15008 (set (match_dup 11)
15009 (unspec:XF [(match_dup 9) (match_dup 8)]
15010 UNSPEC_FSCALE_EXP))])
15011 (set (match_dup 12) (minus:XF (match_dup 10)
15012 (float_extend:XF (match_dup 13))))
15013 (set (match_operand:XF 0 "register_operand")
15014 (plus:XF (match_dup 12) (match_dup 7)))]
15015 "TARGET_USE_FANCY_MATH_387
15016 && flag_unsafe_math_optimizations"
15020 if (optimize_insn_for_size_p ())
15023 for (i = 2; i < 13; i++)
15024 operands[i] = gen_reg_rtx (XFmode);
15027 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15029 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15032 (define_expand "expm1<mode>2"
15033 [(use (match_operand:MODEF 0 "register_operand"))
15034 (use (match_operand:MODEF 1 "general_operand"))]
15035 "TARGET_USE_FANCY_MATH_387
15036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15037 || TARGET_MIX_SSE_I387)
15038 && flag_unsafe_math_optimizations"
15042 if (optimize_insn_for_size_p ())
15045 op0 = gen_reg_rtx (XFmode);
15046 op1 = gen_reg_rtx (XFmode);
15048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15049 emit_insn (gen_expm1xf2 (op0, op1));
15050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15054 (define_expand "ldexpxf3"
15055 [(match_operand:XF 0 "register_operand")
15056 (match_operand:XF 1 "register_operand")
15057 (match_operand:SI 2 "register_operand")]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations"
15062 if (optimize_insn_for_size_p ())
15065 tmp1 = gen_reg_rtx (XFmode);
15066 tmp2 = gen_reg_rtx (XFmode);
15068 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15069 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15070 operands[1], tmp1));
15074 (define_expand "ldexp<mode>3"
15075 [(use (match_operand:MODEF 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "general_operand"))
15077 (use (match_operand:SI 2 "register_operand"))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080 || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations"
15085 if (optimize_insn_for_size_p ())
15088 op0 = gen_reg_rtx (XFmode);
15089 op1 = gen_reg_rtx (XFmode);
15091 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15092 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15097 (define_expand "scalbxf3"
15098 [(parallel [(set (match_operand:XF 0 " register_operand")
15099 (unspec:XF [(match_operand:XF 1 "register_operand")
15100 (match_operand:XF 2 "register_operand")]
15101 UNSPEC_FSCALE_FRACT))
15103 (unspec:XF [(match_dup 1) (match_dup 2)]
15104 UNSPEC_FSCALE_EXP))])]
15105 "TARGET_USE_FANCY_MATH_387
15106 && flag_unsafe_math_optimizations"
15108 if (optimize_insn_for_size_p ())
15111 operands[3] = gen_reg_rtx (XFmode);
15114 (define_expand "scalb<mode>3"
15115 [(use (match_operand:MODEF 0 "register_operand"))
15116 (use (match_operand:MODEF 1 "general_operand"))
15117 (use (match_operand:MODEF 2 "general_operand"))]
15118 "TARGET_USE_FANCY_MATH_387
15119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15120 || TARGET_MIX_SSE_I387)
15121 && flag_unsafe_math_optimizations"
15125 if (optimize_insn_for_size_p ())
15128 op0 = gen_reg_rtx (XFmode);
15129 op1 = gen_reg_rtx (XFmode);
15130 op2 = gen_reg_rtx (XFmode);
15132 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15133 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15134 emit_insn (gen_scalbxf3 (op0, op1, op2));
15135 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15139 (define_expand "significandxf2"
15140 [(parallel [(set (match_operand:XF 0 "register_operand")
15141 (unspec:XF [(match_operand:XF 1 "register_operand")]
15142 UNSPEC_XTRACT_FRACT))
15144 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15145 "TARGET_USE_FANCY_MATH_387
15146 && flag_unsafe_math_optimizations"
15147 "operands[2] = gen_reg_rtx (XFmode);")
15149 (define_expand "significand<mode>2"
15150 [(use (match_operand:MODEF 0 "register_operand"))
15151 (use (match_operand:MODEF 1 "register_operand"))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15154 || TARGET_MIX_SSE_I387)
15155 && flag_unsafe_math_optimizations"
15157 rtx op0 = gen_reg_rtx (XFmode);
15158 rtx op1 = gen_reg_rtx (XFmode);
15160 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15166 (define_insn "sse4_1_round<mode>2"
15167 [(set (match_operand:MODEF 0 "register_operand" "=x")
15168 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15169 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15172 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15173 [(set_attr "type" "ssecvt")
15174 (set_attr "prefix_extra" "1")
15175 (set_attr "prefix" "maybe_vex")
15176 (set_attr "mode" "<MODE>")])
15178 (define_insn "rintxf2"
15179 [(set (match_operand:XF 0 "register_operand" "=f")
15180 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations"
15185 [(set_attr "type" "fpspc")
15186 (set_attr "mode" "XF")])
15188 (define_expand "rint<mode>2"
15189 [(use (match_operand:MODEF 0 "register_operand"))
15190 (use (match_operand:MODEF 1 "register_operand"))]
15191 "(TARGET_USE_FANCY_MATH_387
15192 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15193 || TARGET_MIX_SSE_I387)
15194 && flag_unsafe_math_optimizations)
15195 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15196 && !flag_trapping_math)"
15198 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15199 && !flag_trapping_math)
15202 emit_insn (gen_sse4_1_round<mode>2
15203 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15204 else if (optimize_insn_for_size_p ())
15207 ix86_expand_rint (operands[0], operands[1]);
15211 rtx op0 = gen_reg_rtx (XFmode);
15212 rtx op1 = gen_reg_rtx (XFmode);
15214 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15215 emit_insn (gen_rintxf2 (op0, op1));
15217 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15222 (define_expand "round<mode>2"
15223 [(match_operand:X87MODEF 0 "register_operand")
15224 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15225 "(TARGET_USE_FANCY_MATH_387
15226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15227 || TARGET_MIX_SSE_I387)
15228 && flag_unsafe_math_optimizations)
15229 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15230 && !flag_trapping_math && !flag_rounding_math)"
15232 if (optimize_insn_for_size_p ())
15235 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15236 && !flag_trapping_math && !flag_rounding_math)
15240 operands[1] = force_reg (<MODE>mode, operands[1]);
15241 ix86_expand_round_sse4 (operands[0], operands[1]);
15243 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15244 ix86_expand_round (operands[0], operands[1]);
15246 ix86_expand_rounddf_32 (operands[0], operands[1]);
15250 operands[1] = force_reg (<MODE>mode, operands[1]);
15251 ix86_emit_i387_round (operands[0], operands[1]);
15256 (define_insn_and_split "*fistdi2_1"
15257 [(set (match_operand:DI 0 "nonimmediate_operand")
15258 (unspec:DI [(match_operand:XF 1 "register_operand")]
15260 "TARGET_USE_FANCY_MATH_387
15261 && can_create_pseudo_p ()"
15266 if (memory_operand (operands[0], VOIDmode))
15267 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15270 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15271 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15276 [(set_attr "type" "fpspc")
15277 (set_attr "mode" "DI")])
15279 (define_insn "fistdi2"
15280 [(set (match_operand:DI 0 "memory_operand" "=m")
15281 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15283 (clobber (match_scratch:XF 2 "=&1f"))]
15284 "TARGET_USE_FANCY_MATH_387"
15285 "* return output_fix_trunc (insn, operands, false);"
15286 [(set_attr "type" "fpspc")
15287 (set_attr "mode" "DI")])
15289 (define_insn "fistdi2_with_temp"
15290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15291 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15293 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15294 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15295 "TARGET_USE_FANCY_MATH_387"
15297 [(set_attr "type" "fpspc")
15298 (set_attr "mode" "DI")])
15301 [(set (match_operand:DI 0 "register_operand")
15302 (unspec:DI [(match_operand:XF 1 "register_operand")]
15304 (clobber (match_operand:DI 2 "memory_operand"))
15305 (clobber (match_scratch 3))]
15307 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15308 (clobber (match_dup 3))])
15309 (set (match_dup 0) (match_dup 2))])
15312 [(set (match_operand:DI 0 "memory_operand")
15313 (unspec:DI [(match_operand:XF 1 "register_operand")]
15315 (clobber (match_operand:DI 2 "memory_operand"))
15316 (clobber (match_scratch 3))]
15318 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15319 (clobber (match_dup 3))])])
15321 (define_insn_and_split "*fist<mode>2_1"
15322 [(set (match_operand:SWI24 0 "register_operand")
15323 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15325 "TARGET_USE_FANCY_MATH_387
15326 && can_create_pseudo_p ()"
15331 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15332 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15336 [(set_attr "type" "fpspc")
15337 (set_attr "mode" "<MODE>")])
15339 (define_insn "fist<mode>2"
15340 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15341 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15343 "TARGET_USE_FANCY_MATH_387"
15344 "* return output_fix_trunc (insn, operands, false);"
15345 [(set_attr "type" "fpspc")
15346 (set_attr "mode" "<MODE>")])
15348 (define_insn "fist<mode>2_with_temp"
15349 [(set (match_operand:SWI24 0 "register_operand" "=r")
15350 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15352 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15353 "TARGET_USE_FANCY_MATH_387"
15355 [(set_attr "type" "fpspc")
15356 (set_attr "mode" "<MODE>")])
15359 [(set (match_operand:SWI24 0 "register_operand")
15360 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15362 (clobber (match_operand:SWI24 2 "memory_operand"))]
15364 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15365 (set (match_dup 0) (match_dup 2))])
15368 [(set (match_operand:SWI24 0 "memory_operand")
15369 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15371 (clobber (match_operand:SWI24 2 "memory_operand"))]
15373 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15375 (define_expand "lrintxf<mode>2"
15376 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15377 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15379 "TARGET_USE_FANCY_MATH_387")
15381 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15382 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15383 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15384 UNSPEC_FIX_NOTRUNC))]
15385 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15387 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15388 [(match_operand:SWI248x 0 "nonimmediate_operand")
15389 (match_operand:X87MODEF 1 "register_operand")]
15390 "(TARGET_USE_FANCY_MATH_387
15391 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15392 || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations)
15394 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15395 && <SWI248x:MODE>mode != HImode
15396 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15397 && !flag_trapping_math && !flag_rounding_math)"
15399 if (optimize_insn_for_size_p ())
15402 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15403 && <SWI248x:MODE>mode != HImode
15404 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15405 && !flag_trapping_math && !flag_rounding_math)
15406 ix86_expand_lround (operands[0], operands[1]);
15408 ix86_emit_i387_round (operands[0], operands[1]);
15412 (define_int_iterator FRNDINT_ROUNDING
15413 [UNSPEC_FRNDINT_FLOOR
15414 UNSPEC_FRNDINT_CEIL
15415 UNSPEC_FRNDINT_TRUNC])
15417 (define_int_iterator FIST_ROUNDING
15421 ;; Base name for define_insn
15422 (define_int_attr rounding_insn
15423 [(UNSPEC_FRNDINT_FLOOR "floor")
15424 (UNSPEC_FRNDINT_CEIL "ceil")
15425 (UNSPEC_FRNDINT_TRUNC "btrunc")
15426 (UNSPEC_FIST_FLOOR "floor")
15427 (UNSPEC_FIST_CEIL "ceil")])
15429 (define_int_attr rounding
15430 [(UNSPEC_FRNDINT_FLOOR "floor")
15431 (UNSPEC_FRNDINT_CEIL "ceil")
15432 (UNSPEC_FRNDINT_TRUNC "trunc")
15433 (UNSPEC_FIST_FLOOR "floor")
15434 (UNSPEC_FIST_CEIL "ceil")])
15436 (define_int_attr ROUNDING
15437 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15438 (UNSPEC_FRNDINT_CEIL "CEIL")
15439 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15440 (UNSPEC_FIST_FLOOR "FLOOR")
15441 (UNSPEC_FIST_CEIL "CEIL")])
15443 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15444 (define_insn_and_split "frndintxf2_<rounding>"
15445 [(set (match_operand:XF 0 "register_operand")
15446 (unspec:XF [(match_operand:XF 1 "register_operand")]
15448 (clobber (reg:CC FLAGS_REG))]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations
15451 && can_create_pseudo_p ()"
15456 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15458 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15459 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15461 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15462 operands[2], operands[3]));
15465 [(set_attr "type" "frndint")
15466 (set_attr "i387_cw" "<rounding>")
15467 (set_attr "mode" "XF")])
15469 (define_insn "frndintxf2_<rounding>_i387"
15470 [(set (match_operand:XF 0 "register_operand" "=f")
15471 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15473 (use (match_operand:HI 2 "memory_operand" "m"))
15474 (use (match_operand:HI 3 "memory_operand" "m"))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && flag_unsafe_math_optimizations"
15477 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15478 [(set_attr "type" "frndint")
15479 (set_attr "i387_cw" "<rounding>")
15480 (set_attr "mode" "XF")])
15482 (define_expand "<rounding_insn>xf2"
15483 [(parallel [(set (match_operand:XF 0 "register_operand")
15484 (unspec:XF [(match_operand:XF 1 "register_operand")]
15486 (clobber (reg:CC FLAGS_REG))])]
15487 "TARGET_USE_FANCY_MATH_387
15488 && flag_unsafe_math_optimizations
15489 && !optimize_insn_for_size_p ()")
15491 (define_expand "<rounding_insn><mode>2"
15492 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15493 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15495 (clobber (reg:CC FLAGS_REG))])]
15496 "(TARGET_USE_FANCY_MATH_387
15497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15498 || TARGET_MIX_SSE_I387)
15499 && flag_unsafe_math_optimizations)
15500 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15501 && !flag_trapping_math)"
15503 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15504 && !flag_trapping_math)
15507 emit_insn (gen_sse4_1_round<mode>2
15508 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15509 else if (optimize_insn_for_size_p ())
15511 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15513 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15514 ix86_expand_floorceil (operands[0], operands[1], true);
15515 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15516 ix86_expand_floorceil (operands[0], operands[1], false);
15517 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15518 ix86_expand_trunc (operands[0], operands[1]);
15520 gcc_unreachable ();
15524 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15525 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15526 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15527 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15528 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15529 ix86_expand_truncdf_32 (operands[0], operands[1]);
15531 gcc_unreachable ();
15538 if (optimize_insn_for_size_p ())
15541 op0 = gen_reg_rtx (XFmode);
15542 op1 = gen_reg_rtx (XFmode);
15543 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15544 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15546 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15551 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15552 (define_insn_and_split "frndintxf2_mask_pm"
15553 [(set (match_operand:XF 0 "register_operand")
15554 (unspec:XF [(match_operand:XF 1 "register_operand")]
15555 UNSPEC_FRNDINT_MASK_PM))
15556 (clobber (reg:CC FLAGS_REG))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && flag_unsafe_math_optimizations
15559 && can_create_pseudo_p ()"
15564 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15566 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15567 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15569 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15570 operands[2], operands[3]));
15573 [(set_attr "type" "frndint")
15574 (set_attr "i387_cw" "mask_pm")
15575 (set_attr "mode" "XF")])
15577 (define_insn "frndintxf2_mask_pm_i387"
15578 [(set (match_operand:XF 0 "register_operand" "=f")
15579 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15580 UNSPEC_FRNDINT_MASK_PM))
15581 (use (match_operand:HI 2 "memory_operand" "m"))
15582 (use (match_operand:HI 3 "memory_operand" "m"))]
15583 "TARGET_USE_FANCY_MATH_387
15584 && flag_unsafe_math_optimizations"
15585 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15586 [(set_attr "type" "frndint")
15587 (set_attr "i387_cw" "mask_pm")
15588 (set_attr "mode" "XF")])
15590 (define_expand "nearbyintxf2"
15591 [(parallel [(set (match_operand:XF 0 "register_operand")
15592 (unspec:XF [(match_operand:XF 1 "register_operand")]
15593 UNSPEC_FRNDINT_MASK_PM))
15594 (clobber (reg:CC FLAGS_REG))])]
15595 "TARGET_USE_FANCY_MATH_387
15596 && flag_unsafe_math_optimizations")
15598 (define_expand "nearbyint<mode>2"
15599 [(use (match_operand:MODEF 0 "register_operand"))
15600 (use (match_operand:MODEF 1 "register_operand"))]
15601 "TARGET_USE_FANCY_MATH_387
15602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15603 || TARGET_MIX_SSE_I387)
15604 && flag_unsafe_math_optimizations"
15606 rtx op0 = gen_reg_rtx (XFmode);
15607 rtx op1 = gen_reg_rtx (XFmode);
15609 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15610 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15612 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15616 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15617 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15618 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15619 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15621 (clobber (reg:CC FLAGS_REG))]
15622 "TARGET_USE_FANCY_MATH_387
15623 && flag_unsafe_math_optimizations
15624 && can_create_pseudo_p ()"
15629 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15631 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15632 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15633 if (memory_operand (operands[0], VOIDmode))
15634 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15635 operands[2], operands[3]));
15638 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15639 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15640 (operands[0], operands[1], operands[2],
15641 operands[3], operands[4]));
15645 [(set_attr "type" "fistp")
15646 (set_attr "i387_cw" "<rounding>")
15647 (set_attr "mode" "<MODE>")])
15649 (define_insn "fistdi2_<rounding>"
15650 [(set (match_operand:DI 0 "memory_operand" "=m")
15651 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15653 (use (match_operand:HI 2 "memory_operand" "m"))
15654 (use (match_operand:HI 3 "memory_operand" "m"))
15655 (clobber (match_scratch:XF 4 "=&1f"))]
15656 "TARGET_USE_FANCY_MATH_387
15657 && flag_unsafe_math_optimizations"
15658 "* return output_fix_trunc (insn, operands, false);"
15659 [(set_attr "type" "fistp")
15660 (set_attr "i387_cw" "<rounding>")
15661 (set_attr "mode" "DI")])
15663 (define_insn "fistdi2_<rounding>_with_temp"
15664 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15665 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15667 (use (match_operand:HI 2 "memory_operand" "m,m"))
15668 (use (match_operand:HI 3 "memory_operand" "m,m"))
15669 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15670 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15671 "TARGET_USE_FANCY_MATH_387
15672 && flag_unsafe_math_optimizations"
15674 [(set_attr "type" "fistp")
15675 (set_attr "i387_cw" "<rounding>")
15676 (set_attr "mode" "DI")])
15679 [(set (match_operand:DI 0 "register_operand")
15680 (unspec:DI [(match_operand:XF 1 "register_operand")]
15682 (use (match_operand:HI 2 "memory_operand"))
15683 (use (match_operand:HI 3 "memory_operand"))
15684 (clobber (match_operand:DI 4 "memory_operand"))
15685 (clobber (match_scratch 5))]
15687 [(parallel [(set (match_dup 4)
15688 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15689 (use (match_dup 2))
15690 (use (match_dup 3))
15691 (clobber (match_dup 5))])
15692 (set (match_dup 0) (match_dup 4))])
15695 [(set (match_operand:DI 0 "memory_operand")
15696 (unspec:DI [(match_operand:XF 1 "register_operand")]
15698 (use (match_operand:HI 2 "memory_operand"))
15699 (use (match_operand:HI 3 "memory_operand"))
15700 (clobber (match_operand:DI 4 "memory_operand"))
15701 (clobber (match_scratch 5))]
15703 [(parallel [(set (match_dup 0)
15704 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15705 (use (match_dup 2))
15706 (use (match_dup 3))
15707 (clobber (match_dup 5))])])
15709 (define_insn "fist<mode>2_<rounding>"
15710 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15711 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15713 (use (match_operand:HI 2 "memory_operand" "m"))
15714 (use (match_operand:HI 3 "memory_operand" "m"))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && flag_unsafe_math_optimizations"
15717 "* return output_fix_trunc (insn, operands, false);"
15718 [(set_attr "type" "fistp")
15719 (set_attr "i387_cw" "<rounding>")
15720 (set_attr "mode" "<MODE>")])
15722 (define_insn "fist<mode>2_<rounding>_with_temp"
15723 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15724 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15726 (use (match_operand:HI 2 "memory_operand" "m,m"))
15727 (use (match_operand:HI 3 "memory_operand" "m,m"))
15728 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15729 "TARGET_USE_FANCY_MATH_387
15730 && flag_unsafe_math_optimizations"
15732 [(set_attr "type" "fistp")
15733 (set_attr "i387_cw" "<rounding>")
15734 (set_attr "mode" "<MODE>")])
15737 [(set (match_operand:SWI24 0 "register_operand")
15738 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15740 (use (match_operand:HI 2 "memory_operand"))
15741 (use (match_operand:HI 3 "memory_operand"))
15742 (clobber (match_operand:SWI24 4 "memory_operand"))]
15744 [(parallel [(set (match_dup 4)
15745 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15746 (use (match_dup 2))
15747 (use (match_dup 3))])
15748 (set (match_dup 0) (match_dup 4))])
15751 [(set (match_operand:SWI24 0 "memory_operand")
15752 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15754 (use (match_operand:HI 2 "memory_operand"))
15755 (use (match_operand:HI 3 "memory_operand"))
15756 (clobber (match_operand:SWI24 4 "memory_operand"))]
15758 [(parallel [(set (match_dup 0)
15759 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15760 (use (match_dup 2))
15761 (use (match_dup 3))])])
15763 (define_expand "l<rounding_insn>xf<mode>2"
15764 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15765 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15767 (clobber (reg:CC FLAGS_REG))])]
15768 "TARGET_USE_FANCY_MATH_387
15769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15770 && flag_unsafe_math_optimizations")
15772 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15773 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15774 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15776 (clobber (reg:CC FLAGS_REG))])]
15777 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15778 && !flag_trapping_math"
15780 if (TARGET_64BIT && optimize_insn_for_size_p ())
15783 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15784 ix86_expand_lfloorceil (operands[0], operands[1], true);
15785 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15786 ix86_expand_lfloorceil (operands[0], operands[1], false);
15788 gcc_unreachable ();
15793 (define_insn "fxam<mode>2_i387"
15794 [(set (match_operand:HI 0 "register_operand" "=a")
15796 [(match_operand:X87MODEF 1 "register_operand" "f")]
15798 "TARGET_USE_FANCY_MATH_387"
15799 "fxam\n\tfnstsw\t%0"
15800 [(set_attr "type" "multi")
15801 (set_attr "length" "4")
15802 (set_attr "unit" "i387")
15803 (set_attr "mode" "<MODE>")])
15805 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15806 [(set (match_operand:HI 0 "register_operand")
15808 [(match_operand:MODEF 1 "memory_operand")]
15810 "TARGET_USE_FANCY_MATH_387
15811 && can_create_pseudo_p ()"
15814 [(set (match_dup 2)(match_dup 1))
15816 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15818 operands[2] = gen_reg_rtx (<MODE>mode);
15820 MEM_VOLATILE_P (operands[1]) = 1;
15822 [(set_attr "type" "multi")
15823 (set_attr "unit" "i387")
15824 (set_attr "mode" "<MODE>")])
15826 (define_expand "isinfxf2"
15827 [(use (match_operand:SI 0 "register_operand"))
15828 (use (match_operand:XF 1 "register_operand"))]
15829 "TARGET_USE_FANCY_MATH_387
15830 && ix86_libc_has_function (function_c99_misc)"
15832 rtx mask = GEN_INT (0x45);
15833 rtx val = GEN_INT (0x05);
15837 rtx scratch = gen_reg_rtx (HImode);
15838 rtx res = gen_reg_rtx (QImode);
15840 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15842 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15843 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15844 cond = gen_rtx_fmt_ee (EQ, QImode,
15845 gen_rtx_REG (CCmode, FLAGS_REG),
15847 emit_insn (gen_rtx_SET (res, cond));
15848 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15852 (define_expand "isinf<mode>2"
15853 [(use (match_operand:SI 0 "register_operand"))
15854 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15855 "TARGET_USE_FANCY_MATH_387
15856 && ix86_libc_has_function (function_c99_misc)
15857 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15859 rtx mask = GEN_INT (0x45);
15860 rtx val = GEN_INT (0x05);
15864 rtx scratch = gen_reg_rtx (HImode);
15865 rtx res = gen_reg_rtx (QImode);
15867 /* Remove excess precision by forcing value through memory. */
15868 if (memory_operand (operands[1], VOIDmode))
15869 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15872 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15874 emit_move_insn (temp, operands[1]);
15875 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15878 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15879 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15880 cond = gen_rtx_fmt_ee (EQ, QImode,
15881 gen_rtx_REG (CCmode, FLAGS_REG),
15883 emit_insn (gen_rtx_SET (res, cond));
15884 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15888 (define_expand "signbitxf2"
15889 [(use (match_operand:SI 0 "register_operand"))
15890 (use (match_operand:XF 1 "register_operand"))]
15891 "TARGET_USE_FANCY_MATH_387"
15893 rtx scratch = gen_reg_rtx (HImode);
15895 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15896 emit_insn (gen_andsi3 (operands[0],
15897 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15901 (define_insn "movmsk_df"
15902 [(set (match_operand:SI 0 "register_operand" "=r")
15904 [(match_operand:DF 1 "register_operand" "x")]
15906 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15907 "%vmovmskpd\t{%1, %0|%0, %1}"
15908 [(set_attr "type" "ssemov")
15909 (set_attr "prefix" "maybe_vex")
15910 (set_attr "mode" "DF")])
15912 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15913 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15914 (define_expand "signbitdf2"
15915 [(use (match_operand:SI 0 "register_operand"))
15916 (use (match_operand:DF 1 "register_operand"))]
15917 "TARGET_USE_FANCY_MATH_387
15918 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15920 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15922 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15923 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15927 rtx scratch = gen_reg_rtx (HImode);
15929 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15930 emit_insn (gen_andsi3 (operands[0],
15931 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15936 (define_expand "signbitsf2"
15937 [(use (match_operand:SI 0 "register_operand"))
15938 (use (match_operand:SF 1 "register_operand"))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15942 rtx scratch = gen_reg_rtx (HImode);
15944 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15945 emit_insn (gen_andsi3 (operands[0],
15946 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15950 ;; Block operation instructions
15953 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15956 [(set_attr "length" "1")
15957 (set_attr "length_immediate" "0")
15958 (set_attr "modrm" "0")])
15960 (define_expand "movmem<mode>"
15961 [(use (match_operand:BLK 0 "memory_operand"))
15962 (use (match_operand:BLK 1 "memory_operand"))
15963 (use (match_operand:SWI48 2 "nonmemory_operand"))
15964 (use (match_operand:SWI48 3 "const_int_operand"))
15965 (use (match_operand:SI 4 "const_int_operand"))
15966 (use (match_operand:SI 5 "const_int_operand"))
15967 (use (match_operand:SI 6 ""))
15968 (use (match_operand:SI 7 ""))
15969 (use (match_operand:SI 8 ""))]
15972 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15973 operands[2], NULL, operands[3],
15974 operands[4], operands[5],
15975 operands[6], operands[7],
15976 operands[8], false))
15982 ;; Most CPUs don't like single string operations
15983 ;; Handle this case here to simplify previous expander.
15985 (define_expand "strmov"
15986 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15987 (set (match_operand 1 "memory_operand") (match_dup 4))
15988 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15989 (clobber (reg:CC FLAGS_REG))])
15990 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15991 (clobber (reg:CC FLAGS_REG))])]
15994 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15996 /* If .md ever supports :P for Pmode, these can be directly
15997 in the pattern above. */
15998 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15999 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16001 /* Can't use this if the user has appropriated esi or edi. */
16002 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16003 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16005 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16006 operands[2], operands[3],
16007 operands[5], operands[6]));
16011 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16014 (define_expand "strmov_singleop"
16015 [(parallel [(set (match_operand 1 "memory_operand")
16016 (match_operand 3 "memory_operand"))
16017 (set (match_operand 0 "register_operand")
16019 (set (match_operand 2 "register_operand")
16020 (match_operand 5))])]
16022 "ix86_current_function_needs_cld = 1;")
16024 (define_insn "*strmovdi_rex_1"
16025 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16026 (mem:DI (match_operand:P 3 "register_operand" "1")))
16027 (set (match_operand:P 0 "register_operand" "=D")
16028 (plus:P (match_dup 2)
16030 (set (match_operand:P 1 "register_operand" "=S")
16031 (plus:P (match_dup 3)
16034 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16036 [(set_attr "type" "str")
16037 (set_attr "memory" "both")
16038 (set_attr "mode" "DI")])
16040 (define_insn "*strmovsi_1"
16041 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16042 (mem:SI (match_operand:P 3 "register_operand" "1")))
16043 (set (match_operand:P 0 "register_operand" "=D")
16044 (plus:P (match_dup 2)
16046 (set (match_operand:P 1 "register_operand" "=S")
16047 (plus:P (match_dup 3)
16049 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16051 [(set_attr "type" "str")
16052 (set_attr "memory" "both")
16053 (set_attr "mode" "SI")])
16055 (define_insn "*strmovhi_1"
16056 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16057 (mem:HI (match_operand:P 3 "register_operand" "1")))
16058 (set (match_operand:P 0 "register_operand" "=D")
16059 (plus:P (match_dup 2)
16061 (set (match_operand:P 1 "register_operand" "=S")
16062 (plus:P (match_dup 3)
16064 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16066 [(set_attr "type" "str")
16067 (set_attr "memory" "both")
16068 (set_attr "mode" "HI")])
16070 (define_insn "*strmovqi_1"
16071 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16072 (mem:QI (match_operand:P 3 "register_operand" "1")))
16073 (set (match_operand:P 0 "register_operand" "=D")
16074 (plus:P (match_dup 2)
16076 (set (match_operand:P 1 "register_operand" "=S")
16077 (plus:P (match_dup 3)
16079 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16081 [(set_attr "type" "str")
16082 (set_attr "memory" "both")
16083 (set (attr "prefix_rex")
16085 (match_test "<P:MODE>mode == DImode")
16087 (const_string "*")))
16088 (set_attr "mode" "QI")])
16090 (define_expand "rep_mov"
16091 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16092 (set (match_operand 0 "register_operand")
16094 (set (match_operand 2 "register_operand")
16096 (set (match_operand 1 "memory_operand")
16097 (match_operand 3 "memory_operand"))
16098 (use (match_dup 4))])]
16100 "ix86_current_function_needs_cld = 1;")
16102 (define_insn "*rep_movdi_rex64"
16103 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16104 (set (match_operand:P 0 "register_operand" "=D")
16105 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16107 (match_operand:P 3 "register_operand" "0")))
16108 (set (match_operand:P 1 "register_operand" "=S")
16109 (plus:P (ashift:P (match_dup 5) (const_int 3))
16110 (match_operand:P 4 "register_operand" "1")))
16111 (set (mem:BLK (match_dup 3))
16112 (mem:BLK (match_dup 4)))
16113 (use (match_dup 5))]
16115 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16117 [(set_attr "type" "str")
16118 (set_attr "prefix_rep" "1")
16119 (set_attr "memory" "both")
16120 (set_attr "mode" "DI")])
16122 (define_insn "*rep_movsi"
16123 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16124 (set (match_operand:P 0 "register_operand" "=D")
16125 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16127 (match_operand:P 3 "register_operand" "0")))
16128 (set (match_operand:P 1 "register_operand" "=S")
16129 (plus:P (ashift:P (match_dup 5) (const_int 2))
16130 (match_operand:P 4 "register_operand" "1")))
16131 (set (mem:BLK (match_dup 3))
16132 (mem:BLK (match_dup 4)))
16133 (use (match_dup 5))]
16134 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16135 "%^rep{%;} movs{l|d}"
16136 [(set_attr "type" "str")
16137 (set_attr "prefix_rep" "1")
16138 (set_attr "memory" "both")
16139 (set_attr "mode" "SI")])
16141 (define_insn "*rep_movqi"
16142 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16143 (set (match_operand:P 0 "register_operand" "=D")
16144 (plus:P (match_operand:P 3 "register_operand" "0")
16145 (match_operand:P 5 "register_operand" "2")))
16146 (set (match_operand:P 1 "register_operand" "=S")
16147 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16148 (set (mem:BLK (match_dup 3))
16149 (mem:BLK (match_dup 4)))
16150 (use (match_dup 5))]
16151 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16153 [(set_attr "type" "str")
16154 (set_attr "prefix_rep" "1")
16155 (set_attr "memory" "both")
16156 (set_attr "mode" "QI")])
16158 (define_expand "setmem<mode>"
16159 [(use (match_operand:BLK 0 "memory_operand"))
16160 (use (match_operand:SWI48 1 "nonmemory_operand"))
16161 (use (match_operand:QI 2 "nonmemory_operand"))
16162 (use (match_operand 3 "const_int_operand"))
16163 (use (match_operand:SI 4 "const_int_operand"))
16164 (use (match_operand:SI 5 "const_int_operand"))
16165 (use (match_operand:SI 6 ""))
16166 (use (match_operand:SI 7 ""))
16167 (use (match_operand:SI 8 ""))]
16170 if (ix86_expand_set_or_movmem (operands[0], NULL,
16171 operands[1], operands[2],
16172 operands[3], operands[4],
16173 operands[5], operands[6],
16174 operands[7], operands[8], true))
16180 ;; Most CPUs don't like single string operations
16181 ;; Handle this case here to simplify previous expander.
16183 (define_expand "strset"
16184 [(set (match_operand 1 "memory_operand")
16185 (match_operand 2 "register_operand"))
16186 (parallel [(set (match_operand 0 "register_operand")
16188 (clobber (reg:CC FLAGS_REG))])]
16191 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16192 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16194 /* If .md ever supports :P for Pmode, this can be directly
16195 in the pattern above. */
16196 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16197 GEN_INT (GET_MODE_SIZE (GET_MODE
16199 /* Can't use this if the user has appropriated eax or edi. */
16200 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16201 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16203 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16209 (define_expand "strset_singleop"
16210 [(parallel [(set (match_operand 1 "memory_operand")
16211 (match_operand 2 "register_operand"))
16212 (set (match_operand 0 "register_operand")
16214 (unspec [(const_int 0)] UNSPEC_STOS)])]
16216 "ix86_current_function_needs_cld = 1;")
16218 (define_insn "*strsetdi_rex_1"
16219 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16220 (match_operand:DI 2 "register_operand" "a"))
16221 (set (match_operand:P 0 "register_operand" "=D")
16222 (plus:P (match_dup 1)
16224 (unspec [(const_int 0)] UNSPEC_STOS)]
16226 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16228 [(set_attr "type" "str")
16229 (set_attr "memory" "store")
16230 (set_attr "mode" "DI")])
16232 (define_insn "*strsetsi_1"
16233 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16234 (match_operand:SI 2 "register_operand" "a"))
16235 (set (match_operand:P 0 "register_operand" "=D")
16236 (plus:P (match_dup 1)
16238 (unspec [(const_int 0)] UNSPEC_STOS)]
16239 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16241 [(set_attr "type" "str")
16242 (set_attr "memory" "store")
16243 (set_attr "mode" "SI")])
16245 (define_insn "*strsethi_1"
16246 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16247 (match_operand:HI 2 "register_operand" "a"))
16248 (set (match_operand:P 0 "register_operand" "=D")
16249 (plus:P (match_dup 1)
16251 (unspec [(const_int 0)] UNSPEC_STOS)]
16252 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16254 [(set_attr "type" "str")
16255 (set_attr "memory" "store")
16256 (set_attr "mode" "HI")])
16258 (define_insn "*strsetqi_1"
16259 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16260 (match_operand:QI 2 "register_operand" "a"))
16261 (set (match_operand:P 0 "register_operand" "=D")
16262 (plus:P (match_dup 1)
16264 (unspec [(const_int 0)] UNSPEC_STOS)]
16265 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16267 [(set_attr "type" "str")
16268 (set_attr "memory" "store")
16269 (set (attr "prefix_rex")
16271 (match_test "<P:MODE>mode == DImode")
16273 (const_string "*")))
16274 (set_attr "mode" "QI")])
16276 (define_expand "rep_stos"
16277 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16278 (set (match_operand 0 "register_operand")
16280 (set (match_operand 2 "memory_operand") (const_int 0))
16281 (use (match_operand 3 "register_operand"))
16282 (use (match_dup 1))])]
16284 "ix86_current_function_needs_cld = 1;")
16286 (define_insn "*rep_stosdi_rex64"
16287 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16288 (set (match_operand:P 0 "register_operand" "=D")
16289 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16291 (match_operand:P 3 "register_operand" "0")))
16292 (set (mem:BLK (match_dup 3))
16294 (use (match_operand:DI 2 "register_operand" "a"))
16295 (use (match_dup 4))]
16297 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16299 [(set_attr "type" "str")
16300 (set_attr "prefix_rep" "1")
16301 (set_attr "memory" "store")
16302 (set_attr "mode" "DI")])
16304 (define_insn "*rep_stossi"
16305 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16306 (set (match_operand:P 0 "register_operand" "=D")
16307 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16309 (match_operand:P 3 "register_operand" "0")))
16310 (set (mem:BLK (match_dup 3))
16312 (use (match_operand:SI 2 "register_operand" "a"))
16313 (use (match_dup 4))]
16314 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16315 "%^rep{%;} stos{l|d}"
16316 [(set_attr "type" "str")
16317 (set_attr "prefix_rep" "1")
16318 (set_attr "memory" "store")
16319 (set_attr "mode" "SI")])
16321 (define_insn "*rep_stosqi"
16322 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16323 (set (match_operand:P 0 "register_operand" "=D")
16324 (plus:P (match_operand:P 3 "register_operand" "0")
16325 (match_operand:P 4 "register_operand" "1")))
16326 (set (mem:BLK (match_dup 3))
16328 (use (match_operand:QI 2 "register_operand" "a"))
16329 (use (match_dup 4))]
16330 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16332 [(set_attr "type" "str")
16333 (set_attr "prefix_rep" "1")
16334 (set_attr "memory" "store")
16335 (set (attr "prefix_rex")
16337 (match_test "<P:MODE>mode == DImode")
16339 (const_string "*")))
16340 (set_attr "mode" "QI")])
16342 (define_expand "cmpstrnsi"
16343 [(set (match_operand:SI 0 "register_operand")
16344 (compare:SI (match_operand:BLK 1 "general_operand")
16345 (match_operand:BLK 2 "general_operand")))
16346 (use (match_operand 3 "general_operand"))
16347 (use (match_operand 4 "immediate_operand"))]
16350 rtx addr1, addr2, out, outlow, count, countreg, align;
16352 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16355 /* Can't use this if the user has appropriated ecx, esi or edi. */
16356 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16361 out = gen_reg_rtx (SImode);
16363 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16364 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16365 if (addr1 != XEXP (operands[1], 0))
16366 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16367 if (addr2 != XEXP (operands[2], 0))
16368 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16370 count = operands[3];
16371 countreg = ix86_zero_extend_to_Pmode (count);
16373 /* %%% Iff we are testing strict equality, we can use known alignment
16374 to good advantage. This may be possible with combine, particularly
16375 once cc0 is dead. */
16376 align = operands[4];
16378 if (CONST_INT_P (count))
16380 if (INTVAL (count) == 0)
16382 emit_move_insn (operands[0], const0_rtx);
16385 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16386 operands[1], operands[2]));
16390 rtx (*gen_cmp) (rtx, rtx);
16392 gen_cmp = (TARGET_64BIT
16393 ? gen_cmpdi_1 : gen_cmpsi_1);
16395 emit_insn (gen_cmp (countreg, countreg));
16396 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16397 operands[1], operands[2]));
16400 outlow = gen_lowpart (QImode, out);
16401 emit_insn (gen_cmpintqi (outlow));
16402 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16404 if (operands[0] != out)
16405 emit_move_insn (operands[0], out);
16410 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16412 (define_expand "cmpintqi"
16413 [(set (match_dup 1)
16414 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16416 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16417 (parallel [(set (match_operand:QI 0 "register_operand")
16418 (minus:QI (match_dup 1)
16420 (clobber (reg:CC FLAGS_REG))])]
16423 operands[1] = gen_reg_rtx (QImode);
16424 operands[2] = gen_reg_rtx (QImode);
16427 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16428 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16430 (define_expand "cmpstrnqi_nz_1"
16431 [(parallel [(set (reg:CC FLAGS_REG)
16432 (compare:CC (match_operand 4 "memory_operand")
16433 (match_operand 5 "memory_operand")))
16434 (use (match_operand 2 "register_operand"))
16435 (use (match_operand:SI 3 "immediate_operand"))
16436 (clobber (match_operand 0 "register_operand"))
16437 (clobber (match_operand 1 "register_operand"))
16438 (clobber (match_dup 2))])]
16440 "ix86_current_function_needs_cld = 1;")
16442 (define_insn "*cmpstrnqi_nz_1"
16443 [(set (reg:CC FLAGS_REG)
16444 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16445 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16446 (use (match_operand:P 6 "register_operand" "2"))
16447 (use (match_operand:SI 3 "immediate_operand" "i"))
16448 (clobber (match_operand:P 0 "register_operand" "=S"))
16449 (clobber (match_operand:P 1 "register_operand" "=D"))
16450 (clobber (match_operand:P 2 "register_operand" "=c"))]
16451 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16453 [(set_attr "type" "str")
16454 (set_attr "mode" "QI")
16455 (set (attr "prefix_rex")
16457 (match_test "<P:MODE>mode == DImode")
16459 (const_string "*")))
16460 (set_attr "prefix_rep" "1")])
16462 ;; The same, but the count is not known to not be zero.
16464 (define_expand "cmpstrnqi_1"
16465 [(parallel [(set (reg:CC FLAGS_REG)
16466 (if_then_else:CC (ne (match_operand 2 "register_operand")
16468 (compare:CC (match_operand 4 "memory_operand")
16469 (match_operand 5 "memory_operand"))
16471 (use (match_operand:SI 3 "immediate_operand"))
16472 (use (reg:CC FLAGS_REG))
16473 (clobber (match_operand 0 "register_operand"))
16474 (clobber (match_operand 1 "register_operand"))
16475 (clobber (match_dup 2))])]
16477 "ix86_current_function_needs_cld = 1;")
16479 (define_insn "*cmpstrnqi_1"
16480 [(set (reg:CC FLAGS_REG)
16481 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16483 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16484 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16486 (use (match_operand:SI 3 "immediate_operand" "i"))
16487 (use (reg:CC FLAGS_REG))
16488 (clobber (match_operand:P 0 "register_operand" "=S"))
16489 (clobber (match_operand:P 1 "register_operand" "=D"))
16490 (clobber (match_operand:P 2 "register_operand" "=c"))]
16491 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16493 [(set_attr "type" "str")
16494 (set_attr "mode" "QI")
16495 (set (attr "prefix_rex")
16497 (match_test "<P:MODE>mode == DImode")
16499 (const_string "*")))
16500 (set_attr "prefix_rep" "1")])
16502 (define_expand "strlen<mode>"
16503 [(set (match_operand:P 0 "register_operand")
16504 (unspec:P [(match_operand:BLK 1 "general_operand")
16505 (match_operand:QI 2 "immediate_operand")
16506 (match_operand 3 "immediate_operand")]
16510 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16516 (define_expand "strlenqi_1"
16517 [(parallel [(set (match_operand 0 "register_operand")
16519 (clobber (match_operand 1 "register_operand"))
16520 (clobber (reg:CC FLAGS_REG))])]
16522 "ix86_current_function_needs_cld = 1;")
16524 (define_insn "*strlenqi_1"
16525 [(set (match_operand:P 0 "register_operand" "=&c")
16526 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16527 (match_operand:QI 2 "register_operand" "a")
16528 (match_operand:P 3 "immediate_operand" "i")
16529 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16530 (clobber (match_operand:P 1 "register_operand" "=D"))
16531 (clobber (reg:CC FLAGS_REG))]
16532 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16533 "%^repnz{%;} scasb"
16534 [(set_attr "type" "str")
16535 (set_attr "mode" "QI")
16536 (set (attr "prefix_rex")
16538 (match_test "<P:MODE>mode == DImode")
16540 (const_string "*")))
16541 (set_attr "prefix_rep" "1")])
16543 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16544 ;; handled in combine, but it is not currently up to the task.
16545 ;; When used for their truth value, the cmpstrn* expanders generate
16554 ;; The intermediate three instructions are unnecessary.
16556 ;; This one handles cmpstrn*_nz_1...
16559 (set (reg:CC FLAGS_REG)
16560 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16561 (mem:BLK (match_operand 5 "register_operand"))))
16562 (use (match_operand 6 "register_operand"))
16563 (use (match_operand:SI 3 "immediate_operand"))
16564 (clobber (match_operand 0 "register_operand"))
16565 (clobber (match_operand 1 "register_operand"))
16566 (clobber (match_operand 2 "register_operand"))])
16567 (set (match_operand:QI 7 "register_operand")
16568 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16569 (set (match_operand:QI 8 "register_operand")
16570 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16571 (set (reg FLAGS_REG)
16572 (compare (match_dup 7) (match_dup 8)))
16574 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16576 (set (reg:CC FLAGS_REG)
16577 (compare:CC (mem:BLK (match_dup 4))
16578 (mem:BLK (match_dup 5))))
16579 (use (match_dup 6))
16580 (use (match_dup 3))
16581 (clobber (match_dup 0))
16582 (clobber (match_dup 1))
16583 (clobber (match_dup 2))])])
16585 ;; ...and this one handles cmpstrn*_1.
16588 (set (reg:CC FLAGS_REG)
16589 (if_then_else:CC (ne (match_operand 6 "register_operand")
16591 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16592 (mem:BLK (match_operand 5 "register_operand")))
16594 (use (match_operand:SI 3 "immediate_operand"))
16595 (use (reg:CC FLAGS_REG))
16596 (clobber (match_operand 0 "register_operand"))
16597 (clobber (match_operand 1 "register_operand"))
16598 (clobber (match_operand 2 "register_operand"))])
16599 (set (match_operand:QI 7 "register_operand")
16600 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16601 (set (match_operand:QI 8 "register_operand")
16602 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16603 (set (reg FLAGS_REG)
16604 (compare (match_dup 7) (match_dup 8)))
16606 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16608 (set (reg:CC FLAGS_REG)
16609 (if_then_else:CC (ne (match_dup 6)
16611 (compare:CC (mem:BLK (match_dup 4))
16612 (mem:BLK (match_dup 5)))
16614 (use (match_dup 3))
16615 (use (reg:CC FLAGS_REG))
16616 (clobber (match_dup 0))
16617 (clobber (match_dup 1))
16618 (clobber (match_dup 2))])])
16620 ;; Conditional move instructions.
16622 (define_expand "mov<mode>cc"
16623 [(set (match_operand:SWIM 0 "register_operand")
16624 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16625 (match_operand:SWIM 2 "<general_operand>")
16626 (match_operand:SWIM 3 "<general_operand>")))]
16628 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16630 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16631 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16632 ;; So just document what we're doing explicitly.
16634 (define_expand "x86_mov<mode>cc_0_m1"
16636 [(set (match_operand:SWI48 0 "register_operand")
16637 (if_then_else:SWI48
16638 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16639 [(match_operand 1 "flags_reg_operand")
16643 (clobber (reg:CC FLAGS_REG))])])
16645 (define_insn "*x86_mov<mode>cc_0_m1"
16646 [(set (match_operand:SWI48 0 "register_operand" "=r")
16647 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16648 [(reg FLAGS_REG) (const_int 0)])
16651 (clobber (reg:CC FLAGS_REG))]
16653 "sbb{<imodesuffix>}\t%0, %0"
16654 ; Since we don't have the proper number of operands for an alu insn,
16655 ; fill in all the blanks.
16656 [(set_attr "type" "alu")
16657 (set_attr "use_carry" "1")
16658 (set_attr "pent_pair" "pu")
16659 (set_attr "memory" "none")
16660 (set_attr "imm_disp" "false")
16661 (set_attr "mode" "<MODE>")
16662 (set_attr "length_immediate" "0")])
16664 (define_insn "*x86_mov<mode>cc_0_m1_se"
16665 [(set (match_operand:SWI48 0 "register_operand" "=r")
16666 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16667 [(reg FLAGS_REG) (const_int 0)])
16670 (clobber (reg:CC FLAGS_REG))]
16672 "sbb{<imodesuffix>}\t%0, %0"
16673 [(set_attr "type" "alu")
16674 (set_attr "use_carry" "1")
16675 (set_attr "pent_pair" "pu")
16676 (set_attr "memory" "none")
16677 (set_attr "imm_disp" "false")
16678 (set_attr "mode" "<MODE>")
16679 (set_attr "length_immediate" "0")])
16681 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16682 [(set (match_operand:SWI48 0 "register_operand" "=r")
16683 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16684 [(reg FLAGS_REG) (const_int 0)])))
16685 (clobber (reg:CC FLAGS_REG))]
16687 "sbb{<imodesuffix>}\t%0, %0"
16688 [(set_attr "type" "alu")
16689 (set_attr "use_carry" "1")
16690 (set_attr "pent_pair" "pu")
16691 (set_attr "memory" "none")
16692 (set_attr "imm_disp" "false")
16693 (set_attr "mode" "<MODE>")
16694 (set_attr "length_immediate" "0")])
16696 (define_insn "*mov<mode>cc_noc"
16697 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16698 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16699 [(reg FLAGS_REG) (const_int 0)])
16700 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16701 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16702 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16704 cmov%O2%C1\t{%2, %0|%0, %2}
16705 cmov%O2%c1\t{%3, %0|%0, %3}"
16706 [(set_attr "type" "icmov")
16707 (set_attr "mode" "<MODE>")])
16709 ;; Don't do conditional moves with memory inputs. This splitter helps
16710 ;; register starved x86_32 by forcing inputs into registers before reload.
16712 [(set (match_operand:SWI248 0 "register_operand")
16713 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16714 [(reg FLAGS_REG) (const_int 0)])
16715 (match_operand:SWI248 2 "nonimmediate_operand")
16716 (match_operand:SWI248 3 "nonimmediate_operand")))]
16717 "!TARGET_64BIT && TARGET_CMOVE
16718 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16719 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16720 && can_create_pseudo_p ()
16721 && optimize_insn_for_speed_p ()"
16722 [(set (match_dup 0)
16723 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16725 if (MEM_P (operands[2]))
16726 operands[2] = force_reg (<MODE>mode, operands[2]);
16727 if (MEM_P (operands[3]))
16728 operands[3] = force_reg (<MODE>mode, operands[3]);
16731 (define_insn "*movqicc_noc"
16732 [(set (match_operand:QI 0 "register_operand" "=r,r")
16733 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16734 [(reg FLAGS_REG) (const_int 0)])
16735 (match_operand:QI 2 "register_operand" "r,0")
16736 (match_operand:QI 3 "register_operand" "0,r")))]
16737 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16739 [(set_attr "type" "icmov")
16740 (set_attr "mode" "QI")])
16743 [(set (match_operand:SWI12 0 "register_operand")
16744 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16745 [(reg FLAGS_REG) (const_int 0)])
16746 (match_operand:SWI12 2 "register_operand")
16747 (match_operand:SWI12 3 "register_operand")))]
16748 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16749 && reload_completed"
16750 [(set (match_dup 0)
16751 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16753 operands[0] = gen_lowpart (SImode, operands[0]);
16754 operands[2] = gen_lowpart (SImode, operands[2]);
16755 operands[3] = gen_lowpart (SImode, operands[3]);
16758 ;; Don't do conditional moves with memory inputs
16760 [(match_scratch:SWI248 2 "r")
16761 (set (match_operand:SWI248 0 "register_operand")
16762 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16763 [(reg FLAGS_REG) (const_int 0)])
16765 (match_operand:SWI248 3 "memory_operand")))]
16766 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16767 && optimize_insn_for_speed_p ()"
16768 [(set (match_dup 2) (match_dup 3))
16770 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16773 [(match_scratch:SWI248 2 "r")
16774 (set (match_operand:SWI248 0 "register_operand")
16775 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16776 [(reg FLAGS_REG) (const_int 0)])
16777 (match_operand:SWI248 3 "memory_operand")
16779 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16780 && optimize_insn_for_speed_p ()"
16781 [(set (match_dup 2) (match_dup 3))
16783 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16785 (define_expand "mov<mode>cc"
16786 [(set (match_operand:X87MODEF 0 "register_operand")
16787 (if_then_else:X87MODEF
16788 (match_operand 1 "comparison_operator")
16789 (match_operand:X87MODEF 2 "register_operand")
16790 (match_operand:X87MODEF 3 "register_operand")))]
16791 "(TARGET_80387 && TARGET_CMOVE)
16792 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16793 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16795 (define_insn "*movxfcc_1"
16796 [(set (match_operand:XF 0 "register_operand" "=f,f")
16797 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16798 [(reg FLAGS_REG) (const_int 0)])
16799 (match_operand:XF 2 "register_operand" "f,0")
16800 (match_operand:XF 3 "register_operand" "0,f")))]
16801 "TARGET_80387 && TARGET_CMOVE"
16803 fcmov%F1\t{%2, %0|%0, %2}
16804 fcmov%f1\t{%3, %0|%0, %3}"
16805 [(set_attr "type" "fcmov")
16806 (set_attr "mode" "XF")])
16808 (define_insn "*movdfcc_1"
16809 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16810 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16811 [(reg FLAGS_REG) (const_int 0)])
16812 (match_operand:DF 2 "nonimmediate_operand"
16814 (match_operand:DF 3 "nonimmediate_operand"
16815 "0 ,f,0 ,rm,0, rm")))]
16816 "TARGET_80387 && TARGET_CMOVE
16817 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16819 fcmov%F1\t{%2, %0|%0, %2}
16820 fcmov%f1\t{%3, %0|%0, %3}
16823 cmov%O2%C1\t{%2, %0|%0, %2}
16824 cmov%O2%c1\t{%3, %0|%0, %3}"
16825 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16826 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16827 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16830 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16831 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16832 [(reg FLAGS_REG) (const_int 0)])
16833 (match_operand:DF 2 "nonimmediate_operand")
16834 (match_operand:DF 3 "nonimmediate_operand")))]
16835 "!TARGET_64BIT && reload_completed"
16836 [(set (match_dup 2)
16837 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16839 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16841 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16842 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16845 (define_insn "*movsfcc_1_387"
16846 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16847 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16848 [(reg FLAGS_REG) (const_int 0)])
16849 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16850 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16851 "TARGET_80387 && TARGET_CMOVE
16852 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16854 fcmov%F1\t{%2, %0|%0, %2}
16855 fcmov%f1\t{%3, %0|%0, %3}
16856 cmov%O2%C1\t{%2, %0|%0, %2}
16857 cmov%O2%c1\t{%3, %0|%0, %3}"
16858 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16859 (set_attr "mode" "SF,SF,SI,SI")])
16861 ;; Don't do conditional moves with memory inputs. This splitter helps
16862 ;; register starved x86_32 by forcing inputs into registers before reload.
16864 [(set (match_operand:MODEF 0 "register_operand")
16865 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16866 [(reg FLAGS_REG) (const_int 0)])
16867 (match_operand:MODEF 2 "nonimmediate_operand")
16868 (match_operand:MODEF 3 "nonimmediate_operand")))]
16869 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16870 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16871 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16872 && can_create_pseudo_p ()
16873 && optimize_insn_for_speed_p ()"
16874 [(set (match_dup 0)
16875 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16877 if (MEM_P (operands[2]))
16878 operands[2] = force_reg (<MODE>mode, operands[2]);
16879 if (MEM_P (operands[3]))
16880 operands[3] = force_reg (<MODE>mode, operands[3]);
16883 ;; Don't do conditional moves with memory inputs
16885 [(match_scratch:MODEF 2 "r")
16886 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16887 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16888 [(reg FLAGS_REG) (const_int 0)])
16890 (match_operand:MODEF 3 "memory_operand")))]
16891 "(<MODE>mode != DFmode || TARGET_64BIT)
16892 && TARGET_80387 && TARGET_CMOVE
16893 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16894 && optimize_insn_for_speed_p ()"
16895 [(set (match_dup 2) (match_dup 3))
16897 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16900 [(match_scratch:MODEF 2 "r")
16901 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16902 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16903 [(reg FLAGS_REG) (const_int 0)])
16904 (match_operand:MODEF 3 "memory_operand")
16906 "(<MODE>mode != DFmode || TARGET_64BIT)
16907 && TARGET_80387 && TARGET_CMOVE
16908 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16909 && optimize_insn_for_speed_p ()"
16910 [(set (match_dup 2) (match_dup 3))
16912 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16914 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16915 ;; the scalar versions to have only XMM registers as operands.
16917 ;; XOP conditional move
16918 (define_insn "*xop_pcmov_<mode>"
16919 [(set (match_operand:MODEF 0 "register_operand" "=x")
16920 (if_then_else:MODEF
16921 (match_operand:MODEF 1 "register_operand" "x")
16922 (match_operand:MODEF 2 "register_operand" "x")
16923 (match_operand:MODEF 3 "register_operand" "x")))]
16925 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16926 [(set_attr "type" "sse4arg")])
16928 ;; These versions of the min/max patterns are intentionally ignorant of
16929 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16930 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16931 ;; are undefined in this condition, we're certain this is correct.
16933 (define_insn "<code><mode>3"
16934 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16936 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16937 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16938 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16940 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16941 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16942 [(set_attr "isa" "noavx,avx")
16943 (set_attr "prefix" "orig,vex")
16944 (set_attr "type" "sseadd")
16945 (set_attr "mode" "<MODE>")])
16947 ;; These versions of the min/max patterns implement exactly the operations
16948 ;; min = (op1 < op2 ? op1 : op2)
16949 ;; max = (!(op1 < op2) ? op1 : op2)
16950 ;; Their operands are not commutative, and thus they may be used in the
16951 ;; presence of -0.0 and NaN.
16953 (define_int_iterator IEEE_MAXMIN
16957 (define_int_attr ieee_maxmin
16958 [(UNSPEC_IEEE_MAX "max")
16959 (UNSPEC_IEEE_MIN "min")])
16961 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16962 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16964 [(match_operand:MODEF 1 "register_operand" "0,v")
16965 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16967 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16969 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16970 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16971 [(set_attr "isa" "noavx,avx")
16972 (set_attr "prefix" "orig,maybe_evex")
16973 (set_attr "type" "sseadd")
16974 (set_attr "mode" "<MODE>")])
16976 ;; Make two stack loads independent:
16978 ;; fld %st(0) -> fld bb
16979 ;; fmul bb fmul %st(1), %st
16981 ;; Actually we only match the last two instructions for simplicity.
16983 [(set (match_operand 0 "fp_register_operand")
16984 (match_operand 1 "fp_register_operand"))
16986 (match_operator 2 "binary_fp_operator"
16988 (match_operand 3 "memory_operand")]))]
16989 "REGNO (operands[0]) != REGNO (operands[1])"
16990 [(set (match_dup 0) (match_dup 3))
16991 (set (match_dup 0) (match_dup 4))]
16993 ;; The % modifier is not operational anymore in peephole2's, so we have to
16994 ;; swap the operands manually in the case of addition and multiplication.
16998 if (COMMUTATIVE_ARITH_P (operands[2]))
16999 op0 = operands[0], op1 = operands[1];
17001 op0 = operands[1], op1 = operands[0];
17003 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17004 GET_MODE (operands[2]),
17008 ;; Conditional addition patterns
17009 (define_expand "add<mode>cc"
17010 [(match_operand:SWI 0 "register_operand")
17011 (match_operand 1 "ordered_comparison_operator")
17012 (match_operand:SWI 2 "register_operand")
17013 (match_operand:SWI 3 "const_int_operand")]
17015 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17017 ;; Misc patterns (?)
17019 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17020 ;; Otherwise there will be nothing to keep
17022 ;; [(set (reg ebp) (reg esp))]
17023 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17024 ;; (clobber (eflags)]
17025 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17027 ;; in proper program order.
17029 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17030 [(set (match_operand:P 0 "register_operand" "=r,r")
17031 (plus:P (match_operand:P 1 "register_operand" "0,r")
17032 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17033 (clobber (reg:CC FLAGS_REG))
17034 (clobber (mem:BLK (scratch)))]
17037 switch (get_attr_type (insn))
17040 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17044 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17045 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17047 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17050 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17051 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17054 [(set (attr "type")
17055 (cond [(and (eq_attr "alternative" "0")
17056 (not (match_test "TARGET_OPT_AGU")))
17057 (const_string "alu")
17058 (match_operand:<MODE> 2 "const0_operand")
17059 (const_string "imov")
17061 (const_string "lea")))
17062 (set (attr "length_immediate")
17063 (cond [(eq_attr "type" "imov")
17065 (and (eq_attr "type" "alu")
17066 (match_operand 2 "const128_operand"))
17069 (const_string "*")))
17070 (set_attr "mode" "<MODE>")])
17072 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17073 [(set (match_operand:P 0 "register_operand" "=r")
17074 (minus:P (match_operand:P 1 "register_operand" "0")
17075 (match_operand:P 2 "register_operand" "r")))
17076 (clobber (reg:CC FLAGS_REG))
17077 (clobber (mem:BLK (scratch)))]
17079 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17080 [(set_attr "type" "alu")
17081 (set_attr "mode" "<MODE>")])
17083 (define_insn "allocate_stack_worker_probe_<mode>"
17084 [(set (match_operand:P 0 "register_operand" "=a")
17085 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17086 UNSPECV_STACK_PROBE))
17087 (clobber (reg:CC FLAGS_REG))]
17088 "ix86_target_stack_probe ()"
17089 "call\t___chkstk_ms"
17090 [(set_attr "type" "multi")
17091 (set_attr "length" "5")])
17093 (define_expand "allocate_stack"
17094 [(match_operand 0 "register_operand")
17095 (match_operand 1 "general_operand")]
17096 "ix86_target_stack_probe ()"
17100 #ifndef CHECK_STACK_LIMIT
17101 #define CHECK_STACK_LIMIT 0
17104 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17105 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17109 rtx (*insn) (rtx, rtx);
17111 x = copy_to_mode_reg (Pmode, operands[1]);
17113 insn = (TARGET_64BIT
17114 ? gen_allocate_stack_worker_probe_di
17115 : gen_allocate_stack_worker_probe_si);
17117 emit_insn (insn (x, x));
17120 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17121 stack_pointer_rtx, 0, OPTAB_DIRECT);
17123 if (x != stack_pointer_rtx)
17124 emit_move_insn (stack_pointer_rtx, x);
17126 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17130 ;; Use IOR for stack probes, this is shorter.
17131 (define_expand "probe_stack"
17132 [(match_operand 0 "memory_operand")]
17135 rtx (*gen_ior3) (rtx, rtx, rtx);
17137 gen_ior3 = (GET_MODE (operands[0]) == DImode
17138 ? gen_iordi3 : gen_iorsi3);
17140 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17144 (define_insn "adjust_stack_and_probe<mode>"
17145 [(set (match_operand:P 0 "register_operand" "=r")
17146 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17147 UNSPECV_PROBE_STACK_RANGE))
17148 (set (reg:P SP_REG)
17149 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17150 (clobber (reg:CC FLAGS_REG))
17151 (clobber (mem:BLK (scratch)))]
17153 "* return output_adjust_stack_and_probe (operands[0]);"
17154 [(set_attr "type" "multi")])
17156 (define_insn "probe_stack_range<mode>"
17157 [(set (match_operand:P 0 "register_operand" "=r")
17158 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17159 (match_operand:P 2 "const_int_operand" "n")]
17160 UNSPECV_PROBE_STACK_RANGE))
17161 (clobber (reg:CC FLAGS_REG))]
17163 "* return output_probe_stack_range (operands[0], operands[2]);"
17164 [(set_attr "type" "multi")])
17166 (define_expand "builtin_setjmp_receiver"
17167 [(label_ref (match_operand 0))]
17168 "!TARGET_64BIT && flag_pic"
17174 rtx_code_label *label_rtx = gen_label_rtx ();
17175 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17176 xops[0] = xops[1] = pic_offset_table_rtx;
17177 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17178 ix86_expand_binary_operator (MINUS, SImode, xops);
17182 emit_insn (gen_set_got (pic_offset_table_rtx));
17186 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17187 ;; Do not split instructions with mask registers.
17189 [(set (match_operand 0 "general_reg_operand")
17190 (match_operator 3 "promotable_binary_operator"
17191 [(match_operand 1 "general_reg_operand")
17192 (match_operand 2 "aligned_operand")]))
17193 (clobber (reg:CC FLAGS_REG))]
17194 "! TARGET_PARTIAL_REG_STALL && reload_completed
17195 && ((GET_MODE (operands[0]) == HImode
17196 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17197 /* ??? next two lines just !satisfies_constraint_K (...) */
17198 || !CONST_INT_P (operands[2])
17199 || satisfies_constraint_K (operands[2])))
17200 || (GET_MODE (operands[0]) == QImode
17201 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17202 [(parallel [(set (match_dup 0)
17203 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17204 (clobber (reg:CC FLAGS_REG))])]
17206 operands[0] = gen_lowpart (SImode, operands[0]);
17207 operands[1] = gen_lowpart (SImode, operands[1]);
17208 if (GET_CODE (operands[3]) != ASHIFT)
17209 operands[2] = gen_lowpart (SImode, operands[2]);
17210 PUT_MODE (operands[3], SImode);
17213 ; Promote the QImode tests, as i386 has encoding of the AND
17214 ; instruction with 32-bit sign-extended immediate and thus the
17215 ; instruction size is unchanged, except in the %eax case for
17216 ; which it is increased by one byte, hence the ! optimize_size.
17218 [(set (match_operand 0 "flags_reg_operand")
17219 (match_operator 2 "compare_operator"
17220 [(and (match_operand 3 "aligned_operand")
17221 (match_operand 4 "const_int_operand"))
17223 (set (match_operand 1 "register_operand")
17224 (and (match_dup 3) (match_dup 4)))]
17225 "! TARGET_PARTIAL_REG_STALL && reload_completed
17226 && optimize_insn_for_speed_p ()
17227 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17228 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17229 /* Ensure that the operand will remain sign-extended immediate. */
17230 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17231 [(parallel [(set (match_dup 0)
17232 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17235 (and:SI (match_dup 3) (match_dup 4)))])]
17238 = gen_int_mode (INTVAL (operands[4])
17239 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17240 operands[1] = gen_lowpart (SImode, operands[1]);
17241 operands[3] = gen_lowpart (SImode, operands[3]);
17244 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17245 ; the TEST instruction with 32-bit sign-extended immediate and thus
17246 ; the instruction size would at least double, which is not what we
17247 ; want even with ! optimize_size.
17249 [(set (match_operand 0 "flags_reg_operand")
17250 (match_operator 1 "compare_operator"
17251 [(and (match_operand:HI 2 "aligned_operand")
17252 (match_operand:HI 3 "const_int_operand"))
17254 "! TARGET_PARTIAL_REG_STALL && reload_completed
17255 && ! TARGET_FAST_PREFIX
17256 && optimize_insn_for_speed_p ()
17257 /* Ensure that the operand will remain sign-extended immediate. */
17258 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17259 [(set (match_dup 0)
17260 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17264 = gen_int_mode (INTVAL (operands[3])
17265 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17266 operands[2] = gen_lowpart (SImode, operands[2]);
17270 [(set (match_operand 0 "register_operand")
17271 (neg (match_operand 1 "register_operand")))
17272 (clobber (reg:CC FLAGS_REG))]
17273 "! TARGET_PARTIAL_REG_STALL && reload_completed
17274 && (GET_MODE (operands[0]) == HImode
17275 || (GET_MODE (operands[0]) == QImode
17276 && (TARGET_PROMOTE_QImode
17277 || optimize_insn_for_size_p ())))"
17278 [(parallel [(set (match_dup 0)
17279 (neg:SI (match_dup 1)))
17280 (clobber (reg:CC FLAGS_REG))])]
17282 operands[0] = gen_lowpart (SImode, operands[0]);
17283 operands[1] = gen_lowpart (SImode, operands[1]);
17286 ;; Do not split instructions with mask regs.
17288 [(set (match_operand 0 "general_reg_operand")
17289 (not (match_operand 1 "general_reg_operand")))]
17290 "! TARGET_PARTIAL_REG_STALL && reload_completed
17291 && (GET_MODE (operands[0]) == HImode
17292 || (GET_MODE (operands[0]) == QImode
17293 && (TARGET_PROMOTE_QImode
17294 || optimize_insn_for_size_p ())))"
17295 [(set (match_dup 0)
17296 (not:SI (match_dup 1)))]
17298 operands[0] = gen_lowpart (SImode, operands[0]);
17299 operands[1] = gen_lowpart (SImode, operands[1]);
17302 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17303 ;; transform a complex memory operation into two memory to register operations.
17305 ;; Don't push memory operands
17307 [(set (match_operand:SWI 0 "push_operand")
17308 (match_operand:SWI 1 "memory_operand"))
17309 (match_scratch:SWI 2 "<r>")]
17310 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17311 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17312 [(set (match_dup 2) (match_dup 1))
17313 (set (match_dup 0) (match_dup 2))])
17315 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17318 [(set (match_operand:SF 0 "push_operand")
17319 (match_operand:SF 1 "memory_operand"))
17320 (match_scratch:SF 2 "r")]
17321 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17322 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17323 [(set (match_dup 2) (match_dup 1))
17324 (set (match_dup 0) (match_dup 2))])
17326 ;; Don't move an immediate directly to memory when the instruction
17327 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17329 [(match_scratch:SWI124 1 "<r>")
17330 (set (match_operand:SWI124 0 "memory_operand")
17332 "optimize_insn_for_speed_p ()
17333 && ((<MODE>mode == HImode
17334 && TARGET_LCP_STALL)
17335 || (!TARGET_USE_MOV0
17336 && TARGET_SPLIT_LONG_MOVES
17337 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17338 && peep2_regno_dead_p (0, FLAGS_REG)"
17339 [(parallel [(set (match_dup 2) (const_int 0))
17340 (clobber (reg:CC FLAGS_REG))])
17341 (set (match_dup 0) (match_dup 1))]
17342 "operands[2] = gen_lowpart (SImode, operands[1]);")
17345 [(match_scratch:SWI124 2 "<r>")
17346 (set (match_operand:SWI124 0 "memory_operand")
17347 (match_operand:SWI124 1 "immediate_operand"))]
17348 "optimize_insn_for_speed_p ()
17349 && ((<MODE>mode == HImode
17350 && TARGET_LCP_STALL)
17351 || (TARGET_SPLIT_LONG_MOVES
17352 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17353 [(set (match_dup 2) (match_dup 1))
17354 (set (match_dup 0) (match_dup 2))])
17356 ;; Don't compare memory with zero, load and use a test instead.
17358 [(set (match_operand 0 "flags_reg_operand")
17359 (match_operator 1 "compare_operator"
17360 [(match_operand:SI 2 "memory_operand")
17362 (match_scratch:SI 3 "r")]
17363 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17364 [(set (match_dup 3) (match_dup 2))
17365 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17367 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17368 ;; Don't split NOTs with a displacement operand, because resulting XOR
17369 ;; will not be pairable anyway.
17371 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17372 ;; represented using a modRM byte. The XOR replacement is long decoded,
17373 ;; so this split helps here as well.
17375 ;; Note: Can't do this as a regular split because we can't get proper
17376 ;; lifetime information then.
17379 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17380 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17381 "optimize_insn_for_speed_p ()
17382 && ((TARGET_NOT_UNPAIRABLE
17383 && (!MEM_P (operands[0])
17384 || !memory_displacement_operand (operands[0], <MODE>mode)))
17385 || (TARGET_NOT_VECTORMODE
17386 && long_memory_operand (operands[0], <MODE>mode)))
17387 && peep2_regno_dead_p (0, FLAGS_REG)"
17388 [(parallel [(set (match_dup 0)
17389 (xor:SWI124 (match_dup 1) (const_int -1)))
17390 (clobber (reg:CC FLAGS_REG))])])
17392 ;; Non pairable "test imm, reg" instructions can be translated to
17393 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17394 ;; byte opcode instead of two, have a short form for byte operands),
17395 ;; so do it for other CPUs as well. Given that the value was dead,
17396 ;; this should not create any new dependencies. Pass on the sub-word
17397 ;; versions if we're concerned about partial register stalls.
17400 [(set (match_operand 0 "flags_reg_operand")
17401 (match_operator 1 "compare_operator"
17402 [(and:SI (match_operand:SI 2 "register_operand")
17403 (match_operand:SI 3 "immediate_operand"))
17405 "ix86_match_ccmode (insn, CCNOmode)
17406 && (true_regnum (operands[2]) != AX_REG
17407 || satisfies_constraint_K (operands[3]))
17408 && peep2_reg_dead_p (1, operands[2])"
17410 [(set (match_dup 0)
17411 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17414 (and:SI (match_dup 2) (match_dup 3)))])])
17416 ;; We don't need to handle HImode case, because it will be promoted to SImode
17417 ;; on ! TARGET_PARTIAL_REG_STALL
17420 [(set (match_operand 0 "flags_reg_operand")
17421 (match_operator 1 "compare_operator"
17422 [(and:QI (match_operand:QI 2 "register_operand")
17423 (match_operand:QI 3 "immediate_operand"))
17425 "! TARGET_PARTIAL_REG_STALL
17426 && ix86_match_ccmode (insn, CCNOmode)
17427 && true_regnum (operands[2]) != AX_REG
17428 && peep2_reg_dead_p (1, operands[2])"
17430 [(set (match_dup 0)
17431 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17434 (and:QI (match_dup 2) (match_dup 3)))])])
17437 [(set (match_operand 0 "flags_reg_operand")
17438 (match_operator 1 "compare_operator"
17441 (match_operand 2 "QIreg_operand")
17444 (match_operand 3 "const_int_operand"))
17446 "! TARGET_PARTIAL_REG_STALL
17447 && ix86_match_ccmode (insn, CCNOmode)
17448 && true_regnum (operands[2]) != AX_REG
17449 && peep2_reg_dead_p (1, operands[2])"
17450 [(parallel [(set (match_dup 0)
17459 (set (zero_extract:SI (match_dup 2)
17467 (match_dup 3)))])])
17469 ;; Don't do logical operations with memory inputs.
17471 [(match_scratch:SI 2 "r")
17472 (parallel [(set (match_operand:SI 0 "register_operand")
17473 (match_operator:SI 3 "arith_or_logical_operator"
17475 (match_operand:SI 1 "memory_operand")]))
17476 (clobber (reg:CC FLAGS_REG))])]
17477 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17478 [(set (match_dup 2) (match_dup 1))
17479 (parallel [(set (match_dup 0)
17480 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17481 (clobber (reg:CC FLAGS_REG))])])
17484 [(match_scratch:SI 2 "r")
17485 (parallel [(set (match_operand:SI 0 "register_operand")
17486 (match_operator:SI 3 "arith_or_logical_operator"
17487 [(match_operand:SI 1 "memory_operand")
17489 (clobber (reg:CC FLAGS_REG))])]
17490 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17491 [(set (match_dup 2) (match_dup 1))
17492 (parallel [(set (match_dup 0)
17493 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17494 (clobber (reg:CC FLAGS_REG))])])
17496 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17497 ;; refers to the destination of the load!
17500 [(set (match_operand:SI 0 "register_operand")
17501 (match_operand:SI 1 "register_operand"))
17502 (parallel [(set (match_dup 0)
17503 (match_operator:SI 3 "commutative_operator"
17505 (match_operand:SI 2 "memory_operand")]))
17506 (clobber (reg:CC FLAGS_REG))])]
17507 "REGNO (operands[0]) != REGNO (operands[1])
17508 && GENERAL_REGNO_P (REGNO (operands[0]))
17509 && GENERAL_REGNO_P (REGNO (operands[1]))"
17510 [(set (match_dup 0) (match_dup 4))
17511 (parallel [(set (match_dup 0)
17512 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17513 (clobber (reg:CC FLAGS_REG))])]
17514 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17517 [(set (match_operand 0 "register_operand")
17518 (match_operand 1 "register_operand"))
17520 (match_operator 3 "commutative_operator"
17522 (match_operand 2 "memory_operand")]))]
17523 "REGNO (operands[0]) != REGNO (operands[1])
17524 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17525 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17526 [(set (match_dup 0) (match_dup 2))
17528 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17530 ; Don't do logical operations with memory outputs
17532 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17533 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17534 ; the same decoder scheduling characteristics as the original.
17537 [(match_scratch:SI 2 "r")
17538 (parallel [(set (match_operand:SI 0 "memory_operand")
17539 (match_operator:SI 3 "arith_or_logical_operator"
17541 (match_operand:SI 1 "nonmemory_operand")]))
17542 (clobber (reg:CC FLAGS_REG))])]
17543 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17544 /* Do not split stack checking probes. */
17545 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17546 [(set (match_dup 2) (match_dup 0))
17547 (parallel [(set (match_dup 2)
17548 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17549 (clobber (reg:CC FLAGS_REG))])
17550 (set (match_dup 0) (match_dup 2))])
17553 [(match_scratch:SI 2 "r")
17554 (parallel [(set (match_operand:SI 0 "memory_operand")
17555 (match_operator:SI 3 "arith_or_logical_operator"
17556 [(match_operand:SI 1 "nonmemory_operand")
17558 (clobber (reg:CC FLAGS_REG))])]
17559 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17560 /* Do not split stack checking probes. */
17561 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17562 [(set (match_dup 2) (match_dup 0))
17563 (parallel [(set (match_dup 2)
17564 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17565 (clobber (reg:CC FLAGS_REG))])
17566 (set (match_dup 0) (match_dup 2))])
17568 ;; Attempt to use arith or logical operations with memory outputs with
17569 ;; setting of flags.
17571 [(set (match_operand:SWI 0 "register_operand")
17572 (match_operand:SWI 1 "memory_operand"))
17573 (parallel [(set (match_dup 0)
17574 (match_operator:SWI 3 "plusminuslogic_operator"
17576 (match_operand:SWI 2 "<nonmemory_operand>")]))
17577 (clobber (reg:CC FLAGS_REG))])
17578 (set (match_dup 1) (match_dup 0))
17579 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17580 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17581 && peep2_reg_dead_p (4, operands[0])
17582 && !reg_overlap_mentioned_p (operands[0], operands[1])
17583 && !reg_overlap_mentioned_p (operands[0], operands[2])
17584 && (<MODE>mode != QImode
17585 || immediate_operand (operands[2], QImode)
17586 || any_QIreg_operand (operands[2], QImode))
17587 && ix86_match_ccmode (peep2_next_insn (3),
17588 (GET_CODE (operands[3]) == PLUS
17589 || GET_CODE (operands[3]) == MINUS)
17590 ? CCGOCmode : CCNOmode)"
17591 [(parallel [(set (match_dup 4) (match_dup 5))
17592 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17593 (match_dup 2)]))])]
17595 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17596 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17597 copy_rtx (operands[1]),
17598 copy_rtx (operands[2]));
17599 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17600 operands[5], const0_rtx);
17604 [(parallel [(set (match_operand:SWI 0 "register_operand")
17605 (match_operator:SWI 2 "plusminuslogic_operator"
17607 (match_operand:SWI 1 "memory_operand")]))
17608 (clobber (reg:CC FLAGS_REG))])
17609 (set (match_dup 1) (match_dup 0))
17610 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17611 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17612 && GET_CODE (operands[2]) != MINUS
17613 && peep2_reg_dead_p (3, operands[0])
17614 && !reg_overlap_mentioned_p (operands[0], operands[1])
17615 && ix86_match_ccmode (peep2_next_insn (2),
17616 GET_CODE (operands[2]) == PLUS
17617 ? CCGOCmode : CCNOmode)"
17618 [(parallel [(set (match_dup 3) (match_dup 4))
17619 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17620 (match_dup 0)]))])]
17622 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17623 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17624 copy_rtx (operands[1]),
17625 copy_rtx (operands[0]));
17626 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17627 operands[4], const0_rtx);
17631 [(set (match_operand:SWI12 0 "register_operand")
17632 (match_operand:SWI12 1 "memory_operand"))
17633 (parallel [(set (match_operand:SI 4 "register_operand")
17634 (match_operator:SI 3 "plusminuslogic_operator"
17636 (match_operand:SI 2 "nonmemory_operand")]))
17637 (clobber (reg:CC FLAGS_REG))])
17638 (set (match_dup 1) (match_dup 0))
17639 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17640 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17641 && REG_P (operands[0]) && REG_P (operands[4])
17642 && REGNO (operands[0]) == REGNO (operands[4])
17643 && peep2_reg_dead_p (4, operands[0])
17644 && (<MODE>mode != QImode
17645 || immediate_operand (operands[2], SImode)
17646 || any_QIreg_operand (operands[2], SImode))
17647 && !reg_overlap_mentioned_p (operands[0], operands[1])
17648 && !reg_overlap_mentioned_p (operands[0], operands[2])
17649 && ix86_match_ccmode (peep2_next_insn (3),
17650 (GET_CODE (operands[3]) == PLUS
17651 || GET_CODE (operands[3]) == MINUS)
17652 ? CCGOCmode : CCNOmode)"
17653 [(parallel [(set (match_dup 4) (match_dup 5))
17654 (set (match_dup 1) (match_dup 6))])]
17656 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17657 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17658 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17659 copy_rtx (operands[1]), operands[2]);
17660 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17661 operands[5], const0_rtx);
17662 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17663 copy_rtx (operands[1]),
17664 copy_rtx (operands[2]));
17667 ;; Attempt to always use XOR for zeroing registers.
17669 [(set (match_operand 0 "register_operand")
17670 (match_operand 1 "const0_operand"))]
17671 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17672 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17673 && GENERAL_REG_P (operands[0])
17674 && peep2_regno_dead_p (0, FLAGS_REG)"
17675 [(parallel [(set (match_dup 0) (const_int 0))
17676 (clobber (reg:CC FLAGS_REG))])]
17677 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17680 [(set (strict_low_part (match_operand 0 "register_operand"))
17682 "(GET_MODE (operands[0]) == QImode
17683 || GET_MODE (operands[0]) == HImode)
17684 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17685 && peep2_regno_dead_p (0, FLAGS_REG)"
17686 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17687 (clobber (reg:CC FLAGS_REG))])])
17689 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17691 [(set (match_operand:SWI248 0 "register_operand")
17693 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17694 && peep2_regno_dead_p (0, FLAGS_REG)"
17695 [(parallel [(set (match_dup 0) (const_int -1))
17696 (clobber (reg:CC FLAGS_REG))])]
17698 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17699 operands[0] = gen_lowpart (SImode, operands[0]);
17702 ;; Attempt to convert simple lea to add/shift.
17703 ;; These can be created by move expanders.
17704 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17705 ;; relevant lea instructions were already split.
17708 [(set (match_operand:SWI48 0 "register_operand")
17709 (plus:SWI48 (match_dup 0)
17710 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17712 && peep2_regno_dead_p (0, FLAGS_REG)"
17713 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17714 (clobber (reg:CC FLAGS_REG))])])
17717 [(set (match_operand:SWI48 0 "register_operand")
17718 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17721 && peep2_regno_dead_p (0, FLAGS_REG)"
17722 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17723 (clobber (reg:CC FLAGS_REG))])])
17726 [(set (match_operand:DI 0 "register_operand")
17728 (plus:SI (match_operand:SI 1 "register_operand")
17729 (match_operand:SI 2 "nonmemory_operand"))))]
17730 "TARGET_64BIT && !TARGET_OPT_AGU
17731 && REGNO (operands[0]) == REGNO (operands[1])
17732 && peep2_regno_dead_p (0, FLAGS_REG)"
17733 [(parallel [(set (match_dup 0)
17734 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17735 (clobber (reg:CC FLAGS_REG))])])
17738 [(set (match_operand:DI 0 "register_operand")
17740 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17741 (match_operand:SI 2 "register_operand"))))]
17742 "TARGET_64BIT && !TARGET_OPT_AGU
17743 && REGNO (operands[0]) == REGNO (operands[2])
17744 && peep2_regno_dead_p (0, FLAGS_REG)"
17745 [(parallel [(set (match_dup 0)
17746 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17747 (clobber (reg:CC FLAGS_REG))])])
17750 [(set (match_operand:SWI48 0 "register_operand")
17751 (mult:SWI48 (match_dup 0)
17752 (match_operand:SWI48 1 "const_int_operand")))]
17753 "exact_log2 (INTVAL (operands[1])) >= 0
17754 && peep2_regno_dead_p (0, FLAGS_REG)"
17755 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17756 (clobber (reg:CC FLAGS_REG))])]
17757 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17760 [(set (match_operand:DI 0 "register_operand")
17762 (mult:SI (match_operand:SI 1 "register_operand")
17763 (match_operand:SI 2 "const_int_operand"))))]
17765 && exact_log2 (INTVAL (operands[2])) >= 0
17766 && REGNO (operands[0]) == REGNO (operands[1])
17767 && peep2_regno_dead_p (0, FLAGS_REG)"
17768 [(parallel [(set (match_dup 0)
17769 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17770 (clobber (reg:CC FLAGS_REG))])]
17771 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17773 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17774 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17775 ;; On many CPUs it is also faster, since special hardware to avoid esp
17776 ;; dependencies is present.
17778 ;; While some of these conversions may be done using splitters, we use
17779 ;; peepholes in order to allow combine_stack_adjustments pass to see
17780 ;; nonobfuscated RTL.
17782 ;; Convert prologue esp subtractions to push.
17783 ;; We need register to push. In order to keep verify_flow_info happy we have
17785 ;; - use scratch and clobber it in order to avoid dependencies
17786 ;; - use already live register
17787 ;; We can't use the second way right now, since there is no reliable way how to
17788 ;; verify that given register is live. First choice will also most likely in
17789 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17790 ;; call clobbered registers are dead. We may want to use base pointer as an
17791 ;; alternative when no register is available later.
17794 [(match_scratch:W 1 "r")
17795 (parallel [(set (reg:P SP_REG)
17796 (plus:P (reg:P SP_REG)
17797 (match_operand:P 0 "const_int_operand")))
17798 (clobber (reg:CC FLAGS_REG))
17799 (clobber (mem:BLK (scratch)))])]
17800 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17801 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17802 [(clobber (match_dup 1))
17803 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17804 (clobber (mem:BLK (scratch)))])])
17807 [(match_scratch:W 1 "r")
17808 (parallel [(set (reg:P SP_REG)
17809 (plus:P (reg:P SP_REG)
17810 (match_operand:P 0 "const_int_operand")))
17811 (clobber (reg:CC FLAGS_REG))
17812 (clobber (mem:BLK (scratch)))])]
17813 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17814 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17815 [(clobber (match_dup 1))
17816 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17817 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17818 (clobber (mem:BLK (scratch)))])])
17820 ;; Convert esp subtractions to push.
17822 [(match_scratch:W 1 "r")
17823 (parallel [(set (reg:P SP_REG)
17824 (plus:P (reg:P SP_REG)
17825 (match_operand:P 0 "const_int_operand")))
17826 (clobber (reg:CC FLAGS_REG))])]
17827 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17828 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17829 [(clobber (match_dup 1))
17830 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17833 [(match_scratch:W 1 "r")
17834 (parallel [(set (reg:P SP_REG)
17835 (plus:P (reg:P SP_REG)
17836 (match_operand:P 0 "const_int_operand")))
17837 (clobber (reg:CC FLAGS_REG))])]
17838 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17839 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17840 [(clobber (match_dup 1))
17841 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17842 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17844 ;; Convert epilogue deallocator to pop.
17846 [(match_scratch:W 1 "r")
17847 (parallel [(set (reg:P SP_REG)
17848 (plus:P (reg:P SP_REG)
17849 (match_operand:P 0 "const_int_operand")))
17850 (clobber (reg:CC FLAGS_REG))
17851 (clobber (mem:BLK (scratch)))])]
17852 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17853 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17854 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17855 (clobber (mem:BLK (scratch)))])])
17857 ;; Two pops case is tricky, since pop causes dependency
17858 ;; on destination register. We use two registers if available.
17860 [(match_scratch:W 1 "r")
17861 (match_scratch:W 2 "r")
17862 (parallel [(set (reg:P SP_REG)
17863 (plus:P (reg:P SP_REG)
17864 (match_operand:P 0 "const_int_operand")))
17865 (clobber (reg:CC FLAGS_REG))
17866 (clobber (mem:BLK (scratch)))])]
17867 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17868 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17869 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17870 (clobber (mem:BLK (scratch)))])
17871 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17874 [(match_scratch:W 1 "r")
17875 (parallel [(set (reg:P SP_REG)
17876 (plus:P (reg:P SP_REG)
17877 (match_operand:P 0 "const_int_operand")))
17878 (clobber (reg:CC FLAGS_REG))
17879 (clobber (mem:BLK (scratch)))])]
17880 "optimize_insn_for_size_p ()
17881 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17882 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17883 (clobber (mem:BLK (scratch)))])
17884 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17886 ;; Convert esp additions to pop.
17888 [(match_scratch:W 1 "r")
17889 (parallel [(set (reg:P SP_REG)
17890 (plus:P (reg:P SP_REG)
17891 (match_operand:P 0 "const_int_operand")))
17892 (clobber (reg:CC FLAGS_REG))])]
17893 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17894 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17896 ;; Two pops case is tricky, since pop causes dependency
17897 ;; on destination register. We use two registers if available.
17899 [(match_scratch:W 1 "r")
17900 (match_scratch:W 2 "r")
17901 (parallel [(set (reg:P SP_REG)
17902 (plus:P (reg:P SP_REG)
17903 (match_operand:P 0 "const_int_operand")))
17904 (clobber (reg:CC FLAGS_REG))])]
17905 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17906 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17907 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17910 [(match_scratch:W 1 "r")
17911 (parallel [(set (reg:P SP_REG)
17912 (plus:P (reg:P SP_REG)
17913 (match_operand:P 0 "const_int_operand")))
17914 (clobber (reg:CC FLAGS_REG))])]
17915 "optimize_insn_for_size_p ()
17916 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17917 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17918 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17920 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17921 ;; required and register dies. Similarly for 128 to -128.
17923 [(set (match_operand 0 "flags_reg_operand")
17924 (match_operator 1 "compare_operator"
17925 [(match_operand 2 "register_operand")
17926 (match_operand 3 "const_int_operand")]))]
17927 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17928 && incdec_operand (operands[3], GET_MODE (operands[3])))
17929 || (!TARGET_FUSE_CMP_AND_BRANCH
17930 && INTVAL (operands[3]) == 128))
17931 && ix86_match_ccmode (insn, CCGCmode)
17932 && peep2_reg_dead_p (1, operands[2])"
17933 [(parallel [(set (match_dup 0)
17934 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17935 (clobber (match_dup 2))])])
17937 ;; Convert imul by three, five and nine into lea
17940 [(set (match_operand:SWI48 0 "register_operand")
17941 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17942 (match_operand:SWI48 2 "const359_operand")))
17943 (clobber (reg:CC FLAGS_REG))])]
17944 "!TARGET_PARTIAL_REG_STALL
17945 || <MODE>mode == SImode
17946 || optimize_function_for_size_p (cfun)"
17947 [(set (match_dup 0)
17948 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17950 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17954 [(set (match_operand:SWI48 0 "register_operand")
17955 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17956 (match_operand:SWI48 2 "const359_operand")))
17957 (clobber (reg:CC FLAGS_REG))])]
17958 "optimize_insn_for_speed_p ()
17959 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17960 [(set (match_dup 0) (match_dup 1))
17962 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17964 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17966 ;; imul $32bit_imm, mem, reg is vector decoded, while
17967 ;; imul $32bit_imm, reg, reg is direct decoded.
17969 [(match_scratch:SWI48 3 "r")
17970 (parallel [(set (match_operand:SWI48 0 "register_operand")
17971 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17972 (match_operand:SWI48 2 "immediate_operand")))
17973 (clobber (reg:CC FLAGS_REG))])]
17974 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17975 && !satisfies_constraint_K (operands[2])"
17976 [(set (match_dup 3) (match_dup 1))
17977 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17978 (clobber (reg:CC FLAGS_REG))])])
17981 [(match_scratch:SI 3 "r")
17982 (parallel [(set (match_operand:DI 0 "register_operand")
17984 (mult:SI (match_operand:SI 1 "memory_operand")
17985 (match_operand:SI 2 "immediate_operand"))))
17986 (clobber (reg:CC FLAGS_REG))])]
17988 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17989 && !satisfies_constraint_K (operands[2])"
17990 [(set (match_dup 3) (match_dup 1))
17991 (parallel [(set (match_dup 0)
17992 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17993 (clobber (reg:CC FLAGS_REG))])])
17995 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17996 ;; Convert it into imul reg, reg
17997 ;; It would be better to force assembler to encode instruction using long
17998 ;; immediate, but there is apparently no way to do so.
18000 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18002 (match_operand:SWI248 1 "nonimmediate_operand")
18003 (match_operand:SWI248 2 "const_int_operand")))
18004 (clobber (reg:CC FLAGS_REG))])
18005 (match_scratch:SWI248 3 "r")]
18006 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18007 && satisfies_constraint_K (operands[2])"
18008 [(set (match_dup 3) (match_dup 2))
18009 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18010 (clobber (reg:CC FLAGS_REG))])]
18012 if (!rtx_equal_p (operands[0], operands[1]))
18013 emit_move_insn (operands[0], operands[1]);
18016 ;; After splitting up read-modify operations, array accesses with memory
18017 ;; operands might end up in form:
18019 ;; movl 4(%esp), %edx
18021 ;; instead of pre-splitting:
18023 ;; addl 4(%esp), %eax
18025 ;; movl 4(%esp), %edx
18026 ;; leal (%edx,%eax,4), %eax
18029 [(match_scratch:W 5 "r")
18030 (parallel [(set (match_operand 0 "register_operand")
18031 (ashift (match_operand 1 "register_operand")
18032 (match_operand 2 "const_int_operand")))
18033 (clobber (reg:CC FLAGS_REG))])
18034 (parallel [(set (match_operand 3 "register_operand")
18035 (plus (match_dup 0)
18036 (match_operand 4 "x86_64_general_operand")))
18037 (clobber (reg:CC FLAGS_REG))])]
18038 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18039 /* Validate MODE for lea. */
18040 && ((!TARGET_PARTIAL_REG_STALL
18041 && (GET_MODE (operands[0]) == QImode
18042 || GET_MODE (operands[0]) == HImode))
18043 || GET_MODE (operands[0]) == SImode
18044 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18045 && (rtx_equal_p (operands[0], operands[3])
18046 || peep2_reg_dead_p (2, operands[0]))
18047 /* We reorder load and the shift. */
18048 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18049 [(set (match_dup 5) (match_dup 4))
18050 (set (match_dup 0) (match_dup 1))]
18052 machine_mode op1mode = GET_MODE (operands[1]);
18053 machine_mode mode = op1mode == DImode ? DImode : SImode;
18054 int scale = 1 << INTVAL (operands[2]);
18055 rtx index = gen_lowpart (word_mode, operands[1]);
18056 rtx base = gen_lowpart (word_mode, operands[5]);
18057 rtx dest = gen_lowpart (mode, operands[3]);
18059 operands[1] = gen_rtx_PLUS (word_mode, base,
18060 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18061 operands[5] = base;
18062 if (mode != word_mode)
18063 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18064 if (op1mode != word_mode)
18065 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18066 operands[0] = dest;
18069 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18070 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18071 ;; caught for use by garbage collectors and the like. Using an insn that
18072 ;; maps to SIGILL makes it more likely the program will rightfully die.
18073 ;; Keeping with tradition, "6" is in honor of #UD.
18074 (define_insn "trap"
18075 [(trap_if (const_int 1) (const_int 6))]
18078 #ifdef HAVE_AS_IX86_UD2
18081 return ASM_SHORT "0x0b0f";
18084 [(set_attr "length" "2")])
18086 (define_expand "prefetch"
18087 [(prefetch (match_operand 0 "address_operand")
18088 (match_operand:SI 1 "const_int_operand")
18089 (match_operand:SI 2 "const_int_operand"))]
18090 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18092 bool write = INTVAL (operands[1]) != 0;
18093 int locality = INTVAL (operands[2]);
18095 gcc_assert (IN_RANGE (locality, 0, 3));
18097 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18098 supported by SSE counterpart or the SSE prefetch is not available
18099 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18101 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18102 operands[2] = const2_rtx;
18103 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18104 operands[2] = GEN_INT (3);
18106 operands[1] = const0_rtx;
18109 (define_insn "*prefetch_sse"
18110 [(prefetch (match_operand 0 "address_operand" "p")
18112 (match_operand:SI 1 "const_int_operand"))]
18113 "TARGET_PREFETCH_SSE"
18115 static const char * const patterns[4] = {
18116 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18119 int locality = INTVAL (operands[1]);
18120 gcc_assert (IN_RANGE (locality, 0, 3));
18122 return patterns[locality];
18124 [(set_attr "type" "sse")
18125 (set_attr "atom_sse_attr" "prefetch")
18126 (set (attr "length_address")
18127 (symbol_ref "memory_address_length (operands[0], false)"))
18128 (set_attr "memory" "none")])
18130 (define_insn "*prefetch_3dnow"
18131 [(prefetch (match_operand 0 "address_operand" "p")
18132 (match_operand:SI 1 "const_int_operand" "n")
18136 if (INTVAL (operands[1]) == 0)
18137 return "prefetch\t%a0";
18139 return "prefetchw\t%a0";
18141 [(set_attr "type" "mmx")
18142 (set (attr "length_address")
18143 (symbol_ref "memory_address_length (operands[0], false)"))
18144 (set_attr "memory" "none")])
18146 (define_insn "*prefetch_prefetchwt1"
18147 [(prefetch (match_operand 0 "address_operand" "p")
18150 "TARGET_PREFETCHWT1"
18151 "prefetchwt1\t%a0";
18152 [(set_attr "type" "sse")
18153 (set (attr "length_address")
18154 (symbol_ref "memory_address_length (operands[0], false)"))
18155 (set_attr "memory" "none")])
18157 (define_expand "stack_protect_set"
18158 [(match_operand 0 "memory_operand")
18159 (match_operand 1 "memory_operand")]
18160 "TARGET_SSP_TLS_GUARD"
18162 rtx (*insn)(rtx, rtx);
18164 #ifdef TARGET_THREAD_SSP_OFFSET
18165 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18166 insn = (TARGET_LP64
18167 ? gen_stack_tls_protect_set_di
18168 : gen_stack_tls_protect_set_si);
18170 insn = (TARGET_LP64
18171 ? gen_stack_protect_set_di
18172 : gen_stack_protect_set_si);
18175 emit_insn (insn (operands[0], operands[1]));
18179 (define_insn "stack_protect_set_<mode>"
18180 [(set (match_operand:PTR 0 "memory_operand" "=m")
18181 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18183 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18184 (clobber (reg:CC FLAGS_REG))]
18185 "TARGET_SSP_TLS_GUARD"
18186 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18187 [(set_attr "type" "multi")])
18189 (define_insn "stack_tls_protect_set_<mode>"
18190 [(set (match_operand:PTR 0 "memory_operand" "=m")
18191 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18192 UNSPEC_SP_TLS_SET))
18193 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18194 (clobber (reg:CC FLAGS_REG))]
18196 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18197 [(set_attr "type" "multi")])
18199 (define_expand "stack_protect_test"
18200 [(match_operand 0 "memory_operand")
18201 (match_operand 1 "memory_operand")
18203 "TARGET_SSP_TLS_GUARD"
18205 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18207 rtx (*insn)(rtx, rtx, rtx);
18209 #ifdef TARGET_THREAD_SSP_OFFSET
18210 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18211 insn = (TARGET_LP64
18212 ? gen_stack_tls_protect_test_di
18213 : gen_stack_tls_protect_test_si);
18215 insn = (TARGET_LP64
18216 ? gen_stack_protect_test_di
18217 : gen_stack_protect_test_si);
18220 emit_insn (insn (flags, operands[0], operands[1]));
18222 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18223 flags, const0_rtx, operands[2]));
18227 (define_insn "stack_protect_test_<mode>"
18228 [(set (match_operand:CCZ 0 "flags_reg_operand")
18229 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18230 (match_operand:PTR 2 "memory_operand" "m")]
18232 (clobber (match_scratch:PTR 3 "=&r"))]
18233 "TARGET_SSP_TLS_GUARD"
18234 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18235 [(set_attr "type" "multi")])
18237 (define_insn "stack_tls_protect_test_<mode>"
18238 [(set (match_operand:CCZ 0 "flags_reg_operand")
18239 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18240 (match_operand:PTR 2 "const_int_operand" "i")]
18241 UNSPEC_SP_TLS_TEST))
18242 (clobber (match_scratch:PTR 3 "=r"))]
18244 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18245 [(set_attr "type" "multi")])
18247 (define_insn "sse4_2_crc32<mode>"
18248 [(set (match_operand:SI 0 "register_operand" "=r")
18250 [(match_operand:SI 1 "register_operand" "0")
18251 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18253 "TARGET_SSE4_2 || TARGET_CRC32"
18254 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18255 [(set_attr "type" "sselog1")
18256 (set_attr "prefix_rep" "1")
18257 (set_attr "prefix_extra" "1")
18258 (set (attr "prefix_data16")
18259 (if_then_else (match_operand:HI 2)
18261 (const_string "*")))
18262 (set (attr "prefix_rex")
18263 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18265 (const_string "*")))
18266 (set_attr "mode" "SI")])
18268 (define_insn "sse4_2_crc32di"
18269 [(set (match_operand:DI 0 "register_operand" "=r")
18271 [(match_operand:DI 1 "register_operand" "0")
18272 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18274 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18275 "crc32{q}\t{%2, %0|%0, %2}"
18276 [(set_attr "type" "sselog1")
18277 (set_attr "prefix_rep" "1")
18278 (set_attr "prefix_extra" "1")
18279 (set_attr "mode" "DI")])
18281 (define_insn "rdpmc"
18282 [(set (match_operand:DI 0 "register_operand" "=A")
18283 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18287 [(set_attr "type" "other")
18288 (set_attr "length" "2")])
18290 (define_insn "rdpmc_rex64"
18291 [(set (match_operand:DI 0 "register_operand" "=a")
18292 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18294 (set (match_operand:DI 1 "register_operand" "=d")
18295 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18298 [(set_attr "type" "other")
18299 (set_attr "length" "2")])
18301 (define_insn "rdtsc"
18302 [(set (match_operand:DI 0 "register_operand" "=A")
18303 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18306 [(set_attr "type" "other")
18307 (set_attr "length" "2")])
18309 (define_insn "rdtsc_rex64"
18310 [(set (match_operand:DI 0 "register_operand" "=a")
18311 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18312 (set (match_operand:DI 1 "register_operand" "=d")
18313 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18316 [(set_attr "type" "other")
18317 (set_attr "length" "2")])
18319 (define_insn "rdtscp"
18320 [(set (match_operand:DI 0 "register_operand" "=A")
18321 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18322 (set (match_operand:SI 1 "register_operand" "=c")
18323 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18326 [(set_attr "type" "other")
18327 (set_attr "length" "3")])
18329 (define_insn "rdtscp_rex64"
18330 [(set (match_operand:DI 0 "register_operand" "=a")
18331 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18332 (set (match_operand:DI 1 "register_operand" "=d")
18333 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18334 (set (match_operand:SI 2 "register_operand" "=c")
18335 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18338 [(set_attr "type" "other")
18339 (set_attr "length" "3")])
18341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18343 ;; FXSR, XSAVE and XSAVEOPT instructions
18345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18347 (define_insn "fxsave"
18348 [(set (match_operand:BLK 0 "memory_operand" "=m")
18349 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18352 [(set_attr "type" "other")
18353 (set_attr "memory" "store")
18354 (set (attr "length")
18355 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18357 (define_insn "fxsave64"
18358 [(set (match_operand:BLK 0 "memory_operand" "=m")
18359 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18360 "TARGET_64BIT && TARGET_FXSR"
18362 [(set_attr "type" "other")
18363 (set_attr "memory" "store")
18364 (set (attr "length")
18365 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18367 (define_insn "fxrstor"
18368 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18372 [(set_attr "type" "other")
18373 (set_attr "memory" "load")
18374 (set (attr "length")
18375 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18377 (define_insn "fxrstor64"
18378 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18379 UNSPECV_FXRSTOR64)]
18380 "TARGET_64BIT && TARGET_FXSR"
18382 [(set_attr "type" "other")
18383 (set_attr "memory" "load")
18384 (set (attr "length")
18385 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18387 (define_int_iterator ANY_XSAVE
18389 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18390 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18391 (UNSPECV_XSAVES "TARGET_XSAVES")])
18393 (define_int_iterator ANY_XSAVE64
18395 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18396 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18397 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18399 (define_int_attr xsave
18400 [(UNSPECV_XSAVE "xsave")
18401 (UNSPECV_XSAVE64 "xsave64")
18402 (UNSPECV_XSAVEOPT "xsaveopt")
18403 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18404 (UNSPECV_XSAVEC "xsavec")
18405 (UNSPECV_XSAVEC64 "xsavec64")
18406 (UNSPECV_XSAVES "xsaves")
18407 (UNSPECV_XSAVES64 "xsaves64")])
18409 (define_int_iterator ANY_XRSTOR
18411 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18413 (define_int_iterator ANY_XRSTOR64
18415 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18417 (define_int_attr xrstor
18418 [(UNSPECV_XRSTOR "xrstor")
18419 (UNSPECV_XRSTOR64 "xrstor")
18420 (UNSPECV_XRSTORS "xrstors")
18421 (UNSPECV_XRSTORS64 "xrstors")])
18423 (define_insn "<xsave>"
18424 [(set (match_operand:BLK 0 "memory_operand" "=m")
18425 (unspec_volatile:BLK
18426 [(match_operand:DI 1 "register_operand" "A")]
18428 "!TARGET_64BIT && TARGET_XSAVE"
18430 [(set_attr "type" "other")
18431 (set_attr "memory" "store")
18432 (set (attr "length")
18433 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18435 (define_insn "<xsave>_rex64"
18436 [(set (match_operand:BLK 0 "memory_operand" "=m")
18437 (unspec_volatile:BLK
18438 [(match_operand:SI 1 "register_operand" "a")
18439 (match_operand:SI 2 "register_operand" "d")]
18441 "TARGET_64BIT && TARGET_XSAVE"
18443 [(set_attr "type" "other")
18444 (set_attr "memory" "store")
18445 (set (attr "length")
18446 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18448 (define_insn "<xsave>"
18449 [(set (match_operand:BLK 0 "memory_operand" "=m")
18450 (unspec_volatile:BLK
18451 [(match_operand:SI 1 "register_operand" "a")
18452 (match_operand:SI 2 "register_operand" "d")]
18454 "TARGET_64BIT && TARGET_XSAVE"
18456 [(set_attr "type" "other")
18457 (set_attr "memory" "store")
18458 (set (attr "length")
18459 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18461 (define_insn "<xrstor>"
18462 [(unspec_volatile:BLK
18463 [(match_operand:BLK 0 "memory_operand" "m")
18464 (match_operand:DI 1 "register_operand" "A")]
18466 "!TARGET_64BIT && TARGET_XSAVE"
18468 [(set_attr "type" "other")
18469 (set_attr "memory" "load")
18470 (set (attr "length")
18471 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18473 (define_insn "<xrstor>_rex64"
18474 [(unspec_volatile:BLK
18475 [(match_operand:BLK 0 "memory_operand" "m")
18476 (match_operand:SI 1 "register_operand" "a")
18477 (match_operand:SI 2 "register_operand" "d")]
18479 "TARGET_64BIT && TARGET_XSAVE"
18481 [(set_attr "type" "other")
18482 (set_attr "memory" "load")
18483 (set (attr "length")
18484 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18486 (define_insn "<xrstor>64"
18487 [(unspec_volatile:BLK
18488 [(match_operand:BLK 0 "memory_operand" "m")
18489 (match_operand:SI 1 "register_operand" "a")
18490 (match_operand:SI 2 "register_operand" "d")]
18492 "TARGET_64BIT && TARGET_XSAVE"
18494 [(set_attr "type" "other")
18495 (set_attr "memory" "load")
18496 (set (attr "length")
18497 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18501 ;; Floating-point instructions for atomic compound assignments
18503 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18505 ; Clobber all floating-point registers on environment save and restore
18506 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18507 (define_insn "fnstenv"
18508 [(set (match_operand:BLK 0 "memory_operand" "=m")
18509 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18510 (clobber (reg:HI FPCR_REG))
18511 (clobber (reg:XF ST0_REG))
18512 (clobber (reg:XF ST1_REG))
18513 (clobber (reg:XF ST2_REG))
18514 (clobber (reg:XF ST3_REG))
18515 (clobber (reg:XF ST4_REG))
18516 (clobber (reg:XF ST5_REG))
18517 (clobber (reg:XF ST6_REG))
18518 (clobber (reg:XF ST7_REG))]
18521 [(set_attr "type" "other")
18522 (set_attr "memory" "store")
18523 (set (attr "length")
18524 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18526 (define_insn "fldenv"
18527 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18529 (clobber (reg:CCFP FPSR_REG))
18530 (clobber (reg:HI FPCR_REG))
18531 (clobber (reg:XF ST0_REG))
18532 (clobber (reg:XF ST1_REG))
18533 (clobber (reg:XF ST2_REG))
18534 (clobber (reg:XF ST3_REG))
18535 (clobber (reg:XF ST4_REG))
18536 (clobber (reg:XF ST5_REG))
18537 (clobber (reg:XF ST6_REG))
18538 (clobber (reg:XF ST7_REG))]
18541 [(set_attr "type" "other")
18542 (set_attr "memory" "load")
18543 (set (attr "length")
18544 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18546 (define_insn "fnstsw"
18547 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18548 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18551 [(set_attr "type" "other,other")
18552 (set_attr "memory" "none,store")
18553 (set (attr "length")
18554 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18556 (define_insn "fnclex"
18557 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18560 [(set_attr "type" "other")
18561 (set_attr "memory" "none")
18562 (set_attr "length" "2")])
18564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18566 ;; LWP instructions
18568 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18570 (define_expand "lwp_llwpcb"
18571 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18572 UNSPECV_LLWP_INTRINSIC)]
18575 (define_insn "*lwp_llwpcb<mode>1"
18576 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18577 UNSPECV_LLWP_INTRINSIC)]
18580 [(set_attr "type" "lwp")
18581 (set_attr "mode" "<MODE>")
18582 (set_attr "length" "5")])
18584 (define_expand "lwp_slwpcb"
18585 [(set (match_operand 0 "register_operand" "=r")
18586 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18591 insn = (Pmode == DImode
18593 : gen_lwp_slwpcbsi);
18595 emit_insn (insn (operands[0]));
18599 (define_insn "lwp_slwpcb<mode>"
18600 [(set (match_operand:P 0 "register_operand" "=r")
18601 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18604 [(set_attr "type" "lwp")
18605 (set_attr "mode" "<MODE>")
18606 (set_attr "length" "5")])
18608 (define_expand "lwp_lwpval<mode>3"
18609 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18610 (match_operand:SI 2 "nonimmediate_operand" "rm")
18611 (match_operand:SI 3 "const_int_operand" "i")]
18612 UNSPECV_LWPVAL_INTRINSIC)]
18614 ;; Avoid unused variable warning.
18615 "(void) operands[0];")
18617 (define_insn "*lwp_lwpval<mode>3_1"
18618 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18619 (match_operand:SI 1 "nonimmediate_operand" "rm")
18620 (match_operand:SI 2 "const_int_operand" "i")]
18621 UNSPECV_LWPVAL_INTRINSIC)]
18623 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18624 [(set_attr "type" "lwp")
18625 (set_attr "mode" "<MODE>")
18626 (set (attr "length")
18627 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18629 (define_expand "lwp_lwpins<mode>3"
18630 [(set (reg:CCC FLAGS_REG)
18631 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18632 (match_operand:SI 2 "nonimmediate_operand" "rm")
18633 (match_operand:SI 3 "const_int_operand" "i")]
18634 UNSPECV_LWPINS_INTRINSIC))
18635 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18636 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18639 (define_insn "*lwp_lwpins<mode>3_1"
18640 [(set (reg:CCC FLAGS_REG)
18641 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18642 (match_operand:SI 1 "nonimmediate_operand" "rm")
18643 (match_operand:SI 2 "const_int_operand" "i")]
18644 UNSPECV_LWPINS_INTRINSIC))]
18646 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18647 [(set_attr "type" "lwp")
18648 (set_attr "mode" "<MODE>")
18649 (set (attr "length")
18650 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18652 (define_int_iterator RDFSGSBASE
18656 (define_int_iterator WRFSGSBASE
18660 (define_int_attr fsgs
18661 [(UNSPECV_RDFSBASE "fs")
18662 (UNSPECV_RDGSBASE "gs")
18663 (UNSPECV_WRFSBASE "fs")
18664 (UNSPECV_WRGSBASE "gs")])
18666 (define_insn "rd<fsgs>base<mode>"
18667 [(set (match_operand:SWI48 0 "register_operand" "=r")
18668 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18669 "TARGET_64BIT && TARGET_FSGSBASE"
18671 [(set_attr "type" "other")
18672 (set_attr "prefix_extra" "2")])
18674 (define_insn "wr<fsgs>base<mode>"
18675 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18677 "TARGET_64BIT && TARGET_FSGSBASE"
18679 [(set_attr "type" "other")
18680 (set_attr "prefix_extra" "2")])
18682 (define_insn "rdrand<mode>_1"
18683 [(set (match_operand:SWI248 0 "register_operand" "=r")
18684 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18685 (set (reg:CCC FLAGS_REG)
18686 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18689 [(set_attr "type" "other")
18690 (set_attr "prefix_extra" "1")])
18692 (define_insn "rdseed<mode>_1"
18693 [(set (match_operand:SWI248 0 "register_operand" "=r")
18694 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18695 (set (reg:CCC FLAGS_REG)
18696 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18699 [(set_attr "type" "other")
18700 (set_attr "prefix_extra" "1")])
18702 (define_expand "pause"
18703 [(set (match_dup 0)
18704 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18707 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18708 MEM_VOLATILE_P (operands[0]) = 1;
18711 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18712 ;; They have the same encoding.
18713 (define_insn "*pause"
18714 [(set (match_operand:BLK 0)
18715 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18718 [(set_attr "length" "2")
18719 (set_attr "memory" "unknown")])
18721 (define_expand "xbegin"
18722 [(set (match_operand:SI 0 "register_operand")
18723 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18726 rtx_code_label *label = gen_label_rtx ();
18728 /* xbegin is emitted as jump_insn, so reload won't be able
18729 to reload its operand. Force the value into AX hard register. */
18730 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18731 emit_move_insn (ax_reg, constm1_rtx);
18733 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18735 emit_label (label);
18736 LABEL_NUSES (label) = 1;
18738 emit_move_insn (operands[0], ax_reg);
18743 (define_insn "xbegin_1"
18745 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18747 (label_ref (match_operand 1))
18749 (set (match_operand:SI 0 "register_operand" "+a")
18750 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18753 [(set_attr "type" "other")
18754 (set_attr "length" "6")])
18756 (define_insn "xend"
18757 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18760 [(set_attr "type" "other")
18761 (set_attr "length" "3")])
18763 (define_insn "xabort"
18764 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18768 [(set_attr "type" "other")
18769 (set_attr "length" "3")])
18771 (define_expand "xtest"
18772 [(set (match_operand:QI 0 "register_operand")
18773 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18776 emit_insn (gen_xtest_1 ());
18778 ix86_expand_setcc (operands[0], NE,
18779 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18783 (define_insn "xtest_1"
18784 [(set (reg:CCZ FLAGS_REG)
18785 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18788 [(set_attr "type" "other")
18789 (set_attr "length" "3")])
18791 (define_insn "pcommit"
18792 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18795 [(set_attr "type" "other")
18796 (set_attr "length" "4")])
18798 (define_insn "clwb"
18799 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18803 [(set_attr "type" "sse")
18804 (set_attr "atom_sse_attr" "fence")
18805 (set_attr "memory" "unknown")])
18807 (define_insn "clflushopt"
18808 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18809 UNSPECV_CLFLUSHOPT)]
18810 "TARGET_CLFLUSHOPT"
18812 [(set_attr "type" "sse")
18813 (set_attr "atom_sse_attr" "fence")
18814 (set_attr "memory" "unknown")])
18816 ;; MPX instructions
18818 (define_expand "<mode>_mk"
18819 [(set (match_operand:BND 0 "register_operand")
18823 [(match_operand:<bnd_ptr> 1 "register_operand")
18824 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18828 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18830 UNSPEC_BNDMK_ADDR);
18833 (define_insn "*<mode>_mk"
18834 [(set (match_operand:BND 0 "register_operand" "=w")
18836 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18838 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18839 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18840 UNSPEC_BNDMK_ADDR)])]
18843 "bndmk\t{%3, %0|%0, %3}"
18844 [(set_attr "type" "mpxmk")])
18846 (define_expand "mov<mode>"
18847 [(set (match_operand:BND 0 "general_operand")
18848 (match_operand:BND 1 "general_operand"))]
18851 ix86_expand_move (<MODE>mode, operands);DONE;
18854 (define_insn "*mov<mode>_internal_mpx"
18855 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18856 (match_operand:BND 1 "general_operand" "wm,w"))]
18858 "bndmov\t{%1, %0|%0, %1}"
18859 [(set_attr "type" "mpxmov")])
18861 (define_expand "<mode>_<bndcheck>"
18862 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18863 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18865 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18868 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18869 MEM_VOLATILE_P (operands[2]) = 1;
18872 (define_insn "*<mode>_<bndcheck>"
18873 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18874 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18875 (set (match_operand:BLK 2 "bnd_mem_operator")
18876 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18878 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18879 [(set_attr "type" "mpxchk")])
18881 (define_expand "<mode>_ldx"
18882 [(parallel [(set (match_operand:BND 0 "register_operand")
18886 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18887 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18889 (use (mem:BLK (match_dup 1)))])]
18892 /* Avoid registers which connot be used as index. */
18893 if (!index_register_operand (operands[2], Pmode))
18895 rtx temp = gen_reg_rtx (Pmode);
18896 emit_move_insn (temp, operands[2]);
18897 operands[2] = temp;
18900 /* If it was a register originally then it may have
18901 mode other than Pmode. We need to extend in such
18902 case because bndldx may work only with Pmode regs. */
18903 if (GET_MODE (operands[2]) != Pmode)
18904 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18906 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18908 UNSPEC_BNDLDX_ADDR);
18911 (define_insn "*<mode>_ldx"
18912 [(parallel [(set (match_operand:BND 0 "register_operand" "=w")
18914 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18916 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18917 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18918 UNSPEC_BNDLDX_ADDR)])]
18920 (use (mem:BLK (match_dup 1)))])]
18922 "bndldx\t{%3, %0|%0, %3}"
18923 [(set_attr "type" "mpxld")])
18925 (define_expand "<mode>_stx"
18926 [(parallel [(unspec [(mem:<bnd_ptr>
18928 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18929 (match_operand:<bnd_ptr> 1 "register_operand")]))
18930 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18932 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18935 /* Avoid registers which connot be used as index. */
18936 if (!index_register_operand (operands[1], Pmode))
18938 rtx temp = gen_reg_rtx (Pmode);
18939 emit_move_insn (temp, operands[1]);
18940 operands[1] = temp;
18943 /* If it was a register originally then it may have
18944 mode other than Pmode. We need to extend in such
18945 case because bndstx may work only with Pmode regs. */
18946 if (GET_MODE (operands[1]) != Pmode)
18947 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18949 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18951 UNSPEC_BNDLDX_ADDR);
18952 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18953 MEM_VOLATILE_P (operands[4]) = 1;
18956 (define_insn "*<mode>_stx"
18957 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18959 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18960 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18961 UNSPEC_BNDLDX_ADDR)])
18962 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18963 (set (match_operand:BLK 4 "bnd_mem_operator")
18964 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18966 "bndstx\t{%2, %3|%3, %2}"
18967 [(set_attr "type" "mpxst")])
18969 (define_insn "move_size_reloc_<mode>"
18970 [(set (match_operand:SWI48 0 "register_operand" "=r")
18972 [(match_operand:SWI48 1 "symbol_operand")]
18976 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18977 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18979 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18981 [(set_attr "type" "imov")
18982 (set_attr "mode" "<MODE>")])
18986 (include "sync.md")