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 (VOIDmode, 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 (VOIDmode, 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)"
4903 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4905 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4907 emit_insn (gen_sse2_loadld (operands[4],
4908 CONST0_RTX (V4SImode), operands[1]));
4910 if (<ssevecmode>mode == V4SFmode)
4911 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4913 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4917 ;; Avoid partial SSE register dependency stalls
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4923 && optimize_function_for_speed_p (cfun)
4924 && reload_completed && SSE_REG_P (operands[0])"
4927 const machine_mode vmode = <MODEF:ssevecmode>mode;
4928 const machine_mode mode = <MODEF:MODE>mode;
4929 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4931 emit_move_insn (op0, CONST0_RTX (vmode));
4933 t = gen_rtx_FLOAT (mode, operands[1]);
4934 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4935 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4936 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4940 ;; Break partial reg stall for cvtsd2ss.
4943 [(set (match_operand:SF 0 "register_operand")
4945 (match_operand:DF 1 "nonimmediate_operand")))]
4946 "TARGET_SSE2 && TARGET_SSE_MATH
4947 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4948 && optimize_function_for_speed_p (cfun)
4949 && SSE_REG_P (operands[0])
4950 && (!SSE_REG_P (operands[1])
4951 || REGNO (operands[0]) != REGNO (operands[1]))
4952 && (!EXT_REX_SSE_REG_P (operands[0])
4953 || TARGET_AVX512VL)"
4957 (float_truncate:V2SF
4962 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4964 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4966 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4969 ;; Break partial reg stall for cvtss2sd.
4972 [(set (match_operand:DF 0 "register_operand")
4974 (match_operand:SF 1 "nonimmediate_operand")))]
4975 "TARGET_SSE2 && TARGET_SSE_MATH
4976 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4977 && optimize_function_for_speed_p (cfun)
4978 && SSE_REG_P (operands[0])
4979 && (!SSE_REG_P (operands[1])
4980 || REGNO (operands[0]) != REGNO (operands[1]))
4981 && (!EXT_REX_SSE_REG_P (operands[0])
4982 || TARGET_AVX512VL)"
4988 (parallel [(const_int 0) (const_int 1)])))
4992 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4994 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4996 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4999 ;; Avoid store forwarding (partial memory) stall penalty
5000 ;; by passing DImode value through XMM registers. */
5002 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5003 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5005 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5006 (clobber (match_scratch:V4SI 3 "=X,x"))
5007 (clobber (match_scratch:V4SI 4 "=X,x"))
5008 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5009 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5010 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5011 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5013 [(set_attr "type" "multi")
5014 (set_attr "mode" "<X87MODEF:MODE>")
5015 (set_attr "unit" "i387")
5016 (set_attr "fp_int_src" "true")])
5019 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5020 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5021 (clobber (match_scratch:V4SI 3))
5022 (clobber (match_scratch:V4SI 4))
5023 (clobber (match_operand:DI 2 "memory_operand"))]
5024 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5025 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5026 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5027 && reload_completed"
5028 [(set (match_dup 2) (match_dup 3))
5029 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5031 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5032 Assemble the 64-bit DImode value in an xmm register. */
5033 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5034 gen_rtx_SUBREG (SImode, operands[1], 0)));
5035 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5036 gen_rtx_SUBREG (SImode, operands[1], 4)));
5037 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5040 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5044 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5045 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5046 (clobber (match_scratch:V4SI 3))
5047 (clobber (match_scratch:V4SI 4))
5048 (clobber (match_operand:DI 2 "memory_operand"))]
5049 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5050 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5051 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5052 && reload_completed"
5053 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5055 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5056 [(set (match_operand:MODEF 0 "register_operand")
5057 (unsigned_float:MODEF
5058 (match_operand:SWI12 1 "nonimmediate_operand")))]
5060 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5062 operands[1] = convert_to_mode (SImode, operands[1], 1);
5063 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5067 ;; Avoid store forwarding (partial memory) stall penalty by extending
5068 ;; SImode value to DImode through XMM register instead of pushing two
5069 ;; SImode values to stack. Also note that fild loads from memory only.
5071 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5072 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5073 (unsigned_float:X87MODEF
5074 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5075 (clobber (match_scratch:DI 3 "=x"))
5076 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5078 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5079 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5081 "&& reload_completed"
5082 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5083 (set (match_dup 2) (match_dup 3))
5085 (float:X87MODEF (match_dup 2)))]
5087 [(set_attr "type" "multi")
5088 (set_attr "mode" "<MODE>")])
5090 (define_expand "floatunssi<mode>2"
5092 [(set (match_operand:X87MODEF 0 "register_operand")
5093 (unsigned_float:X87MODEF
5094 (match_operand:SI 1 "nonimmediate_operand")))
5095 (clobber (match_scratch:DI 3))
5096 (clobber (match_dup 2))])]
5098 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5099 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5100 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5102 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5104 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5108 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5111 (define_expand "floatunsdisf2"
5112 [(use (match_operand:SF 0 "register_operand"))
5113 (use (match_operand:DI 1 "nonimmediate_operand"))]
5114 "TARGET_64BIT && TARGET_SSE_MATH"
5115 "x86_emit_floatuns (operands); DONE;")
5117 (define_expand "floatunsdidf2"
5118 [(use (match_operand:DF 0 "register_operand"))
5119 (use (match_operand:DI 1 "nonimmediate_operand"))]
5120 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5121 && TARGET_SSE2 && TARGET_SSE_MATH"
5124 x86_emit_floatuns (operands);
5126 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5130 ;; Load effective address instructions
5132 (define_insn_and_split "*lea<mode>"
5133 [(set (match_operand:SWI48 0 "register_operand" "=r")
5134 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5137 if (SImode_address_operand (operands[1], VOIDmode))
5139 gcc_assert (TARGET_64BIT);
5140 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5143 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5145 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5148 machine_mode mode = <MODE>mode;
5151 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5152 change operands[] array behind our back. */
5153 pat = PATTERN (curr_insn);
5155 operands[0] = SET_DEST (pat);
5156 operands[1] = SET_SRC (pat);
5158 /* Emit all operations in SImode for zero-extended addresses. */
5159 if (SImode_address_operand (operands[1], VOIDmode))
5162 ix86_split_lea_for_addr (curr_insn, operands, mode);
5164 /* Zero-extend return register to DImode for zero-extended addresses. */
5165 if (mode != <MODE>mode)
5166 emit_insn (gen_zero_extendsidi2
5167 (operands[0], gen_lowpart (mode, operands[0])));
5171 [(set_attr "type" "lea")
5174 (match_operand 1 "SImode_address_operand")
5176 (const_string "<MODE>")))])
5180 (define_expand "add<mode>3"
5181 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5182 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5183 (match_operand:SDWIM 2 "<general_operand>")))]
5185 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5187 (define_insn_and_split "*add<dwi>3_doubleword"
5188 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5190 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5191 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5192 (clobber (reg:CC FLAGS_REG))]
5193 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5196 [(parallel [(set (reg:CC FLAGS_REG)
5197 (unspec:CC [(match_dup 1) (match_dup 2)]
5200 (plus:DWIH (match_dup 1) (match_dup 2)))])
5201 (parallel [(set (match_dup 3)
5205 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5207 (clobber (reg:CC FLAGS_REG))])]
5208 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5210 (define_insn "*add<mode>3_cc"
5211 [(set (reg:CC FLAGS_REG)
5213 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5214 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5216 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5217 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5218 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5219 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5220 [(set_attr "type" "alu")
5221 (set_attr "mode" "<MODE>")])
5223 (define_insn "addqi3_cc"
5224 [(set (reg:CC FLAGS_REG)
5226 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5227 (match_operand:QI 2 "general_operand" "qn,qm")]
5229 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5230 (plus:QI (match_dup 1) (match_dup 2)))]
5231 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5232 "add{b}\t{%2, %0|%0, %2}"
5233 [(set_attr "type" "alu")
5234 (set_attr "mode" "QI")])
5236 (define_insn "*add<mode>_1"
5237 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5239 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5240 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5241 (clobber (reg:CC FLAGS_REG))]
5242 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5244 switch (get_attr_type (insn))
5250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251 if (operands[2] == const1_rtx)
5252 return "inc{<imodesuffix>}\t%0";
5255 gcc_assert (operands[2] == constm1_rtx);
5256 return "dec{<imodesuffix>}\t%0";
5260 /* For most processors, ADD is faster than LEA. This alternative
5261 was added to use ADD as much as possible. */
5262 if (which_alternative == 2)
5263 std::swap (operands[1], operands[2]);
5265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5267 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5269 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5273 (cond [(eq_attr "alternative" "3")
5274 (const_string "lea")
5275 (match_operand:SWI48 2 "incdec_operand")
5276 (const_string "incdec")
5278 (const_string "alu")))
5279 (set (attr "length_immediate")
5281 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5283 (const_string "*")))
5284 (set_attr "mode" "<MODE>")])
5286 ;; It may seem that nonimmediate operand is proper one for operand 1.
5287 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5288 ;; we take care in ix86_binary_operator_ok to not allow two memory
5289 ;; operands so proper swapping will be done in reload. This allow
5290 ;; patterns constructed from addsi_1 to match.
5292 (define_insn "addsi_1_zext"
5293 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5295 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5296 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5297 (clobber (reg:CC FLAGS_REG))]
5298 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5300 switch (get_attr_type (insn))
5306 if (operands[2] == const1_rtx)
5307 return "inc{l}\t%k0";
5310 gcc_assert (operands[2] == constm1_rtx);
5311 return "dec{l}\t%k0";
5315 /* For most processors, ADD is faster than LEA. This alternative
5316 was added to use ADD as much as possible. */
5317 if (which_alternative == 1)
5318 std::swap (operands[1], operands[2]);
5320 if (x86_maybe_negate_const_int (&operands[2], SImode))
5321 return "sub{l}\t{%2, %k0|%k0, %2}";
5323 return "add{l}\t{%2, %k0|%k0, %2}";
5327 (cond [(eq_attr "alternative" "2")
5328 (const_string "lea")
5329 (match_operand:SI 2 "incdec_operand")
5330 (const_string "incdec")
5332 (const_string "alu")))
5333 (set (attr "length_immediate")
5335 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5337 (const_string "*")))
5338 (set_attr "mode" "SI")])
5340 (define_insn "*addhi_1"
5341 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5342 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5343 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5344 (clobber (reg:CC FLAGS_REG))]
5345 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5347 switch (get_attr_type (insn))
5353 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354 if (operands[2] == const1_rtx)
5355 return "inc{w}\t%0";
5358 gcc_assert (operands[2] == constm1_rtx);
5359 return "dec{w}\t%0";
5363 /* For most processors, ADD is faster than LEA. This alternative
5364 was added to use ADD as much as possible. */
5365 if (which_alternative == 2)
5366 std::swap (operands[1], operands[2]);
5368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369 if (x86_maybe_negate_const_int (&operands[2], HImode))
5370 return "sub{w}\t{%2, %0|%0, %2}";
5372 return "add{w}\t{%2, %0|%0, %2}";
5376 (cond [(eq_attr "alternative" "3")
5377 (const_string "lea")
5378 (match_operand:HI 2 "incdec_operand")
5379 (const_string "incdec")
5381 (const_string "alu")))
5382 (set (attr "length_immediate")
5384 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5386 (const_string "*")))
5387 (set_attr "mode" "HI,HI,HI,SI")])
5389 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5390 (define_insn "*addqi_1"
5391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5392 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5393 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5394 (clobber (reg:CC FLAGS_REG))]
5395 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5397 bool widen = (which_alternative == 3 || which_alternative == 4);
5399 switch (get_attr_type (insn))
5405 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5406 if (operands[2] == const1_rtx)
5407 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5410 gcc_assert (operands[2] == constm1_rtx);
5411 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5415 /* For most processors, ADD is faster than LEA. These alternatives
5416 were added to use ADD as much as possible. */
5417 if (which_alternative == 2 || which_alternative == 4)
5418 std::swap (operands[1], operands[2]);
5420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5421 if (x86_maybe_negate_const_int (&operands[2], QImode))
5424 return "sub{l}\t{%2, %k0|%k0, %2}";
5426 return "sub{b}\t{%2, %0|%0, %2}";
5429 return "add{l}\t{%k2, %k0|%k0, %k2}";
5431 return "add{b}\t{%2, %0|%0, %2}";
5435 (cond [(eq_attr "alternative" "5")
5436 (const_string "lea")
5437 (match_operand:QI 2 "incdec_operand")
5438 (const_string "incdec")
5440 (const_string "alu")))
5441 (set (attr "length_immediate")
5443 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5445 (const_string "*")))
5446 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5448 (define_insn "*addqi_1_slp"
5449 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5450 (plus:QI (match_dup 0)
5451 (match_operand:QI 1 "general_operand" "qn,qm")))
5452 (clobber (reg:CC FLAGS_REG))]
5453 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5456 switch (get_attr_type (insn))
5459 if (operands[1] == const1_rtx)
5460 return "inc{b}\t%0";
5463 gcc_assert (operands[1] == constm1_rtx);
5464 return "dec{b}\t%0";
5468 if (x86_maybe_negate_const_int (&operands[1], QImode))
5469 return "sub{b}\t{%1, %0|%0, %1}";
5471 return "add{b}\t{%1, %0|%0, %1}";
5475 (if_then_else (match_operand:QI 1 "incdec_operand")
5476 (const_string "incdec")
5477 (const_string "alu1")))
5478 (set (attr "memory")
5479 (if_then_else (match_operand 1 "memory_operand")
5480 (const_string "load")
5481 (const_string "none")))
5482 (set_attr "mode" "QI")])
5484 ;; Split non destructive adds if we cannot use lea.
5486 [(set (match_operand:SWI48 0 "register_operand")
5487 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5488 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5489 (clobber (reg:CC FLAGS_REG))]
5490 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5491 [(set (match_dup 0) (match_dup 1))
5492 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5493 (clobber (reg:CC FLAGS_REG))])])
5495 ;; Convert add to the lea pattern to avoid flags dependency.
5497 [(set (match_operand:SWI 0 "register_operand")
5498 (plus:SWI (match_operand:SWI 1 "register_operand")
5499 (match_operand:SWI 2 "<nonmemory_operand>")))
5500 (clobber (reg:CC FLAGS_REG))]
5501 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5504 machine_mode mode = <MODE>mode;
5507 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5510 operands[0] = gen_lowpart (mode, operands[0]);
5511 operands[1] = gen_lowpart (mode, operands[1]);
5512 operands[2] = gen_lowpart (mode, operands[2]);
5515 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5517 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5521 ;; Split non destructive adds if we cannot use lea.
5523 [(set (match_operand:DI 0 "register_operand")
5525 (plus:SI (match_operand:SI 1 "register_operand")
5526 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5527 (clobber (reg:CC FLAGS_REG))]
5529 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5530 [(set (match_dup 3) (match_dup 1))
5531 (parallel [(set (match_dup 0)
5532 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5533 (clobber (reg:CC FLAGS_REG))])]
5534 "operands[3] = gen_lowpart (SImode, operands[0]);")
5536 ;; Convert add to the lea pattern to avoid flags dependency.
5538 [(set (match_operand:DI 0 "register_operand")
5540 (plus:SI (match_operand:SI 1 "register_operand")
5541 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5542 (clobber (reg:CC FLAGS_REG))]
5543 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5545 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5547 (define_insn "*add<mode>_2"
5548 [(set (reg FLAGS_REG)
5551 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5552 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5554 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5555 (plus:SWI (match_dup 1) (match_dup 2)))]
5556 "ix86_match_ccmode (insn, CCGOCmode)
5557 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5559 switch (get_attr_type (insn))
5562 if (operands[2] == const1_rtx)
5563 return "inc{<imodesuffix>}\t%0";
5566 gcc_assert (operands[2] == constm1_rtx);
5567 return "dec{<imodesuffix>}\t%0";
5571 if (which_alternative == 2)
5572 std::swap (operands[1], operands[2]);
5574 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5575 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5576 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5578 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5582 (if_then_else (match_operand:SWI 2 "incdec_operand")
5583 (const_string "incdec")
5584 (const_string "alu")))
5585 (set (attr "length_immediate")
5587 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5589 (const_string "*")))
5590 (set_attr "mode" "<MODE>")])
5592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5593 (define_insn "*addsi_2_zext"
5594 [(set (reg FLAGS_REG)
5596 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5597 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5599 (set (match_operand:DI 0 "register_operand" "=r,r")
5600 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5601 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5602 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5604 switch (get_attr_type (insn))
5607 if (operands[2] == const1_rtx)
5608 return "inc{l}\t%k0";
5611 gcc_assert (operands[2] == constm1_rtx);
5612 return "dec{l}\t%k0";
5616 if (which_alternative == 1)
5617 std::swap (operands[1], operands[2]);
5619 if (x86_maybe_negate_const_int (&operands[2], SImode))
5620 return "sub{l}\t{%2, %k0|%k0, %2}";
5622 return "add{l}\t{%2, %k0|%k0, %2}";
5626 (if_then_else (match_operand:SI 2 "incdec_operand")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set (attr "length_immediate")
5631 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5633 (const_string "*")))
5634 (set_attr "mode" "SI")])
5636 (define_insn "*add<mode>_3"
5637 [(set (reg FLAGS_REG)
5639 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5640 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5641 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5642 "ix86_match_ccmode (insn, CCZmode)
5643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5645 switch (get_attr_type (insn))
5648 if (operands[2] == const1_rtx)
5649 return "inc{<imodesuffix>}\t%0";
5652 gcc_assert (operands[2] == constm1_rtx);
5653 return "dec{<imodesuffix>}\t%0";
5657 if (which_alternative == 1)
5658 std::swap (operands[1], operands[2]);
5660 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5661 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5662 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5664 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5668 (if_then_else (match_operand:SWI 2 "incdec_operand")
5669 (const_string "incdec")
5670 (const_string "alu")))
5671 (set (attr "length_immediate")
5673 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5675 (const_string "*")))
5676 (set_attr "mode" "<MODE>")])
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680 [(set (reg FLAGS_REG)
5682 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5683 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5684 (set (match_operand:DI 0 "register_operand" "=r,r")
5685 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5686 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5687 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5689 switch (get_attr_type (insn))
5692 if (operands[2] == const1_rtx)
5693 return "inc{l}\t%k0";
5696 gcc_assert (operands[2] == constm1_rtx);
5697 return "dec{l}\t%k0";
5701 if (which_alternative == 1)
5702 std::swap (operands[1], operands[2]);
5704 if (x86_maybe_negate_const_int (&operands[2], SImode))
5705 return "sub{l}\t{%2, %k0|%k0, %2}";
5707 return "add{l}\t{%2, %k0|%k0, %2}";
5711 (if_then_else (match_operand:SI 2 "incdec_operand")
5712 (const_string "incdec")
5713 (const_string "alu")))
5714 (set (attr "length_immediate")
5716 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5718 (const_string "*")))
5719 (set_attr "mode" "SI")])
5721 ; For comparisons against 1, -1 and 128, we may generate better code
5722 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5723 ; is matched then. We can't accept general immediate, because for
5724 ; case of overflows, the result is messed up.
5725 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5726 ; only for comparisons not depending on it.
5728 (define_insn "*adddi_4"
5729 [(set (reg FLAGS_REG)
5731 (match_operand:DI 1 "nonimmediate_operand" "0")
5732 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5733 (clobber (match_scratch:DI 0 "=rm"))]
5735 && ix86_match_ccmode (insn, CCGCmode)"
5737 switch (get_attr_type (insn))
5740 if (operands[2] == constm1_rtx)
5741 return "inc{q}\t%0";
5744 gcc_assert (operands[2] == const1_rtx);
5745 return "dec{q}\t%0";
5749 if (x86_maybe_negate_const_int (&operands[2], DImode))
5750 return "add{q}\t{%2, %0|%0, %2}";
5752 return "sub{q}\t{%2, %0|%0, %2}";
5756 (if_then_else (match_operand:DI 2 "incdec_operand")
5757 (const_string "incdec")
5758 (const_string "alu")))
5759 (set (attr "length_immediate")
5761 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5763 (const_string "*")))
5764 (set_attr "mode" "DI")])
5766 ; For comparisons against 1, -1 and 128, we may generate better code
5767 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5768 ; is matched then. We can't accept general immediate, because for
5769 ; case of overflows, the result is messed up.
5770 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5771 ; only for comparisons not depending on it.
5773 (define_insn "*add<mode>_4"
5774 [(set (reg FLAGS_REG)
5776 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5777 (match_operand:SWI124 2 "const_int_operand" "n")))
5778 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5779 "ix86_match_ccmode (insn, CCGCmode)"
5781 switch (get_attr_type (insn))
5784 if (operands[2] == constm1_rtx)
5785 return "inc{<imodesuffix>}\t%0";
5788 gcc_assert (operands[2] == const1_rtx);
5789 return "dec{<imodesuffix>}\t%0";
5793 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5794 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5796 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5800 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5801 (const_string "incdec")
5802 (const_string "alu")))
5803 (set (attr "length_immediate")
5805 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5807 (const_string "*")))
5808 (set_attr "mode" "<MODE>")])
5810 (define_insn "*add<mode>_5"
5811 [(set (reg FLAGS_REG)
5814 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5815 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5817 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5818 "ix86_match_ccmode (insn, CCGOCmode)
5819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5821 switch (get_attr_type (insn))
5824 if (operands[2] == const1_rtx)
5825 return "inc{<imodesuffix>}\t%0";
5828 gcc_assert (operands[2] == constm1_rtx);
5829 return "dec{<imodesuffix>}\t%0";
5833 if (which_alternative == 1)
5834 std::swap (operands[1], operands[2]);
5836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5838 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5840 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5844 (if_then_else (match_operand:SWI 2 "incdec_operand")
5845 (const_string "incdec")
5846 (const_string "alu")))
5847 (set (attr "length_immediate")
5849 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5851 (const_string "*")))
5852 (set_attr "mode" "<MODE>")])
5854 (define_insn "addqi_ext_1"
5855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5860 (match_operand 1 "ext_register_operand" "0,0")
5863 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5864 (clobber (reg:CC FLAGS_REG))]
5867 switch (get_attr_type (insn))
5870 if (operands[2] == const1_rtx)
5871 return "inc{b}\t%h0";
5874 gcc_assert (operands[2] == constm1_rtx);
5875 return "dec{b}\t%h0";
5879 return "add{b}\t{%2, %h0|%h0, %2}";
5882 [(set_attr "isa" "*,nox64")
5884 (if_then_else (match_operand:QI 2 "incdec_operand")
5885 (const_string "incdec")
5886 (const_string "alu")))
5887 (set_attr "modrm" "1")
5888 (set_attr "mode" "QI")])
5890 (define_insn "*addqi_ext_2"
5891 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5896 (match_operand 1 "ext_register_operand" "%0")
5900 (match_operand 2 "ext_register_operand" "Q")
5903 (clobber (reg:CC FLAGS_REG))]
5905 "add{b}\t{%h2, %h0|%h0, %h2}"
5906 [(set_attr "type" "alu")
5907 (set_attr "mode" "QI")])
5909 ;; Add with jump on overflow.
5910 (define_expand "addv<mode>4"
5911 [(parallel [(set (reg:CCO FLAGS_REG)
5914 (match_operand:SWI 1 "nonimmediate_operand"))
5917 (plus:SWI (match_dup 1)
5918 (match_operand:SWI 2
5919 "<general_operand>")))))
5920 (set (match_operand:SWI 0 "register_operand")
5921 (plus:SWI (match_dup 1) (match_dup 2)))])
5922 (set (pc) (if_then_else
5923 (eq (reg:CCO FLAGS_REG) (const_int 0))
5924 (label_ref (match_operand 3))
5928 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5929 if (CONST_INT_P (operands[2]))
5930 operands[4] = operands[2];
5932 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5935 (define_insn "*addv<mode>4"
5936 [(set (reg:CCO FLAGS_REG)
5939 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5941 (match_operand:SWI 2 "<general_sext_operand>"
5944 (plus:SWI (match_dup 1) (match_dup 2)))))
5945 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5946 (plus:SWI (match_dup 1) (match_dup 2)))]
5947 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5948 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5949 [(set_attr "type" "alu")
5950 (set_attr "mode" "<MODE>")])
5952 (define_insn "*addv<mode>4_1"
5953 [(set (reg:CCO FLAGS_REG)
5956 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5957 (match_operand:<DWI> 3 "const_int_operand" "i"))
5959 (plus:SWI (match_dup 1)
5960 (match_operand:SWI 2 "x86_64_immediate_operand"
5962 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5963 (plus:SWI (match_dup 1) (match_dup 2)))]
5964 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5965 && CONST_INT_P (operands[2])
5966 && INTVAL (operands[2]) == INTVAL (operands[3])"
5967 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5968 [(set_attr "type" "alu")
5969 (set_attr "mode" "<MODE>")
5970 (set (attr "length_immediate")
5971 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5973 (match_test "<MODE_SIZE> == 8")
5975 (const_string "<MODE_SIZE>")))])
5977 ;; The lea patterns for modes less than 32 bits need to be matched by
5978 ;; several insns converted to real lea by splitters.
5980 (define_insn_and_split "*lea_general_1"
5981 [(set (match_operand 0 "register_operand" "=r")
5982 (plus (plus (match_operand 1 "index_register_operand" "l")
5983 (match_operand 2 "register_operand" "r"))
5984 (match_operand 3 "immediate_operand" "i")))]
5985 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5986 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5987 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5988 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5989 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5990 || GET_MODE (operands[3]) == VOIDmode)"
5992 "&& reload_completed"
5995 machine_mode mode = SImode;
5998 operands[0] = gen_lowpart (mode, operands[0]);
5999 operands[1] = gen_lowpart (mode, operands[1]);
6000 operands[2] = gen_lowpart (mode, operands[2]);
6001 operands[3] = gen_lowpart (mode, operands[3]);
6003 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6006 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6009 [(set_attr "type" "lea")
6010 (set_attr "mode" "SI")])
6012 (define_insn_and_split "*lea_general_2"
6013 [(set (match_operand 0 "register_operand" "=r")
6014 (plus (mult (match_operand 1 "index_register_operand" "l")
6015 (match_operand 2 "const248_operand" "n"))
6016 (match_operand 3 "nonmemory_operand" "ri")))]
6017 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021 || GET_MODE (operands[3]) == VOIDmode)"
6023 "&& reload_completed"
6026 machine_mode mode = SImode;
6029 operands[0] = gen_lowpart (mode, operands[0]);
6030 operands[1] = gen_lowpart (mode, operands[1]);
6031 operands[3] = gen_lowpart (mode, operands[3]);
6033 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6039 [(set_attr "type" "lea")
6040 (set_attr "mode" "SI")])
6042 (define_insn_and_split "*lea_general_3"
6043 [(set (match_operand 0 "register_operand" "=r")
6044 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6045 (match_operand 2 "const248_operand" "n"))
6046 (match_operand 3 "register_operand" "r"))
6047 (match_operand 4 "immediate_operand" "i")))]
6048 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6049 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6050 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6051 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6053 "&& reload_completed"
6056 machine_mode mode = SImode;
6059 operands[0] = gen_lowpart (mode, operands[0]);
6060 operands[1] = gen_lowpart (mode, operands[1]);
6061 operands[3] = gen_lowpart (mode, operands[3]);
6062 operands[4] = gen_lowpart (mode, operands[4]);
6064 pat = gen_rtx_PLUS (mode,
6066 gen_rtx_MULT (mode, operands[1],
6071 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6074 [(set_attr "type" "lea")
6075 (set_attr "mode" "SI")])
6077 (define_insn_and_split "*lea_general_4"
6078 [(set (match_operand 0 "register_operand" "=r")
6080 (match_operand 1 "index_register_operand" "l")
6081 (match_operand 2 "const_int_operand" "n"))
6082 (match_operand 3 "const_int_operand" "n")))]
6083 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6084 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6085 || GET_MODE (operands[0]) == SImode
6086 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6087 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6088 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6089 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6090 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6092 "&& reload_completed"
6095 machine_mode mode = GET_MODE (operands[0]);
6098 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6101 operands[0] = gen_lowpart (mode, operands[0]);
6102 operands[1] = gen_lowpart (mode, operands[1]);
6105 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6107 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6108 INTVAL (operands[3]));
6110 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6113 [(set_attr "type" "lea")
6115 (if_then_else (match_operand:DI 0)
6117 (const_string "SI")))])
6119 ;; Subtract instructions
6121 (define_expand "sub<mode>3"
6122 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6123 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6124 (match_operand:SDWIM 2 "<general_operand>")))]
6126 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6128 (define_insn_and_split "*sub<dwi>3_doubleword"
6129 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6131 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6132 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6137 [(parallel [(set (reg:CC FLAGS_REG)
6138 (compare:CC (match_dup 1) (match_dup 2)))
6140 (minus:DWIH (match_dup 1) (match_dup 2)))])
6141 (parallel [(set (match_dup 3)
6145 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6147 (clobber (reg:CC FLAGS_REG))])]
6148 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6150 (define_insn "*sub<mode>_1"
6151 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6153 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6154 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6155 (clobber (reg:CC FLAGS_REG))]
6156 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6157 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6158 [(set_attr "type" "alu")
6159 (set_attr "mode" "<MODE>")])
6161 (define_insn "*subsi_1_zext"
6162 [(set (match_operand:DI 0 "register_operand" "=r")
6164 (minus:SI (match_operand:SI 1 "register_operand" "0")
6165 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6166 (clobber (reg:CC FLAGS_REG))]
6167 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6168 "sub{l}\t{%2, %k0|%k0, %2}"
6169 [(set_attr "type" "alu")
6170 (set_attr "mode" "SI")])
6172 (define_insn "*subqi_1_slp"
6173 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6174 (minus:QI (match_dup 0)
6175 (match_operand:QI 1 "general_operand" "qn,qm")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6178 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6179 "sub{b}\t{%1, %0|%0, %1}"
6180 [(set_attr "type" "alu1")
6181 (set_attr "mode" "QI")])
6183 (define_insn "*sub<mode>_2"
6184 [(set (reg FLAGS_REG)
6187 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6188 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6190 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6191 (minus:SWI (match_dup 1) (match_dup 2)))]
6192 "ix86_match_ccmode (insn, CCGOCmode)
6193 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6194 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6195 [(set_attr "type" "alu")
6196 (set_attr "mode" "<MODE>")])
6198 (define_insn "*subsi_2_zext"
6199 [(set (reg FLAGS_REG)
6201 (minus:SI (match_operand:SI 1 "register_operand" "0")
6202 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6204 (set (match_operand:DI 0 "register_operand" "=r")
6206 (minus:SI (match_dup 1)
6208 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6209 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6210 "sub{l}\t{%2, %k0|%k0, %2}"
6211 [(set_attr "type" "alu")
6212 (set_attr "mode" "SI")])
6214 ;; Subtract with jump on overflow.
6215 (define_expand "subv<mode>4"
6216 [(parallel [(set (reg:CCO FLAGS_REG)
6217 (eq:CCO (minus:<DWI>
6219 (match_operand:SWI 1 "nonimmediate_operand"))
6222 (minus:SWI (match_dup 1)
6223 (match_operand:SWI 2
6224 "<general_operand>")))))
6225 (set (match_operand:SWI 0 "register_operand")
6226 (minus:SWI (match_dup 1) (match_dup 2)))])
6227 (set (pc) (if_then_else
6228 (eq (reg:CCO FLAGS_REG) (const_int 0))
6229 (label_ref (match_operand 3))
6233 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6234 if (CONST_INT_P (operands[2]))
6235 operands[4] = operands[2];
6237 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6240 (define_insn "*subv<mode>4"
6241 [(set (reg:CCO FLAGS_REG)
6242 (eq:CCO (minus:<DWI>
6244 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6246 (match_operand:SWI 2 "<general_sext_operand>"
6249 (minus:SWI (match_dup 1) (match_dup 2)))))
6250 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6251 (minus:SWI (match_dup 1) (match_dup 2)))]
6252 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6253 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6254 [(set_attr "type" "alu")
6255 (set_attr "mode" "<MODE>")])
6257 (define_insn "*subv<mode>4_1"
6258 [(set (reg:CCO FLAGS_REG)
6259 (eq:CCO (minus:<DWI>
6261 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6262 (match_operand:<DWI> 3 "const_int_operand" "i"))
6264 (minus:SWI (match_dup 1)
6265 (match_operand:SWI 2 "x86_64_immediate_operand"
6267 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6268 (minus:SWI (match_dup 1) (match_dup 2)))]
6269 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6270 && CONST_INT_P (operands[2])
6271 && INTVAL (operands[2]) == INTVAL (operands[3])"
6272 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6273 [(set_attr "type" "alu")
6274 (set_attr "mode" "<MODE>")
6275 (set (attr "length_immediate")
6276 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6278 (match_test "<MODE_SIZE> == 8")
6280 (const_string "<MODE_SIZE>")))])
6282 (define_insn "*sub<mode>_3"
6283 [(set (reg FLAGS_REG)
6284 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6285 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6286 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6287 (minus:SWI (match_dup 1) (match_dup 2)))]
6288 "ix86_match_ccmode (insn, CCmode)
6289 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6290 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6291 [(set_attr "type" "alu")
6292 (set_attr "mode" "<MODE>")])
6294 (define_insn "*subsi_3_zext"
6295 [(set (reg FLAGS_REG)
6296 (compare (match_operand:SI 1 "register_operand" "0")
6297 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6298 (set (match_operand:DI 0 "register_operand" "=r")
6300 (minus:SI (match_dup 1)
6302 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6303 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6304 "sub{l}\t{%2, %1|%1, %2}"
6305 [(set_attr "type" "alu")
6306 (set_attr "mode" "SI")])
6308 ;; Add with carry and subtract with borrow
6310 (define_expand "<plusminus_insn><mode>3_carry"
6312 [(set (match_operand:SWI 0 "nonimmediate_operand")
6314 (match_operand:SWI 1 "nonimmediate_operand")
6315 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6316 [(match_operand 3 "flags_reg_operand")
6318 (match_operand:SWI 2 "<general_operand>"))))
6319 (clobber (reg:CC FLAGS_REG))])]
6320 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6322 (define_insn "*<plusminus_insn><mode>3_carry"
6323 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6325 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6327 (match_operator 3 "ix86_carry_flag_operator"
6328 [(reg FLAGS_REG) (const_int 0)])
6329 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6330 (clobber (reg:CC FLAGS_REG))]
6331 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6332 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6333 [(set_attr "type" "alu")
6334 (set_attr "use_carry" "1")
6335 (set_attr "pent_pair" "pu")
6336 (set_attr "mode" "<MODE>")])
6338 (define_insn "*addsi3_carry_zext"
6339 [(set (match_operand:DI 0 "register_operand" "=r")
6341 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6342 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6343 [(reg FLAGS_REG) (const_int 0)])
6344 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6345 (clobber (reg:CC FLAGS_REG))]
6346 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6347 "adc{l}\t{%2, %k0|%k0, %2}"
6348 [(set_attr "type" "alu")
6349 (set_attr "use_carry" "1")
6350 (set_attr "pent_pair" "pu")
6351 (set_attr "mode" "SI")])
6353 (define_insn "*subsi3_carry_zext"
6354 [(set (match_operand:DI 0 "register_operand" "=r")
6356 (minus:SI (match_operand:SI 1 "register_operand" "0")
6357 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6358 [(reg FLAGS_REG) (const_int 0)])
6359 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6360 (clobber (reg:CC FLAGS_REG))]
6361 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6362 "sbb{l}\t{%2, %k0|%k0, %2}"
6363 [(set_attr "type" "alu")
6364 (set_attr "pent_pair" "pu")
6365 (set_attr "mode" "SI")])
6369 (define_insn "adcx<mode>3"
6370 [(set (reg:CCC FLAGS_REG)
6373 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6375 (match_operator 4 "ix86_carry_flag_operator"
6376 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6377 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6379 (set (match_operand:SWI48 0 "register_operand" "=r")
6380 (plus:SWI48 (match_dup 1)
6381 (plus:SWI48 (match_op_dup 4
6382 [(match_dup 3) (const_int 0)])
6384 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6385 "adcx\t{%2, %0|%0, %2}"
6386 [(set_attr "type" "alu")
6387 (set_attr "use_carry" "1")
6388 (set_attr "mode" "<MODE>")])
6390 ;; Overflow setting add instructions
6392 (define_insn "*add<mode>3_cconly_overflow"
6393 [(set (reg:CCC FLAGS_REG)
6396 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6397 (match_operand:SWI 2 "<general_operand>" "<g>"))
6399 (clobber (match_scratch:SWI 0 "=<r>"))]
6400 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6401 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "<MODE>")])
6405 (define_insn "*add<mode>3_cc_overflow"
6406 [(set (reg:CCC FLAGS_REG)
6409 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6410 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6412 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6413 (plus:SWI (match_dup 1) (match_dup 2)))]
6414 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6415 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6419 (define_insn "*addsi3_zext_cc_overflow"
6420 [(set (reg:CCC FLAGS_REG)
6423 (match_operand:SI 1 "nonimmediate_operand" "%0")
6424 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6426 (set (match_operand:DI 0 "register_operand" "=r")
6427 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6428 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6429 "add{l}\t{%2, %k0|%k0, %2}"
6430 [(set_attr "type" "alu")
6431 (set_attr "mode" "SI")])
6433 ;; The patterns that match these are at the end of this file.
6435 (define_expand "<plusminus_insn>xf3"
6436 [(set (match_operand:XF 0 "register_operand")
6438 (match_operand:XF 1 "register_operand")
6439 (match_operand:XF 2 "register_operand")))]
6442 (define_expand "<plusminus_insn><mode>3"
6443 [(set (match_operand:MODEF 0 "register_operand")
6445 (match_operand:MODEF 1 "register_operand")
6446 (match_operand:MODEF 2 "nonimmediate_operand")))]
6447 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6450 ;; Multiply instructions
6452 (define_expand "mul<mode>3"
6453 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6455 (match_operand:SWIM248 1 "register_operand")
6456 (match_operand:SWIM248 2 "<general_operand>")))
6457 (clobber (reg:CC FLAGS_REG))])])
6459 (define_expand "mulqi3"
6460 [(parallel [(set (match_operand:QI 0 "register_operand")
6462 (match_operand:QI 1 "register_operand")
6463 (match_operand:QI 2 "nonimmediate_operand")))
6464 (clobber (reg:CC FLAGS_REG))])]
6465 "TARGET_QIMODE_MATH")
6468 ;; IMUL reg32/64, reg32/64, imm8 Direct
6469 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6470 ;; IMUL reg32/64, reg32/64, imm32 Direct
6471 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6472 ;; IMUL reg32/64, reg32/64 Direct
6473 ;; IMUL reg32/64, mem32/64 Direct
6475 ;; On BDVER1, all above IMULs use DirectPath
6477 (define_insn "*mul<mode>3_1"
6478 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6480 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6481 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6482 (clobber (reg:CC FLAGS_REG))]
6483 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6485 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6486 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6487 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6488 [(set_attr "type" "imul")
6489 (set_attr "prefix_0f" "0,0,1")
6490 (set (attr "athlon_decode")
6491 (cond [(eq_attr "cpu" "athlon")
6492 (const_string "vector")
6493 (eq_attr "alternative" "1")
6494 (const_string "vector")
6495 (and (eq_attr "alternative" "2")
6496 (match_operand 1 "memory_operand"))
6497 (const_string "vector")]
6498 (const_string "direct")))
6499 (set (attr "amdfam10_decode")
6500 (cond [(and (eq_attr "alternative" "0,1")
6501 (match_operand 1 "memory_operand"))
6502 (const_string "vector")]
6503 (const_string "direct")))
6504 (set_attr "bdver1_decode" "direct")
6505 (set_attr "mode" "<MODE>")])
6507 (define_insn "*mulsi3_1_zext"
6508 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6510 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6511 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6512 (clobber (reg:CC FLAGS_REG))]
6514 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6516 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6517 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6518 imul{l}\t{%2, %k0|%k0, %2}"
6519 [(set_attr "type" "imul")
6520 (set_attr "prefix_0f" "0,0,1")
6521 (set (attr "athlon_decode")
6522 (cond [(eq_attr "cpu" "athlon")
6523 (const_string "vector")
6524 (eq_attr "alternative" "1")
6525 (const_string "vector")
6526 (and (eq_attr "alternative" "2")
6527 (match_operand 1 "memory_operand"))
6528 (const_string "vector")]
6529 (const_string "direct")))
6530 (set (attr "amdfam10_decode")
6531 (cond [(and (eq_attr "alternative" "0,1")
6532 (match_operand 1 "memory_operand"))
6533 (const_string "vector")]
6534 (const_string "direct")))
6535 (set_attr "bdver1_decode" "direct")
6536 (set_attr "mode" "SI")])
6539 ;; IMUL reg16, reg16, imm8 VectorPath
6540 ;; IMUL reg16, mem16, imm8 VectorPath
6541 ;; IMUL reg16, reg16, imm16 VectorPath
6542 ;; IMUL reg16, mem16, imm16 VectorPath
6543 ;; IMUL reg16, reg16 Direct
6544 ;; IMUL reg16, mem16 Direct
6546 ;; On BDVER1, all HI MULs use DoublePath
6548 (define_insn "*mulhi3_1"
6549 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6550 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6551 (match_operand:HI 2 "general_operand" "K,n,mr")))
6552 (clobber (reg:CC FLAGS_REG))]
6554 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6556 imul{w}\t{%2, %1, %0|%0, %1, %2}
6557 imul{w}\t{%2, %1, %0|%0, %1, %2}
6558 imul{w}\t{%2, %0|%0, %2}"
6559 [(set_attr "type" "imul")
6560 (set_attr "prefix_0f" "0,0,1")
6561 (set (attr "athlon_decode")
6562 (cond [(eq_attr "cpu" "athlon")
6563 (const_string "vector")
6564 (eq_attr "alternative" "1,2")
6565 (const_string "vector")]
6566 (const_string "direct")))
6567 (set (attr "amdfam10_decode")
6568 (cond [(eq_attr "alternative" "0,1")
6569 (const_string "vector")]
6570 (const_string "direct")))
6571 (set_attr "bdver1_decode" "double")
6572 (set_attr "mode" "HI")])
6574 ;;On AMDFAM10 and BDVER1
6578 (define_insn "*mulqi3_1"
6579 [(set (match_operand:QI 0 "register_operand" "=a")
6580 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6581 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6582 (clobber (reg:CC FLAGS_REG))]
6584 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6586 [(set_attr "type" "imul")
6587 (set_attr "length_immediate" "0")
6588 (set (attr "athlon_decode")
6589 (if_then_else (eq_attr "cpu" "athlon")
6590 (const_string "vector")
6591 (const_string "direct")))
6592 (set_attr "amdfam10_decode" "direct")
6593 (set_attr "bdver1_decode" "direct")
6594 (set_attr "mode" "QI")])
6596 ;; Multiply with jump on overflow.
6597 (define_expand "mulv<mode>4"
6598 [(parallel [(set (reg:CCO FLAGS_REG)
6601 (match_operand:SWI48 1 "register_operand"))
6604 (mult:SWI48 (match_dup 1)
6605 (match_operand:SWI48 2
6606 "<general_operand>")))))
6607 (set (match_operand:SWI48 0 "register_operand")
6608 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6609 (set (pc) (if_then_else
6610 (eq (reg:CCO FLAGS_REG) (const_int 0))
6611 (label_ref (match_operand 3))
6615 if (CONST_INT_P (operands[2]))
6616 operands[4] = operands[2];
6618 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6621 (define_insn "*mulv<mode>4"
6622 [(set (reg:CCO FLAGS_REG)
6625 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6627 (match_operand:SWI48 2 "<general_sext_operand>"
6630 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6631 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6632 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6633 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6635 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6636 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6637 [(set_attr "type" "imul")
6638 (set_attr "prefix_0f" "0,1")
6639 (set (attr "athlon_decode")
6640 (cond [(eq_attr "cpu" "athlon")
6641 (const_string "vector")
6642 (eq_attr "alternative" "0")
6643 (const_string "vector")
6644 (and (eq_attr "alternative" "1")
6645 (match_operand 1 "memory_operand"))
6646 (const_string "vector")]
6647 (const_string "direct")))
6648 (set (attr "amdfam10_decode")
6649 (cond [(and (eq_attr "alternative" "1")
6650 (match_operand 1 "memory_operand"))
6651 (const_string "vector")]
6652 (const_string "direct")))
6653 (set_attr "bdver1_decode" "direct")
6654 (set_attr "mode" "<MODE>")])
6656 (define_insn "*mulv<mode>4_1"
6657 [(set (reg:CCO FLAGS_REG)
6660 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6661 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6663 (mult:SWI48 (match_dup 1)
6664 (match_operand:SWI 2 "x86_64_immediate_operand"
6666 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6667 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6668 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6669 && CONST_INT_P (operands[2])
6670 && INTVAL (operands[2]) == INTVAL (operands[3])"
6672 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6673 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6674 [(set_attr "type" "imul")
6675 (set (attr "athlon_decode")
6676 (cond [(eq_attr "cpu" "athlon")
6677 (const_string "vector")
6678 (eq_attr "alternative" "1")
6679 (const_string "vector")]
6680 (const_string "direct")))
6681 (set (attr "amdfam10_decode")
6682 (cond [(match_operand 1 "memory_operand")
6683 (const_string "vector")]
6684 (const_string "direct")))
6685 (set_attr "bdver1_decode" "direct")
6686 (set_attr "mode" "<MODE>")
6687 (set (attr "length_immediate")
6688 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6690 (match_test "<MODE_SIZE> == 8")
6692 (const_string "<MODE_SIZE>")))])
6694 (define_expand "umulv<mode>4"
6695 [(parallel [(set (reg:CCO FLAGS_REG)
6698 (match_operand:SWI48 1
6699 "nonimmediate_operand"))
6701 (match_operand:SWI48 2
6702 "nonimmediate_operand")))
6704 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6705 (set (match_operand:SWI48 0 "register_operand")
6706 (mult:SWI48 (match_dup 1) (match_dup 2)))
6707 (clobber (match_scratch:SWI48 4))])
6708 (set (pc) (if_then_else
6709 (eq (reg:CCO FLAGS_REG) (const_int 0))
6710 (label_ref (match_operand 3))
6714 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6715 operands[1] = force_reg (<MODE>mode, operands[1]);
6718 (define_insn "*umulv<mode>4"
6719 [(set (reg:CCO FLAGS_REG)
6722 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6724 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6726 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6727 (set (match_operand:SWI48 0 "register_operand" "=a")
6728 (mult:SWI48 (match_dup 1) (match_dup 2)))
6729 (clobber (match_scratch:SWI48 3 "=d"))]
6730 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6731 "mul{<imodesuffix>}\t%2"
6732 [(set_attr "type" "imul")
6733 (set_attr "length_immediate" "0")
6734 (set (attr "athlon_decode")
6735 (if_then_else (eq_attr "cpu" "athlon")
6736 (const_string "vector")
6737 (const_string "double")))
6738 (set_attr "amdfam10_decode" "double")
6739 (set_attr "bdver1_decode" "direct")
6740 (set_attr "mode" "<MODE>")])
6742 (define_expand "<u>mulvqi4"
6743 [(parallel [(set (reg:CCO FLAGS_REG)
6746 (match_operand:QI 1 "nonimmediate_operand"))
6748 (match_operand:QI 2 "nonimmediate_operand")))
6750 (mult:QI (match_dup 1) (match_dup 2)))))
6751 (set (match_operand:QI 0 "register_operand")
6752 (mult:QI (match_dup 1) (match_dup 2)))])
6753 (set (pc) (if_then_else
6754 (eq (reg:CCO FLAGS_REG) (const_int 0))
6755 (label_ref (match_operand 3))
6757 "TARGET_QIMODE_MATH"
6759 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6760 operands[1] = force_reg (QImode, operands[1]);
6763 (define_insn "*<u>mulvqi4"
6764 [(set (reg:CCO FLAGS_REG)
6767 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6769 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6771 (mult:QI (match_dup 1) (match_dup 2)))))
6772 (set (match_operand:QI 0 "register_operand" "=a")
6773 (mult:QI (match_dup 1) (match_dup 2)))]
6775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776 "<sgnprefix>mul{b}\t%2"
6777 [(set_attr "type" "imul")
6778 (set_attr "length_immediate" "0")
6779 (set (attr "athlon_decode")
6780 (if_then_else (eq_attr "cpu" "athlon")
6781 (const_string "vector")
6782 (const_string "direct")))
6783 (set_attr "amdfam10_decode" "direct")
6784 (set_attr "bdver1_decode" "direct")
6785 (set_attr "mode" "QI")])
6787 (define_expand "<u>mul<mode><dwi>3"
6788 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6791 (match_operand:DWIH 1 "nonimmediate_operand"))
6793 (match_operand:DWIH 2 "register_operand"))))
6794 (clobber (reg:CC FLAGS_REG))])])
6796 (define_expand "<u>mulqihi3"
6797 [(parallel [(set (match_operand:HI 0 "register_operand")
6800 (match_operand:QI 1 "nonimmediate_operand"))
6802 (match_operand:QI 2 "register_operand"))))
6803 (clobber (reg:CC FLAGS_REG))])]
6804 "TARGET_QIMODE_MATH")
6806 (define_insn "*bmi2_umul<mode><dwi>3_1"
6807 [(set (match_operand:DWIH 0 "register_operand" "=r")
6809 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6810 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6811 (set (match_operand:DWIH 1 "register_operand" "=r")
6814 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6815 (zero_extend:<DWI> (match_dup 3)))
6816 (match_operand:QI 4 "const_int_operand" "n"))))]
6817 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6818 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6819 "mulx\t{%3, %0, %1|%1, %0, %3}"
6820 [(set_attr "type" "imulx")
6821 (set_attr "prefix" "vex")
6822 (set_attr "mode" "<MODE>")])
6824 (define_insn "*umul<mode><dwi>3_1"
6825 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6828 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6830 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6835 mul{<imodesuffix>}\t%2"
6836 [(set_attr "isa" "bmi2,*")
6837 (set_attr "type" "imulx,imul")
6838 (set_attr "length_immediate" "*,0")
6839 (set (attr "athlon_decode")
6840 (cond [(eq_attr "alternative" "1")
6841 (if_then_else (eq_attr "cpu" "athlon")
6842 (const_string "vector")
6843 (const_string "double"))]
6844 (const_string "*")))
6845 (set_attr "amdfam10_decode" "*,double")
6846 (set_attr "bdver1_decode" "*,direct")
6847 (set_attr "prefix" "vex,orig")
6848 (set_attr "mode" "<MODE>")])
6850 ;; Convert mul to the mulx pattern to avoid flags dependency.
6852 [(set (match_operand:<DWI> 0 "register_operand")
6855 (match_operand:DWIH 1 "register_operand"))
6857 (match_operand:DWIH 2 "nonimmediate_operand"))))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "TARGET_BMI2 && reload_completed
6860 && true_regnum (operands[1]) == DX_REG"
6861 [(parallel [(set (match_dup 3)
6862 (mult:DWIH (match_dup 1) (match_dup 2)))
6866 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6867 (zero_extend:<DWI> (match_dup 2)))
6870 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6872 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6875 (define_insn "*mul<mode><dwi>3_1"
6876 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6879 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6881 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884 "imul{<imodesuffix>}\t%2"
6885 [(set_attr "type" "imul")
6886 (set_attr "length_immediate" "0")
6887 (set (attr "athlon_decode")
6888 (if_then_else (eq_attr "cpu" "athlon")
6889 (const_string "vector")
6890 (const_string "double")))
6891 (set_attr "amdfam10_decode" "double")
6892 (set_attr "bdver1_decode" "direct")
6893 (set_attr "mode" "<MODE>")])
6895 (define_insn "*<u>mulqihi3_1"
6896 [(set (match_operand:HI 0 "register_operand" "=a")
6899 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6901 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6902 (clobber (reg:CC FLAGS_REG))]
6904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6905 "<sgnprefix>mul{b}\t%2"
6906 [(set_attr "type" "imul")
6907 (set_attr "length_immediate" "0")
6908 (set (attr "athlon_decode")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "direct")))
6912 (set_attr "amdfam10_decode" "direct")
6913 (set_attr "bdver1_decode" "direct")
6914 (set_attr "mode" "QI")])
6916 (define_expand "<s>mul<mode>3_highpart"
6917 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6922 (match_operand:SWI48 1 "nonimmediate_operand"))
6924 (match_operand:SWI48 2 "register_operand")))
6926 (clobber (match_scratch:SWI48 3))
6927 (clobber (reg:CC FLAGS_REG))])]
6929 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6931 (define_insn "*<s>muldi3_highpart_1"
6932 [(set (match_operand:DI 0 "register_operand" "=d")
6937 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6939 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6941 (clobber (match_scratch:DI 3 "=1"))
6942 (clobber (reg:CC FLAGS_REG))]
6944 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945 "<sgnprefix>mul{q}\t%2"
6946 [(set_attr "type" "imul")
6947 (set_attr "length_immediate" "0")
6948 (set (attr "athlon_decode")
6949 (if_then_else (eq_attr "cpu" "athlon")
6950 (const_string "vector")
6951 (const_string "double")))
6952 (set_attr "amdfam10_decode" "double")
6953 (set_attr "bdver1_decode" "direct")
6954 (set_attr "mode" "DI")])
6956 (define_insn "*<s>mulsi3_highpart_1"
6957 [(set (match_operand:SI 0 "register_operand" "=d")
6962 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6964 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6966 (clobber (match_scratch:SI 3 "=1"))
6967 (clobber (reg:CC FLAGS_REG))]
6968 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6969 "<sgnprefix>mul{l}\t%2"
6970 [(set_attr "type" "imul")
6971 (set_attr "length_immediate" "0")
6972 (set (attr "athlon_decode")
6973 (if_then_else (eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (const_string "double")))
6976 (set_attr "amdfam10_decode" "double")
6977 (set_attr "bdver1_decode" "direct")
6978 (set_attr "mode" "SI")])
6980 (define_insn "*<s>mulsi3_highpart_zext"
6981 [(set (match_operand:DI 0 "register_operand" "=d")
6982 (zero_extend:DI (truncate:SI
6984 (mult:DI (any_extend:DI
6985 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6987 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6989 (clobber (match_scratch:SI 3 "=1"))
6990 (clobber (reg:CC FLAGS_REG))]
6992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 "<sgnprefix>mul{l}\t%2"
6994 [(set_attr "type" "imul")
6995 (set_attr "length_immediate" "0")
6996 (set (attr "athlon_decode")
6997 (if_then_else (eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (const_string "double")))
7000 (set_attr "amdfam10_decode" "double")
7001 (set_attr "bdver1_decode" "direct")
7002 (set_attr "mode" "SI")])
7004 ;; The patterns that match these are at the end of this file.
7006 (define_expand "mulxf3"
7007 [(set (match_operand:XF 0 "register_operand")
7008 (mult:XF (match_operand:XF 1 "register_operand")
7009 (match_operand:XF 2 "register_operand")))]
7012 (define_expand "mul<mode>3"
7013 [(set (match_operand:MODEF 0 "register_operand")
7014 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7015 (match_operand:MODEF 2 "nonimmediate_operand")))]
7016 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7017 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7019 ;; Divide instructions
7021 ;; The patterns that match these are at the end of this file.
7023 (define_expand "divxf3"
7024 [(set (match_operand:XF 0 "register_operand")
7025 (div:XF (match_operand:XF 1 "register_operand")
7026 (match_operand:XF 2 "register_operand")))]
7029 (define_expand "divdf3"
7030 [(set (match_operand:DF 0 "register_operand")
7031 (div:DF (match_operand:DF 1 "register_operand")
7032 (match_operand:DF 2 "nonimmediate_operand")))]
7033 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7034 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7036 (define_expand "divsf3"
7037 [(set (match_operand:SF 0 "register_operand")
7038 (div:SF (match_operand:SF 1 "register_operand")
7039 (match_operand:SF 2 "nonimmediate_operand")))]
7040 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7045 && optimize_insn_for_speed_p ()
7046 && flag_finite_math_only && !flag_trapping_math
7047 && flag_unsafe_math_optimizations)
7049 ix86_emit_swdivsf (operands[0], operands[1],
7050 operands[2], SFmode);
7055 ;; Divmod instructions.
7057 (define_expand "divmod<mode>4"
7058 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7060 (match_operand:SWIM248 1 "register_operand")
7061 (match_operand:SWIM248 2 "nonimmediate_operand")))
7062 (set (match_operand:SWIM248 3 "register_operand")
7063 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7064 (clobber (reg:CC FLAGS_REG))])])
7066 ;; Split with 8bit unsigned divide:
7067 ;; if (dividend an divisor are in [0-255])
7068 ;; use 8bit unsigned integer divide
7070 ;; use original integer divide
7072 [(set (match_operand:SWI48 0 "register_operand")
7073 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7074 (match_operand:SWI48 3 "nonimmediate_operand")))
7075 (set (match_operand:SWI48 1 "register_operand")
7076 (mod:SWI48 (match_dup 2) (match_dup 3)))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "TARGET_USE_8BIT_IDIV
7079 && TARGET_QIMODE_MATH
7080 && can_create_pseudo_p ()
7081 && !optimize_insn_for_size_p ()"
7083 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7085 (define_insn_and_split "divmod<mode>4_1"
7086 [(set (match_operand:SWI48 0 "register_operand" "=a")
7087 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7088 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7089 (set (match_operand:SWI48 1 "register_operand" "=&d")
7090 (mod:SWI48 (match_dup 2) (match_dup 3)))
7091 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7092 (clobber (reg:CC FLAGS_REG))]
7096 [(parallel [(set (match_dup 1)
7097 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7098 (clobber (reg:CC FLAGS_REG))])
7099 (parallel [(set (match_dup 0)
7100 (div:SWI48 (match_dup 2) (match_dup 3)))
7102 (mod:SWI48 (match_dup 2) (match_dup 3)))
7104 (clobber (reg:CC FLAGS_REG))])]
7106 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7108 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7109 operands[4] = operands[2];
7112 /* Avoid use of cltd in favor of a mov+shift. */
7113 emit_move_insn (operands[1], operands[2]);
7114 operands[4] = operands[1];
7117 [(set_attr "type" "multi")
7118 (set_attr "mode" "<MODE>")])
7120 (define_insn_and_split "*divmod<mode>4"
7121 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7122 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7123 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7124 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7125 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7126 (clobber (reg:CC FLAGS_REG))]
7130 [(parallel [(set (match_dup 1)
7131 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7132 (clobber (reg:CC FLAGS_REG))])
7133 (parallel [(set (match_dup 0)
7134 (div:SWIM248 (match_dup 2) (match_dup 3)))
7136 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7138 (clobber (reg:CC FLAGS_REG))])]
7140 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7142 if (<MODE>mode != HImode
7143 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7144 operands[4] = operands[2];
7147 /* Avoid use of cltd in favor of a mov+shift. */
7148 emit_move_insn (operands[1], operands[2]);
7149 operands[4] = operands[1];
7152 [(set_attr "type" "multi")
7153 (set_attr "mode" "<MODE>")])
7155 (define_insn "*divmod<mode>4_noext"
7156 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7157 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7158 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7159 (set (match_operand:SWIM248 1 "register_operand" "=d")
7160 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7161 (use (match_operand:SWIM248 4 "register_operand" "1"))
7162 (clobber (reg:CC FLAGS_REG))]
7164 "idiv{<imodesuffix>}\t%3"
7165 [(set_attr "type" "idiv")
7166 (set_attr "mode" "<MODE>")])
7168 (define_expand "divmodqi4"
7169 [(parallel [(set (match_operand:QI 0 "register_operand")
7171 (match_operand:QI 1 "register_operand")
7172 (match_operand:QI 2 "nonimmediate_operand")))
7173 (set (match_operand:QI 3 "register_operand")
7174 (mod:QI (match_dup 1) (match_dup 2)))
7175 (clobber (reg:CC FLAGS_REG))])]
7176 "TARGET_QIMODE_MATH"
7181 tmp0 = gen_reg_rtx (HImode);
7182 tmp1 = gen_reg_rtx (HImode);
7184 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7186 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7187 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7189 /* Extract remainder from AH. */
7190 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7191 insn = emit_move_insn (operands[3], tmp1);
7193 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7194 set_unique_reg_note (insn, REG_EQUAL, mod);
7196 /* Extract quotient from AL. */
7197 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7199 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7200 set_unique_reg_note (insn, REG_EQUAL, div);
7205 ;; Divide AX by r/m8, with result stored in
7208 ;; Change div/mod to HImode and extend the second argument to HImode
7209 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7210 ;; combine may fail.
7211 (define_insn "divmodhiqi3"
7212 [(set (match_operand:HI 0 "register_operand" "=a")
7217 (mod:HI (match_operand:HI 1 "register_operand" "0")
7219 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7223 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7224 (clobber (reg:CC FLAGS_REG))]
7225 "TARGET_QIMODE_MATH"
7227 [(set_attr "type" "idiv")
7228 (set_attr "mode" "QI")])
7230 (define_expand "udivmod<mode>4"
7231 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7233 (match_operand:SWIM248 1 "register_operand")
7234 (match_operand:SWIM248 2 "nonimmediate_operand")))
7235 (set (match_operand:SWIM248 3 "register_operand")
7236 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7237 (clobber (reg:CC FLAGS_REG))])])
7239 ;; Split with 8bit unsigned divide:
7240 ;; if (dividend an divisor are in [0-255])
7241 ;; use 8bit unsigned integer divide
7243 ;; use original integer divide
7245 [(set (match_operand:SWI48 0 "register_operand")
7246 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7247 (match_operand:SWI48 3 "nonimmediate_operand")))
7248 (set (match_operand:SWI48 1 "register_operand")
7249 (umod:SWI48 (match_dup 2) (match_dup 3)))
7250 (clobber (reg:CC FLAGS_REG))]
7251 "TARGET_USE_8BIT_IDIV
7252 && TARGET_QIMODE_MATH
7253 && can_create_pseudo_p ()
7254 && !optimize_insn_for_size_p ()"
7256 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7258 (define_insn_and_split "udivmod<mode>4_1"
7259 [(set (match_operand:SWI48 0 "register_operand" "=a")
7260 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7261 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWI48 1 "register_operand" "=&d")
7263 (umod:SWI48 (match_dup 2) (match_dup 3)))
7264 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7265 (clobber (reg:CC FLAGS_REG))]
7269 [(set (match_dup 1) (const_int 0))
7270 (parallel [(set (match_dup 0)
7271 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7273 (umod:SWI48 (match_dup 2) (match_dup 3)))
7275 (clobber (reg:CC FLAGS_REG))])]
7277 [(set_attr "type" "multi")
7278 (set_attr "mode" "<MODE>")])
7280 (define_insn_and_split "*udivmod<mode>4"
7281 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7282 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7283 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7284 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7285 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7286 (clobber (reg:CC FLAGS_REG))]
7290 [(set (match_dup 1) (const_int 0))
7291 (parallel [(set (match_dup 0)
7292 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7294 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7296 (clobber (reg:CC FLAGS_REG))])]
7298 [(set_attr "type" "multi")
7299 (set_attr "mode" "<MODE>")])
7301 ;; Optimize division or modulo by constant power of 2, if the constant
7302 ;; materializes only after expansion.
7303 (define_insn_and_split "*udivmod<mode>4_pow2"
7304 [(set (match_operand:SWI48 0 "register_operand" "=r")
7305 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7306 (match_operand:SWI48 3 "const_int_operand" "n")))
7307 (set (match_operand:SWI48 1 "register_operand" "=r")
7308 (umod:SWI48 (match_dup 2) (match_dup 3)))
7309 (clobber (reg:CC FLAGS_REG))]
7310 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7311 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7314 [(set (match_dup 1) (match_dup 2))
7315 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7316 (clobber (reg:CC FLAGS_REG))])
7317 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7318 (clobber (reg:CC FLAGS_REG))])]
7320 int v = exact_log2 (UINTVAL (operands[3]));
7321 operands[4] = GEN_INT (v);
7322 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7324 [(set_attr "type" "multi")
7325 (set_attr "mode" "<MODE>")])
7327 (define_insn "*udivmod<mode>4_noext"
7328 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7329 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7330 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7331 (set (match_operand:SWIM248 1 "register_operand" "=d")
7332 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7333 (use (match_operand:SWIM248 4 "register_operand" "1"))
7334 (clobber (reg:CC FLAGS_REG))]
7336 "div{<imodesuffix>}\t%3"
7337 [(set_attr "type" "idiv")
7338 (set_attr "mode" "<MODE>")])
7340 (define_expand "udivmodqi4"
7341 [(parallel [(set (match_operand:QI 0 "register_operand")
7343 (match_operand:QI 1 "register_operand")
7344 (match_operand:QI 2 "nonimmediate_operand")))
7345 (set (match_operand:QI 3 "register_operand")
7346 (umod:QI (match_dup 1) (match_dup 2)))
7347 (clobber (reg:CC FLAGS_REG))])]
7348 "TARGET_QIMODE_MATH"
7353 tmp0 = gen_reg_rtx (HImode);
7354 tmp1 = gen_reg_rtx (HImode);
7356 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7358 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7359 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7361 /* Extract remainder from AH. */
7362 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7363 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7364 insn = emit_move_insn (operands[3], tmp1);
7366 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7367 set_unique_reg_note (insn, REG_EQUAL, mod);
7369 /* Extract quotient from AL. */
7370 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7372 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7373 set_unique_reg_note (insn, REG_EQUAL, div);
7378 (define_insn "udivmodhiqi3"
7379 [(set (match_operand:HI 0 "register_operand" "=a")
7384 (mod:HI (match_operand:HI 1 "register_operand" "0")
7386 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7390 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7391 (clobber (reg:CC FLAGS_REG))]
7392 "TARGET_QIMODE_MATH"
7394 [(set_attr "type" "idiv")
7395 (set_attr "mode" "QI")])
7397 ;; We cannot use div/idiv for double division, because it causes
7398 ;; "division by zero" on the overflow and that's not what we expect
7399 ;; from truncate. Because true (non truncating) double division is
7400 ;; never generated, we can't create this insn anyway.
7403 ; [(set (match_operand:SI 0 "register_operand" "=a")
7405 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7407 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7408 ; (set (match_operand:SI 3 "register_operand" "=d")
7410 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7411 ; (clobber (reg:CC FLAGS_REG))]
7413 ; "div{l}\t{%2, %0|%0, %2}"
7414 ; [(set_attr "type" "idiv")])
7416 ;;- Logical AND instructions
7418 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7419 ;; Note that this excludes ah.
7421 (define_expand "testsi_ccno_1"
7422 [(set (reg:CCNO FLAGS_REG)
7424 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7425 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7428 (define_expand "testqi_ccz_1"
7429 [(set (reg:CCZ FLAGS_REG)
7430 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7431 (match_operand:QI 1 "nonmemory_operand"))
7434 (define_expand "testdi_ccno_1"
7435 [(set (reg:CCNO FLAGS_REG)
7437 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7438 (match_operand:DI 1 "x86_64_szext_general_operand"))
7440 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7442 (define_insn "*testdi_1"
7443 [(set (reg FLAGS_REG)
7446 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7447 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7449 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7452 test{l}\t{%k1, %k0|%k0, %k1}
7453 test{l}\t{%k1, %k0|%k0, %k1}
7454 test{q}\t{%1, %0|%0, %1}
7455 test{q}\t{%1, %0|%0, %1}
7456 test{q}\t{%1, %0|%0, %1}"
7457 [(set_attr "type" "test")
7458 (set_attr "modrm" "0,1,0,1,1")
7459 (set_attr "mode" "SI,SI,DI,DI,DI")])
7461 (define_insn "*testqi_1_maybe_si"
7462 [(set (reg FLAGS_REG)
7465 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7466 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7468 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7469 && ix86_match_ccmode (insn,
7470 CONST_INT_P (operands[1])
7471 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7473 if (which_alternative == 3)
7475 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7476 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7477 return "test{l}\t{%1, %k0|%k0, %1}";
7479 return "test{b}\t{%1, %0|%0, %1}";
7481 [(set_attr "type" "test")
7482 (set_attr "modrm" "0,1,1,1")
7483 (set_attr "mode" "QI,QI,QI,SI")
7484 (set_attr "pent_pair" "uv,np,uv,np")])
7486 (define_insn "*test<mode>_1"
7487 [(set (reg FLAGS_REG)
7490 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7491 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7493 "ix86_match_ccmode (insn, CCNOmode)
7494 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7495 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7496 [(set_attr "type" "test")
7497 (set_attr "modrm" "0,1,1")
7498 (set_attr "mode" "<MODE>")
7499 (set_attr "pent_pair" "uv,np,uv")])
7501 (define_expand "testqi_ext_ccno_0"
7502 [(set (reg:CCNO FLAGS_REG)
7506 (match_operand 0 "ext_register_operand")
7509 (match_operand 1 "const_int_operand"))
7512 (define_insn "*testqi_ext_0"
7513 [(set (reg FLAGS_REG)
7517 (match_operand 0 "ext_register_operand" "Q")
7520 (match_operand 1 "const_int_operand" "n"))
7522 "ix86_match_ccmode (insn, CCNOmode)"
7523 "test{b}\t{%1, %h0|%h0, %1}"
7524 [(set_attr "type" "test")
7525 (set_attr "mode" "QI")
7526 (set_attr "length_immediate" "1")
7527 (set_attr "modrm" "1")
7528 (set_attr "pent_pair" "np")])
7530 (define_insn "*testqi_ext_1"
7531 [(set (reg FLAGS_REG)
7535 (match_operand 0 "ext_register_operand" "Q,Q")
7539 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7541 "ix86_match_ccmode (insn, CCNOmode)"
7542 "test{b}\t{%1, %h0|%h0, %1}"
7543 [(set_attr "isa" "*,nox64")
7544 (set_attr "type" "test")
7545 (set_attr "mode" "QI")])
7547 (define_insn "*testqi_ext_2"
7548 [(set (reg FLAGS_REG)
7552 (match_operand 0 "ext_register_operand" "Q")
7556 (match_operand 1 "ext_register_operand" "Q")
7560 "ix86_match_ccmode (insn, CCNOmode)"
7561 "test{b}\t{%h1, %h0|%h0, %h1}"
7562 [(set_attr "type" "test")
7563 (set_attr "mode" "QI")])
7565 ;; Combine likes to form bit extractions for some tests. Humor it.
7566 (define_insn "*testqi_ext_3"
7567 [(set (reg FLAGS_REG)
7568 (compare (zero_extract:SWI48
7569 (match_operand 0 "nonimmediate_operand" "rm")
7570 (match_operand:SWI48 1 "const_int_operand")
7571 (match_operand:SWI48 2 "const_int_operand"))
7573 "ix86_match_ccmode (insn, CCNOmode)
7574 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7575 || GET_MODE (operands[0]) == SImode
7576 || GET_MODE (operands[0]) == HImode
7577 || GET_MODE (operands[0]) == QImode)
7578 /* Ensure that resulting mask is zero or sign extended operand. */
7579 && INTVAL (operands[2]) >= 0
7580 && ((INTVAL (operands[1]) > 0
7581 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7582 || (<MODE>mode == DImode
7583 && INTVAL (operands[1]) > 32
7584 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7588 [(set (match_operand 0 "flags_reg_operand")
7589 (match_operator 1 "compare_operator"
7591 (match_operand 2 "nonimmediate_operand")
7592 (match_operand 3 "const_int_operand")
7593 (match_operand 4 "const_int_operand"))
7595 "ix86_match_ccmode (insn, CCNOmode)"
7596 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7598 rtx val = operands[2];
7599 HOST_WIDE_INT len = INTVAL (operands[3]);
7600 HOST_WIDE_INT pos = INTVAL (operands[4]);
7602 machine_mode mode, submode;
7604 mode = GET_MODE (val);
7607 /* ??? Combine likes to put non-volatile mem extractions in QImode
7608 no matter the size of the test. So find a mode that works. */
7609 if (! MEM_VOLATILE_P (val))
7611 mode = smallest_mode_for_size (pos + len, MODE_INT);
7612 val = adjust_address (val, mode, 0);
7615 else if (GET_CODE (val) == SUBREG
7616 && (submode = GET_MODE (SUBREG_REG (val)),
7617 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7618 && pos + len <= GET_MODE_BITSIZE (submode)
7619 && GET_MODE_CLASS (submode) == MODE_INT)
7621 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7623 val = SUBREG_REG (val);
7625 else if (mode == HImode && pos + len <= 8)
7627 /* Small HImode tests can be converted to QImode. */
7629 val = gen_lowpart (QImode, val);
7632 if (len == HOST_BITS_PER_WIDE_INT)
7635 mask = ((HOST_WIDE_INT)1 << len) - 1;
7638 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7641 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7642 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7643 ;; this is relatively important trick.
7644 ;; Do the conversion only post-reload to avoid limiting of the register class
7647 [(set (match_operand 0 "flags_reg_operand")
7648 (match_operator 1 "compare_operator"
7649 [(and (match_operand 2 "QIreg_operand")
7650 (match_operand 3 "const_int_operand"))
7653 && GET_MODE (operands[2]) != QImode
7654 && ((ix86_match_ccmode (insn, CCZmode)
7655 && !(INTVAL (operands[3]) & ~(255 << 8)))
7656 || (ix86_match_ccmode (insn, CCNOmode)
7657 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7660 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7664 operands[2] = gen_lowpart (SImode, operands[2]);
7665 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7669 [(set (match_operand 0 "flags_reg_operand")
7670 (match_operator 1 "compare_operator"
7671 [(and (match_operand 2 "nonimmediate_operand")
7672 (match_operand 3 "const_int_operand"))
7675 && GET_MODE (operands[2]) != QImode
7676 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7677 && ((ix86_match_ccmode (insn, CCZmode)
7678 && !(INTVAL (operands[3]) & ~255))
7679 || (ix86_match_ccmode (insn, CCNOmode)
7680 && !(INTVAL (operands[3]) & ~127)))"
7682 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7685 operands[2] = gen_lowpart (QImode, operands[2]);
7686 operands[3] = gen_lowpart (QImode, operands[3]);
7690 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7691 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7692 (match_operand:SWI1248x 2 "mask_reg_operand")))
7693 (clobber (reg:CC FLAGS_REG))]
7694 "TARGET_AVX512F && reload_completed"
7696 (any_logic:SWI1248x (match_dup 1)
7699 (define_insn "*k<logic><mode>"
7700 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7701 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7702 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7705 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7706 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7708 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7710 [(set_attr "mode" "<MODE>")
7711 (set_attr "type" "msklog")
7712 (set_attr "prefix" "vex")])
7714 ;; %%% This used to optimize known byte-wide and operations to memory,
7715 ;; and sometimes to QImode registers. If this is considered useful,
7716 ;; it should be done with splitters.
7718 (define_expand "and<mode>3"
7719 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7720 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7721 (match_operand:SWIM 2 "<general_szext_operand>")))]
7724 machine_mode mode = <MODE>mode;
7725 rtx (*insn) (rtx, rtx);
7727 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7729 HOST_WIDE_INT ival = INTVAL (operands[2]);
7731 if (ival == (HOST_WIDE_INT) 0xffffffff)
7733 else if (ival == 0xffff)
7735 else if (ival == 0xff)
7739 if (mode == <MODE>mode)
7741 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7745 if (<MODE>mode == DImode)
7746 insn = (mode == SImode)
7747 ? gen_zero_extendsidi2
7749 ? gen_zero_extendhidi2
7750 : gen_zero_extendqidi2;
7751 else if (<MODE>mode == SImode)
7752 insn = (mode == HImode)
7753 ? gen_zero_extendhisi2
7754 : gen_zero_extendqisi2;
7755 else if (<MODE>mode == HImode)
7756 insn = gen_zero_extendqihi2;
7760 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7764 (define_insn "*anddi_1"
7765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7767 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7768 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7769 (clobber (reg:CC FLAGS_REG))]
7770 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7772 switch (get_attr_type (insn))
7778 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7781 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7782 if (get_attr_mode (insn) == MODE_SI)
7783 return "and{l}\t{%k2, %k0|%k0, %k2}";
7785 return "and{q}\t{%2, %0|%0, %2}";
7788 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7789 (set_attr "length_immediate" "*,*,*,0,0")
7790 (set (attr "prefix_rex")
7792 (and (eq_attr "type" "imovx")
7793 (and (match_test "INTVAL (operands[2]) == 0xff")
7794 (match_operand 1 "ext_QIreg_operand")))
7796 (const_string "*")))
7797 (set_attr "mode" "SI,DI,DI,SI,DI")])
7799 (define_insn "*andsi_1"
7800 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7801 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7802 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7803 (clobber (reg:CC FLAGS_REG))]
7804 "ix86_binary_operator_ok (AND, SImode, operands)"
7806 switch (get_attr_type (insn))
7812 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816 return "and{l}\t{%2, %0|%0, %2}";
7819 [(set_attr "type" "alu,alu,imovx,msklog")
7820 (set (attr "prefix_rex")
7822 (and (eq_attr "type" "imovx")
7823 (and (match_test "INTVAL (operands[2]) == 0xff")
7824 (match_operand 1 "ext_QIreg_operand")))
7826 (const_string "*")))
7827 (set_attr "length_immediate" "*,*,0,0")
7828 (set_attr "mode" "SI")])
7830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7831 (define_insn "*andsi_1_zext"
7832 [(set (match_operand:DI 0 "register_operand" "=r")
7834 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7835 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7838 "and{l}\t{%2, %k0|%k0, %2}"
7839 [(set_attr "type" "alu")
7840 (set_attr "mode" "SI")])
7842 (define_insn "*andhi_1"
7843 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7844 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7845 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7846 (clobber (reg:CC FLAGS_REG))]
7847 "ix86_binary_operator_ok (AND, HImode, operands)"
7849 switch (get_attr_type (insn))
7855 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7859 return "and{w}\t{%2, %0|%0, %2}";
7862 [(set_attr "type" "alu,alu,imovx,msklog")
7863 (set_attr "length_immediate" "*,*,0,*")
7864 (set (attr "prefix_rex")
7866 (and (eq_attr "type" "imovx")
7867 (match_operand 1 "ext_QIreg_operand"))
7869 (const_string "*")))
7870 (set_attr "mode" "HI,HI,SI,HI")])
7872 ;; %%% Potential partial reg stall on alternative 2. What to do?
7873 (define_insn "*andqi_1"
7874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7875 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7876 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "ix86_binary_operator_ok (AND, QImode, operands)"
7880 switch (which_alternative)
7884 return "and{b}\t{%2, %0|%0, %2}";
7886 return "and{l}\t{%k2, %k0|%k0, %k2}";
7888 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7889 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7894 [(set_attr "type" "alu,alu,alu,msklog")
7895 (set_attr "mode" "QI,QI,SI,HI")])
7897 (define_insn "*andqi_1_slp"
7898 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7899 (and:QI (match_dup 0)
7900 (match_operand:QI 1 "general_operand" "qn,qmn")))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7904 "and{b}\t{%1, %0|%0, %1}"
7905 [(set_attr "type" "alu1")
7906 (set_attr "mode" "QI")])
7908 (define_insn "kandn<mode>"
7909 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7912 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7913 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7914 (clobber (reg:CC FLAGS_REG))]
7917 switch (which_alternative)
7920 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7924 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7925 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7927 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7932 [(set_attr "isa" "bmi,*,avx512f")
7933 (set_attr "type" "bitmanip,*,msklog")
7934 (set_attr "prefix" "*,*,vex")
7935 (set_attr "btver2_decode" "direct,*,*")
7936 (set_attr "mode" "<MODE>")])
7939 [(set (match_operand:SWI12 0 "general_reg_operand")
7943 (match_operand:SWI12 1 "general_reg_operand")))
7944 (clobber (reg:CC FLAGS_REG))]
7945 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7947 (not:HI (match_dup 0)))
7948 (parallel [(set (match_dup 0)
7949 (and:HI (match_dup 0)
7951 (clobber (reg:CC FLAGS_REG))])])
7953 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7955 [(set (match_operand:DI 0 "register_operand")
7956 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7957 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7958 (clobber (reg:CC FLAGS_REG))]
7960 [(parallel [(set (match_dup 0)
7961 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7962 (clobber (reg:CC FLAGS_REG))])]
7963 "operands[2] = gen_lowpart (SImode, operands[2]);")
7966 [(set (match_operand:SWI248 0 "register_operand")
7967 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7968 (match_operand:SWI248 2 "const_int_operand")))
7969 (clobber (reg:CC FLAGS_REG))]
7971 && true_regnum (operands[0]) != true_regnum (operands[1])"
7974 HOST_WIDE_INT ival = INTVAL (operands[2]);
7976 rtx (*insn) (rtx, rtx);
7978 if (ival == (HOST_WIDE_INT) 0xffffffff)
7980 else if (ival == 0xffff)
7984 gcc_assert (ival == 0xff);
7988 if (<MODE>mode == DImode)
7989 insn = (mode == SImode)
7990 ? gen_zero_extendsidi2
7992 ? gen_zero_extendhidi2
7993 : gen_zero_extendqidi2;
7996 if (<MODE>mode != SImode)
7997 /* Zero extend to SImode to avoid partial register stalls. */
7998 operands[0] = gen_lowpart (SImode, operands[0]);
8000 insn = (mode == HImode)
8001 ? gen_zero_extendhisi2
8002 : gen_zero_extendqisi2;
8004 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8009 [(set (match_operand:SWI48 0 "register_operand")
8010 (and:SWI48 (match_dup 0)
8011 (const_int -65536)))
8012 (clobber (reg:CC FLAGS_REG))]
8013 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8014 || optimize_function_for_size_p (cfun)"
8015 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8016 "operands[1] = gen_lowpart (HImode, operands[0]);")
8019 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8020 (and:SWI248 (match_dup 0)
8022 (clobber (reg:CC FLAGS_REG))]
8023 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8024 && reload_completed"
8025 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8026 "operands[1] = gen_lowpart (QImode, operands[0]);")
8029 [(set (match_operand:SWI248 0 "QIreg_operand")
8030 (and:SWI248 (match_dup 0)
8031 (const_int -65281)))
8032 (clobber (reg:CC FLAGS_REG))]
8033 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034 && reload_completed"
8035 [(parallel [(set (zero_extract:SI (match_dup 0)
8039 (zero_extract:SI (match_dup 0)
8042 (zero_extract:SI (match_dup 0)
8045 (clobber (reg:CC FLAGS_REG))])]
8046 "operands[0] = gen_lowpart (SImode, operands[0]);")
8048 (define_insn "*anddi_2"
8049 [(set (reg FLAGS_REG)
8052 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056 (and:DI (match_dup 1) (match_dup 2)))]
8058 && ix86_match_ccmode
8060 /* If we are going to emit andl instead of andq, and the operands[2]
8061 constant might have the SImode sign bit set, make sure the sign
8062 flag isn't tested, because the instruction will set the sign flag
8063 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8064 conservatively assume it might have bit 31 set. */
8065 (satisfies_constraint_Z (operands[2])
8066 && (!CONST_INT_P (operands[2])
8067 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8068 ? CCZmode : CCNOmode)
8069 && ix86_binary_operator_ok (AND, DImode, operands)"
8071 and{l}\t{%k2, %k0|%k0, %k2}
8072 and{q}\t{%2, %0|%0, %2}
8073 and{q}\t{%2, %0|%0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "SI,DI,DI")])
8077 (define_insn "*andqi_2_maybe_si"
8078 [(set (reg FLAGS_REG)
8080 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8081 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8083 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8084 (and:QI (match_dup 1) (match_dup 2)))]
8085 "ix86_binary_operator_ok (AND, QImode, operands)
8086 && ix86_match_ccmode (insn,
8087 CONST_INT_P (operands[2])
8088 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8090 if (which_alternative == 2)
8092 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8093 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8094 return "and{l}\t{%2, %k0|%k0, %2}";
8096 return "and{b}\t{%2, %0|%0, %2}";
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "QI,QI,SI")])
8101 (define_insn "*and<mode>_2"
8102 [(set (reg FLAGS_REG)
8103 (compare (and:SWI124
8104 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8105 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8107 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8108 (and:SWI124 (match_dup 1) (match_dup 2)))]
8109 "ix86_match_ccmode (insn, CCNOmode)
8110 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8111 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8112 [(set_attr "type" "alu")
8113 (set_attr "mode" "<MODE>")])
8115 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8116 (define_insn "*andsi_2_zext"
8117 [(set (reg FLAGS_REG)
8119 (match_operand:SI 1 "nonimmediate_operand" "%0")
8120 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8122 (set (match_operand:DI 0 "register_operand" "=r")
8123 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8124 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8125 && ix86_binary_operator_ok (AND, SImode, operands)"
8126 "and{l}\t{%2, %k0|%k0, %2}"
8127 [(set_attr "type" "alu")
8128 (set_attr "mode" "SI")])
8130 (define_insn "*andqi_2_slp"
8131 [(set (reg FLAGS_REG)
8133 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8134 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8136 (set (strict_low_part (match_dup 0))
8137 (and:QI (match_dup 0) (match_dup 1)))]
8138 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8139 && ix86_match_ccmode (insn, CCNOmode)
8140 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8141 "and{b}\t{%1, %0|%0, %1}"
8142 [(set_attr "type" "alu1")
8143 (set_attr "mode" "QI")])
8145 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8146 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8147 ;; for a QImode operand, which of course failed.
8148 (define_insn "andqi_ext_0"
8149 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8154 (match_operand 1 "ext_register_operand" "0")
8157 (match_operand 2 "const_int_operand" "n")))
8158 (clobber (reg:CC FLAGS_REG))]
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8166 ;; Generated by peephole translating test to and. This shows up
8167 ;; often in fp comparisons.
8168 (define_insn "*andqi_ext_0_cc"
8169 [(set (reg FLAGS_REG)
8173 (match_operand 1 "ext_register_operand" "0")
8176 (match_operand 2 "const_int_operand" "n"))
8178 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8187 "ix86_match_ccmode (insn, CCNOmode)"
8188 "and{b}\t{%2, %h0|%h0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "length_immediate" "1")
8191 (set_attr "modrm" "1")
8192 (set_attr "mode" "QI")])
8194 (define_insn "*andqi_ext_1"
8195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8200 (match_operand 1 "ext_register_operand" "0,0")
8204 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8205 (clobber (reg:CC FLAGS_REG))]
8207 "and{b}\t{%2, %h0|%h0, %2}"
8208 [(set_attr "isa" "*,nox64")
8209 (set_attr "type" "alu")
8210 (set_attr "length_immediate" "0")
8211 (set_attr "mode" "QI")])
8213 (define_insn "*andqi_ext_2"
8214 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8219 (match_operand 1 "ext_register_operand" "%0")
8223 (match_operand 2 "ext_register_operand" "Q")
8226 (clobber (reg:CC FLAGS_REG))]
8228 "and{b}\t{%h2, %h0|%h0, %h2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "length_immediate" "0")
8231 (set_attr "mode" "QI")])
8233 ;; Convert wide AND instructions with immediate operand to shorter QImode
8234 ;; equivalents when possible.
8235 ;; Don't do the splitting with memory operands, since it introduces risk
8236 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8237 ;; for size, but that can (should?) be handled by generic code instead.
8239 [(set (match_operand 0 "QIreg_operand")
8240 (and (match_operand 1 "register_operand")
8241 (match_operand 2 "const_int_operand")))
8242 (clobber (reg:CC FLAGS_REG))]
8244 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8245 && !(~INTVAL (operands[2]) & ~(255 << 8))
8246 && GET_MODE (operands[0]) != QImode"
8247 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8248 (and:SI (zero_extract:SI (match_dup 1)
8249 (const_int 8) (const_int 8))
8251 (clobber (reg:CC FLAGS_REG))])]
8253 operands[0] = gen_lowpart (SImode, operands[0]);
8254 operands[1] = gen_lowpart (SImode, operands[1]);
8255 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8258 ;; Since AND can be encoded with sign extended immediate, this is only
8259 ;; profitable when 7th bit is not set.
8261 [(set (match_operand 0 "any_QIreg_operand")
8262 (and (match_operand 1 "general_operand")
8263 (match_operand 2 "const_int_operand")))
8264 (clobber (reg:CC FLAGS_REG))]
8266 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8267 && !(~INTVAL (operands[2]) & ~255)
8268 && !(INTVAL (operands[2]) & 128)
8269 && GET_MODE (operands[0]) != QImode"
8270 [(parallel [(set (strict_low_part (match_dup 0))
8271 (and:QI (match_dup 1)
8273 (clobber (reg:CC FLAGS_REG))])]
8275 operands[0] = gen_lowpart (QImode, operands[0]);
8276 operands[1] = gen_lowpart (QImode, operands[1]);
8277 operands[2] = gen_lowpart (QImode, operands[2]);
8280 ;; Logical inclusive and exclusive OR instructions
8282 ;; %%% This used to optimize known byte-wide and operations to memory.
8283 ;; If this is considered useful, it should be done with splitters.
8285 (define_expand "<code><mode>3"
8286 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8287 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8288 (match_operand:SWIM 2 "<general_operand>")))]
8290 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8292 (define_insn "*<code><mode>_1"
8293 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8295 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8296 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8297 (clobber (reg:CC FLAGS_REG))]
8298 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8300 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8301 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8302 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8303 [(set_attr "type" "alu,alu,msklog")
8304 (set_attr "mode" "<MODE>")])
8306 (define_insn "*<code>hi_1"
8307 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8309 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8310 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8314 <logic>{w}\t{%2, %0|%0, %2}
8315 <logic>{w}\t{%2, %0|%0, %2}
8316 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8317 [(set_attr "type" "alu,alu,msklog")
8318 (set_attr "mode" "HI")])
8320 ;; %%% Potential partial reg stall on alternative 2. What to do?
8321 (define_insn "*<code>qi_1"
8322 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8323 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8324 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8328 <logic>{b}\t{%2, %0|%0, %2}
8329 <logic>{b}\t{%2, %0|%0, %2}
8330 <logic>{l}\t{%k2, %k0|%k0, %k2}
8331 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8332 [(set_attr "type" "alu,alu,alu,msklog")
8333 (set_attr "mode" "QI,QI,SI,HI")])
8335 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8336 (define_insn "*<code>si_1_zext"
8337 [(set (match_operand:DI 0 "register_operand" "=r")
8339 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8340 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8343 "<logic>{l}\t{%2, %k0|%k0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "mode" "SI")])
8347 (define_insn "*<code>si_1_zext_imm"
8348 [(set (match_operand:DI 0 "register_operand" "=r")
8350 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8351 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8352 (clobber (reg:CC FLAGS_REG))]
8353 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8354 "<logic>{l}\t{%2, %k0|%k0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "SI")])
8358 (define_insn "*<code>qi_1_slp"
8359 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8360 (any_or:QI (match_dup 0)
8361 (match_operand:QI 1 "general_operand" "qmn,qn")))
8362 (clobber (reg:CC FLAGS_REG))]
8363 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8365 "<logic>{b}\t{%1, %0|%0, %1}"
8366 [(set_attr "type" "alu1")
8367 (set_attr "mode" "QI")])
8369 (define_insn "*<code><mode>_2"
8370 [(set (reg FLAGS_REG)
8371 (compare (any_or:SWI
8372 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8373 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8375 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8376 (any_or:SWI (match_dup 1) (match_dup 2)))]
8377 "ix86_match_ccmode (insn, CCNOmode)
8378 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8379 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "<MODE>")])
8383 (define_insn "kxnor<mode>"
8384 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8387 (match_operand:SWI12 1 "register_operand" "0,k")
8388 (match_operand:SWI12 2 "register_operand" "r,k"))))
8389 (clobber (reg:CC FLAGS_REG))]
8392 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8393 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8394 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8396 [(set_attr "type" "*,msklog")
8397 (set_attr "prefix" "*,vex")
8398 (set_attr "mode" "<MODE>")])
8400 (define_insn "kxnor<mode>"
8401 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8404 (match_operand:SWI48x 1 "register_operand" "0,k")
8405 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8406 (clobber (reg:CC FLAGS_REG))]
8410 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8411 [(set_attr "type" "*,msklog")
8412 (set_attr "prefix" "*,vex")
8413 (set_attr "mode" "<MODE>")])
8416 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8420 (match_operand:SWI1248x 1 "general_reg_operand"))))
8421 (clobber (reg:CC FLAGS_REG))]
8422 "TARGET_AVX512F && reload_completed"
8423 [(parallel [(set (match_dup 0)
8424 (xor:HI (match_dup 0)
8426 (clobber (reg:CC FLAGS_REG))])
8428 (not:HI (match_dup 0)))])
8430 ;;There are kortrest[bdq] but no intrinsics for them.
8431 ;;We probably don't need to implement them.
8432 (define_insn "kortestzhi"
8433 [(set (reg:CCZ FLAGS_REG)
8436 (match_operand:HI 0 "register_operand" "k")
8437 (match_operand:HI 1 "register_operand" "k"))
8439 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8440 "kortestw\t{%1, %0|%0, %1}"
8441 [(set_attr "mode" "HI")
8442 (set_attr "type" "msklog")
8443 (set_attr "prefix" "vex")])
8445 (define_insn "kortestchi"
8446 [(set (reg:CCC FLAGS_REG)
8449 (match_operand:HI 0 "register_operand" "k")
8450 (match_operand:HI 1 "register_operand" "k"))
8452 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8453 "kortestw\t{%1, %0|%0, %1}"
8454 [(set_attr "mode" "HI")
8455 (set_attr "type" "msklog")
8456 (set_attr "prefix" "vex")])
8458 (define_insn "kunpckhi"
8459 [(set (match_operand:HI 0 "register_operand" "=k")
8462 (match_operand:HI 1 "register_operand" "k")
8464 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8466 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8467 [(set_attr "mode" "HI")
8468 (set_attr "type" "msklog")
8469 (set_attr "prefix" "vex")])
8471 (define_insn "kunpcksi"
8472 [(set (match_operand:SI 0 "register_operand" "=k")
8475 (match_operand:SI 1 "register_operand" "k")
8477 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8479 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8480 [(set_attr "mode" "SI")])
8482 (define_insn "kunpckdi"
8483 [(set (match_operand:DI 0 "register_operand" "=k")
8486 (match_operand:DI 1 "register_operand" "k")
8488 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8490 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8491 [(set_attr "mode" "DI")])
8493 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8494 ;; ??? Special case for immediate operand is missing - it is tricky.
8495 (define_insn "*<code>si_2_zext"
8496 [(set (reg FLAGS_REG)
8497 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8498 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8500 (set (match_operand:DI 0 "register_operand" "=r")
8501 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8502 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8503 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8504 "<logic>{l}\t{%2, %k0|%k0, %2}"
8505 [(set_attr "type" "alu")
8506 (set_attr "mode" "SI")])
8508 (define_insn "*<code>si_2_zext_imm"
8509 [(set (reg FLAGS_REG)
8511 (match_operand:SI 1 "nonimmediate_operand" "%0")
8512 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8516 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8517 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8518 "<logic>{l}\t{%2, %k0|%k0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "SI")])
8522 (define_insn "*<code>qi_2_slp"
8523 [(set (reg FLAGS_REG)
8524 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8525 (match_operand:QI 1 "general_operand" "qmn,qn"))
8527 (set (strict_low_part (match_dup 0))
8528 (any_or:QI (match_dup 0) (match_dup 1)))]
8529 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8530 && ix86_match_ccmode (insn, CCNOmode)
8531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8532 "<logic>{b}\t{%1, %0|%0, %1}"
8533 [(set_attr "type" "alu1")
8534 (set_attr "mode" "QI")])
8536 (define_insn "*<code><mode>_3"
8537 [(set (reg FLAGS_REG)
8538 (compare (any_or:SWI
8539 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8540 (match_operand:SWI 2 "<general_operand>" "<g>"))
8542 (clobber (match_scratch:SWI 0 "=<r>"))]
8543 "ix86_match_ccmode (insn, CCNOmode)
8544 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8545 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8546 [(set_attr "type" "alu")
8547 (set_attr "mode" "<MODE>")])
8549 (define_insn "*<code>qi_ext_0"
8550 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8555 (match_operand 1 "ext_register_operand" "0")
8558 (match_operand 2 "const_int_operand" "n")))
8559 (clobber (reg:CC FLAGS_REG))]
8560 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8561 "<logic>{b}\t{%2, %h0|%h0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "length_immediate" "1")
8564 (set_attr "modrm" "1")
8565 (set_attr "mode" "QI")])
8567 (define_insn "*<code>qi_ext_1"
8568 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8573 (match_operand 1 "ext_register_operand" "0,0")
8577 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8578 (clobber (reg:CC FLAGS_REG))]
8579 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8580 "<logic>{b}\t{%2, %h0|%h0, %2}"
8581 [(set_attr "isa" "*,nox64")
8582 (set_attr "type" "alu")
8583 (set_attr "length_immediate" "0")
8584 (set_attr "mode" "QI")])
8586 (define_insn "*<code>qi_ext_2"
8587 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8591 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8594 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8597 (clobber (reg:CC FLAGS_REG))]
8598 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8599 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8600 [(set_attr "type" "alu")
8601 (set_attr "length_immediate" "0")
8602 (set_attr "mode" "QI")])
8605 [(set (match_operand 0 "QIreg_operand")
8606 (any_or (match_operand 1 "register_operand")
8607 (match_operand 2 "const_int_operand")))
8608 (clobber (reg:CC FLAGS_REG))]
8610 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8611 && !(INTVAL (operands[2]) & ~(255 << 8))
8612 && GET_MODE (operands[0]) != QImode"
8613 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8614 (any_or:SI (zero_extract:SI (match_dup 1)
8615 (const_int 8) (const_int 8))
8617 (clobber (reg:CC FLAGS_REG))])]
8619 operands[0] = gen_lowpart (SImode, operands[0]);
8620 operands[1] = gen_lowpart (SImode, operands[1]);
8621 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8624 ;; Since OR can be encoded with sign extended immediate, this is only
8625 ;; profitable when 7th bit is set.
8627 [(set (match_operand 0 "any_QIreg_operand")
8628 (any_or (match_operand 1 "general_operand")
8629 (match_operand 2 "const_int_operand")))
8630 (clobber (reg:CC FLAGS_REG))]
8632 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8633 && !(INTVAL (operands[2]) & ~255)
8634 && (INTVAL (operands[2]) & 128)
8635 && GET_MODE (operands[0]) != QImode"
8636 [(parallel [(set (strict_low_part (match_dup 0))
8637 (any_or:QI (match_dup 1)
8639 (clobber (reg:CC FLAGS_REG))])]
8641 operands[0] = gen_lowpart (QImode, operands[0]);
8642 operands[1] = gen_lowpart (QImode, operands[1]);
8643 operands[2] = gen_lowpart (QImode, operands[2]);
8646 (define_expand "xorqi_cc_ext_1"
8648 (set (reg:CCNO FLAGS_REG)
8652 (match_operand 1 "ext_register_operand")
8655 (match_operand:QI 2 "const_int_operand"))
8657 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8667 (define_insn "*xorqi_cc_ext_1"
8668 [(set (reg FLAGS_REG)
8672 (match_operand 1 "ext_register_operand" "0,0")
8675 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8677 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8686 "ix86_match_ccmode (insn, CCNOmode)"
8687 "xor{b}\t{%2, %h0|%h0, %2}"
8688 [(set_attr "isa" "*,nox64")
8689 (set_attr "type" "alu")
8690 (set_attr "modrm" "1")
8691 (set_attr "mode" "QI")])
8693 ;; Negation instructions
8695 (define_expand "neg<mode>2"
8696 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8697 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8699 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8701 (define_insn_and_split "*neg<dwi>2_doubleword"
8702 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8703 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8704 (clobber (reg:CC FLAGS_REG))]
8705 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8709 [(set (reg:CCZ FLAGS_REG)
8710 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8711 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8714 (plus:DWIH (match_dup 3)
8715 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8717 (clobber (reg:CC FLAGS_REG))])
8720 (neg:DWIH (match_dup 2)))
8721 (clobber (reg:CC FLAGS_REG))])]
8722 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8724 (define_insn "*neg<mode>2_1"
8725 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8726 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8727 (clobber (reg:CC FLAGS_REG))]
8728 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8729 "neg{<imodesuffix>}\t%0"
8730 [(set_attr "type" "negnot")
8731 (set_attr "mode" "<MODE>")])
8733 ;; Combine is quite creative about this pattern.
8734 (define_insn "*negsi2_1_zext"
8735 [(set (match_operand:DI 0 "register_operand" "=r")
8737 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8740 (clobber (reg:CC FLAGS_REG))]
8741 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8743 [(set_attr "type" "negnot")
8744 (set_attr "mode" "SI")])
8746 ;; The problem with neg is that it does not perform (compare x 0),
8747 ;; it really performs (compare 0 x), which leaves us with the zero
8748 ;; flag being the only useful item.
8750 (define_insn "*neg<mode>2_cmpz"
8751 [(set (reg:CCZ FLAGS_REG)
8753 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8755 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8756 (neg:SWI (match_dup 1)))]
8757 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8758 "neg{<imodesuffix>}\t%0"
8759 [(set_attr "type" "negnot")
8760 (set_attr "mode" "<MODE>")])
8762 (define_insn "*negsi2_cmpz_zext"
8763 [(set (reg:CCZ FLAGS_REG)
8767 (match_operand:DI 1 "register_operand" "0")
8771 (set (match_operand:DI 0 "register_operand" "=r")
8772 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8775 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8777 [(set_attr "type" "negnot")
8778 (set_attr "mode" "SI")])
8780 ;; Negate with jump on overflow.
8781 (define_expand "negv<mode>3"
8782 [(parallel [(set (reg:CCO FLAGS_REG)
8783 (ne:CCO (match_operand:SWI 1 "register_operand")
8785 (set (match_operand:SWI 0 "register_operand")
8786 (neg:SWI (match_dup 1)))])
8787 (set (pc) (if_then_else
8788 (eq (reg:CCO FLAGS_REG) (const_int 0))
8789 (label_ref (match_operand 2))
8794 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8798 (define_insn "*negv<mode>3"
8799 [(set (reg:CCO FLAGS_REG)
8800 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8801 (match_operand:SWI 2 "const_int_operand")))
8802 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8803 (neg:SWI (match_dup 1)))]
8804 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8805 && mode_signbit_p (<MODE>mode, operands[2])"
8806 "neg{<imodesuffix>}\t%0"
8807 [(set_attr "type" "negnot")
8808 (set_attr "mode" "<MODE>")])
8810 ;; Changing of sign for FP values is doable using integer unit too.
8812 (define_expand "<code><mode>2"
8813 [(set (match_operand:X87MODEF 0 "register_operand")
8814 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8815 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8816 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8818 (define_insn "*absneg<mode>2_mixed"
8819 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8820 (match_operator:MODEF 3 "absneg_operator"
8821 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8822 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8823 (clobber (reg:CC FLAGS_REG))]
8824 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8826 [(set (attr "enabled")
8827 (cond [(eq_attr "alternative" "2")
8828 (symbol_ref "TARGET_MIX_SSE_I387")
8830 (symbol_ref "true")))])
8832 (define_insn "*absneg<mode>2_i387"
8833 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8834 (match_operator:X87MODEF 3 "absneg_operator"
8835 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8836 (use (match_operand 2))
8837 (clobber (reg:CC FLAGS_REG))]
8838 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8841 (define_expand "<code>tf2"
8842 [(set (match_operand:TF 0 "register_operand")
8843 (absneg:TF (match_operand:TF 1 "register_operand")))]
8845 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8847 (define_insn "*absnegtf2_sse"
8848 [(set (match_operand:TF 0 "register_operand" "=x,x")
8849 (match_operator:TF 3 "absneg_operator"
8850 [(match_operand:TF 1 "register_operand" "0,x")]))
8851 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8852 (clobber (reg:CC FLAGS_REG))]
8856 ;; Splitters for fp abs and neg.
8859 [(set (match_operand 0 "fp_register_operand")
8860 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8861 (use (match_operand 2))
8862 (clobber (reg:CC FLAGS_REG))]
8864 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8867 [(set (match_operand 0 "register_operand")
8868 (match_operator 3 "absneg_operator"
8869 [(match_operand 1 "register_operand")]))
8870 (use (match_operand 2 "nonimmediate_operand"))
8871 (clobber (reg:CC FLAGS_REG))]
8872 "reload_completed && SSE_REG_P (operands[0])"
8873 [(set (match_dup 0) (match_dup 3))]
8875 machine_mode mode = GET_MODE (operands[0]);
8876 machine_mode vmode = GET_MODE (operands[2]);
8879 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8880 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8881 if (operands_match_p (operands[0], operands[2]))
8882 std::swap (operands[1], operands[2]);
8883 if (GET_CODE (operands[3]) == ABS)
8884 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8886 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8891 [(set (match_operand:SF 0 "register_operand")
8892 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8893 (use (match_operand:V4SF 2))
8894 (clobber (reg:CC FLAGS_REG))]
8896 [(parallel [(set (match_dup 0) (match_dup 1))
8897 (clobber (reg:CC FLAGS_REG))])]
8900 operands[0] = gen_lowpart (SImode, operands[0]);
8901 if (GET_CODE (operands[1]) == ABS)
8903 tmp = gen_int_mode (0x7fffffff, SImode);
8904 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8908 tmp = gen_int_mode (0x80000000, SImode);
8909 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8915 [(set (match_operand:DF 0 "register_operand")
8916 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8917 (use (match_operand 2))
8918 (clobber (reg:CC FLAGS_REG))]
8920 [(parallel [(set (match_dup 0) (match_dup 1))
8921 (clobber (reg:CC FLAGS_REG))])]
8926 tmp = gen_lowpart (DImode, operands[0]);
8927 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8930 if (GET_CODE (operands[1]) == ABS)
8933 tmp = gen_rtx_NOT (DImode, tmp);
8937 operands[0] = gen_highpart (SImode, operands[0]);
8938 if (GET_CODE (operands[1]) == ABS)
8940 tmp = gen_int_mode (0x7fffffff, SImode);
8941 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8945 tmp = gen_int_mode (0x80000000, SImode);
8946 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8953 [(set (match_operand:XF 0 "register_operand")
8954 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8955 (use (match_operand 2))
8956 (clobber (reg:CC FLAGS_REG))]
8958 [(parallel [(set (match_dup 0) (match_dup 1))
8959 (clobber (reg:CC FLAGS_REG))])]
8962 operands[0] = gen_rtx_REG (SImode,
8963 true_regnum (operands[0])
8964 + (TARGET_64BIT ? 1 : 2));
8965 if (GET_CODE (operands[1]) == ABS)
8967 tmp = GEN_INT (0x7fff);
8968 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8972 tmp = GEN_INT (0x8000);
8973 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8978 ;; Conditionalize these after reload. If they match before reload, we
8979 ;; lose the clobber and ability to use integer instructions.
8981 (define_insn "*<code><mode>2_1"
8982 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8983 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8985 && (reload_completed
8986 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8987 "f<absneg_mnemonic>"
8988 [(set_attr "type" "fsgn")
8989 (set_attr "mode" "<MODE>")])
8991 (define_insn "*<code>extendsfdf2"
8992 [(set (match_operand:DF 0 "register_operand" "=f")
8993 (absneg:DF (float_extend:DF
8994 (match_operand:SF 1 "register_operand" "0"))))]
8995 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8996 "f<absneg_mnemonic>"
8997 [(set_attr "type" "fsgn")
8998 (set_attr "mode" "DF")])
9000 (define_insn "*<code>extendsfxf2"
9001 [(set (match_operand:XF 0 "register_operand" "=f")
9002 (absneg:XF (float_extend:XF
9003 (match_operand:SF 1 "register_operand" "0"))))]
9005 "f<absneg_mnemonic>"
9006 [(set_attr "type" "fsgn")
9007 (set_attr "mode" "XF")])
9009 (define_insn "*<code>extenddfxf2"
9010 [(set (match_operand:XF 0 "register_operand" "=f")
9011 (absneg:XF (float_extend:XF
9012 (match_operand:DF 1 "register_operand" "0"))))]
9014 "f<absneg_mnemonic>"
9015 [(set_attr "type" "fsgn")
9016 (set_attr "mode" "XF")])
9018 ;; Copysign instructions
9020 (define_mode_iterator CSGNMODE [SF DF TF])
9021 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9023 (define_expand "copysign<mode>3"
9024 [(match_operand:CSGNMODE 0 "register_operand")
9025 (match_operand:CSGNMODE 1 "nonmemory_operand")
9026 (match_operand:CSGNMODE 2 "register_operand")]
9027 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9028 || (TARGET_SSE && (<MODE>mode == TFmode))"
9029 "ix86_expand_copysign (operands); DONE;")
9031 (define_insn_and_split "copysign<mode>3_const"
9032 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9034 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9035 (match_operand:CSGNMODE 2 "register_operand" "0")
9036 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9038 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9039 || (TARGET_SSE && (<MODE>mode == TFmode))"
9041 "&& reload_completed"
9043 "ix86_split_copysign_const (operands); DONE;")
9045 (define_insn "copysign<mode>3_var"
9046 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9048 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9049 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9050 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9051 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9053 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9054 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9055 || (TARGET_SSE && (<MODE>mode == TFmode))"
9059 [(set (match_operand:CSGNMODE 0 "register_operand")
9061 [(match_operand:CSGNMODE 2 "register_operand")
9062 (match_operand:CSGNMODE 3 "register_operand")
9063 (match_operand:<CSGNVMODE> 4)
9064 (match_operand:<CSGNVMODE> 5)]
9066 (clobber (match_scratch:<CSGNVMODE> 1))]
9067 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9068 || (TARGET_SSE && (<MODE>mode == TFmode)))
9069 && reload_completed"
9071 "ix86_split_copysign_var (operands); DONE;")
9073 ;; One complement instructions
9075 (define_expand "one_cmpl<mode>2"
9076 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9077 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9079 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9081 (define_insn "*one_cmpl<mode>2_1"
9082 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9083 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9084 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9086 not{<imodesuffix>}\t%0
9087 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9088 [(set_attr "isa" "*,avx512bw")
9089 (set_attr "type" "negnot,msklog")
9090 (set_attr "prefix" "*,vex")
9091 (set_attr "mode" "<MODE>")])
9093 (define_insn "*one_cmplhi2_1"
9094 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9095 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9096 "ix86_unary_operator_ok (NOT, HImode, operands)"
9099 knotw\t{%1, %0|%0, %1}"
9100 [(set_attr "isa" "*,avx512f")
9101 (set_attr "type" "negnot,msklog")
9102 (set_attr "prefix" "*,vex")
9103 (set_attr "mode" "HI")])
9105 ;; %%% Potential partial reg stall on alternative 1. What to do?
9106 (define_insn "*one_cmplqi2_1"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9108 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9109 "ix86_unary_operator_ok (NOT, QImode, operands)"
9111 switch (which_alternative)
9114 return "not{b}\t%0";
9116 return "not{l}\t%k0";
9118 if (TARGET_AVX512DQ)
9119 return "knotb\t{%1, %0|%0, %1}";
9120 return "knotw\t{%1, %0|%0, %1}";
9125 [(set_attr "isa" "*,*,avx512f")
9126 (set_attr "type" "negnot,negnot,msklog")
9127 (set_attr "prefix" "*,*,vex")
9128 (set_attr "mode" "QI,SI,QI")])
9130 ;; ??? Currently never generated - xor is used instead.
9131 (define_insn "*one_cmplsi2_1_zext"
9132 [(set (match_operand:DI 0 "register_operand" "=r")
9134 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9135 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9137 [(set_attr "type" "negnot")
9138 (set_attr "mode" "SI")])
9140 (define_insn "*one_cmpl<mode>2_2"
9141 [(set (reg FLAGS_REG)
9142 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9144 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9145 (not:SWI (match_dup 1)))]
9146 "ix86_match_ccmode (insn, CCNOmode)
9147 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9149 [(set_attr "type" "alu1")
9150 (set_attr "mode" "<MODE>")])
9153 [(set (match_operand 0 "flags_reg_operand")
9154 (match_operator 2 "compare_operator"
9155 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9157 (set (match_operand:SWI 1 "nonimmediate_operand")
9158 (not:SWI (match_dup 3)))]
9159 "ix86_match_ccmode (insn, CCNOmode)"
9160 [(parallel [(set (match_dup 0)
9161 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9164 (xor:SWI (match_dup 3) (const_int -1)))])])
9166 ;; ??? Currently never generated - xor is used instead.
9167 (define_insn "*one_cmplsi2_2_zext"
9168 [(set (reg FLAGS_REG)
9169 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9171 (set (match_operand:DI 0 "register_operand" "=r")
9172 (zero_extend:DI (not:SI (match_dup 1))))]
9173 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9174 && ix86_unary_operator_ok (NOT, SImode, operands)"
9176 [(set_attr "type" "alu1")
9177 (set_attr "mode" "SI")])
9180 [(set (match_operand 0 "flags_reg_operand")
9181 (match_operator 2 "compare_operator"
9182 [(not:SI (match_operand:SI 3 "register_operand"))
9184 (set (match_operand:DI 1 "register_operand")
9185 (zero_extend:DI (not:SI (match_dup 3))))]
9186 "ix86_match_ccmode (insn, CCNOmode)"
9187 [(parallel [(set (match_dup 0)
9188 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9191 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9193 ;; Shift instructions
9195 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9196 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9197 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9198 ;; from the assembler input.
9200 ;; This instruction shifts the target reg/mem as usual, but instead of
9201 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9202 ;; is a left shift double, bits are taken from the high order bits of
9203 ;; reg, else if the insn is a shift right double, bits are taken from the
9204 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9205 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9207 ;; Since sh[lr]d does not change the `reg' operand, that is done
9208 ;; separately, making all shifts emit pairs of shift double and normal
9209 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9210 ;; support a 63 bit shift, each shift where the count is in a reg expands
9211 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9213 ;; If the shift count is a constant, we need never emit more than one
9214 ;; shift pair, instead using moves and sign extension for counts greater
9217 (define_expand "ashl<mode>3"
9218 [(set (match_operand:SDWIM 0 "<shift_operand>")
9219 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9220 (match_operand:QI 2 "nonmemory_operand")))]
9222 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9224 (define_insn "*ashl<mode>3_doubleword"
9225 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9226 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9227 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9228 (clobber (reg:CC FLAGS_REG))]
9231 [(set_attr "type" "multi")])
9234 [(set (match_operand:DWI 0 "register_operand")
9235 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9236 (match_operand:QI 2 "nonmemory_operand")))
9237 (clobber (reg:CC FLAGS_REG))]
9238 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9240 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9242 ;; By default we don't ask for a scratch register, because when DWImode
9243 ;; values are manipulated, registers are already at a premium. But if
9244 ;; we have one handy, we won't turn it away.
9247 [(match_scratch:DWIH 3 "r")
9248 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9250 (match_operand:<DWI> 1 "nonmemory_operand")
9251 (match_operand:QI 2 "nonmemory_operand")))
9252 (clobber (reg:CC FLAGS_REG))])
9256 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9258 (define_insn "x86_64_shld"
9259 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9260 (ior:DI (ashift:DI (match_dup 0)
9261 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9262 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9263 (minus:QI (const_int 64) (match_dup 2)))))
9264 (clobber (reg:CC FLAGS_REG))]
9266 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9267 [(set_attr "type" "ishift")
9268 (set_attr "prefix_0f" "1")
9269 (set_attr "mode" "DI")
9270 (set_attr "athlon_decode" "vector")
9271 (set_attr "amdfam10_decode" "vector")
9272 (set_attr "bdver1_decode" "vector")])
9274 (define_insn "x86_shld"
9275 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9276 (ior:SI (ashift:SI (match_dup 0)
9277 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9278 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9279 (minus:QI (const_int 32) (match_dup 2)))))
9280 (clobber (reg:CC FLAGS_REG))]
9282 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9283 [(set_attr "type" "ishift")
9284 (set_attr "prefix_0f" "1")
9285 (set_attr "mode" "SI")
9286 (set_attr "pent_pair" "np")
9287 (set_attr "athlon_decode" "vector")
9288 (set_attr "amdfam10_decode" "vector")
9289 (set_attr "bdver1_decode" "vector")])
9291 (define_expand "x86_shift<mode>_adj_1"
9292 [(set (reg:CCZ FLAGS_REG)
9293 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9296 (set (match_operand:SWI48 0 "register_operand")
9297 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9298 (match_operand:SWI48 1 "register_operand")
9301 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9302 (match_operand:SWI48 3 "register_operand")
9305 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9307 (define_expand "x86_shift<mode>_adj_2"
9308 [(use (match_operand:SWI48 0 "register_operand"))
9309 (use (match_operand:SWI48 1 "register_operand"))
9310 (use (match_operand:QI 2 "register_operand"))]
9313 rtx_code_label *label = gen_label_rtx ();
9316 emit_insn (gen_testqi_ccz_1 (operands[2],
9317 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9319 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9320 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9321 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9322 gen_rtx_LABEL_REF (VOIDmode, label),
9324 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9325 JUMP_LABEL (tmp) = label;
9327 emit_move_insn (operands[0], operands[1]);
9328 ix86_expand_clear (operands[1]);
9331 LABEL_NUSES (label) = 1;
9336 ;; Avoid useless masking of count operand.
9337 (define_insn "*ashl<mode>3_mask"
9338 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9340 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9343 (match_operand:SI 2 "register_operand" "c")
9344 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9345 (clobber (reg:CC FLAGS_REG))]
9346 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9347 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9348 == GET_MODE_BITSIZE (<MODE>mode)-1"
9350 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9352 [(set_attr "type" "ishift")
9353 (set_attr "mode" "<MODE>")])
9355 (define_insn "*bmi2_ashl<mode>3_1"
9356 [(set (match_operand:SWI48 0 "register_operand" "=r")
9357 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9358 (match_operand:SWI48 2 "register_operand" "r")))]
9360 "shlx\t{%2, %1, %0|%0, %1, %2}"
9361 [(set_attr "type" "ishiftx")
9362 (set_attr "mode" "<MODE>")])
9364 (define_insn "*ashl<mode>3_1"
9365 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9366 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9367 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9371 switch (get_attr_type (insn))
9378 gcc_assert (operands[2] == const1_rtx);
9379 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9380 return "add{<imodesuffix>}\t%0, %0";
9383 if (operands[2] == const1_rtx
9384 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9385 return "sal{<imodesuffix>}\t%0";
9387 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9390 [(set_attr "isa" "*,*,bmi2")
9392 (cond [(eq_attr "alternative" "1")
9393 (const_string "lea")
9394 (eq_attr "alternative" "2")
9395 (const_string "ishiftx")
9396 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9397 (match_operand 0 "register_operand"))
9398 (match_operand 2 "const1_operand"))
9399 (const_string "alu")
9401 (const_string "ishift")))
9402 (set (attr "length_immediate")
9404 (ior (eq_attr "type" "alu")
9405 (and (eq_attr "type" "ishift")
9406 (and (match_operand 2 "const1_operand")
9407 (ior (match_test "TARGET_SHIFT1")
9408 (match_test "optimize_function_for_size_p (cfun)")))))
9410 (const_string "*")))
9411 (set_attr "mode" "<MODE>")])
9413 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9415 [(set (match_operand:SWI48 0 "register_operand")
9416 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9417 (match_operand:QI 2 "register_operand")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_BMI2 && reload_completed"
9421 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9422 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9424 (define_insn "*bmi2_ashlsi3_1_zext"
9425 [(set (match_operand:DI 0 "register_operand" "=r")
9427 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9428 (match_operand:SI 2 "register_operand" "r"))))]
9429 "TARGET_64BIT && TARGET_BMI2"
9430 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9431 [(set_attr "type" "ishiftx")
9432 (set_attr "mode" "SI")])
9434 (define_insn "*ashlsi3_1_zext"
9435 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9437 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9438 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9439 (clobber (reg:CC FLAGS_REG))]
9440 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9442 switch (get_attr_type (insn))
9449 gcc_assert (operands[2] == const1_rtx);
9450 return "add{l}\t%k0, %k0";
9453 if (operands[2] == const1_rtx
9454 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9455 return "sal{l}\t%k0";
9457 return "sal{l}\t{%2, %k0|%k0, %2}";
9460 [(set_attr "isa" "*,*,bmi2")
9462 (cond [(eq_attr "alternative" "1")
9463 (const_string "lea")
9464 (eq_attr "alternative" "2")
9465 (const_string "ishiftx")
9466 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9467 (match_operand 2 "const1_operand"))
9468 (const_string "alu")
9470 (const_string "ishift")))
9471 (set (attr "length_immediate")
9473 (ior (eq_attr "type" "alu")
9474 (and (eq_attr "type" "ishift")
9475 (and (match_operand 2 "const1_operand")
9476 (ior (match_test "TARGET_SHIFT1")
9477 (match_test "optimize_function_for_size_p (cfun)")))))
9479 (const_string "*")))
9480 (set_attr "mode" "SI")])
9482 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9484 [(set (match_operand:DI 0 "register_operand")
9486 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9487 (match_operand:QI 2 "register_operand"))))
9488 (clobber (reg:CC FLAGS_REG))]
9489 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9491 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9492 "operands[2] = gen_lowpart (SImode, operands[2]);")
9494 (define_insn "*ashlhi3_1"
9495 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9496 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9497 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9501 switch (get_attr_type (insn))
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{w}\t%0, %0";
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{w}\t%0";
9515 return "sal{w}\t{%2, %0|%0, %2}";
9519 (cond [(eq_attr "alternative" "1")
9520 (const_string "lea")
9521 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9522 (match_operand 0 "register_operand"))
9523 (match_operand 2 "const1_operand"))
9524 (const_string "alu")
9526 (const_string "ishift")))
9527 (set (attr "length_immediate")
9529 (ior (eq_attr "type" "alu")
9530 (and (eq_attr "type" "ishift")
9531 (and (match_operand 2 "const1_operand")
9532 (ior (match_test "TARGET_SHIFT1")
9533 (match_test "optimize_function_for_size_p (cfun)")))))
9535 (const_string "*")))
9536 (set_attr "mode" "HI,SI")])
9538 ;; %%% Potential partial reg stall on alternative 1. What to do?
9539 (define_insn "*ashlqi3_1"
9540 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9541 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9542 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9546 switch (get_attr_type (insn))
9552 gcc_assert (operands[2] == const1_rtx);
9553 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9554 return "add{l}\t%k0, %k0";
9556 return "add{b}\t%0, %0";
9559 if (operands[2] == const1_rtx
9560 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9562 if (get_attr_mode (insn) == MODE_SI)
9563 return "sal{l}\t%k0";
9565 return "sal{b}\t%0";
9569 if (get_attr_mode (insn) == MODE_SI)
9570 return "sal{l}\t{%2, %k0|%k0, %2}";
9572 return "sal{b}\t{%2, %0|%0, %2}";
9577 (cond [(eq_attr "alternative" "2")
9578 (const_string "lea")
9579 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9580 (match_operand 0 "register_operand"))
9581 (match_operand 2 "const1_operand"))
9582 (const_string "alu")
9584 (const_string "ishift")))
9585 (set (attr "length_immediate")
9587 (ior (eq_attr "type" "alu")
9588 (and (eq_attr "type" "ishift")
9589 (and (match_operand 2 "const1_operand")
9590 (ior (match_test "TARGET_SHIFT1")
9591 (match_test "optimize_function_for_size_p (cfun)")))))
9593 (const_string "*")))
9594 (set_attr "mode" "QI,SI,SI")])
9596 (define_insn "*ashlqi3_1_slp"
9597 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9598 (ashift:QI (match_dup 0)
9599 (match_operand:QI 1 "nonmemory_operand" "cI")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "(optimize_function_for_size_p (cfun)
9602 || !TARGET_PARTIAL_FLAG_REG_STALL
9603 || (operands[1] == const1_rtx
9605 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9607 switch (get_attr_type (insn))
9610 gcc_assert (operands[1] == const1_rtx);
9611 return "add{b}\t%0, %0";
9614 if (operands[1] == const1_rtx
9615 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616 return "sal{b}\t%0";
9618 return "sal{b}\t{%1, %0|%0, %1}";
9622 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9623 (match_operand 0 "register_operand"))
9624 (match_operand 1 "const1_operand"))
9625 (const_string "alu")
9627 (const_string "ishift1")))
9628 (set (attr "length_immediate")
9630 (ior (eq_attr "type" "alu")
9631 (and (eq_attr "type" "ishift1")
9632 (and (match_operand 1 "const1_operand")
9633 (ior (match_test "TARGET_SHIFT1")
9634 (match_test "optimize_function_for_size_p (cfun)")))))
9636 (const_string "*")))
9637 (set_attr "mode" "QI")])
9639 ;; Convert ashift to the lea pattern to avoid flags dependency.
9641 [(set (match_operand 0 "register_operand")
9642 (ashift (match_operand 1 "index_register_operand")
9643 (match_operand:QI 2 "const_int_operand")))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9647 && true_regnum (operands[0]) != true_regnum (operands[1])"
9650 machine_mode mode = GET_MODE (operands[0]);
9653 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9656 operands[0] = gen_lowpart (mode, operands[0]);
9657 operands[1] = gen_lowpart (mode, operands[1]);
9660 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9662 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9664 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9668 ;; Convert ashift to the lea pattern to avoid flags dependency.
9670 [(set (match_operand:DI 0 "register_operand")
9672 (ashift:SI (match_operand:SI 1 "index_register_operand")
9673 (match_operand:QI 2 "const_int_operand"))))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "TARGET_64BIT && reload_completed
9676 && true_regnum (operands[0]) != true_regnum (operands[1])"
9678 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9680 operands[1] = gen_lowpart (SImode, operands[1]);
9681 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9684 ;; This pattern can't accept a variable shift count, since shifts by
9685 ;; zero don't affect the flags. We assume that shifts by constant
9686 ;; zero are optimized away.
9687 (define_insn "*ashl<mode>3_cmp"
9688 [(set (reg FLAGS_REG)
9690 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9691 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9693 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9694 (ashift:SWI (match_dup 1) (match_dup 2)))]
9695 "(optimize_function_for_size_p (cfun)
9696 || !TARGET_PARTIAL_FLAG_REG_STALL
9697 || (operands[2] == const1_rtx
9699 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9700 && ix86_match_ccmode (insn, CCGOCmode)
9701 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9703 switch (get_attr_type (insn))
9706 gcc_assert (operands[2] == const1_rtx);
9707 return "add{<imodesuffix>}\t%0, %0";
9710 if (operands[2] == const1_rtx
9711 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9712 return "sal{<imodesuffix>}\t%0";
9714 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9718 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9719 (match_operand 0 "register_operand"))
9720 (match_operand 2 "const1_operand"))
9721 (const_string "alu")
9723 (const_string "ishift")))
9724 (set (attr "length_immediate")
9726 (ior (eq_attr "type" "alu")
9727 (and (eq_attr "type" "ishift")
9728 (and (match_operand 2 "const1_operand")
9729 (ior (match_test "TARGET_SHIFT1")
9730 (match_test "optimize_function_for_size_p (cfun)")))))
9732 (const_string "*")))
9733 (set_attr "mode" "<MODE>")])
9735 (define_insn "*ashlsi3_cmp_zext"
9736 [(set (reg FLAGS_REG)
9738 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9739 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9741 (set (match_operand:DI 0 "register_operand" "=r")
9742 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9744 && (optimize_function_for_size_p (cfun)
9745 || !TARGET_PARTIAL_FLAG_REG_STALL
9746 || (operands[2] == const1_rtx
9748 || TARGET_DOUBLE_WITH_ADD)))
9749 && ix86_match_ccmode (insn, CCGOCmode)
9750 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9752 switch (get_attr_type (insn))
9755 gcc_assert (operands[2] == const1_rtx);
9756 return "add{l}\t%k0, %k0";
9759 if (operands[2] == const1_rtx
9760 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9761 return "sal{l}\t%k0";
9763 return "sal{l}\t{%2, %k0|%k0, %2}";
9767 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9768 (match_operand 2 "const1_operand"))
9769 (const_string "alu")
9771 (const_string "ishift")))
9772 (set (attr "length_immediate")
9774 (ior (eq_attr "type" "alu")
9775 (and (eq_attr "type" "ishift")
9776 (and (match_operand 2 "const1_operand")
9777 (ior (match_test "TARGET_SHIFT1")
9778 (match_test "optimize_function_for_size_p (cfun)")))))
9780 (const_string "*")))
9781 (set_attr "mode" "SI")])
9783 (define_insn "*ashl<mode>3_cconly"
9784 [(set (reg FLAGS_REG)
9786 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9787 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9789 (clobber (match_scratch:SWI 0 "=<r>"))]
9790 "(optimize_function_for_size_p (cfun)
9791 || !TARGET_PARTIAL_FLAG_REG_STALL
9792 || (operands[2] == const1_rtx
9794 || TARGET_DOUBLE_WITH_ADD)))
9795 && ix86_match_ccmode (insn, CCGOCmode)"
9797 switch (get_attr_type (insn))
9800 gcc_assert (operands[2] == const1_rtx);
9801 return "add{<imodesuffix>}\t%0, %0";
9804 if (operands[2] == const1_rtx
9805 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9806 return "sal{<imodesuffix>}\t%0";
9808 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9812 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9813 (match_operand 0 "register_operand"))
9814 (match_operand 2 "const1_operand"))
9815 (const_string "alu")
9817 (const_string "ishift")))
9818 (set (attr "length_immediate")
9820 (ior (eq_attr "type" "alu")
9821 (and (eq_attr "type" "ishift")
9822 (and (match_operand 2 "const1_operand")
9823 (ior (match_test "TARGET_SHIFT1")
9824 (match_test "optimize_function_for_size_p (cfun)")))))
9826 (const_string "*")))
9827 (set_attr "mode" "<MODE>")])
9829 ;; See comment above `ashl<mode>3' about how this works.
9831 (define_expand "<shift_insn><mode>3"
9832 [(set (match_operand:SDWIM 0 "<shift_operand>")
9833 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9834 (match_operand:QI 2 "nonmemory_operand")))]
9836 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9838 ;; Avoid useless masking of count operand.
9839 (define_insn "*<shift_insn><mode>3_mask"
9840 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9842 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9845 (match_operand:SI 2 "register_operand" "c")
9846 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9849 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9850 == GET_MODE_BITSIZE (<MODE>mode)-1"
9852 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9854 [(set_attr "type" "ishift")
9855 (set_attr "mode" "<MODE>")])
9857 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9858 [(set (match_operand:DWI 0 "register_operand" "=r")
9859 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9860 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9861 (clobber (reg:CC FLAGS_REG))]
9864 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9866 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9867 [(set_attr "type" "multi")])
9869 ;; By default we don't ask for a scratch register, because when DWImode
9870 ;; values are manipulated, registers are already at a premium. But if
9871 ;; we have one handy, we won't turn it away.
9874 [(match_scratch:DWIH 3 "r")
9875 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9877 (match_operand:<DWI> 1 "register_operand")
9878 (match_operand:QI 2 "nonmemory_operand")))
9879 (clobber (reg:CC FLAGS_REG))])
9883 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9885 (define_insn "x86_64_shrd"
9886 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9887 (ior:DI (lshiftrt:DI (match_dup 0)
9888 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9889 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9890 (minus:QI (const_int 64) (match_dup 2)))))
9891 (clobber (reg:CC FLAGS_REG))]
9893 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9894 [(set_attr "type" "ishift")
9895 (set_attr "prefix_0f" "1")
9896 (set_attr "mode" "DI")
9897 (set_attr "athlon_decode" "vector")
9898 (set_attr "amdfam10_decode" "vector")
9899 (set_attr "bdver1_decode" "vector")])
9901 (define_insn "x86_shrd"
9902 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9903 (ior:SI (lshiftrt:SI (match_dup 0)
9904 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9905 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9906 (minus:QI (const_int 32) (match_dup 2)))))
9907 (clobber (reg:CC FLAGS_REG))]
9909 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9910 [(set_attr "type" "ishift")
9911 (set_attr "prefix_0f" "1")
9912 (set_attr "mode" "SI")
9913 (set_attr "pent_pair" "np")
9914 (set_attr "athlon_decode" "vector")
9915 (set_attr "amdfam10_decode" "vector")
9916 (set_attr "bdver1_decode" "vector")])
9918 (define_insn "ashrdi3_cvt"
9919 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9920 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9921 (match_operand:QI 2 "const_int_operand")))
9922 (clobber (reg:CC FLAGS_REG))]
9923 "TARGET_64BIT && INTVAL (operands[2]) == 63
9924 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9925 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9928 sar{q}\t{%2, %0|%0, %2}"
9929 [(set_attr "type" "imovx,ishift")
9930 (set_attr "prefix_0f" "0,*")
9931 (set_attr "length_immediate" "0,*")
9932 (set_attr "modrm" "0,1")
9933 (set_attr "mode" "DI")])
9935 (define_insn "ashrsi3_cvt"
9936 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9937 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9938 (match_operand:QI 2 "const_int_operand")))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "INTVAL (operands[2]) == 31
9941 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9942 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9945 sar{l}\t{%2, %0|%0, %2}"
9946 [(set_attr "type" "imovx,ishift")
9947 (set_attr "prefix_0f" "0,*")
9948 (set_attr "length_immediate" "0,*")
9949 (set_attr "modrm" "0,1")
9950 (set_attr "mode" "SI")])
9952 (define_insn "*ashrsi3_cvt_zext"
9953 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9956 (match_operand:QI 2 "const_int_operand"))))
9957 (clobber (reg:CC FLAGS_REG))]
9958 "TARGET_64BIT && INTVAL (operands[2]) == 31
9959 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9960 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9963 sar{l}\t{%2, %k0|%k0, %2}"
9964 [(set_attr "type" "imovx,ishift")
9965 (set_attr "prefix_0f" "0,*")
9966 (set_attr "length_immediate" "0,*")
9967 (set_attr "modrm" "0,1")
9968 (set_attr "mode" "SI")])
9970 (define_expand "x86_shift<mode>_adj_3"
9971 [(use (match_operand:SWI48 0 "register_operand"))
9972 (use (match_operand:SWI48 1 "register_operand"))
9973 (use (match_operand:QI 2 "register_operand"))]
9976 rtx_code_label *label = gen_label_rtx ();
9979 emit_insn (gen_testqi_ccz_1 (operands[2],
9980 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9982 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9983 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9984 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9985 gen_rtx_LABEL_REF (VOIDmode, label),
9987 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9988 JUMP_LABEL (tmp) = label;
9990 emit_move_insn (operands[0], operands[1]);
9991 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9992 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9994 LABEL_NUSES (label) = 1;
9999 (define_insn "*bmi2_<shift_insn><mode>3_1"
10000 [(set (match_operand:SWI48 0 "register_operand" "=r")
10001 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10002 (match_operand:SWI48 2 "register_operand" "r")))]
10004 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10005 [(set_attr "type" "ishiftx")
10006 (set_attr "mode" "<MODE>")])
10008 (define_insn "*<shift_insn><mode>3_1"
10009 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10011 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10012 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10016 switch (get_attr_type (insn))
10022 if (operands[2] == const1_rtx
10023 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10024 return "<shift>{<imodesuffix>}\t%0";
10026 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10029 [(set_attr "isa" "*,bmi2")
10030 (set_attr "type" "ishift,ishiftx")
10031 (set (attr "length_immediate")
10033 (and (match_operand 2 "const1_operand")
10034 (ior (match_test "TARGET_SHIFT1")
10035 (match_test "optimize_function_for_size_p (cfun)")))
10037 (const_string "*")))
10038 (set_attr "mode" "<MODE>")])
10040 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10042 [(set (match_operand:SWI48 0 "register_operand")
10043 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10044 (match_operand:QI 2 "register_operand")))
10045 (clobber (reg:CC FLAGS_REG))]
10046 "TARGET_BMI2 && reload_completed"
10047 [(set (match_dup 0)
10048 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10049 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10051 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10052 [(set (match_operand:DI 0 "register_operand" "=r")
10054 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10055 (match_operand:SI 2 "register_operand" "r"))))]
10056 "TARGET_64BIT && TARGET_BMI2"
10057 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10058 [(set_attr "type" "ishiftx")
10059 (set_attr "mode" "SI")])
10061 (define_insn "*<shift_insn>si3_1_zext"
10062 [(set (match_operand:DI 0 "register_operand" "=r,r")
10064 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10065 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10066 (clobber (reg:CC FLAGS_REG))]
10067 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10069 switch (get_attr_type (insn))
10075 if (operands[2] == const1_rtx
10076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10077 return "<shift>{l}\t%k0";
10079 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10082 [(set_attr "isa" "*,bmi2")
10083 (set_attr "type" "ishift,ishiftx")
10084 (set (attr "length_immediate")
10086 (and (match_operand 2 "const1_operand")
10087 (ior (match_test "TARGET_SHIFT1")
10088 (match_test "optimize_function_for_size_p (cfun)")))
10090 (const_string "*")))
10091 (set_attr "mode" "SI")])
10093 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10095 [(set (match_operand:DI 0 "register_operand")
10097 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10098 (match_operand:QI 2 "register_operand"))))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10101 [(set (match_dup 0)
10102 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10103 "operands[2] = gen_lowpart (SImode, operands[2]);")
10105 (define_insn "*<shift_insn><mode>3_1"
10106 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10108 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10109 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10110 (clobber (reg:CC FLAGS_REG))]
10111 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113 if (operands[2] == const1_rtx
10114 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10115 return "<shift>{<imodesuffix>}\t%0";
10117 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119 [(set_attr "type" "ishift")
10120 (set (attr "length_immediate")
10122 (and (match_operand 2 "const1_operand")
10123 (ior (match_test "TARGET_SHIFT1")
10124 (match_test "optimize_function_for_size_p (cfun)")))
10126 (const_string "*")))
10127 (set_attr "mode" "<MODE>")])
10129 (define_insn "*<shift_insn>qi3_1_slp"
10130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10131 (any_shiftrt:QI (match_dup 0)
10132 (match_operand:QI 1 "nonmemory_operand" "cI")))
10133 (clobber (reg:CC FLAGS_REG))]
10134 "(optimize_function_for_size_p (cfun)
10135 || !TARGET_PARTIAL_REG_STALL
10136 || (operands[1] == const1_rtx
10137 && TARGET_SHIFT1))"
10139 if (operands[1] == const1_rtx
10140 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10141 return "<shift>{b}\t%0";
10143 return "<shift>{b}\t{%1, %0|%0, %1}";
10145 [(set_attr "type" "ishift1")
10146 (set (attr "length_immediate")
10148 (and (match_operand 1 "const1_operand")
10149 (ior (match_test "TARGET_SHIFT1")
10150 (match_test "optimize_function_for_size_p (cfun)")))
10152 (const_string "*")))
10153 (set_attr "mode" "QI")])
10155 ;; This pattern can't accept a variable shift count, since shifts by
10156 ;; zero don't affect the flags. We assume that shifts by constant
10157 ;; zero are optimized away.
10158 (define_insn "*<shift_insn><mode>3_cmp"
10159 [(set (reg FLAGS_REG)
10162 (match_operand:SWI 1 "nonimmediate_operand" "0")
10163 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10165 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10166 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10167 "(optimize_function_for_size_p (cfun)
10168 || !TARGET_PARTIAL_FLAG_REG_STALL
10169 || (operands[2] == const1_rtx
10171 && ix86_match_ccmode (insn, CCGOCmode)
10172 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10174 if (operands[2] == const1_rtx
10175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10176 return "<shift>{<imodesuffix>}\t%0";
10178 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10180 [(set_attr "type" "ishift")
10181 (set (attr "length_immediate")
10183 (and (match_operand 2 "const1_operand")
10184 (ior (match_test "TARGET_SHIFT1")
10185 (match_test "optimize_function_for_size_p (cfun)")))
10187 (const_string "*")))
10188 (set_attr "mode" "<MODE>")])
10190 (define_insn "*<shift_insn>si3_cmp_zext"
10191 [(set (reg FLAGS_REG)
10193 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10194 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10196 (set (match_operand:DI 0 "register_operand" "=r")
10197 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10199 && (optimize_function_for_size_p (cfun)
10200 || !TARGET_PARTIAL_FLAG_REG_STALL
10201 || (operands[2] == const1_rtx
10203 && ix86_match_ccmode (insn, CCGOCmode)
10204 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10206 if (operands[2] == const1_rtx
10207 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10208 return "<shift>{l}\t%k0";
10210 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10212 [(set_attr "type" "ishift")
10213 (set (attr "length_immediate")
10215 (and (match_operand 2 "const1_operand")
10216 (ior (match_test "TARGET_SHIFT1")
10217 (match_test "optimize_function_for_size_p (cfun)")))
10219 (const_string "*")))
10220 (set_attr "mode" "SI")])
10222 (define_insn "*<shift_insn><mode>3_cconly"
10223 [(set (reg FLAGS_REG)
10226 (match_operand:SWI 1 "register_operand" "0")
10227 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10229 (clobber (match_scratch:SWI 0 "=<r>"))]
10230 "(optimize_function_for_size_p (cfun)
10231 || !TARGET_PARTIAL_FLAG_REG_STALL
10232 || (operands[2] == const1_rtx
10234 && ix86_match_ccmode (insn, CCGOCmode)"
10236 if (operands[2] == const1_rtx
10237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238 return "<shift>{<imodesuffix>}\t%0";
10240 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242 [(set_attr "type" "ishift")
10243 (set (attr "length_immediate")
10245 (and (match_operand 2 "const1_operand")
10246 (ior (match_test "TARGET_SHIFT1")
10247 (match_test "optimize_function_for_size_p (cfun)")))
10249 (const_string "*")))
10250 (set_attr "mode" "<MODE>")])
10252 ;; Rotate instructions
10254 (define_expand "<rotate_insn>ti3"
10255 [(set (match_operand:TI 0 "register_operand")
10256 (any_rotate:TI (match_operand:TI 1 "register_operand")
10257 (match_operand:QI 2 "nonmemory_operand")))]
10260 if (const_1_to_63_operand (operands[2], VOIDmode))
10261 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10262 (operands[0], operands[1], operands[2]));
10269 (define_expand "<rotate_insn>di3"
10270 [(set (match_operand:DI 0 "shiftdi_operand")
10271 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10272 (match_operand:QI 2 "nonmemory_operand")))]
10276 ix86_expand_binary_operator (<CODE>, DImode, operands);
10277 else if (const_1_to_31_operand (operands[2], VOIDmode))
10278 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10279 (operands[0], operands[1], operands[2]));
10286 (define_expand "<rotate_insn><mode>3"
10287 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10288 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10289 (match_operand:QI 2 "nonmemory_operand")))]
10291 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10293 ;; Avoid useless masking of count operand.
10294 (define_insn "*<rotate_insn><mode>3_mask"
10295 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10297 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10300 (match_operand:SI 2 "register_operand" "c")
10301 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10302 (clobber (reg:CC FLAGS_REG))]
10303 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10304 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10305 == GET_MODE_BITSIZE (<MODE>mode)-1"
10307 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10309 [(set_attr "type" "rotate")
10310 (set_attr "mode" "<MODE>")])
10312 ;; Implement rotation using two double-precision
10313 ;; shift instructions and a scratch register.
10315 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10316 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10317 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10318 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10319 (clobber (reg:CC FLAGS_REG))
10320 (clobber (match_scratch:DWIH 3 "=&r"))]
10324 [(set (match_dup 3) (match_dup 4))
10326 [(set (match_dup 4)
10327 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10328 (lshiftrt:DWIH (match_dup 5)
10329 (minus:QI (match_dup 6) (match_dup 2)))))
10330 (clobber (reg:CC FLAGS_REG))])
10332 [(set (match_dup 5)
10333 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10334 (lshiftrt:DWIH (match_dup 3)
10335 (minus:QI (match_dup 6) (match_dup 2)))))
10336 (clobber (reg:CC FLAGS_REG))])]
10338 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10340 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10343 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10344 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10345 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10346 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10347 (clobber (reg:CC FLAGS_REG))
10348 (clobber (match_scratch:DWIH 3 "=&r"))]
10352 [(set (match_dup 3) (match_dup 4))
10354 [(set (match_dup 4)
10355 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10356 (ashift:DWIH (match_dup 5)
10357 (minus:QI (match_dup 6) (match_dup 2)))))
10358 (clobber (reg:CC FLAGS_REG))])
10360 [(set (match_dup 5)
10361 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10362 (ashift:DWIH (match_dup 3)
10363 (minus:QI (match_dup 6) (match_dup 2)))))
10364 (clobber (reg:CC FLAGS_REG))])]
10366 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10368 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10371 (define_insn "*bmi2_rorx<mode>3_1"
10372 [(set (match_operand:SWI48 0 "register_operand" "=r")
10373 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10374 (match_operand:QI 2 "immediate_operand" "<S>")))]
10376 "rorx\t{%2, %1, %0|%0, %1, %2}"
10377 [(set_attr "type" "rotatex")
10378 (set_attr "mode" "<MODE>")])
10380 (define_insn "*<rotate_insn><mode>3_1"
10381 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10383 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10384 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10388 switch (get_attr_type (insn))
10394 if (operands[2] == const1_rtx
10395 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10396 return "<rotate>{<imodesuffix>}\t%0";
10398 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10401 [(set_attr "isa" "*,bmi2")
10402 (set_attr "type" "rotate,rotatex")
10403 (set (attr "length_immediate")
10405 (and (eq_attr "type" "rotate")
10406 (and (match_operand 2 "const1_operand")
10407 (ior (match_test "TARGET_SHIFT1")
10408 (match_test "optimize_function_for_size_p (cfun)"))))
10410 (const_string "*")))
10411 (set_attr "mode" "<MODE>")])
10413 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10415 [(set (match_operand:SWI48 0 "register_operand")
10416 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10417 (match_operand:QI 2 "immediate_operand")))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "TARGET_BMI2 && reload_completed"
10420 [(set (match_dup 0)
10421 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10424 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10428 [(set (match_operand:SWI48 0 "register_operand")
10429 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10430 (match_operand:QI 2 "immediate_operand")))
10431 (clobber (reg:CC FLAGS_REG))]
10432 "TARGET_BMI2 && reload_completed"
10433 [(set (match_dup 0)
10434 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10436 (define_insn "*bmi2_rorxsi3_1_zext"
10437 [(set (match_operand:DI 0 "register_operand" "=r")
10439 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10440 (match_operand:QI 2 "immediate_operand" "I"))))]
10441 "TARGET_64BIT && TARGET_BMI2"
10442 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10443 [(set_attr "type" "rotatex")
10444 (set_attr "mode" "SI")])
10446 (define_insn "*<rotate_insn>si3_1_zext"
10447 [(set (match_operand:DI 0 "register_operand" "=r,r")
10449 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10450 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10451 (clobber (reg:CC FLAGS_REG))]
10452 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10454 switch (get_attr_type (insn))
10460 if (operands[2] == const1_rtx
10461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10462 return "<rotate>{l}\t%k0";
10464 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10467 [(set_attr "isa" "*,bmi2")
10468 (set_attr "type" "rotate,rotatex")
10469 (set (attr "length_immediate")
10471 (and (eq_attr "type" "rotate")
10472 (and (match_operand 2 "const1_operand")
10473 (ior (match_test "TARGET_SHIFT1")
10474 (match_test "optimize_function_for_size_p (cfun)"))))
10476 (const_string "*")))
10477 (set_attr "mode" "SI")])
10479 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10481 [(set (match_operand:DI 0 "register_operand")
10483 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10484 (match_operand:QI 2 "immediate_operand"))))
10485 (clobber (reg:CC FLAGS_REG))]
10486 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10487 [(set (match_dup 0)
10488 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10491 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10495 [(set (match_operand:DI 0 "register_operand")
10497 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10498 (match_operand:QI 2 "immediate_operand"))))
10499 (clobber (reg:CC FLAGS_REG))]
10500 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10501 [(set (match_dup 0)
10502 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10504 (define_insn "*<rotate_insn><mode>3_1"
10505 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10506 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10507 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10508 (clobber (reg:CC FLAGS_REG))]
10509 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10511 if (operands[2] == const1_rtx
10512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10513 return "<rotate>{<imodesuffix>}\t%0";
10515 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10517 [(set_attr "type" "rotate")
10518 (set (attr "length_immediate")
10520 (and (match_operand 2 "const1_operand")
10521 (ior (match_test "TARGET_SHIFT1")
10522 (match_test "optimize_function_for_size_p (cfun)")))
10524 (const_string "*")))
10525 (set_attr "mode" "<MODE>")])
10527 (define_insn "*<rotate_insn>qi3_1_slp"
10528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10529 (any_rotate:QI (match_dup 0)
10530 (match_operand:QI 1 "nonmemory_operand" "cI")))
10531 (clobber (reg:CC FLAGS_REG))]
10532 "(optimize_function_for_size_p (cfun)
10533 || !TARGET_PARTIAL_REG_STALL
10534 || (operands[1] == const1_rtx
10535 && TARGET_SHIFT1))"
10537 if (operands[1] == const1_rtx
10538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10539 return "<rotate>{b}\t%0";
10541 return "<rotate>{b}\t{%1, %0|%0, %1}";
10543 [(set_attr "type" "rotate1")
10544 (set (attr "length_immediate")
10546 (and (match_operand 1 "const1_operand")
10547 (ior (match_test "TARGET_SHIFT1")
10548 (match_test "optimize_function_for_size_p (cfun)")))
10550 (const_string "*")))
10551 (set_attr "mode" "QI")])
10554 [(set (match_operand:HI 0 "register_operand")
10555 (any_rotate:HI (match_dup 0) (const_int 8)))
10556 (clobber (reg:CC FLAGS_REG))]
10558 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10559 [(parallel [(set (strict_low_part (match_dup 0))
10560 (bswap:HI (match_dup 0)))
10561 (clobber (reg:CC FLAGS_REG))])])
10563 ;; Bit set / bit test instructions
10565 (define_expand "extv"
10566 [(set (match_operand:SI 0 "register_operand")
10567 (sign_extract:SI (match_operand:SI 1 "register_operand")
10568 (match_operand:SI 2 "const8_operand")
10569 (match_operand:SI 3 "const8_operand")))]
10572 /* Handle extractions from %ah et al. */
10573 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10576 /* From mips.md: extract_bit_field doesn't verify that our source
10577 matches the predicate, so check it again here. */
10578 if (! ext_register_operand (operands[1], VOIDmode))
10582 (define_expand "extzv"
10583 [(set (match_operand:SI 0 "register_operand")
10584 (zero_extract:SI (match_operand 1 "ext_register_operand")
10585 (match_operand:SI 2 "const8_operand")
10586 (match_operand:SI 3 "const8_operand")))]
10589 /* Handle extractions from %ah et al. */
10590 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10593 /* From mips.md: extract_bit_field doesn't verify that our source
10594 matches the predicate, so check it again here. */
10595 if (! ext_register_operand (operands[1], VOIDmode))
10599 (define_expand "insv"
10600 [(set (zero_extract (match_operand 0 "register_operand")
10601 (match_operand 1 "const_int_operand")
10602 (match_operand 2 "const_int_operand"))
10603 (match_operand 3 "register_operand"))]
10606 rtx (*gen_mov_insv_1) (rtx, rtx);
10608 if (ix86_expand_pinsr (operands))
10611 /* Handle insertions to %ah et al. */
10612 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10615 /* From mips.md: insert_bit_field doesn't verify that our source
10616 matches the predicate, so check it again here. */
10617 if (! ext_register_operand (operands[0], VOIDmode))
10620 gen_mov_insv_1 = (TARGET_64BIT
10621 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10623 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10627 ;; %%% bts, btr, btc, bt.
10628 ;; In general these instructions are *slow* when applied to memory,
10629 ;; since they enforce atomic operation. When applied to registers,
10630 ;; it depends on the cpu implementation. They're never faster than
10631 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10632 ;; no point. But in 64-bit, we can't hold the relevant immediates
10633 ;; within the instruction itself, so operating on bits in the high
10634 ;; 32-bits of a register becomes easier.
10636 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10637 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10638 ;; negdf respectively, so they can never be disabled entirely.
10640 (define_insn "*btsq"
10641 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10643 (match_operand:DI 1 "const_0_to_63_operand"))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10647 "bts{q}\t{%1, %0|%0, %1}"
10648 [(set_attr "type" "alu1")
10649 (set_attr "prefix_0f" "1")
10650 (set_attr "mode" "DI")])
10652 (define_insn "*btrq"
10653 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10655 (match_operand:DI 1 "const_0_to_63_operand"))
10657 (clobber (reg:CC FLAGS_REG))]
10658 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10659 "btr{q}\t{%1, %0|%0, %1}"
10660 [(set_attr "type" "alu1")
10661 (set_attr "prefix_0f" "1")
10662 (set_attr "mode" "DI")])
10664 (define_insn "*btcq"
10665 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10667 (match_operand:DI 1 "const_0_to_63_operand"))
10668 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10669 (clobber (reg:CC FLAGS_REG))]
10670 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10671 "btc{q}\t{%1, %0|%0, %1}"
10672 [(set_attr "type" "alu1")
10673 (set_attr "prefix_0f" "1")
10674 (set_attr "mode" "DI")])
10676 ;; Allow Nocona to avoid these instructions if a register is available.
10679 [(match_scratch:DI 2 "r")
10680 (parallel [(set (zero_extract:DI
10681 (match_operand:DI 0 "register_operand")
10683 (match_operand:DI 1 "const_0_to_63_operand"))
10685 (clobber (reg:CC FLAGS_REG))])]
10686 "TARGET_64BIT && !TARGET_USE_BT"
10689 int i = INTVAL (operands[1]);
10691 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10695 emit_move_insn (operands[2], op1);
10699 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10704 [(match_scratch:DI 2 "r")
10705 (parallel [(set (zero_extract:DI
10706 (match_operand:DI 0 "register_operand")
10708 (match_operand:DI 1 "const_0_to_63_operand"))
10710 (clobber (reg:CC FLAGS_REG))])]
10711 "TARGET_64BIT && !TARGET_USE_BT"
10714 int i = INTVAL (operands[1]);
10716 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10720 emit_move_insn (operands[2], op1);
10724 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10729 [(match_scratch:DI 2 "r")
10730 (parallel [(set (zero_extract:DI
10731 (match_operand:DI 0 "register_operand")
10733 (match_operand:DI 1 "const_0_to_63_operand"))
10734 (not:DI (zero_extract:DI
10735 (match_dup 0) (const_int 1) (match_dup 1))))
10736 (clobber (reg:CC FLAGS_REG))])]
10737 "TARGET_64BIT && !TARGET_USE_BT"
10740 int i = INTVAL (operands[1]);
10742 rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10746 emit_move_insn (operands[2], op1);
10750 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10754 (define_insn "*bt<mode>"
10755 [(set (reg:CCC FLAGS_REG)
10757 (zero_extract:SWI48
10758 (match_operand:SWI48 0 "register_operand" "r")
10760 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10762 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10763 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10764 [(set_attr "type" "alu1")
10765 (set_attr "prefix_0f" "1")
10766 (set_attr "mode" "<MODE>")])
10768 ;; Store-flag instructions.
10770 ;; For all sCOND expanders, also expand the compare or test insn that
10771 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10773 (define_insn_and_split "*setcc_di_1"
10774 [(set (match_operand:DI 0 "register_operand" "=q")
10775 (match_operator:DI 1 "ix86_comparison_operator"
10776 [(reg FLAGS_REG) (const_int 0)]))]
10777 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10779 "&& reload_completed"
10780 [(set (match_dup 2) (match_dup 1))
10781 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10783 PUT_MODE (operands[1], QImode);
10784 operands[2] = gen_lowpart (QImode, operands[0]);
10787 (define_insn_and_split "*setcc_si_1_and"
10788 [(set (match_operand:SI 0 "register_operand" "=q")
10789 (match_operator:SI 1 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)]))
10791 (clobber (reg:CC FLAGS_REG))]
10792 "!TARGET_PARTIAL_REG_STALL
10793 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10795 "&& reload_completed"
10796 [(set (match_dup 2) (match_dup 1))
10797 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10798 (clobber (reg:CC FLAGS_REG))])]
10800 PUT_MODE (operands[1], QImode);
10801 operands[2] = gen_lowpart (QImode, operands[0]);
10804 (define_insn_and_split "*setcc_si_1_movzbl"
10805 [(set (match_operand:SI 0 "register_operand" "=q")
10806 (match_operator:SI 1 "ix86_comparison_operator"
10807 [(reg FLAGS_REG) (const_int 0)]))]
10808 "!TARGET_PARTIAL_REG_STALL
10809 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10811 "&& reload_completed"
10812 [(set (match_dup 2) (match_dup 1))
10813 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10815 PUT_MODE (operands[1], QImode);
10816 operands[2] = gen_lowpart (QImode, operands[0]);
10819 (define_insn "*setcc_qi"
10820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10821 (match_operator:QI 1 "ix86_comparison_operator"
10822 [(reg FLAGS_REG) (const_int 0)]))]
10825 [(set_attr "type" "setcc")
10826 (set_attr "mode" "QI")])
10828 (define_insn "*setcc_qi_slp"
10829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10830 (match_operator:QI 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)]))]
10834 [(set_attr "type" "setcc")
10835 (set_attr "mode" "QI")])
10837 ;; In general it is not safe to assume too much about CCmode registers,
10838 ;; so simplify-rtx stops when it sees a second one. Under certain
10839 ;; conditions this is safe on x86, so help combine not create
10846 [(set (match_operand:QI 0 "nonimmediate_operand")
10847 (ne:QI (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10851 [(set (match_dup 0) (match_dup 1))]
10852 "PUT_MODE (operands[1], QImode);")
10855 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10856 (ne:QI (match_operator 1 "ix86_comparison_operator"
10857 [(reg FLAGS_REG) (const_int 0)])
10860 [(set (match_dup 0) (match_dup 1))]
10861 "PUT_MODE (operands[1], QImode);")
10864 [(set (match_operand:QI 0 "nonimmediate_operand")
10865 (eq:QI (match_operator 1 "ix86_comparison_operator"
10866 [(reg FLAGS_REG) (const_int 0)])
10869 [(set (match_dup 0) (match_dup 1))]
10871 rtx new_op1 = copy_rtx (operands[1]);
10872 operands[1] = new_op1;
10873 PUT_MODE (new_op1, QImode);
10874 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10875 GET_MODE (XEXP (new_op1, 0))));
10877 /* Make sure that (a) the CCmode we have for the flags is strong
10878 enough for the reversed compare or (b) we have a valid FP compare. */
10879 if (! ix86_comparison_operator (new_op1, VOIDmode))
10884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10885 (eq:QI (match_operator 1 "ix86_comparison_operator"
10886 [(reg FLAGS_REG) (const_int 0)])
10889 [(set (match_dup 0) (match_dup 1))]
10891 rtx new_op1 = copy_rtx (operands[1]);
10892 operands[1] = new_op1;
10893 PUT_MODE (new_op1, QImode);
10894 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10895 GET_MODE (XEXP (new_op1, 0))));
10897 /* Make sure that (a) the CCmode we have for the flags is strong
10898 enough for the reversed compare or (b) we have a valid FP compare. */
10899 if (! ix86_comparison_operator (new_op1, VOIDmode))
10903 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10904 ;; subsequent logical operations are used to imitate conditional moves.
10905 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10908 (define_insn "setcc_<mode>_sse"
10909 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10910 (match_operator:MODEF 3 "sse_comparison_operator"
10911 [(match_operand:MODEF 1 "register_operand" "0,x")
10912 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10913 "SSE_FLOAT_MODE_P (<MODE>mode)"
10915 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10916 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10917 [(set_attr "isa" "noavx,avx")
10918 (set_attr "type" "ssecmp")
10919 (set_attr "length_immediate" "1")
10920 (set_attr "prefix" "orig,vex")
10921 (set_attr "mode" "<MODE>")])
10923 ;; Basic conditional jump instructions.
10924 ;; We ignore the overflow flag for signed branch instructions.
10926 (define_insn "*jcc_1_bnd"
10928 (if_then_else (match_operator 1 "ix86_comparison_operator"
10929 [(reg FLAGS_REG) (const_int 0)])
10930 (label_ref (match_operand 0))
10932 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10934 [(set_attr "type" "ibr")
10935 (set_attr "modrm" "0")
10936 (set (attr "length")
10937 (if_then_else (and (ge (minus (match_dup 0) (pc))
10939 (lt (minus (match_dup 0) (pc))
10944 (define_insn "*jcc_1"
10946 (if_then_else (match_operator 1 "ix86_comparison_operator"
10947 [(reg FLAGS_REG) (const_int 0)])
10948 (label_ref (match_operand 0))
10952 [(set_attr "type" "ibr")
10953 (set_attr "modrm" "0")
10954 (set (attr "length")
10955 (if_then_else (and (ge (minus (match_dup 0) (pc))
10957 (lt (minus (match_dup 0) (pc))
10962 (define_insn "*jcc_2_bnd"
10964 (if_then_else (match_operator 1 "ix86_comparison_operator"
10965 [(reg FLAGS_REG) (const_int 0)])
10967 (label_ref (match_operand 0))))]
10968 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10970 [(set_attr "type" "ibr")
10971 (set_attr "modrm" "0")
10972 (set (attr "length")
10973 (if_then_else (and (ge (minus (match_dup 0) (pc))
10975 (lt (minus (match_dup 0) (pc))
10980 (define_insn "*jcc_2"
10982 (if_then_else (match_operator 1 "ix86_comparison_operator"
10983 [(reg FLAGS_REG) (const_int 0)])
10985 (label_ref (match_operand 0))))]
10988 [(set_attr "type" "ibr")
10989 (set_attr "modrm" "0")
10990 (set (attr "length")
10991 (if_then_else (and (ge (minus (match_dup 0) (pc))
10993 (lt (minus (match_dup 0) (pc))
10998 ;; In general it is not safe to assume too much about CCmode registers,
10999 ;; so simplify-rtx stops when it sees a second one. Under certain
11000 ;; conditions this is safe on x86, so help combine not create
11008 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11009 [(reg FLAGS_REG) (const_int 0)])
11011 (label_ref (match_operand 1))
11015 (if_then_else (match_dup 0)
11016 (label_ref (match_dup 1))
11018 "PUT_MODE (operands[0], VOIDmode);")
11022 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11023 [(reg FLAGS_REG) (const_int 0)])
11025 (label_ref (match_operand 1))
11029 (if_then_else (match_dup 0)
11030 (label_ref (match_dup 1))
11033 rtx new_op0 = copy_rtx (operands[0]);
11034 operands[0] = new_op0;
11035 PUT_MODE (new_op0, VOIDmode);
11036 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11037 GET_MODE (XEXP (new_op0, 0))));
11039 /* Make sure that (a) the CCmode we have for the flags is strong
11040 enough for the reversed compare or (b) we have a valid FP compare. */
11041 if (! ix86_comparison_operator (new_op0, VOIDmode))
11045 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11046 ;; pass generates from shift insn with QImode operand. Actually, the mode
11047 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11048 ;; appropriate modulo of the bit offset value.
11050 (define_insn_and_split "*jcc_bt<mode>"
11052 (if_then_else (match_operator 0 "bt_comparison_operator"
11053 [(zero_extract:SWI48
11054 (match_operand:SWI48 1 "register_operand" "r")
11057 (match_operand:QI 2 "register_operand" "r")))
11059 (label_ref (match_operand 3))
11061 (clobber (reg:CC FLAGS_REG))]
11062 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11065 [(set (reg:CCC FLAGS_REG)
11067 (zero_extract:SWI48
11073 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11074 (label_ref (match_dup 3))
11077 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11079 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11082 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11083 ;; zero extended to SImode.
11084 (define_insn_and_split "*jcc_bt<mode>_1"
11086 (if_then_else (match_operator 0 "bt_comparison_operator"
11087 [(zero_extract:SWI48
11088 (match_operand:SWI48 1 "register_operand" "r")
11090 (match_operand:SI 2 "register_operand" "r"))
11092 (label_ref (match_operand 3))
11094 (clobber (reg:CC FLAGS_REG))]
11095 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11098 [(set (reg:CCC FLAGS_REG)
11100 (zero_extract:SWI48
11106 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11107 (label_ref (match_dup 3))
11110 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11112 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11115 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11116 ;; also for DImode, this is what combine produces.
11117 (define_insn_and_split "*jcc_bt<mode>_mask"
11119 (if_then_else (match_operator 0 "bt_comparison_operator"
11120 [(zero_extract:SWI48
11121 (match_operand:SWI48 1 "register_operand" "r")
11124 (match_operand:SI 2 "register_operand" "r")
11125 (match_operand:SI 3 "const_int_operand" "n")))])
11126 (label_ref (match_operand 4))
11128 (clobber (reg:CC FLAGS_REG))]
11129 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11130 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11131 == GET_MODE_BITSIZE (<MODE>mode)-1"
11134 [(set (reg:CCC FLAGS_REG)
11136 (zero_extract:SWI48
11142 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11143 (label_ref (match_dup 4))
11146 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11148 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11151 (define_insn_and_split "*jcc_btsi_1"
11153 (if_then_else (match_operator 0 "bt_comparison_operator"
11156 (match_operand:SI 1 "register_operand" "r")
11157 (match_operand:QI 2 "register_operand" "r"))
11160 (label_ref (match_operand 3))
11162 (clobber (reg:CC FLAGS_REG))]
11163 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11166 [(set (reg:CCC FLAGS_REG)
11174 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11175 (label_ref (match_dup 3))
11178 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11180 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11183 ;; avoid useless masking of bit offset operand
11184 (define_insn_and_split "*jcc_btsi_mask_1"
11187 (match_operator 0 "bt_comparison_operator"
11190 (match_operand:SI 1 "register_operand" "r")
11193 (match_operand:SI 2 "register_operand" "r")
11194 (match_operand:SI 3 "const_int_operand" "n")) 0))
11197 (label_ref (match_operand 4))
11199 (clobber (reg:CC FLAGS_REG))]
11200 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11201 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11204 [(set (reg:CCC FLAGS_REG)
11212 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11213 (label_ref (match_dup 4))
11215 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11217 ;; Define combination compare-and-branch fp compare instructions to help
11220 (define_insn "*jcc<mode>_0_i387"
11222 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11223 [(match_operand:X87MODEF 1 "register_operand" "f")
11224 (match_operand:X87MODEF 2 "const0_operand")])
11225 (label_ref (match_operand 3))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 4 "=a"))]
11230 "TARGET_80387 && !TARGET_CMOVE"
11233 (define_insn "*jcc<mode>_0_r_i387"
11235 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11236 [(match_operand:X87MODEF 1 "register_operand" "f")
11237 (match_operand:X87MODEF 2 "const0_operand")])
11239 (label_ref (match_operand 3))))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 4 "=a"))]
11243 "TARGET_80387 && !TARGET_CMOVE"
11246 (define_insn "*jccxf_i387"
11248 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11249 [(match_operand:XF 1 "register_operand" "f")
11250 (match_operand:XF 2 "register_operand" "f")])
11251 (label_ref (match_operand 3))
11253 (clobber (reg:CCFP FPSR_REG))
11254 (clobber (reg:CCFP FLAGS_REG))
11255 (clobber (match_scratch:HI 4 "=a"))]
11256 "TARGET_80387 && !TARGET_CMOVE"
11259 (define_insn "*jccxf_r_i387"
11261 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11262 [(match_operand:XF 1 "register_operand" "f")
11263 (match_operand:XF 2 "register_operand" "f")])
11265 (label_ref (match_operand 3))))
11266 (clobber (reg:CCFP FPSR_REG))
11267 (clobber (reg:CCFP FLAGS_REG))
11268 (clobber (match_scratch:HI 4 "=a"))]
11269 "TARGET_80387 && !TARGET_CMOVE"
11272 (define_insn "*jcc<mode>_i387"
11274 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11275 [(match_operand:MODEF 1 "register_operand" "f")
11276 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11277 (label_ref (match_operand 3))
11279 (clobber (reg:CCFP FPSR_REG))
11280 (clobber (reg:CCFP FLAGS_REG))
11281 (clobber (match_scratch:HI 4 "=a"))]
11282 "TARGET_80387 && !TARGET_CMOVE"
11285 (define_insn "*jcc<mode>_r_i387"
11287 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11288 [(match_operand:MODEF 1 "register_operand" "f")
11289 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11291 (label_ref (match_operand 3))))
11292 (clobber (reg:CCFP FPSR_REG))
11293 (clobber (reg:CCFP FLAGS_REG))
11294 (clobber (match_scratch:HI 4 "=a"))]
11295 "TARGET_80387 && !TARGET_CMOVE"
11298 (define_insn "*jccu<mode>_i387"
11300 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11301 [(match_operand:X87MODEF 1 "register_operand" "f")
11302 (match_operand:X87MODEF 2 "register_operand" "f")])
11303 (label_ref (match_operand 3))
11305 (clobber (reg:CCFP FPSR_REG))
11306 (clobber (reg:CCFP FLAGS_REG))
11307 (clobber (match_scratch:HI 4 "=a"))]
11308 "TARGET_80387 && !TARGET_CMOVE"
11311 (define_insn "*jccu<mode>_r_i387"
11313 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11314 [(match_operand:X87MODEF 1 "register_operand" "f")
11315 (match_operand:X87MODEF 2 "register_operand" "f")])
11317 (label_ref (match_operand 3))))
11318 (clobber (reg:CCFP FPSR_REG))
11319 (clobber (reg:CCFP FLAGS_REG))
11320 (clobber (match_scratch:HI 4 "=a"))]
11321 "TARGET_80387 && !TARGET_CMOVE"
11326 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11327 [(match_operand:X87MODEF 1 "register_operand")
11328 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11330 (match_operand 4)))
11331 (clobber (reg:CCFP FPSR_REG))
11332 (clobber (reg:CCFP FLAGS_REG))]
11333 "TARGET_80387 && !TARGET_CMOVE
11334 && reload_completed"
11337 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11338 operands[3], operands[4], NULL_RTX);
11344 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11345 [(match_operand:X87MODEF 1 "register_operand")
11346 (match_operand:X87MODEF 2 "general_operand")])
11348 (match_operand 4)))
11349 (clobber (reg:CCFP FPSR_REG))
11350 (clobber (reg:CCFP FLAGS_REG))
11351 (clobber (match_scratch:HI 5))]
11352 "TARGET_80387 && !TARGET_CMOVE
11353 && reload_completed"
11356 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11357 operands[3], operands[4], operands[5]);
11361 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11362 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11363 ;; with a precedence over other operators and is always put in the first
11364 ;; place. Swap condition and operands to match ficom instruction.
11366 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11369 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11370 [(match_operator:X87MODEF 1 "float_operator"
11371 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11372 (match_operand:X87MODEF 3 "register_operand" "f")])
11373 (label_ref (match_operand 4))
11375 (clobber (reg:CCFP FPSR_REG))
11376 (clobber (reg:CCFP FLAGS_REG))
11377 (clobber (match_scratch:HI 5 "=a"))]
11378 "TARGET_80387 && !TARGET_CMOVE
11379 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11380 || optimize_function_for_size_p (cfun))"
11383 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11386 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11387 [(match_operator:X87MODEF 1 "float_operator"
11388 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11389 (match_operand:X87MODEF 3 "register_operand" "f")])
11391 (label_ref (match_operand 4))))
11392 (clobber (reg:CCFP FPSR_REG))
11393 (clobber (reg:CCFP FLAGS_REG))
11394 (clobber (match_scratch:HI 5 "=a"))]
11395 "TARGET_80387 && !TARGET_CMOVE
11396 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11397 || optimize_function_for_size_p (cfun))"
11403 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11404 [(match_operator:X87MODEF 1 "float_operator"
11405 [(match_operand:SWI24 2 "memory_operand")])
11406 (match_operand:X87MODEF 3 "register_operand")])
11408 (match_operand 5)))
11409 (clobber (reg:CCFP FPSR_REG))
11410 (clobber (reg:CCFP FLAGS_REG))
11411 (clobber (match_scratch:HI 6))]
11412 "TARGET_80387 && !TARGET_CMOVE
11413 && reload_completed"
11416 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11417 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11418 operands[4], operands[5], operands[6]);
11422 ;; Unconditional and other jump instructions
11424 (define_insn "jump_bnd"
11426 (label_ref (match_operand 0)))]
11427 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11429 [(set_attr "type" "ibr")
11430 (set (attr "length")
11431 (if_then_else (and (ge (minus (match_dup 0) (pc))
11433 (lt (minus (match_dup 0) (pc))
11437 (set_attr "modrm" "0")])
11439 (define_insn "jump"
11441 (label_ref (match_operand 0)))]
11444 [(set_attr "type" "ibr")
11445 (set (attr "length")
11446 (if_then_else (and (ge (minus (match_dup 0) (pc))
11448 (lt (minus (match_dup 0) (pc))
11452 (set_attr "modrm" "0")])
11454 (define_expand "indirect_jump"
11455 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11459 operands[0] = convert_memory_address (word_mode, operands[0]);
11462 (define_insn "*indirect_jump"
11463 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11466 [(set_attr "type" "ibr")
11467 (set_attr "length_immediate" "0")])
11469 (define_expand "tablejump"
11470 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11471 (use (label_ref (match_operand 1)))])]
11474 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11475 relative. Convert the relative address to an absolute address. */
11479 enum rtx_code code;
11481 /* We can't use @GOTOFF for text labels on VxWorks;
11482 see gotoff_operand. */
11483 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11487 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11489 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11493 op1 = pic_offset_table_rtx;
11498 op0 = pic_offset_table_rtx;
11502 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11507 operands[0] = convert_memory_address (word_mode, operands[0]);
11510 (define_insn "*tablejump_1"
11511 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11512 (use (label_ref (match_operand 1)))]
11515 [(set_attr "type" "ibr")
11516 (set_attr "length_immediate" "0")])
11518 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11521 [(set (reg FLAGS_REG) (match_operand 0))
11522 (set (match_operand:QI 1 "register_operand")
11523 (match_operator:QI 2 "ix86_comparison_operator"
11524 [(reg FLAGS_REG) (const_int 0)]))
11525 (set (match_operand 3 "any_QIreg_operand")
11526 (zero_extend (match_dup 1)))]
11527 "(peep2_reg_dead_p (3, operands[1])
11528 || operands_match_p (operands[1], operands[3]))
11529 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11530 [(set (match_dup 4) (match_dup 0))
11531 (set (strict_low_part (match_dup 5))
11534 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11535 operands[5] = gen_lowpart (QImode, operands[3]);
11536 ix86_expand_clear (operands[3]);
11540 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11541 (match_operand 4)])
11542 (set (match_operand:QI 1 "register_operand")
11543 (match_operator:QI 2 "ix86_comparison_operator"
11544 [(reg FLAGS_REG) (const_int 0)]))
11545 (set (match_operand 3 "any_QIreg_operand")
11546 (zero_extend (match_dup 1)))]
11547 "(peep2_reg_dead_p (3, operands[1])
11548 || operands_match_p (operands[1], operands[3]))
11549 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11550 && ! (GET_CODE (operands[4]) == CLOBBER
11551 && reg_mentioned_p (operands[3], operands[4]))"
11552 [(parallel [(set (match_dup 5) (match_dup 0))
11554 (set (strict_low_part (match_dup 6))
11557 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11558 operands[6] = gen_lowpart (QImode, operands[3]);
11559 ix86_expand_clear (operands[3]);
11562 ;; Similar, but match zero extend with andsi3.
11565 [(set (reg FLAGS_REG) (match_operand 0))
11566 (set (match_operand:QI 1 "register_operand")
11567 (match_operator:QI 2 "ix86_comparison_operator"
11568 [(reg FLAGS_REG) (const_int 0)]))
11569 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11570 (and:SI (match_dup 3) (const_int 255)))
11571 (clobber (reg:CC FLAGS_REG))])]
11572 "REGNO (operands[1]) == REGNO (operands[3])
11573 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11574 [(set (match_dup 4) (match_dup 0))
11575 (set (strict_low_part (match_dup 5))
11578 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11579 operands[5] = gen_lowpart (QImode, operands[3]);
11580 ix86_expand_clear (operands[3]);
11584 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11585 (match_operand 4)])
11586 (set (match_operand:QI 1 "register_operand")
11587 (match_operator:QI 2 "ix86_comparison_operator"
11588 [(reg FLAGS_REG) (const_int 0)]))
11589 (parallel [(set (match_operand 3 "any_QIreg_operand")
11590 (zero_extend (match_dup 1)))
11591 (clobber (reg:CC FLAGS_REG))])]
11592 "(peep2_reg_dead_p (3, operands[1])
11593 || operands_match_p (operands[1], operands[3]))
11594 && ! reg_overlap_mentioned_p (operands[3], operands[0])
11595 && ! (GET_CODE (operands[4]) == CLOBBER
11596 && reg_mentioned_p (operands[3], operands[4]))"
11597 [(parallel [(set (match_dup 5) (match_dup 0))
11599 (set (strict_low_part (match_dup 6))
11602 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11603 operands[6] = gen_lowpart (QImode, operands[3]);
11604 ix86_expand_clear (operands[3]);
11607 ;; Call instructions.
11609 ;; The predicates normally associated with named expanders are not properly
11610 ;; checked for calls. This is a bug in the generic code, but it isn't that
11611 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11613 ;; P6 processors will jump to the address after the decrement when %esp
11614 ;; is used as a call operand, so they will execute return address as a code.
11615 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11617 ;; Register constraint for call instruction.
11618 (define_mode_attr c [(SI "l") (DI "r")])
11620 ;; Call subroutine returning no value.
11622 (define_expand "call"
11623 [(call (match_operand:QI 0)
11625 (use (match_operand 2))]
11628 ix86_expand_call (NULL, operands[0], operands[1],
11629 operands[2], NULL, false);
11633 (define_expand "sibcall"
11634 [(call (match_operand:QI 0)
11636 (use (match_operand 2))]
11639 ix86_expand_call (NULL, operands[0], operands[1],
11640 operands[2], NULL, true);
11644 (define_insn "*call"
11645 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11646 (match_operand 1))]
11647 "!SIBLING_CALL_P (insn)"
11648 "* return ix86_output_call_insn (insn, operands[0]);"
11649 [(set_attr "type" "call")])
11651 (define_insn "*sibcall"
11652 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11653 (match_operand 1))]
11654 "SIBLING_CALL_P (insn)"
11655 "* return ix86_output_call_insn (insn, operands[0]);"
11656 [(set_attr "type" "call")])
11658 (define_insn "*sibcall_memory"
11659 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11661 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11663 "* return ix86_output_call_insn (insn, operands[0]);"
11664 [(set_attr "type" "call")])
11667 [(set (match_operand:W 0 "register_operand")
11668 (match_operand:W 1 "memory_operand"))
11669 (call (mem:QI (match_dup 0))
11670 (match_operand 3))]
11671 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11672 && peep2_reg_dead_p (2, operands[0])"
11673 [(parallel [(call (mem:QI (match_dup 1))
11675 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11678 [(set (match_operand:W 0 "register_operand")
11679 (match_operand:W 1 "memory_operand"))
11680 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11681 (call (mem:QI (match_dup 0))
11682 (match_operand 3))]
11683 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11684 && peep2_reg_dead_p (3, operands[0])"
11685 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11686 (parallel [(call (mem:QI (match_dup 1))
11688 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11690 (define_expand "call_pop"
11691 [(parallel [(call (match_operand:QI 0)
11692 (match_operand:SI 1))
11693 (set (reg:SI SP_REG)
11694 (plus:SI (reg:SI SP_REG)
11695 (match_operand:SI 3)))])]
11698 ix86_expand_call (NULL, operands[0], operands[1],
11699 operands[2], operands[3], false);
11703 (define_insn "*call_pop"
11704 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11706 (set (reg:SI SP_REG)
11707 (plus:SI (reg:SI SP_REG)
11708 (match_operand:SI 2 "immediate_operand" "i")))]
11709 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11710 "* return ix86_output_call_insn (insn, operands[0]);"
11711 [(set_attr "type" "call")])
11713 (define_insn "*sibcall_pop"
11714 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11716 (set (reg:SI SP_REG)
11717 (plus:SI (reg:SI SP_REG)
11718 (match_operand:SI 2 "immediate_operand" "i")))]
11719 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11720 "* return ix86_output_call_insn (insn, operands[0]);"
11721 [(set_attr "type" "call")])
11723 (define_insn "*sibcall_pop_memory"
11724 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11726 (set (reg:SI SP_REG)
11727 (plus:SI (reg:SI SP_REG)
11728 (match_operand:SI 2 "immediate_operand" "i")))
11729 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11731 "* return ix86_output_call_insn (insn, operands[0]);"
11732 [(set_attr "type" "call")])
11735 [(set (match_operand:SI 0 "register_operand")
11736 (match_operand:SI 1 "memory_operand"))
11737 (parallel [(call (mem:QI (match_dup 0))
11739 (set (reg:SI SP_REG)
11740 (plus:SI (reg:SI SP_REG)
11741 (match_operand:SI 4 "immediate_operand")))])]
11742 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11743 && peep2_reg_dead_p (2, operands[0])"
11744 [(parallel [(call (mem:QI (match_dup 1))
11746 (set (reg:SI SP_REG)
11747 (plus:SI (reg:SI SP_REG)
11749 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11752 [(set (match_operand:SI 0 "register_operand")
11753 (match_operand:SI 1 "memory_operand"))
11754 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11755 (parallel [(call (mem:QI (match_dup 0))
11757 (set (reg:SI SP_REG)
11758 (plus:SI (reg:SI SP_REG)
11759 (match_operand:SI 4 "immediate_operand")))])]
11760 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11761 && peep2_reg_dead_p (3, operands[0])"
11762 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11763 (parallel [(call (mem:QI (match_dup 1))
11765 (set (reg:SI SP_REG)
11766 (plus:SI (reg:SI SP_REG)
11768 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11770 ;; Combining simple memory jump instruction
11773 [(set (match_operand:W 0 "register_operand")
11774 (match_operand:W 1 "memory_operand"))
11775 (set (pc) (match_dup 0))]
11776 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11777 [(set (pc) (match_dup 1))])
11779 ;; Call subroutine, returning value in operand 0
11781 (define_expand "call_value"
11782 [(set (match_operand 0)
11783 (call (match_operand:QI 1)
11784 (match_operand 2)))
11785 (use (match_operand 3))]
11788 ix86_expand_call (operands[0], operands[1], operands[2],
11789 operands[3], NULL, false);
11793 (define_expand "sibcall_value"
11794 [(set (match_operand 0)
11795 (call (match_operand:QI 1)
11796 (match_operand 2)))
11797 (use (match_operand 3))]
11800 ix86_expand_call (operands[0], operands[1], operands[2],
11801 operands[3], NULL, true);
11805 (define_insn "*call_value"
11806 [(set (match_operand 0)
11807 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11808 (match_operand 2)))]
11809 "!SIBLING_CALL_P (insn)"
11810 "* return ix86_output_call_insn (insn, operands[1]);"
11811 [(set_attr "type" "callv")])
11813 (define_insn "*sibcall_value"
11814 [(set (match_operand 0)
11815 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11816 (match_operand 2)))]
11817 "SIBLING_CALL_P (insn)"
11818 "* return ix86_output_call_insn (insn, operands[1]);"
11819 [(set_attr "type" "callv")])
11821 (define_insn "*sibcall_value_memory"
11822 [(set (match_operand 0)
11823 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11824 (match_operand 2)))
11825 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11827 "* return ix86_output_call_insn (insn, operands[1]);"
11828 [(set_attr "type" "callv")])
11831 [(set (match_operand:W 0 "register_operand")
11832 (match_operand:W 1 "memory_operand"))
11833 (set (match_operand 2)
11834 (call (mem:QI (match_dup 0))
11835 (match_operand 3)))]
11836 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11837 && peep2_reg_dead_p (2, operands[0])"
11838 [(parallel [(set (match_dup 2)
11839 (call (mem:QI (match_dup 1))
11841 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11844 [(set (match_operand:W 0 "register_operand")
11845 (match_operand:W 1 "memory_operand"))
11846 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11847 (set (match_operand 2)
11848 (call (mem:QI (match_dup 0))
11849 (match_operand 3)))]
11850 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11851 && peep2_reg_dead_p (3, operands[0])"
11852 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11853 (parallel [(set (match_dup 2)
11854 (call (mem:QI (match_dup 1))
11856 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11858 (define_expand "call_value_pop"
11859 [(parallel [(set (match_operand 0)
11860 (call (match_operand:QI 1)
11861 (match_operand:SI 2)))
11862 (set (reg:SI SP_REG)
11863 (plus:SI (reg:SI SP_REG)
11864 (match_operand:SI 4)))])]
11867 ix86_expand_call (operands[0], operands[1], operands[2],
11868 operands[3], operands[4], false);
11872 (define_insn "*call_value_pop"
11873 [(set (match_operand 0)
11874 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11875 (match_operand 2)))
11876 (set (reg:SI SP_REG)
11877 (plus:SI (reg:SI SP_REG)
11878 (match_operand:SI 3 "immediate_operand" "i")))]
11879 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11880 "* return ix86_output_call_insn (insn, operands[1]);"
11881 [(set_attr "type" "callv")])
11883 (define_insn "*sibcall_value_pop"
11884 [(set (match_operand 0)
11885 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11886 (match_operand 2)))
11887 (set (reg:SI SP_REG)
11888 (plus:SI (reg:SI SP_REG)
11889 (match_operand:SI 3 "immediate_operand" "i")))]
11890 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11891 "* return ix86_output_call_insn (insn, operands[1]);"
11892 [(set_attr "type" "callv")])
11894 (define_insn "*sibcall_value_pop_memory"
11895 [(set (match_operand 0)
11896 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11897 (match_operand 2)))
11898 (set (reg:SI SP_REG)
11899 (plus:SI (reg:SI SP_REG)
11900 (match_operand:SI 3 "immediate_operand" "i")))
11901 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11903 "* return ix86_output_call_insn (insn, operands[1]);"
11904 [(set_attr "type" "callv")])
11907 [(set (match_operand:SI 0 "register_operand")
11908 (match_operand:SI 1 "memory_operand"))
11909 (parallel [(set (match_operand 2)
11910 (call (mem:QI (match_dup 0))
11911 (match_operand 3)))
11912 (set (reg:SI SP_REG)
11913 (plus:SI (reg:SI SP_REG)
11914 (match_operand:SI 4 "immediate_operand")))])]
11915 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11916 && peep2_reg_dead_p (2, operands[0])"
11917 [(parallel [(set (match_dup 2)
11918 (call (mem:QI (match_dup 1))
11920 (set (reg:SI SP_REG)
11921 (plus:SI (reg:SI SP_REG)
11923 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11926 [(set (match_operand:SI 0 "register_operand")
11927 (match_operand:SI 1 "memory_operand"))
11928 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11929 (parallel [(set (match_operand 2)
11930 (call (mem:QI (match_dup 0))
11931 (match_operand 3)))
11932 (set (reg:SI SP_REG)
11933 (plus:SI (reg:SI SP_REG)
11934 (match_operand:SI 4 "immediate_operand")))])]
11935 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11936 && peep2_reg_dead_p (3, operands[0])"
11937 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11938 (parallel [(set (match_dup 2)
11939 (call (mem:QI (match_dup 1))
11941 (set (reg:SI SP_REG)
11942 (plus:SI (reg:SI SP_REG)
11944 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11946 ;; Call subroutine returning any type.
11948 (define_expand "untyped_call"
11949 [(parallel [(call (match_operand 0)
11952 (match_operand 2)])]
11957 /* In order to give reg-stack an easier job in validating two
11958 coprocessor registers as containing a possible return value,
11959 simply pretend the untyped call returns a complex long double
11962 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11963 and should have the default ABI. */
11965 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11966 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11967 operands[0], const0_rtx,
11968 GEN_INT ((TARGET_64BIT
11969 ? (ix86_abi == SYSV_ABI
11970 ? X86_64_SSE_REGPARM_MAX
11971 : X86_64_MS_SSE_REGPARM_MAX)
11972 : X86_32_SSE_REGPARM_MAX)
11976 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11978 rtx set = XVECEXP (operands[2], 0, i);
11979 emit_move_insn (SET_DEST (set), SET_SRC (set));
11982 /* The optimizer does not know that the call sets the function value
11983 registers we stored in the result block. We avoid problems by
11984 claiming that all hard registers are used and clobbered at this
11986 emit_insn (gen_blockage ());
11991 ;; Prologue and epilogue instructions
11993 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11994 ;; all of memory. This blocks insns from being moved across this point.
11996 (define_insn "blockage"
11997 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12000 [(set_attr "length" "0")])
12002 ;; Do not schedule instructions accessing memory across this point.
12004 (define_expand "memory_blockage"
12005 [(set (match_dup 0)
12006 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12009 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12010 MEM_VOLATILE_P (operands[0]) = 1;
12013 (define_insn "*memory_blockage"
12014 [(set (match_operand:BLK 0)
12015 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12018 [(set_attr "length" "0")])
12020 ;; As USE insns aren't meaningful after reload, this is used instead
12021 ;; to prevent deleting instructions setting registers for PIC code
12022 (define_insn "prologue_use"
12023 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12026 [(set_attr "length" "0")])
12028 ;; Insn emitted into the body of a function to return from a function.
12029 ;; This is only done if the function's epilogue is known to be simple.
12030 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12032 (define_expand "return"
12034 "ix86_can_use_return_insn_p ()"
12036 if (crtl->args.pops_args)
12038 rtx popc = GEN_INT (crtl->args.pops_args);
12039 emit_jump_insn (gen_simple_return_pop_internal (popc));
12044 ;; We need to disable this for TARGET_SEH, as otherwise
12045 ;; shrink-wrapped prologue gets enabled too. This might exceed
12046 ;; the maximum size of prologue in unwind information.
12048 (define_expand "simple_return"
12052 if (crtl->args.pops_args)
12054 rtx popc = GEN_INT (crtl->args.pops_args);
12055 emit_jump_insn (gen_simple_return_pop_internal (popc));
12060 (define_insn "simple_return_internal"
12064 [(set_attr "length_nobnd" "1")
12065 (set_attr "atom_unit" "jeu")
12066 (set_attr "length_immediate" "0")
12067 (set_attr "modrm" "0")])
12069 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12070 ;; instruction Athlon and K8 have.
12072 (define_insn "simple_return_internal_long"
12074 (unspec [(const_int 0)] UNSPEC_REP)]
12077 if (ix86_bnd_prefixed_insn_p (insn))
12080 return "rep%; ret";
12082 [(set_attr "length" "2")
12083 (set_attr "atom_unit" "jeu")
12084 (set_attr "length_immediate" "0")
12085 (set_attr "prefix_rep" "1")
12086 (set_attr "modrm" "0")])
12088 (define_insn "simple_return_pop_internal"
12090 (use (match_operand:SI 0 "const_int_operand"))]
12093 [(set_attr "length_nobnd" "3")
12094 (set_attr "atom_unit" "jeu")
12095 (set_attr "length_immediate" "2")
12096 (set_attr "modrm" "0")])
12098 (define_insn "simple_return_indirect_internal"
12100 (use (match_operand:SI 0 "register_operand" "r"))]
12103 [(set_attr "type" "ibr")
12104 (set_attr "length_immediate" "0")])
12110 [(set_attr "length" "1")
12111 (set_attr "length_immediate" "0")
12112 (set_attr "modrm" "0")])
12114 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12115 (define_insn "nops"
12116 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12120 int num = INTVAL (operands[0]);
12122 gcc_assert (IN_RANGE (num, 1, 8));
12125 fputs ("\tnop\n", asm_out_file);
12129 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12130 (set_attr "length_immediate" "0")
12131 (set_attr "modrm" "0")])
12133 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12134 ;; branch prediction penalty for the third jump in a 16-byte
12138 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12141 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12142 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12144 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12145 The align insn is used to avoid 3 jump instructions in the row to improve
12146 branch prediction and the benefits hardly outweigh the cost of extra 8
12147 nops on the average inserted by full alignment pseudo operation. */
12151 [(set_attr "length" "16")])
12153 (define_expand "prologue"
12156 "ix86_expand_prologue (); DONE;")
12158 (define_insn "set_got"
12159 [(set (match_operand:SI 0 "register_operand" "=r")
12160 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12161 (clobber (reg:CC FLAGS_REG))]
12163 "* return output_set_got (operands[0], NULL_RTX);"
12164 [(set_attr "type" "multi")
12165 (set_attr "length" "12")])
12167 (define_insn "set_got_labelled"
12168 [(set (match_operand:SI 0 "register_operand" "=r")
12169 (unspec:SI [(label_ref (match_operand 1))]
12171 (clobber (reg:CC FLAGS_REG))]
12173 "* return output_set_got (operands[0], operands[1]);"
12174 [(set_attr "type" "multi")
12175 (set_attr "length" "12")])
12177 (define_insn "set_got_rex64"
12178 [(set (match_operand:DI 0 "register_operand" "=r")
12179 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12181 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12182 [(set_attr "type" "lea")
12183 (set_attr "length_address" "4")
12184 (set_attr "mode" "DI")])
12186 (define_insn "set_rip_rex64"
12187 [(set (match_operand:DI 0 "register_operand" "=r")
12188 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12190 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12191 [(set_attr "type" "lea")
12192 (set_attr "length_address" "4")
12193 (set_attr "mode" "DI")])
12195 (define_insn "set_got_offset_rex64"
12196 [(set (match_operand:DI 0 "register_operand" "=r")
12198 [(label_ref (match_operand 1))]
12199 UNSPEC_SET_GOT_OFFSET))]
12201 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12202 [(set_attr "type" "imov")
12203 (set_attr "length_immediate" "0")
12204 (set_attr "length_address" "8")
12205 (set_attr "mode" "DI")])
12207 (define_expand "epilogue"
12210 "ix86_expand_epilogue (1); DONE;")
12212 (define_expand "sibcall_epilogue"
12215 "ix86_expand_epilogue (0); DONE;")
12217 (define_expand "eh_return"
12218 [(use (match_operand 0 "register_operand"))]
12221 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12223 /* Tricky bit: we write the address of the handler to which we will
12224 be returning into someone else's stack frame, one word below the
12225 stack address we wish to restore. */
12226 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12227 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12228 tmp = gen_rtx_MEM (Pmode, tmp);
12229 emit_move_insn (tmp, ra);
12231 emit_jump_insn (gen_eh_return_internal ());
12236 (define_insn_and_split "eh_return_internal"
12240 "epilogue_completed"
12242 "ix86_expand_epilogue (2); DONE;")
12244 (define_insn "leave"
12245 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12246 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12247 (clobber (mem:BLK (scratch)))]
12250 [(set_attr "type" "leave")])
12252 (define_insn "leave_rex64"
12253 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12254 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12255 (clobber (mem:BLK (scratch)))]
12258 [(set_attr "type" "leave")])
12260 ;; Handle -fsplit-stack.
12262 (define_expand "split_stack_prologue"
12266 ix86_expand_split_stack_prologue ();
12270 ;; In order to support the call/return predictor, we use a return
12271 ;; instruction which the middle-end doesn't see.
12272 (define_insn "split_stack_return"
12273 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12274 UNSPECV_SPLIT_STACK_RETURN)]
12277 if (operands[0] == const0_rtx)
12282 [(set_attr "atom_unit" "jeu")
12283 (set_attr "modrm" "0")
12284 (set (attr "length")
12285 (if_then_else (match_operand:SI 0 "const0_operand")
12288 (set (attr "length_immediate")
12289 (if_then_else (match_operand:SI 0 "const0_operand")
12293 ;; If there are operand 0 bytes available on the stack, jump to
12296 (define_expand "split_stack_space_check"
12297 [(set (pc) (if_then_else
12298 (ltu (minus (reg SP_REG)
12299 (match_operand 0 "register_operand"))
12300 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12301 (label_ref (match_operand 1))
12305 rtx reg, size, limit;
12307 reg = gen_reg_rtx (Pmode);
12308 size = force_reg (Pmode, operands[0]);
12309 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12310 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12311 UNSPEC_STACK_CHECK);
12312 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12313 ix86_expand_branch (GEU, reg, limit, operands[1]);
12318 ;; Bit manipulation instructions.
12320 (define_expand "ffs<mode>2"
12321 [(set (match_dup 2) (const_int -1))
12322 (parallel [(set (match_dup 3) (match_dup 4))
12323 (set (match_operand:SWI48 0 "register_operand")
12325 (match_operand:SWI48 1 "nonimmediate_operand")))])
12326 (set (match_dup 0) (if_then_else:SWI48
12327 (eq (match_dup 3) (const_int 0))
12330 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12331 (clobber (reg:CC FLAGS_REG))])]
12334 machine_mode flags_mode;
12336 if (<MODE>mode == SImode && !TARGET_CMOVE)
12338 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12343 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12345 operands[2] = gen_reg_rtx (<MODE>mode);
12346 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12347 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12350 (define_insn_and_split "ffssi2_no_cmove"
12351 [(set (match_operand:SI 0 "register_operand" "=r")
12352 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12353 (clobber (match_scratch:SI 2 "=&q"))
12354 (clobber (reg:CC FLAGS_REG))]
12357 "&& reload_completed"
12358 [(parallel [(set (match_dup 4) (match_dup 5))
12359 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12360 (set (strict_low_part (match_dup 3))
12361 (eq:QI (match_dup 4) (const_int 0)))
12362 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12363 (clobber (reg:CC FLAGS_REG))])
12364 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12365 (clobber (reg:CC FLAGS_REG))])
12366 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12367 (clobber (reg:CC FLAGS_REG))])]
12369 machine_mode flags_mode
12370 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12372 operands[3] = gen_lowpart (QImode, operands[2]);
12373 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12374 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12376 ix86_expand_clear (operands[2]);
12379 (define_insn "*tzcnt<mode>_1"
12380 [(set (reg:CCC FLAGS_REG)
12381 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12383 (set (match_operand:SWI48 0 "register_operand" "=r")
12384 (ctz:SWI48 (match_dup 1)))]
12385 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12386 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12387 [(set_attr "type" "alu1")
12388 (set_attr "prefix_0f" "1")
12389 (set_attr "prefix_rep" "1")
12390 (set_attr "btver2_decode" "double")
12391 (set_attr "mode" "<MODE>")])
12393 (define_insn "*bsf<mode>_1"
12394 [(set (reg:CCZ FLAGS_REG)
12395 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12397 (set (match_operand:SWI48 0 "register_operand" "=r")
12398 (ctz:SWI48 (match_dup 1)))]
12400 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12401 [(set_attr "type" "alu1")
12402 (set_attr "prefix_0f" "1")
12403 (set_attr "btver2_decode" "double")
12404 (set_attr "mode" "<MODE>")])
12406 (define_expand "ctz<mode>2"
12408 [(set (match_operand:SWI248 0 "register_operand")
12410 (match_operand:SWI248 1 "nonimmediate_operand")))
12411 (clobber (reg:CC FLAGS_REG))])])
12413 ; False dependency happens when destination is only updated by tzcnt,
12414 ; lzcnt or popcnt. There is no false dependency when destination is
12415 ; also used in source.
12416 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12417 [(set (match_operand:SWI48 0 "register_operand" "=r")
12419 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "(TARGET_BMI || TARGET_GENERIC)
12422 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12424 "&& reload_completed"
12426 [(set (match_dup 0)
12427 (ctz:SWI48 (match_dup 1)))
12428 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12429 (clobber (reg:CC FLAGS_REG))])]
12431 if (!reg_mentioned_p (operands[0], operands[1]))
12432 ix86_expand_clear (operands[0]);
12435 (define_insn "*ctz<mode>2_falsedep"
12436 [(set (match_operand:SWI48 0 "register_operand" "=r")
12438 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12439 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12440 UNSPEC_INSN_FALSE_DEP)
12441 (clobber (reg:CC FLAGS_REG))]
12445 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12446 else if (TARGET_GENERIC)
12447 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12448 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12450 gcc_unreachable ();
12452 [(set_attr "type" "alu1")
12453 (set_attr "prefix_0f" "1")
12454 (set_attr "prefix_rep" "1")
12455 (set_attr "mode" "<MODE>")])
12457 (define_insn "*ctz<mode>2"
12458 [(set (match_operand:SWI248 0 "register_operand" "=r")
12459 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12460 (clobber (reg:CC FLAGS_REG))]
12464 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12465 else if (optimize_function_for_size_p (cfun))
12467 else if (TARGET_GENERIC)
12468 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12469 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12471 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12473 [(set_attr "type" "alu1")
12474 (set_attr "prefix_0f" "1")
12475 (set (attr "prefix_rep")
12477 (ior (match_test "TARGET_BMI")
12478 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12479 (match_test "TARGET_GENERIC")))
12481 (const_string "0")))
12482 (set_attr "mode" "<MODE>")])
12484 (define_expand "clz<mode>2"
12486 [(set (match_operand:SWI248 0 "register_operand")
12489 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12490 (clobber (reg:CC FLAGS_REG))])
12492 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12493 (clobber (reg:CC FLAGS_REG))])]
12498 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12501 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12504 (define_expand "clz<mode>2_lzcnt"
12506 [(set (match_operand:SWI248 0 "register_operand")
12508 (match_operand:SWI248 1 "nonimmediate_operand")))
12509 (clobber (reg:CC FLAGS_REG))])]
12512 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12513 [(set (match_operand:SWI48 0 "register_operand" "=r")
12515 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12516 (clobber (reg:CC FLAGS_REG))]
12518 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12520 "&& reload_completed"
12522 [(set (match_dup 0)
12523 (clz:SWI48 (match_dup 1)))
12524 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12525 (clobber (reg:CC FLAGS_REG))])]
12527 if (!reg_mentioned_p (operands[0], operands[1]))
12528 ix86_expand_clear (operands[0]);
12531 (define_insn "*clz<mode>2_lzcnt_falsedep"
12532 [(set (match_operand:SWI48 0 "register_operand" "=r")
12534 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12535 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12536 UNSPEC_INSN_FALSE_DEP)
12537 (clobber (reg:CC FLAGS_REG))]
12539 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12540 [(set_attr "prefix_rep" "1")
12541 (set_attr "type" "bitmanip")
12542 (set_attr "mode" "<MODE>")])
12544 (define_insn "*clz<mode>2_lzcnt"
12545 [(set (match_operand:SWI248 0 "register_operand" "=r")
12546 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12547 (clobber (reg:CC FLAGS_REG))]
12549 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12550 [(set_attr "prefix_rep" "1")
12551 (set_attr "type" "bitmanip")
12552 (set_attr "mode" "<MODE>")])
12554 ;; BMI instructions.
12555 (define_insn "*bmi_andn_<mode>"
12556 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12558 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12559 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12560 (clobber (reg:CC FLAGS_REG))]
12562 "andn\t{%2, %1, %0|%0, %1, %2}"
12563 [(set_attr "type" "bitmanip")
12564 (set_attr "btver2_decode" "direct, double")
12565 (set_attr "mode" "<MODE>")])
12567 (define_insn "*bmi_andn_<mode>_ccno"
12568 [(set (reg FLAGS_REG)
12571 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12572 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12574 (clobber (match_scratch:SWI48 0 "=r,r"))]
12575 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12576 "andn\t{%2, %1, %0|%0, %1, %2}"
12577 [(set_attr "type" "bitmanip")
12578 (set_attr "btver2_decode" "direct, double")
12579 (set_attr "mode" "<MODE>")])
12581 (define_insn "bmi_bextr_<mode>"
12582 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12583 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12584 (match_operand:SWI48 2 "register_operand" "r,r")]
12586 (clobber (reg:CC FLAGS_REG))]
12588 "bextr\t{%2, %1, %0|%0, %1, %2}"
12589 [(set_attr "type" "bitmanip")
12590 (set_attr "btver2_decode" "direct, double")
12591 (set_attr "mode" "<MODE>")])
12593 (define_insn "*bmi_bextr_<mode>_ccz"
12594 [(set (reg:CCZ FLAGS_REG)
12596 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12597 (match_operand:SWI48 2 "register_operand" "r,r")]
12600 (clobber (match_scratch:SWI48 0 "=r,r"))]
12602 "bextr\t{%2, %1, %0|%0, %1, %2}"
12603 [(set_attr "type" "bitmanip")
12604 (set_attr "btver2_decode" "direct, double")
12605 (set_attr "mode" "<MODE>")])
12607 (define_insn "*bmi_blsi_<mode>"
12608 [(set (match_operand:SWI48 0 "register_operand" "=r")
12611 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12613 (clobber (reg:CC FLAGS_REG))]
12615 "blsi\t{%1, %0|%0, %1}"
12616 [(set_attr "type" "bitmanip")
12617 (set_attr "btver2_decode" "double")
12618 (set_attr "mode" "<MODE>")])
12620 (define_insn "*bmi_blsmsk_<mode>"
12621 [(set (match_operand:SWI48 0 "register_operand" "=r")
12624 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12627 (clobber (reg:CC FLAGS_REG))]
12629 "blsmsk\t{%1, %0|%0, %1}"
12630 [(set_attr "type" "bitmanip")
12631 (set_attr "btver2_decode" "double")
12632 (set_attr "mode" "<MODE>")])
12634 (define_insn "*bmi_blsr_<mode>"
12635 [(set (match_operand:SWI48 0 "register_operand" "=r")
12638 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12641 (clobber (reg:CC FLAGS_REG))]
12643 "blsr\t{%1, %0|%0, %1}"
12644 [(set_attr "type" "bitmanip")
12645 (set_attr "btver2_decode" "double")
12646 (set_attr "mode" "<MODE>")])
12648 ;; BMI2 instructions.
12649 (define_expand "bmi2_bzhi_<mode>3"
12651 [(set (match_operand:SWI48 0 "register_operand")
12652 (zero_extract:SWI48
12653 (match_operand:SWI48 1 "nonimmediate_operand")
12655 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12659 (clobber (reg:CC FLAGS_REG))])]
12661 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12663 (define_insn "*bmi2_bzhi_<mode>3"
12664 [(set (match_operand:SWI48 0 "register_operand" "=r")
12665 (zero_extract:SWI48
12666 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12668 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12670 (match_operand:SWI48 3 "const_int_operand" "n"))
12672 (clobber (reg:CC FLAGS_REG))]
12673 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12674 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12675 [(set_attr "type" "bitmanip")
12676 (set_attr "prefix" "vex")
12677 (set_attr "mode" "<MODE>")])
12679 (define_mode_attr k [(SI "k") (DI "q")])
12681 (define_insn "*bmi2_bzhi_<mode>3_1"
12682 [(set (match_operand:SWI48 0 "register_operand" "=r")
12683 (zero_extract:SWI48
12684 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12686 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12687 (match_operand:SWI48 3 "const_int_operand" "n"))
12689 (clobber (reg:CC FLAGS_REG))]
12690 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12691 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12692 [(set_attr "type" "bitmanip")
12693 (set_attr "prefix" "vex")
12694 (set_attr "mode" "<MODE>")])
12696 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12697 [(set (reg:CCZ FLAGS_REG)
12699 (zero_extract:SWI48
12700 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12702 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12703 (match_operand:SWI48 3 "const_int_operand" "n"))
12706 (clobber (match_scratch:SWI48 0 "=r"))]
12707 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12708 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12709 [(set_attr "type" "bitmanip")
12710 (set_attr "prefix" "vex")
12711 (set_attr "mode" "<MODE>")])
12713 (define_insn "bmi2_pdep_<mode>3"
12714 [(set (match_operand:SWI48 0 "register_operand" "=r")
12715 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12716 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12719 "pdep\t{%2, %1, %0|%0, %1, %2}"
12720 [(set_attr "type" "bitmanip")
12721 (set_attr "prefix" "vex")
12722 (set_attr "mode" "<MODE>")])
12724 (define_insn "bmi2_pext_<mode>3"
12725 [(set (match_operand:SWI48 0 "register_operand" "=r")
12726 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12727 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12730 "pext\t{%2, %1, %0|%0, %1, %2}"
12731 [(set_attr "type" "bitmanip")
12732 (set_attr "prefix" "vex")
12733 (set_attr "mode" "<MODE>")])
12735 ;; TBM instructions.
12736 (define_insn "tbm_bextri_<mode>"
12737 [(set (match_operand:SWI48 0 "register_operand" "=r")
12738 (zero_extract:SWI48
12739 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12740 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12741 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12742 (clobber (reg:CC FLAGS_REG))]
12745 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12746 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12748 [(set_attr "type" "bitmanip")
12749 (set_attr "mode" "<MODE>")])
12751 (define_insn "*tbm_blcfill_<mode>"
12752 [(set (match_operand:SWI48 0 "register_operand" "=r")
12755 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12758 (clobber (reg:CC FLAGS_REG))]
12760 "blcfill\t{%1, %0|%0, %1}"
12761 [(set_attr "type" "bitmanip")
12762 (set_attr "mode" "<MODE>")])
12764 (define_insn "*tbm_blci_<mode>"
12765 [(set (match_operand:SWI48 0 "register_operand" "=r")
12769 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12772 (clobber (reg:CC FLAGS_REG))]
12774 "blci\t{%1, %0|%0, %1}"
12775 [(set_attr "type" "bitmanip")
12776 (set_attr "mode" "<MODE>")])
12778 (define_insn "*tbm_blcic_<mode>"
12779 [(set (match_operand:SWI48 0 "register_operand" "=r")
12782 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12786 (clobber (reg:CC FLAGS_REG))]
12788 "blcic\t{%1, %0|%0, %1}"
12789 [(set_attr "type" "bitmanip")
12790 (set_attr "mode" "<MODE>")])
12792 (define_insn "*tbm_blcmsk_<mode>"
12793 [(set (match_operand:SWI48 0 "register_operand" "=r")
12796 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12799 (clobber (reg:CC FLAGS_REG))]
12801 "blcmsk\t{%1, %0|%0, %1}"
12802 [(set_attr "type" "bitmanip")
12803 (set_attr "mode" "<MODE>")])
12805 (define_insn "*tbm_blcs_<mode>"
12806 [(set (match_operand:SWI48 0 "register_operand" "=r")
12809 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12812 (clobber (reg:CC FLAGS_REG))]
12814 "blcs\t{%1, %0|%0, %1}"
12815 [(set_attr "type" "bitmanip")
12816 (set_attr "mode" "<MODE>")])
12818 (define_insn "*tbm_blsfill_<mode>"
12819 [(set (match_operand:SWI48 0 "register_operand" "=r")
12822 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12825 (clobber (reg:CC FLAGS_REG))]
12827 "blsfill\t{%1, %0|%0, %1}"
12828 [(set_attr "type" "bitmanip")
12829 (set_attr "mode" "<MODE>")])
12831 (define_insn "*tbm_blsic_<mode>"
12832 [(set (match_operand:SWI48 0 "register_operand" "=r")
12835 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12839 (clobber (reg:CC FLAGS_REG))]
12841 "blsic\t{%1, %0|%0, %1}"
12842 [(set_attr "type" "bitmanip")
12843 (set_attr "mode" "<MODE>")])
12845 (define_insn "*tbm_t1mskc_<mode>"
12846 [(set (match_operand:SWI48 0 "register_operand" "=r")
12849 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12853 (clobber (reg:CC FLAGS_REG))]
12855 "t1mskc\t{%1, %0|%0, %1}"
12856 [(set_attr "type" "bitmanip")
12857 (set_attr "mode" "<MODE>")])
12859 (define_insn "*tbm_tzmsk_<mode>"
12860 [(set (match_operand:SWI48 0 "register_operand" "=r")
12863 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12867 (clobber (reg:CC FLAGS_REG))]
12869 "tzmsk\t{%1, %0|%0, %1}"
12870 [(set_attr "type" "bitmanip")
12871 (set_attr "mode" "<MODE>")])
12873 (define_insn "bsr_rex64"
12874 [(set (match_operand:DI 0 "register_operand" "=r")
12875 (minus:DI (const_int 63)
12876 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12877 (clobber (reg:CC FLAGS_REG))]
12879 "bsr{q}\t{%1, %0|%0, %1}"
12880 [(set_attr "type" "alu1")
12881 (set_attr "prefix_0f" "1")
12882 (set_attr "mode" "DI")])
12885 [(set (match_operand:SI 0 "register_operand" "=r")
12886 (minus:SI (const_int 31)
12887 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12888 (clobber (reg:CC FLAGS_REG))]
12890 "bsr{l}\t{%1, %0|%0, %1}"
12891 [(set_attr "type" "alu1")
12892 (set_attr "prefix_0f" "1")
12893 (set_attr "mode" "SI")])
12895 (define_insn "*bsrhi"
12896 [(set (match_operand:HI 0 "register_operand" "=r")
12897 (minus:HI (const_int 15)
12898 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12899 (clobber (reg:CC FLAGS_REG))]
12901 "bsr{w}\t{%1, %0|%0, %1}"
12902 [(set_attr "type" "alu1")
12903 (set_attr "prefix_0f" "1")
12904 (set_attr "mode" "HI")])
12906 (define_expand "popcount<mode>2"
12908 [(set (match_operand:SWI248 0 "register_operand")
12910 (match_operand:SWI248 1 "nonimmediate_operand")))
12911 (clobber (reg:CC FLAGS_REG))])]
12914 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12915 [(set (match_operand:SWI48 0 "register_operand" "=r")
12917 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12918 (clobber (reg:CC FLAGS_REG))]
12920 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12922 "&& reload_completed"
12924 [(set (match_dup 0)
12925 (popcount:SWI48 (match_dup 1)))
12926 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12927 (clobber (reg:CC FLAGS_REG))])]
12929 if (!reg_mentioned_p (operands[0], operands[1]))
12930 ix86_expand_clear (operands[0]);
12933 (define_insn "*popcount<mode>2_falsedep"
12934 [(set (match_operand:SWI48 0 "register_operand" "=r")
12936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12937 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12938 UNSPEC_INSN_FALSE_DEP)
12939 (clobber (reg:CC FLAGS_REG))]
12943 return "popcnt\t{%1, %0|%0, %1}";
12945 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12948 [(set_attr "prefix_rep" "1")
12949 (set_attr "type" "bitmanip")
12950 (set_attr "mode" "<MODE>")])
12952 (define_insn "*popcount<mode>2"
12953 [(set (match_operand:SWI248 0 "register_operand" "=r")
12955 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12956 (clobber (reg:CC FLAGS_REG))]
12960 return "popcnt\t{%1, %0|%0, %1}";
12962 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12965 [(set_attr "prefix_rep" "1")
12966 (set_attr "type" "bitmanip")
12967 (set_attr "mode" "<MODE>")])
12969 (define_expand "bswapdi2"
12970 [(set (match_operand:DI 0 "register_operand")
12971 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12975 operands[1] = force_reg (DImode, operands[1]);
12978 (define_expand "bswapsi2"
12979 [(set (match_operand:SI 0 "register_operand")
12980 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12985 else if (TARGET_BSWAP)
12986 operands[1] = force_reg (SImode, operands[1]);
12989 rtx x = operands[0];
12991 emit_move_insn (x, operands[1]);
12992 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12993 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12994 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12999 (define_insn "*bswap<mode>2_movbe"
13000 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13001 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13003 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13006 movbe\t{%1, %0|%0, %1}
13007 movbe\t{%1, %0|%0, %1}"
13008 [(set_attr "type" "bitmanip,imov,imov")
13009 (set_attr "modrm" "0,1,1")
13010 (set_attr "prefix_0f" "*,1,1")
13011 (set_attr "prefix_extra" "*,1,1")
13012 (set_attr "mode" "<MODE>")])
13014 (define_insn "*bswap<mode>2"
13015 [(set (match_operand:SWI48 0 "register_operand" "=r")
13016 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13019 [(set_attr "type" "bitmanip")
13020 (set_attr "modrm" "0")
13021 (set_attr "mode" "<MODE>")])
13023 (define_insn "*bswaphi_lowpart_1"
13024 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13025 (bswap:HI (match_dup 0)))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13029 xchg{b}\t{%h0, %b0|%b0, %h0}
13030 rol{w}\t{$8, %0|%0, 8}"
13031 [(set_attr "length" "2,4")
13032 (set_attr "mode" "QI,HI")])
13034 (define_insn "bswaphi_lowpart"
13035 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13036 (bswap:HI (match_dup 0)))
13037 (clobber (reg:CC FLAGS_REG))]
13039 "rol{w}\t{$8, %0|%0, 8}"
13040 [(set_attr "length" "4")
13041 (set_attr "mode" "HI")])
13043 (define_expand "paritydi2"
13044 [(set (match_operand:DI 0 "register_operand")
13045 (parity:DI (match_operand:DI 1 "register_operand")))]
13048 rtx scratch = gen_reg_rtx (QImode);
13051 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13052 NULL_RTX, operands[1]));
13054 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13055 gen_rtx_REG (CCmode, FLAGS_REG),
13057 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13060 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13063 rtx tmp = gen_reg_rtx (SImode);
13065 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13066 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13071 (define_expand "paritysi2"
13072 [(set (match_operand:SI 0 "register_operand")
13073 (parity:SI (match_operand:SI 1 "register_operand")))]
13076 rtx scratch = gen_reg_rtx (QImode);
13079 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13081 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13082 gen_rtx_REG (CCmode, FLAGS_REG),
13084 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13086 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13090 (define_insn_and_split "paritydi2_cmp"
13091 [(set (reg:CC FLAGS_REG)
13092 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13094 (clobber (match_scratch:DI 0 "=r"))
13095 (clobber (match_scratch:SI 1 "=&r"))
13096 (clobber (match_scratch:HI 2 "=Q"))]
13099 "&& reload_completed"
13101 [(set (match_dup 1)
13102 (xor:SI (match_dup 1) (match_dup 4)))
13103 (clobber (reg:CC FLAGS_REG))])
13105 [(set (reg:CC FLAGS_REG)
13106 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13107 (clobber (match_dup 1))
13108 (clobber (match_dup 2))])]
13110 operands[4] = gen_lowpart (SImode, operands[3]);
13114 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13115 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13118 operands[1] = gen_highpart (SImode, operands[3]);
13121 (define_insn_and_split "paritysi2_cmp"
13122 [(set (reg:CC FLAGS_REG)
13123 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13125 (clobber (match_scratch:SI 0 "=r"))
13126 (clobber (match_scratch:HI 1 "=&Q"))]
13129 "&& reload_completed"
13131 [(set (match_dup 1)
13132 (xor:HI (match_dup 1) (match_dup 3)))
13133 (clobber (reg:CC FLAGS_REG))])
13135 [(set (reg:CC FLAGS_REG)
13136 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13137 (clobber (match_dup 1))])]
13139 operands[3] = gen_lowpart (HImode, operands[2]);
13141 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13142 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13145 (define_insn "*parityhi2_cmp"
13146 [(set (reg:CC FLAGS_REG)
13147 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13149 (clobber (match_scratch:HI 0 "=Q"))]
13151 "xor{b}\t{%h0, %b0|%b0, %h0}"
13152 [(set_attr "length" "2")
13153 (set_attr "mode" "HI")])
13156 ;; Thread-local storage patterns for ELF.
13158 ;; Note that these code sequences must appear exactly as shown
13159 ;; in order to allow linker relaxation.
13161 (define_insn "*tls_global_dynamic_32_gnu"
13162 [(set (match_operand:SI 0 "register_operand" "=a")
13164 [(match_operand:SI 1 "register_operand" "b")
13165 (match_operand 2 "tls_symbolic_operand")
13166 (match_operand 3 "constant_call_address_operand" "Bz")
13169 (clobber (match_scratch:SI 4 "=d"))
13170 (clobber (match_scratch:SI 5 "=c"))
13171 (clobber (reg:CC FLAGS_REG))]
13172 "!TARGET_64BIT && TARGET_GNU_TLS"
13175 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13176 if (TARGET_SUN_TLS)
13177 #ifdef HAVE_AS_IX86_TLSGDPLT
13178 return "call\t%a2@tlsgdplt";
13180 return "call\t%p3@plt";
13182 return "call\t%P3";
13184 [(set_attr "type" "multi")
13185 (set_attr "length" "12")])
13187 (define_expand "tls_global_dynamic_32"
13189 [(set (match_operand:SI 0 "register_operand")
13190 (unspec:SI [(match_operand:SI 2 "register_operand")
13191 (match_operand 1 "tls_symbolic_operand")
13192 (match_operand 3 "constant_call_address_operand")
13195 (clobber (match_scratch:SI 4))
13196 (clobber (match_scratch:SI 5))
13197 (clobber (reg:CC FLAGS_REG))])]
13199 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13201 (define_insn "*tls_global_dynamic_64_<mode>"
13202 [(set (match_operand:P 0 "register_operand" "=a")
13204 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13205 (match_operand 3)))
13206 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13211 fputs (ASM_BYTE "0x66\n", asm_out_file);
13213 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13214 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13215 fputs ("\trex64\n", asm_out_file);
13216 if (TARGET_SUN_TLS)
13217 return "call\t%p2@plt";
13218 return "call\t%P2";
13220 [(set_attr "type" "multi")
13221 (set (attr "length")
13222 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13224 (define_insn "*tls_global_dynamic_64_largepic"
13225 [(set (match_operand:DI 0 "register_operand" "=a")
13227 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13228 (match_operand:DI 3 "immediate_operand" "i")))
13229 (match_operand 4)))
13230 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13232 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13233 && GET_CODE (operands[3]) == CONST
13234 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13235 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13238 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13239 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13240 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13241 return "call\t{*%%rax|rax}";
13243 [(set_attr "type" "multi")
13244 (set_attr "length" "22")])
13246 (define_expand "tls_global_dynamic_64_<mode>"
13248 [(set (match_operand:P 0 "register_operand")
13250 (mem:QI (match_operand 2))
13252 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13255 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13257 (define_insn "*tls_local_dynamic_base_32_gnu"
13258 [(set (match_operand:SI 0 "register_operand" "=a")
13260 [(match_operand:SI 1 "register_operand" "b")
13261 (match_operand 2 "constant_call_address_operand" "Bz")
13263 UNSPEC_TLS_LD_BASE))
13264 (clobber (match_scratch:SI 3 "=d"))
13265 (clobber (match_scratch:SI 4 "=c"))
13266 (clobber (reg:CC FLAGS_REG))]
13267 "!TARGET_64BIT && TARGET_GNU_TLS"
13270 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13271 if (TARGET_SUN_TLS)
13273 if (HAVE_AS_IX86_TLSLDMPLT)
13274 return "call\t%&@tlsldmplt";
13276 return "call\t%p2@plt";
13278 return "call\t%P2";
13280 [(set_attr "type" "multi")
13281 (set_attr "length" "11")])
13283 (define_expand "tls_local_dynamic_base_32"
13285 [(set (match_operand:SI 0 "register_operand")
13287 [(match_operand:SI 1 "register_operand")
13288 (match_operand 2 "constant_call_address_operand")
13290 UNSPEC_TLS_LD_BASE))
13291 (clobber (match_scratch:SI 3))
13292 (clobber (match_scratch:SI 4))
13293 (clobber (reg:CC FLAGS_REG))])]
13295 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13297 (define_insn "*tls_local_dynamic_base_64_<mode>"
13298 [(set (match_operand:P 0 "register_operand" "=a")
13300 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13301 (match_operand 2)))
13302 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13306 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13307 if (TARGET_SUN_TLS)
13308 return "call\t%p1@plt";
13309 return "call\t%P1";
13311 [(set_attr "type" "multi")
13312 (set_attr "length" "12")])
13314 (define_insn "*tls_local_dynamic_base_64_largepic"
13315 [(set (match_operand:DI 0 "register_operand" "=a")
13317 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13318 (match_operand:DI 2 "immediate_operand" "i")))
13319 (match_operand 3)))
13320 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13321 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13322 && GET_CODE (operands[2]) == CONST
13323 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13324 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13327 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13328 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13329 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13330 return "call\t{*%%rax|rax}";
13332 [(set_attr "type" "multi")
13333 (set_attr "length" "22")])
13335 (define_expand "tls_local_dynamic_base_64_<mode>"
13337 [(set (match_operand:P 0 "register_operand")
13339 (mem:QI (match_operand 1))
13341 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13343 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13345 ;; Local dynamic of a single variable is a lose. Show combine how
13346 ;; to convert that back to global dynamic.
13348 (define_insn_and_split "*tls_local_dynamic_32_once"
13349 [(set (match_operand:SI 0 "register_operand" "=a")
13351 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13352 (match_operand 2 "constant_call_address_operand" "Bz")
13354 UNSPEC_TLS_LD_BASE)
13355 (const:SI (unspec:SI
13356 [(match_operand 3 "tls_symbolic_operand")]
13358 (clobber (match_scratch:SI 4 "=d"))
13359 (clobber (match_scratch:SI 5 "=c"))
13360 (clobber (reg:CC FLAGS_REG))]
13365 [(set (match_dup 0)
13366 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13369 (clobber (match_dup 4))
13370 (clobber (match_dup 5))
13371 (clobber (reg:CC FLAGS_REG))])])
13373 ;; Segment register for the thread base ptr load
13374 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13376 ;; Load and add the thread base pointer from %<tp_seg>:0.
13377 (define_insn "*load_tp_x32"
13378 [(set (match_operand:SI 0 "register_operand" "=r")
13379 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13381 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13382 [(set_attr "type" "imov")
13383 (set_attr "modrm" "0")
13384 (set_attr "length" "7")
13385 (set_attr "memory" "load")
13386 (set_attr "imm_disp" "false")])
13388 (define_insn "*load_tp_x32_zext"
13389 [(set (match_operand:DI 0 "register_operand" "=r")
13390 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13392 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13393 [(set_attr "type" "imov")
13394 (set_attr "modrm" "0")
13395 (set_attr "length" "7")
13396 (set_attr "memory" "load")
13397 (set_attr "imm_disp" "false")])
13399 (define_insn "*load_tp_<mode>"
13400 [(set (match_operand:P 0 "register_operand" "=r")
13401 (unspec:P [(const_int 0)] UNSPEC_TP))]
13403 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13404 [(set_attr "type" "imov")
13405 (set_attr "modrm" "0")
13406 (set_attr "length" "7")
13407 (set_attr "memory" "load")
13408 (set_attr "imm_disp" "false")])
13410 (define_insn "*add_tp_x32"
13411 [(set (match_operand:SI 0 "register_operand" "=r")
13412 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13413 (match_operand:SI 1 "register_operand" "0")))
13414 (clobber (reg:CC FLAGS_REG))]
13416 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13417 [(set_attr "type" "alu")
13418 (set_attr "modrm" "0")
13419 (set_attr "length" "7")
13420 (set_attr "memory" "load")
13421 (set_attr "imm_disp" "false")])
13423 (define_insn "*add_tp_x32_zext"
13424 [(set (match_operand:DI 0 "register_operand" "=r")
13426 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13427 (match_operand:SI 1 "register_operand" "0"))))
13428 (clobber (reg:CC FLAGS_REG))]
13430 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13431 [(set_attr "type" "alu")
13432 (set_attr "modrm" "0")
13433 (set_attr "length" "7")
13434 (set_attr "memory" "load")
13435 (set_attr "imm_disp" "false")])
13437 (define_insn "*add_tp_<mode>"
13438 [(set (match_operand:P 0 "register_operand" "=r")
13439 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13440 (match_operand:P 1 "register_operand" "0")))
13441 (clobber (reg:CC FLAGS_REG))]
13443 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13444 [(set_attr "type" "alu")
13445 (set_attr "modrm" "0")
13446 (set_attr "length" "7")
13447 (set_attr "memory" "load")
13448 (set_attr "imm_disp" "false")])
13450 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13451 ;; %rax as destination of the initial executable code sequence.
13452 (define_insn "tls_initial_exec_64_sun"
13453 [(set (match_operand:DI 0 "register_operand" "=a")
13455 [(match_operand 1 "tls_symbolic_operand")]
13456 UNSPEC_TLS_IE_SUN))
13457 (clobber (reg:CC FLAGS_REG))]
13458 "TARGET_64BIT && TARGET_SUN_TLS"
13461 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13462 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13464 [(set_attr "type" "multi")])
13466 ;; GNU2 TLS patterns can be split.
13468 (define_expand "tls_dynamic_gnu2_32"
13469 [(set (match_dup 3)
13470 (plus:SI (match_operand:SI 2 "register_operand")
13472 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13475 [(set (match_operand:SI 0 "register_operand")
13476 (unspec:SI [(match_dup 1) (match_dup 3)
13477 (match_dup 2) (reg:SI SP_REG)]
13479 (clobber (reg:CC FLAGS_REG))])]
13480 "!TARGET_64BIT && TARGET_GNU2_TLS"
13482 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13483 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13486 (define_insn "*tls_dynamic_gnu2_lea_32"
13487 [(set (match_operand:SI 0 "register_operand" "=r")
13488 (plus:SI (match_operand:SI 1 "register_operand" "b")
13490 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13491 UNSPEC_TLSDESC))))]
13492 "!TARGET_64BIT && TARGET_GNU2_TLS"
13493 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13494 [(set_attr "type" "lea")
13495 (set_attr "mode" "SI")
13496 (set_attr "length" "6")
13497 (set_attr "length_address" "4")])
13499 (define_insn "*tls_dynamic_gnu2_call_32"
13500 [(set (match_operand:SI 0 "register_operand" "=a")
13501 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13502 (match_operand:SI 2 "register_operand" "0")
13503 ;; we have to make sure %ebx still points to the GOT
13504 (match_operand:SI 3 "register_operand" "b")
13507 (clobber (reg:CC FLAGS_REG))]
13508 "!TARGET_64BIT && TARGET_GNU2_TLS"
13509 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13510 [(set_attr "type" "call")
13511 (set_attr "length" "2")
13512 (set_attr "length_address" "0")])
13514 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13515 [(set (match_operand:SI 0 "register_operand" "=&a")
13517 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13518 (match_operand:SI 4)
13519 (match_operand:SI 2 "register_operand" "b")
13522 (const:SI (unspec:SI
13523 [(match_operand 1 "tls_symbolic_operand")]
13525 (clobber (reg:CC FLAGS_REG))]
13526 "!TARGET_64BIT && TARGET_GNU2_TLS"
13529 [(set (match_dup 0) (match_dup 5))]
13531 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13532 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13535 (define_expand "tls_dynamic_gnu2_64"
13536 [(set (match_dup 2)
13537 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13540 [(set (match_operand:DI 0 "register_operand")
13541 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13543 (clobber (reg:CC FLAGS_REG))])]
13544 "TARGET_64BIT && TARGET_GNU2_TLS"
13546 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13547 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13550 (define_insn "*tls_dynamic_gnu2_lea_64"
13551 [(set (match_operand:DI 0 "register_operand" "=r")
13552 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13554 "TARGET_64BIT && TARGET_GNU2_TLS"
13555 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13556 [(set_attr "type" "lea")
13557 (set_attr "mode" "DI")
13558 (set_attr "length" "7")
13559 (set_attr "length_address" "4")])
13561 (define_insn "*tls_dynamic_gnu2_call_64"
13562 [(set (match_operand:DI 0 "register_operand" "=a")
13563 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13564 (match_operand:DI 2 "register_operand" "0")
13567 (clobber (reg:CC FLAGS_REG))]
13568 "TARGET_64BIT && TARGET_GNU2_TLS"
13569 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13570 [(set_attr "type" "call")
13571 (set_attr "length" "2")
13572 (set_attr "length_address" "0")])
13574 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13575 [(set (match_operand:DI 0 "register_operand" "=&a")
13577 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13578 (match_operand:DI 3)
13581 (const:DI (unspec:DI
13582 [(match_operand 1 "tls_symbolic_operand")]
13584 (clobber (reg:CC FLAGS_REG))]
13585 "TARGET_64BIT && TARGET_GNU2_TLS"
13588 [(set (match_dup 0) (match_dup 4))]
13590 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13591 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13594 ;; These patterns match the binary 387 instructions for addM3, subM3,
13595 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13596 ;; SFmode. The first is the normal insn, the second the same insn but
13597 ;; with one operand a conversion, and the third the same insn but with
13598 ;; the other operand a conversion. The conversion may be SFmode or
13599 ;; SImode if the target mode DFmode, but only SImode if the target mode
13602 ;; Gcc is slightly more smart about handling normal two address instructions
13603 ;; so use special patterns for add and mull.
13605 (define_insn "*fop_<mode>_comm_mixed"
13606 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13607 (match_operator:MODEF 3 "binary_fp_operator"
13608 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13609 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13610 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13611 && COMMUTATIVE_ARITH_P (operands[3])
13612 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13613 "* return output_387_binary_op (insn, operands);"
13614 [(set (attr "type")
13615 (if_then_else (eq_attr "alternative" "1,2")
13616 (if_then_else (match_operand:MODEF 3 "mult_operator")
13617 (const_string "ssemul")
13618 (const_string "sseadd"))
13619 (if_then_else (match_operand:MODEF 3 "mult_operator")
13620 (const_string "fmul")
13621 (const_string "fop"))))
13622 (set_attr "isa" "*,noavx,avx")
13623 (set_attr "prefix" "orig,orig,vex")
13624 (set_attr "mode" "<MODE>")
13625 (set (attr "enabled")
13626 (cond [(eq_attr "alternative" "0")
13627 (symbol_ref "TARGET_MIX_SSE_I387")
13629 (const_string "*")))])
13631 (define_insn "*fop_<mode>_comm_i387"
13632 [(set (match_operand:MODEF 0 "register_operand" "=f")
13633 (match_operator:MODEF 3 "binary_fp_operator"
13634 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13635 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13636 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13637 && COMMUTATIVE_ARITH_P (operands[3])
13638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13639 "* return output_387_binary_op (insn, operands);"
13640 [(set (attr "type")
13641 (if_then_else (match_operand:MODEF 3 "mult_operator")
13642 (const_string "fmul")
13643 (const_string "fop")))
13644 (set_attr "mode" "<MODE>")])
13646 (define_insn "*rcpsf2_sse"
13647 [(set (match_operand:SF 0 "register_operand" "=x")
13648 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13651 "%vrcpss\t{%1, %d0|%d0, %1}"
13652 [(set_attr "type" "sse")
13653 (set_attr "atom_sse_attr" "rcp")
13654 (set_attr "btver2_sse_attr" "rcp")
13655 (set_attr "prefix" "maybe_vex")
13656 (set_attr "mode" "SF")])
13658 (define_insn "*fop_<mode>_1_mixed"
13659 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13660 (match_operator:MODEF 3 "binary_fp_operator"
13661 [(match_operand:MODEF 1
13662 "register_mixssei387nonimm_operand" "0,fm,0,v")
13663 (match_operand:MODEF 2
13664 "nonimmediate_operand" "fm,0,xm,vm")]))]
13665 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13666 && !COMMUTATIVE_ARITH_P (operands[3])
13667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13668 "* return output_387_binary_op (insn, operands);"
13669 [(set (attr "type")
13670 (cond [(and (eq_attr "alternative" "2,3")
13671 (match_operand:MODEF 3 "mult_operator"))
13672 (const_string "ssemul")
13673 (and (eq_attr "alternative" "2,3")
13674 (match_operand:MODEF 3 "div_operator"))
13675 (const_string "ssediv")
13676 (eq_attr "alternative" "2,3")
13677 (const_string "sseadd")
13678 (match_operand:MODEF 3 "mult_operator")
13679 (const_string "fmul")
13680 (match_operand:MODEF 3 "div_operator")
13681 (const_string "fdiv")
13683 (const_string "fop")))
13684 (set_attr "isa" "*,*,noavx,avx")
13685 (set_attr "prefix" "orig,orig,orig,vex")
13686 (set_attr "mode" "<MODE>")
13687 (set (attr "enabled")
13688 (cond [(eq_attr "alternative" "0,1")
13689 (symbol_ref "TARGET_MIX_SSE_I387")
13691 (const_string "*")))])
13693 ;; This pattern is not fully shadowed by the pattern above.
13694 (define_insn "*fop_<mode>_1_i387"
13695 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13696 (match_operator:MODEF 3 "binary_fp_operator"
13697 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13698 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13699 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13700 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13701 && !COMMUTATIVE_ARITH_P (operands[3])
13702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13703 "* return output_387_binary_op (insn, operands);"
13704 [(set (attr "type")
13705 (cond [(match_operand:MODEF 3 "mult_operator")
13706 (const_string "fmul")
13707 (match_operand:MODEF 3 "div_operator")
13708 (const_string "fdiv")
13710 (const_string "fop")))
13711 (set_attr "mode" "<MODE>")])
13713 ;; ??? Add SSE splitters for these!
13714 (define_insn "*fop_<MODEF:mode>_2_i387"
13715 [(set (match_operand:MODEF 0 "register_operand" "=f")
13716 (match_operator:MODEF 3 "binary_fp_operator"
13718 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13719 (match_operand:MODEF 2 "register_operand" "0")]))]
13720 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13721 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13722 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13723 || optimize_function_for_size_p (cfun))"
13724 { return output_387_binary_op (insn, operands); }
13725 [(set (attr "type")
13726 (cond [(match_operand:MODEF 3 "mult_operator")
13727 (const_string "fmul")
13728 (match_operand:MODEF 3 "div_operator")
13729 (const_string "fdiv")
13731 (const_string "fop")))
13732 (set_attr "fp_int_src" "true")
13733 (set_attr "mode" "<SWI24:MODE>")])
13735 (define_insn "*fop_<MODEF:mode>_3_i387"
13736 [(set (match_operand:MODEF 0 "register_operand" "=f")
13737 (match_operator:MODEF 3 "binary_fp_operator"
13738 [(match_operand:MODEF 1 "register_operand" "0")
13740 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13741 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13742 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13743 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13744 || optimize_function_for_size_p (cfun))"
13745 { return output_387_binary_op (insn, operands); }
13746 [(set (attr "type")
13747 (cond [(match_operand:MODEF 3 "mult_operator")
13748 (const_string "fmul")
13749 (match_operand:MODEF 3 "div_operator")
13750 (const_string "fdiv")
13752 (const_string "fop")))
13753 (set_attr "fp_int_src" "true")
13754 (set_attr "mode" "<MODE>")])
13756 (define_insn "*fop_df_4_i387"
13757 [(set (match_operand:DF 0 "register_operand" "=f,f")
13758 (match_operator:DF 3 "binary_fp_operator"
13760 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13761 (match_operand:DF 2 "register_operand" "0,f")]))]
13762 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13763 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13765 "* return output_387_binary_op (insn, operands);"
13766 [(set (attr "type")
13767 (cond [(match_operand:DF 3 "mult_operator")
13768 (const_string "fmul")
13769 (match_operand:DF 3 "div_operator")
13770 (const_string "fdiv")
13772 (const_string "fop")))
13773 (set_attr "mode" "SF")])
13775 (define_insn "*fop_df_5_i387"
13776 [(set (match_operand:DF 0 "register_operand" "=f,f")
13777 (match_operator:DF 3 "binary_fp_operator"
13778 [(match_operand:DF 1 "register_operand" "0,f")
13780 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13781 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13782 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13783 "* return output_387_binary_op (insn, operands);"
13784 [(set (attr "type")
13785 (cond [(match_operand:DF 3 "mult_operator")
13786 (const_string "fmul")
13787 (match_operand:DF 3 "div_operator")
13788 (const_string "fdiv")
13790 (const_string "fop")))
13791 (set_attr "mode" "SF")])
13793 (define_insn "*fop_df_6_i387"
13794 [(set (match_operand:DF 0 "register_operand" "=f,f")
13795 (match_operator:DF 3 "binary_fp_operator"
13797 (match_operand:SF 1 "register_operand" "0,f"))
13799 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13800 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13801 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13802 "* return output_387_binary_op (insn, operands);"
13803 [(set (attr "type")
13804 (cond [(match_operand:DF 3 "mult_operator")
13805 (const_string "fmul")
13806 (match_operand:DF 3 "div_operator")
13807 (const_string "fdiv")
13809 (const_string "fop")))
13810 (set_attr "mode" "SF")])
13812 (define_insn "*fop_xf_comm_i387"
13813 [(set (match_operand:XF 0 "register_operand" "=f")
13814 (match_operator:XF 3 "binary_fp_operator"
13815 [(match_operand:XF 1 "register_operand" "%0")
13816 (match_operand:XF 2 "register_operand" "f")]))]
13818 && COMMUTATIVE_ARITH_P (operands[3])"
13819 "* return output_387_binary_op (insn, operands);"
13820 [(set (attr "type")
13821 (if_then_else (match_operand:XF 3 "mult_operator")
13822 (const_string "fmul")
13823 (const_string "fop")))
13824 (set_attr "mode" "XF")])
13826 (define_insn "*fop_xf_1_i387"
13827 [(set (match_operand:XF 0 "register_operand" "=f,f")
13828 (match_operator:XF 3 "binary_fp_operator"
13829 [(match_operand:XF 1 "register_operand" "0,f")
13830 (match_operand:XF 2 "register_operand" "f,0")]))]
13832 && !COMMUTATIVE_ARITH_P (operands[3])"
13833 "* return output_387_binary_op (insn, operands);"
13834 [(set (attr "type")
13835 (cond [(match_operand:XF 3 "mult_operator")
13836 (const_string "fmul")
13837 (match_operand:XF 3 "div_operator")
13838 (const_string "fdiv")
13840 (const_string "fop")))
13841 (set_attr "mode" "XF")])
13843 (define_insn "*fop_xf_2_i387"
13844 [(set (match_operand:XF 0 "register_operand" "=f")
13845 (match_operator:XF 3 "binary_fp_operator"
13847 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13848 (match_operand:XF 2 "register_operand" "0")]))]
13850 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13851 { return output_387_binary_op (insn, operands); }
13852 [(set (attr "type")
13853 (cond [(match_operand:XF 3 "mult_operator")
13854 (const_string "fmul")
13855 (match_operand:XF 3 "div_operator")
13856 (const_string "fdiv")
13858 (const_string "fop")))
13859 (set_attr "fp_int_src" "true")
13860 (set_attr "mode" "<MODE>")])
13862 (define_insn "*fop_xf_3_i387"
13863 [(set (match_operand:XF 0 "register_operand" "=f")
13864 (match_operator:XF 3 "binary_fp_operator"
13865 [(match_operand:XF 1 "register_operand" "0")
13867 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13869 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13870 { return output_387_binary_op (insn, operands); }
13871 [(set (attr "type")
13872 (cond [(match_operand:XF 3 "mult_operator")
13873 (const_string "fmul")
13874 (match_operand:XF 3 "div_operator")
13875 (const_string "fdiv")
13877 (const_string "fop")))
13878 (set_attr "fp_int_src" "true")
13879 (set_attr "mode" "<MODE>")])
13881 (define_insn "*fop_xf_4_i387"
13882 [(set (match_operand:XF 0 "register_operand" "=f,f")
13883 (match_operator:XF 3 "binary_fp_operator"
13885 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13886 (match_operand:XF 2 "register_operand" "0,f")]))]
13888 "* return output_387_binary_op (insn, operands);"
13889 [(set (attr "type")
13890 (cond [(match_operand:XF 3 "mult_operator")
13891 (const_string "fmul")
13892 (match_operand:XF 3 "div_operator")
13893 (const_string "fdiv")
13895 (const_string "fop")))
13896 (set_attr "mode" "<MODE>")])
13898 (define_insn "*fop_xf_5_i387"
13899 [(set (match_operand:XF 0 "register_operand" "=f,f")
13900 (match_operator:XF 3 "binary_fp_operator"
13901 [(match_operand:XF 1 "register_operand" "0,f")
13903 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13905 "* return output_387_binary_op (insn, operands);"
13906 [(set (attr "type")
13907 (cond [(match_operand:XF 3 "mult_operator")
13908 (const_string "fmul")
13909 (match_operand:XF 3 "div_operator")
13910 (const_string "fdiv")
13912 (const_string "fop")))
13913 (set_attr "mode" "<MODE>")])
13915 (define_insn "*fop_xf_6_i387"
13916 [(set (match_operand:XF 0 "register_operand" "=f,f")
13917 (match_operator:XF 3 "binary_fp_operator"
13919 (match_operand:MODEF 1 "register_operand" "0,f"))
13921 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13923 "* return output_387_binary_op (insn, operands);"
13924 [(set (attr "type")
13925 (cond [(match_operand:XF 3 "mult_operator")
13926 (const_string "fmul")
13927 (match_operand:XF 3 "div_operator")
13928 (const_string "fdiv")
13930 (const_string "fop")))
13931 (set_attr "mode" "<MODE>")])
13933 ;; FPU special functions.
13935 ;; This pattern implements a no-op XFmode truncation for
13936 ;; all fancy i386 XFmode math functions.
13938 (define_insn "truncxf<mode>2_i387_noop_unspec"
13939 [(set (match_operand:MODEF 0 "register_operand" "=f")
13940 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13941 UNSPEC_TRUNC_NOOP))]
13942 "TARGET_USE_FANCY_MATH_387"
13943 "* return output_387_reg_move (insn, operands);"
13944 [(set_attr "type" "fmov")
13945 (set_attr "mode" "<MODE>")])
13947 (define_insn "sqrtxf2"
13948 [(set (match_operand:XF 0 "register_operand" "=f")
13949 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13950 "TARGET_USE_FANCY_MATH_387"
13952 [(set_attr "type" "fpspc")
13953 (set_attr "mode" "XF")
13954 (set_attr "athlon_decode" "direct")
13955 (set_attr "amdfam10_decode" "direct")
13956 (set_attr "bdver1_decode" "direct")])
13958 (define_insn "sqrt_extend<mode>xf2_i387"
13959 [(set (match_operand:XF 0 "register_operand" "=f")
13962 (match_operand:MODEF 1 "register_operand" "0"))))]
13963 "TARGET_USE_FANCY_MATH_387"
13965 [(set_attr "type" "fpspc")
13966 (set_attr "mode" "XF")
13967 (set_attr "athlon_decode" "direct")
13968 (set_attr "amdfam10_decode" "direct")
13969 (set_attr "bdver1_decode" "direct")])
13971 (define_insn "*rsqrtsf2_sse"
13972 [(set (match_operand:SF 0 "register_operand" "=x")
13973 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13976 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13977 [(set_attr "type" "sse")
13978 (set_attr "atom_sse_attr" "rcp")
13979 (set_attr "btver2_sse_attr" "rcp")
13980 (set_attr "prefix" "maybe_vex")
13981 (set_attr "mode" "SF")])
13983 (define_expand "rsqrtsf2"
13984 [(set (match_operand:SF 0 "register_operand")
13985 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13989 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13993 (define_insn "*sqrt<mode>2_sse"
13994 [(set (match_operand:MODEF 0 "register_operand" "=v")
13996 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
13997 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13998 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13999 [(set_attr "type" "sse")
14000 (set_attr "atom_sse_attr" "sqrt")
14001 (set_attr "btver2_sse_attr" "sqrt")
14002 (set_attr "prefix" "maybe_vex")
14003 (set_attr "mode" "<MODE>")
14004 (set_attr "athlon_decode" "*")
14005 (set_attr "amdfam10_decode" "*")
14006 (set_attr "bdver1_decode" "*")])
14008 (define_expand "sqrt<mode>2"
14009 [(set (match_operand:MODEF 0 "register_operand")
14011 (match_operand:MODEF 1 "nonimmediate_operand")))]
14012 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14013 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14015 if (<MODE>mode == SFmode
14017 && TARGET_RECIP_SQRT
14018 && !optimize_function_for_size_p (cfun)
14019 && flag_finite_math_only && !flag_trapping_math
14020 && flag_unsafe_math_optimizations)
14022 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14026 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14028 rtx op0 = gen_reg_rtx (XFmode);
14029 rtx op1 = force_reg (<MODE>mode, operands[1]);
14031 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14032 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14037 (define_insn "fpremxf4_i387"
14038 [(set (match_operand:XF 0 "register_operand" "=f")
14039 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14040 (match_operand:XF 3 "register_operand" "1")]
14042 (set (match_operand:XF 1 "register_operand" "=u")
14043 (unspec:XF [(match_dup 2) (match_dup 3)]
14045 (set (reg:CCFP FPSR_REG)
14046 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14048 "TARGET_USE_FANCY_MATH_387
14049 && flag_finite_math_only"
14051 [(set_attr "type" "fpspc")
14052 (set_attr "mode" "XF")])
14054 (define_expand "fmodxf3"
14055 [(use (match_operand:XF 0 "register_operand"))
14056 (use (match_operand:XF 1 "general_operand"))
14057 (use (match_operand:XF 2 "general_operand"))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_finite_math_only"
14061 rtx_code_label *label = gen_label_rtx ();
14063 rtx op1 = gen_reg_rtx (XFmode);
14064 rtx op2 = gen_reg_rtx (XFmode);
14066 emit_move_insn (op2, operands[2]);
14067 emit_move_insn (op1, operands[1]);
14069 emit_label (label);
14070 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14071 ix86_emit_fp_unordered_jump (label);
14072 LABEL_NUSES (label) = 1;
14074 emit_move_insn (operands[0], op1);
14078 (define_expand "fmod<mode>3"
14079 [(use (match_operand:MODEF 0 "register_operand"))
14080 (use (match_operand:MODEF 1 "general_operand"))
14081 (use (match_operand:MODEF 2 "general_operand"))]
14082 "TARGET_USE_FANCY_MATH_387
14083 && flag_finite_math_only"
14085 rtx (*gen_truncxf) (rtx, rtx);
14087 rtx_code_label *label = gen_label_rtx ();
14089 rtx op1 = gen_reg_rtx (XFmode);
14090 rtx op2 = gen_reg_rtx (XFmode);
14092 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14093 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14095 emit_label (label);
14096 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14097 ix86_emit_fp_unordered_jump (label);
14098 LABEL_NUSES (label) = 1;
14100 /* Truncate the result properly for strict SSE math. */
14101 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14102 && !TARGET_MIX_SSE_I387)
14103 gen_truncxf = gen_truncxf<mode>2;
14105 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14107 emit_insn (gen_truncxf (operands[0], op1));
14111 (define_insn "fprem1xf4_i387"
14112 [(set (match_operand:XF 0 "register_operand" "=f")
14113 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14114 (match_operand:XF 3 "register_operand" "1")]
14116 (set (match_operand:XF 1 "register_operand" "=u")
14117 (unspec:XF [(match_dup 2) (match_dup 3)]
14119 (set (reg:CCFP FPSR_REG)
14120 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14122 "TARGET_USE_FANCY_MATH_387
14123 && flag_finite_math_only"
14125 [(set_attr "type" "fpspc")
14126 (set_attr "mode" "XF")])
14128 (define_expand "remainderxf3"
14129 [(use (match_operand:XF 0 "register_operand"))
14130 (use (match_operand:XF 1 "general_operand"))
14131 (use (match_operand:XF 2 "general_operand"))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && flag_finite_math_only"
14135 rtx_code_label *label = gen_label_rtx ();
14137 rtx op1 = gen_reg_rtx (XFmode);
14138 rtx op2 = gen_reg_rtx (XFmode);
14140 emit_move_insn (op2, operands[2]);
14141 emit_move_insn (op1, operands[1]);
14143 emit_label (label);
14144 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14145 ix86_emit_fp_unordered_jump (label);
14146 LABEL_NUSES (label) = 1;
14148 emit_move_insn (operands[0], op1);
14152 (define_expand "remainder<mode>3"
14153 [(use (match_operand:MODEF 0 "register_operand"))
14154 (use (match_operand:MODEF 1 "general_operand"))
14155 (use (match_operand:MODEF 2 "general_operand"))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_finite_math_only"
14159 rtx (*gen_truncxf) (rtx, rtx);
14161 rtx_code_label *label = gen_label_rtx ();
14163 rtx op1 = gen_reg_rtx (XFmode);
14164 rtx op2 = gen_reg_rtx (XFmode);
14166 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14167 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14169 emit_label (label);
14171 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14172 ix86_emit_fp_unordered_jump (label);
14173 LABEL_NUSES (label) = 1;
14175 /* Truncate the result properly for strict SSE math. */
14176 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14177 && !TARGET_MIX_SSE_I387)
14178 gen_truncxf = gen_truncxf<mode>2;
14180 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14182 emit_insn (gen_truncxf (operands[0], op1));
14186 (define_int_iterator SINCOS
14190 (define_int_attr sincos
14191 [(UNSPEC_SIN "sin")
14192 (UNSPEC_COS "cos")])
14194 (define_insn "*<sincos>xf2_i387"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14201 [(set_attr "type" "fpspc")
14202 (set_attr "mode" "XF")])
14204 (define_insn "*<sincos>_extend<mode>xf2_i387"
14205 [(set (match_operand:XF 0 "register_operand" "=f")
14206 (unspec:XF [(float_extend:XF
14207 (match_operand:MODEF 1 "register_operand" "0"))]
14209 "TARGET_USE_FANCY_MATH_387
14210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211 || TARGET_MIX_SSE_I387)
14212 && flag_unsafe_math_optimizations"
14214 [(set_attr "type" "fpspc")
14215 (set_attr "mode" "XF")])
14217 ;; When sincos pattern is defined, sin and cos builtin functions will be
14218 ;; expanded to sincos pattern with one of its outputs left unused.
14219 ;; CSE pass will figure out if two sincos patterns can be combined,
14220 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14221 ;; depending on the unused output.
14223 (define_insn "sincosxf3"
14224 [(set (match_operand:XF 0 "register_operand" "=f")
14225 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14226 UNSPEC_SINCOS_COS))
14227 (set (match_operand:XF 1 "register_operand" "=u")
14228 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14229 "TARGET_USE_FANCY_MATH_387
14230 && flag_unsafe_math_optimizations"
14232 [(set_attr "type" "fpspc")
14233 (set_attr "mode" "XF")])
14236 [(set (match_operand:XF 0 "register_operand")
14237 (unspec:XF [(match_operand:XF 2 "register_operand")]
14238 UNSPEC_SINCOS_COS))
14239 (set (match_operand:XF 1 "register_operand")
14240 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14241 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14242 && can_create_pseudo_p ()"
14243 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14246 [(set (match_operand:XF 0 "register_operand")
14247 (unspec:XF [(match_operand:XF 2 "register_operand")]
14248 UNSPEC_SINCOS_COS))
14249 (set (match_operand:XF 1 "register_operand")
14250 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14251 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14252 && can_create_pseudo_p ()"
14253 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14255 (define_insn "sincos_extend<mode>xf3_i387"
14256 [(set (match_operand:XF 0 "register_operand" "=f")
14257 (unspec:XF [(float_extend:XF
14258 (match_operand:MODEF 2 "register_operand" "0"))]
14259 UNSPEC_SINCOS_COS))
14260 (set (match_operand:XF 1 "register_operand" "=u")
14261 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14267 [(set_attr "type" "fpspc")
14268 (set_attr "mode" "XF")])
14271 [(set (match_operand:XF 0 "register_operand")
14272 (unspec:XF [(float_extend:XF
14273 (match_operand:MODEF 2 "register_operand"))]
14274 UNSPEC_SINCOS_COS))
14275 (set (match_operand:XF 1 "register_operand")
14276 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14277 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14278 && can_create_pseudo_p ()"
14279 [(set (match_dup 1)
14280 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14283 [(set (match_operand:XF 0 "register_operand")
14284 (unspec:XF [(float_extend:XF
14285 (match_operand:MODEF 2 "register_operand"))]
14286 UNSPEC_SINCOS_COS))
14287 (set (match_operand:XF 1 "register_operand")
14288 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14289 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14290 && can_create_pseudo_p ()"
14291 [(set (match_dup 0)
14292 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14294 (define_expand "sincos<mode>3"
14295 [(use (match_operand:MODEF 0 "register_operand"))
14296 (use (match_operand:MODEF 1 "register_operand"))
14297 (use (match_operand:MODEF 2 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14303 rtx op0 = gen_reg_rtx (XFmode);
14304 rtx op1 = gen_reg_rtx (XFmode);
14306 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14307 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14308 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14312 (define_insn "fptanxf4_i387"
14313 [(set (match_operand:XF 0 "register_operand" "=f")
14314 (match_operand:XF 3 "const_double_operand" "F"))
14315 (set (match_operand:XF 1 "register_operand" "=u")
14316 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14318 "TARGET_USE_FANCY_MATH_387
14319 && flag_unsafe_math_optimizations
14320 && standard_80387_constant_p (operands[3]) == 2"
14322 [(set_attr "type" "fpspc")
14323 (set_attr "mode" "XF")])
14325 (define_insn "fptan_extend<mode>xf4_i387"
14326 [(set (match_operand:MODEF 0 "register_operand" "=f")
14327 (match_operand:MODEF 3 "const_double_operand" "F"))
14328 (set (match_operand:XF 1 "register_operand" "=u")
14329 (unspec:XF [(float_extend:XF
14330 (match_operand:MODEF 2 "register_operand" "0"))]
14332 "TARGET_USE_FANCY_MATH_387
14333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334 || TARGET_MIX_SSE_I387)
14335 && flag_unsafe_math_optimizations
14336 && standard_80387_constant_p (operands[3]) == 2"
14338 [(set_attr "type" "fpspc")
14339 (set_attr "mode" "XF")])
14341 (define_expand "tanxf2"
14342 [(use (match_operand:XF 0 "register_operand"))
14343 (use (match_operand:XF 1 "register_operand"))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14347 rtx one = gen_reg_rtx (XFmode);
14348 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14350 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14354 (define_expand "tan<mode>2"
14355 [(use (match_operand:MODEF 0 "register_operand"))
14356 (use (match_operand:MODEF 1 "register_operand"))]
14357 "TARGET_USE_FANCY_MATH_387
14358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14359 || TARGET_MIX_SSE_I387)
14360 && flag_unsafe_math_optimizations"
14362 rtx op0 = gen_reg_rtx (XFmode);
14364 rtx one = gen_reg_rtx (<MODE>mode);
14365 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14367 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14368 operands[1], op2));
14369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14373 (define_insn "*fpatanxf3_i387"
14374 [(set (match_operand:XF 0 "register_operand" "=f")
14375 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14376 (match_operand:XF 2 "register_operand" "u")]
14378 (clobber (match_scratch:XF 3 "=2"))]
14379 "TARGET_USE_FANCY_MATH_387
14380 && flag_unsafe_math_optimizations"
14382 [(set_attr "type" "fpspc")
14383 (set_attr "mode" "XF")])
14385 (define_insn "fpatan_extend<mode>xf3_i387"
14386 [(set (match_operand:XF 0 "register_operand" "=f")
14387 (unspec:XF [(float_extend:XF
14388 (match_operand:MODEF 1 "register_operand" "0"))
14390 (match_operand:MODEF 2 "register_operand" "u"))]
14392 (clobber (match_scratch:XF 3 "=2"))]
14393 "TARGET_USE_FANCY_MATH_387
14394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395 || TARGET_MIX_SSE_I387)
14396 && flag_unsafe_math_optimizations"
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "XF")])
14401 (define_expand "atan2xf3"
14402 [(parallel [(set (match_operand:XF 0 "register_operand")
14403 (unspec:XF [(match_operand:XF 2 "register_operand")
14404 (match_operand:XF 1 "register_operand")]
14406 (clobber (match_scratch:XF 3))])]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations")
14410 (define_expand "atan2<mode>3"
14411 [(use (match_operand:MODEF 0 "register_operand"))
14412 (use (match_operand:MODEF 1 "register_operand"))
14413 (use (match_operand:MODEF 2 "register_operand"))]
14414 "TARGET_USE_FANCY_MATH_387
14415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14416 || TARGET_MIX_SSE_I387)
14417 && flag_unsafe_math_optimizations"
14419 rtx op0 = gen_reg_rtx (XFmode);
14421 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14426 (define_expand "atanxf2"
14427 [(parallel [(set (match_operand:XF 0 "register_operand")
14428 (unspec:XF [(match_dup 2)
14429 (match_operand:XF 1 "register_operand")]
14431 (clobber (match_scratch:XF 3))])]
14432 "TARGET_USE_FANCY_MATH_387
14433 && flag_unsafe_math_optimizations"
14435 operands[2] = gen_reg_rtx (XFmode);
14436 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14439 (define_expand "atan<mode>2"
14440 [(use (match_operand:MODEF 0 "register_operand"))
14441 (use (match_operand:MODEF 1 "register_operand"))]
14442 "TARGET_USE_FANCY_MATH_387
14443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14444 || TARGET_MIX_SSE_I387)
14445 && flag_unsafe_math_optimizations"
14447 rtx op0 = gen_reg_rtx (XFmode);
14449 rtx op2 = gen_reg_rtx (<MODE>mode);
14450 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14452 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14453 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14457 (define_expand "asinxf2"
14458 [(set (match_dup 2)
14459 (mult:XF (match_operand:XF 1 "register_operand")
14461 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14462 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14463 (parallel [(set (match_operand:XF 0 "register_operand")
14464 (unspec:XF [(match_dup 5) (match_dup 1)]
14466 (clobber (match_scratch:XF 6))])]
14467 "TARGET_USE_FANCY_MATH_387
14468 && flag_unsafe_math_optimizations"
14472 if (optimize_insn_for_size_p ())
14475 for (i = 2; i < 6; i++)
14476 operands[i] = gen_reg_rtx (XFmode);
14478 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14481 (define_expand "asin<mode>2"
14482 [(use (match_operand:MODEF 0 "register_operand"))
14483 (use (match_operand:MODEF 1 "general_operand"))]
14484 "TARGET_USE_FANCY_MATH_387
14485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14486 || TARGET_MIX_SSE_I387)
14487 && flag_unsafe_math_optimizations"
14489 rtx op0 = gen_reg_rtx (XFmode);
14490 rtx op1 = gen_reg_rtx (XFmode);
14492 if (optimize_insn_for_size_p ())
14495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496 emit_insn (gen_asinxf2 (op0, op1));
14497 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14501 (define_expand "acosxf2"
14502 [(set (match_dup 2)
14503 (mult:XF (match_operand:XF 1 "register_operand")
14505 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14506 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14507 (parallel [(set (match_operand:XF 0 "register_operand")
14508 (unspec:XF [(match_dup 1) (match_dup 5)]
14510 (clobber (match_scratch:XF 6))])]
14511 "TARGET_USE_FANCY_MATH_387
14512 && flag_unsafe_math_optimizations"
14516 if (optimize_insn_for_size_p ())
14519 for (i = 2; i < 6; i++)
14520 operands[i] = gen_reg_rtx (XFmode);
14522 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14525 (define_expand "acos<mode>2"
14526 [(use (match_operand:MODEF 0 "register_operand"))
14527 (use (match_operand:MODEF 1 "general_operand"))]
14528 "TARGET_USE_FANCY_MATH_387
14529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14530 || TARGET_MIX_SSE_I387)
14531 && flag_unsafe_math_optimizations"
14533 rtx op0 = gen_reg_rtx (XFmode);
14534 rtx op1 = gen_reg_rtx (XFmode);
14536 if (optimize_insn_for_size_p ())
14539 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14540 emit_insn (gen_acosxf2 (op0, op1));
14541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14545 (define_insn "fyl2xxf3_i387"
14546 [(set (match_operand:XF 0 "register_operand" "=f")
14547 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14548 (match_operand:XF 2 "register_operand" "u")]
14550 (clobber (match_scratch:XF 3 "=2"))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14557 (define_insn "fyl2x_extend<mode>xf3_i387"
14558 [(set (match_operand:XF 0 "register_operand" "=f")
14559 (unspec:XF [(float_extend:XF
14560 (match_operand:MODEF 1 "register_operand" "0"))
14561 (match_operand:XF 2 "register_operand" "u")]
14563 (clobber (match_scratch:XF 3 "=2"))]
14564 "TARGET_USE_FANCY_MATH_387
14565 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14566 || TARGET_MIX_SSE_I387)
14567 && flag_unsafe_math_optimizations"
14569 [(set_attr "type" "fpspc")
14570 (set_attr "mode" "XF")])
14572 (define_expand "logxf2"
14573 [(parallel [(set (match_operand:XF 0 "register_operand")
14574 (unspec:XF [(match_operand:XF 1 "register_operand")
14575 (match_dup 2)] UNSPEC_FYL2X))
14576 (clobber (match_scratch:XF 3))])]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14580 operands[2] = gen_reg_rtx (XFmode);
14581 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14584 (define_expand "log<mode>2"
14585 [(use (match_operand:MODEF 0 "register_operand"))
14586 (use (match_operand:MODEF 1 "register_operand"))]
14587 "TARGET_USE_FANCY_MATH_387
14588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14589 || TARGET_MIX_SSE_I387)
14590 && flag_unsafe_math_optimizations"
14592 rtx op0 = gen_reg_rtx (XFmode);
14594 rtx op2 = gen_reg_rtx (XFmode);
14595 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14597 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14598 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14602 (define_expand "log10xf2"
14603 [(parallel [(set (match_operand:XF 0 "register_operand")
14604 (unspec:XF [(match_operand:XF 1 "register_operand")
14605 (match_dup 2)] UNSPEC_FYL2X))
14606 (clobber (match_scratch:XF 3))])]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14610 operands[2] = gen_reg_rtx (XFmode);
14611 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14614 (define_expand "log10<mode>2"
14615 [(use (match_operand:MODEF 0 "register_operand"))
14616 (use (match_operand:MODEF 1 "register_operand"))]
14617 "TARGET_USE_FANCY_MATH_387
14618 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14619 || TARGET_MIX_SSE_I387)
14620 && flag_unsafe_math_optimizations"
14622 rtx op0 = gen_reg_rtx (XFmode);
14624 rtx op2 = gen_reg_rtx (XFmode);
14625 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14627 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14628 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14632 (define_expand "log2xf2"
14633 [(parallel [(set (match_operand:XF 0 "register_operand")
14634 (unspec:XF [(match_operand:XF 1 "register_operand")
14635 (match_dup 2)] UNSPEC_FYL2X))
14636 (clobber (match_scratch:XF 3))])]
14637 "TARGET_USE_FANCY_MATH_387
14638 && flag_unsafe_math_optimizations"
14640 operands[2] = gen_reg_rtx (XFmode);
14641 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14644 (define_expand "log2<mode>2"
14645 [(use (match_operand:MODEF 0 "register_operand"))
14646 (use (match_operand:MODEF 1 "register_operand"))]
14647 "TARGET_USE_FANCY_MATH_387
14648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649 || TARGET_MIX_SSE_I387)
14650 && flag_unsafe_math_optimizations"
14652 rtx op0 = gen_reg_rtx (XFmode);
14654 rtx op2 = gen_reg_rtx (XFmode);
14655 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14657 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14658 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14662 (define_insn "fyl2xp1xf3_i387"
14663 [(set (match_operand:XF 0 "register_operand" "=f")
14664 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14665 (match_operand:XF 2 "register_operand" "u")]
14667 (clobber (match_scratch:XF 3 "=2"))]
14668 "TARGET_USE_FANCY_MATH_387
14669 && flag_unsafe_math_optimizations"
14671 [(set_attr "type" "fpspc")
14672 (set_attr "mode" "XF")])
14674 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (unspec:XF [(float_extend:XF
14677 (match_operand:MODEF 1 "register_operand" "0"))
14678 (match_operand:XF 2 "register_operand" "u")]
14680 (clobber (match_scratch:XF 3 "=2"))]
14681 "TARGET_USE_FANCY_MATH_387
14682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14683 || TARGET_MIX_SSE_I387)
14684 && flag_unsafe_math_optimizations"
14686 [(set_attr "type" "fpspc")
14687 (set_attr "mode" "XF")])
14689 (define_expand "log1pxf2"
14690 [(use (match_operand:XF 0 "register_operand"))
14691 (use (match_operand:XF 1 "register_operand"))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations"
14695 if (optimize_insn_for_size_p ())
14698 ix86_emit_i387_log1p (operands[0], operands[1]);
14702 (define_expand "log1p<mode>2"
14703 [(use (match_operand:MODEF 0 "register_operand"))
14704 (use (match_operand:MODEF 1 "register_operand"))]
14705 "TARGET_USE_FANCY_MATH_387
14706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14707 || TARGET_MIX_SSE_I387)
14708 && flag_unsafe_math_optimizations"
14712 if (optimize_insn_for_size_p ())
14715 op0 = gen_reg_rtx (XFmode);
14717 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14719 ix86_emit_i387_log1p (op0, operands[1]);
14720 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14724 (define_insn "fxtractxf3_i387"
14725 [(set (match_operand:XF 0 "register_operand" "=f")
14726 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14727 UNSPEC_XTRACT_FRACT))
14728 (set (match_operand:XF 1 "register_operand" "=u")
14729 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && flag_unsafe_math_optimizations"
14733 [(set_attr "type" "fpspc")
14734 (set_attr "mode" "XF")])
14736 (define_insn "fxtract_extend<mode>xf3_i387"
14737 [(set (match_operand:XF 0 "register_operand" "=f")
14738 (unspec:XF [(float_extend:XF
14739 (match_operand:MODEF 2 "register_operand" "0"))]
14740 UNSPEC_XTRACT_FRACT))
14741 (set (match_operand:XF 1 "register_operand" "=u")
14742 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14743 "TARGET_USE_FANCY_MATH_387
14744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14745 || TARGET_MIX_SSE_I387)
14746 && flag_unsafe_math_optimizations"
14748 [(set_attr "type" "fpspc")
14749 (set_attr "mode" "XF")])
14751 (define_expand "logbxf2"
14752 [(parallel [(set (match_dup 2)
14753 (unspec:XF [(match_operand:XF 1 "register_operand")]
14754 UNSPEC_XTRACT_FRACT))
14755 (set (match_operand:XF 0 "register_operand")
14756 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations"
14759 "operands[2] = gen_reg_rtx (XFmode);")
14761 (define_expand "logb<mode>2"
14762 [(use (match_operand:MODEF 0 "register_operand"))
14763 (use (match_operand:MODEF 1 "register_operand"))]
14764 "TARGET_USE_FANCY_MATH_387
14765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14766 || TARGET_MIX_SSE_I387)
14767 && flag_unsafe_math_optimizations"
14769 rtx op0 = gen_reg_rtx (XFmode);
14770 rtx op1 = gen_reg_rtx (XFmode);
14772 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14773 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14777 (define_expand "ilogbxf2"
14778 [(use (match_operand:SI 0 "register_operand"))
14779 (use (match_operand:XF 1 "register_operand"))]
14780 "TARGET_USE_FANCY_MATH_387
14781 && flag_unsafe_math_optimizations"
14785 if (optimize_insn_for_size_p ())
14788 op0 = gen_reg_rtx (XFmode);
14789 op1 = gen_reg_rtx (XFmode);
14791 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14792 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14796 (define_expand "ilogb<mode>2"
14797 [(use (match_operand:SI 0 "register_operand"))
14798 (use (match_operand:MODEF 1 "register_operand"))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14801 || TARGET_MIX_SSE_I387)
14802 && flag_unsafe_math_optimizations"
14806 if (optimize_insn_for_size_p ())
14809 op0 = gen_reg_rtx (XFmode);
14810 op1 = gen_reg_rtx (XFmode);
14812 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14813 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14817 (define_insn "*f2xm1xf2_i387"
14818 [(set (match_operand:XF 0 "register_operand" "=f")
14819 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14821 "TARGET_USE_FANCY_MATH_387
14822 && flag_unsafe_math_optimizations"
14824 [(set_attr "type" "fpspc")
14825 (set_attr "mode" "XF")])
14827 (define_insn "fscalexf4_i387"
14828 [(set (match_operand:XF 0 "register_operand" "=f")
14829 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14830 (match_operand:XF 3 "register_operand" "1")]
14831 UNSPEC_FSCALE_FRACT))
14832 (set (match_operand:XF 1 "register_operand" "=u")
14833 (unspec:XF [(match_dup 2) (match_dup 3)]
14834 UNSPEC_FSCALE_EXP))]
14835 "TARGET_USE_FANCY_MATH_387
14836 && flag_unsafe_math_optimizations"
14838 [(set_attr "type" "fpspc")
14839 (set_attr "mode" "XF")])
14841 (define_expand "expNcorexf3"
14842 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14843 (match_operand:XF 2 "register_operand")))
14844 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14845 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14846 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14847 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14848 (parallel [(set (match_operand:XF 0 "register_operand")
14849 (unspec:XF [(match_dup 8) (match_dup 4)]
14850 UNSPEC_FSCALE_FRACT))
14852 (unspec:XF [(match_dup 8) (match_dup 4)]
14853 UNSPEC_FSCALE_EXP))])]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14859 if (optimize_insn_for_size_p ())
14862 for (i = 3; i < 10; i++)
14863 operands[i] = gen_reg_rtx (XFmode);
14865 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14868 (define_expand "expxf2"
14869 [(use (match_operand:XF 0 "register_operand"))
14870 (use (match_operand:XF 1 "register_operand"))]
14871 "TARGET_USE_FANCY_MATH_387
14872 && flag_unsafe_math_optimizations"
14876 if (optimize_insn_for_size_p ())
14879 op2 = gen_reg_rtx (XFmode);
14880 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14882 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14886 (define_expand "exp<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand"))
14888 (use (match_operand:MODEF 1 "general_operand"))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations"
14896 if (optimize_insn_for_size_p ())
14899 op0 = gen_reg_rtx (XFmode);
14900 op1 = gen_reg_rtx (XFmode);
14902 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14903 emit_insn (gen_expxf2 (op0, op1));
14904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14908 (define_expand "exp10xf2"
14909 [(use (match_operand:XF 0 "register_operand"))
14910 (use (match_operand:XF 1 "register_operand"))]
14911 "TARGET_USE_FANCY_MATH_387
14912 && flag_unsafe_math_optimizations"
14916 if (optimize_insn_for_size_p ())
14919 op2 = gen_reg_rtx (XFmode);
14920 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14922 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14926 (define_expand "exp10<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand"))
14928 (use (match_operand:MODEF 1 "general_operand"))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
14932 && flag_unsafe_math_optimizations"
14936 if (optimize_insn_for_size_p ())
14939 op0 = gen_reg_rtx (XFmode);
14940 op1 = gen_reg_rtx (XFmode);
14942 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14943 emit_insn (gen_exp10xf2 (op0, op1));
14944 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14948 (define_expand "exp2xf2"
14949 [(use (match_operand:XF 0 "register_operand"))
14950 (use (match_operand:XF 1 "register_operand"))]
14951 "TARGET_USE_FANCY_MATH_387
14952 && flag_unsafe_math_optimizations"
14956 if (optimize_insn_for_size_p ())
14959 op2 = gen_reg_rtx (XFmode);
14960 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14962 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14966 (define_expand "exp2<mode>2"
14967 [(use (match_operand:MODEF 0 "register_operand"))
14968 (use (match_operand:MODEF 1 "general_operand"))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971 || TARGET_MIX_SSE_I387)
14972 && flag_unsafe_math_optimizations"
14976 if (optimize_insn_for_size_p ())
14979 op0 = gen_reg_rtx (XFmode);
14980 op1 = gen_reg_rtx (XFmode);
14982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14983 emit_insn (gen_exp2xf2 (op0, op1));
14984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14988 (define_expand "expm1xf2"
14989 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14991 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14992 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14993 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14994 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14995 (parallel [(set (match_dup 7)
14996 (unspec:XF [(match_dup 6) (match_dup 4)]
14997 UNSPEC_FSCALE_FRACT))
14999 (unspec:XF [(match_dup 6) (match_dup 4)]
15000 UNSPEC_FSCALE_EXP))])
15001 (parallel [(set (match_dup 10)
15002 (unspec:XF [(match_dup 9) (match_dup 8)]
15003 UNSPEC_FSCALE_FRACT))
15004 (set (match_dup 11)
15005 (unspec:XF [(match_dup 9) (match_dup 8)]
15006 UNSPEC_FSCALE_EXP))])
15007 (set (match_dup 12) (minus:XF (match_dup 10)
15008 (float_extend:XF (match_dup 13))))
15009 (set (match_operand:XF 0 "register_operand")
15010 (plus:XF (match_dup 12) (match_dup 7)))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15016 if (optimize_insn_for_size_p ())
15019 for (i = 2; i < 13; i++)
15020 operands[i] = gen_reg_rtx (XFmode);
15023 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15025 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15028 (define_expand "expm1<mode>2"
15029 [(use (match_operand:MODEF 0 "register_operand"))
15030 (use (match_operand:MODEF 1 "general_operand"))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15033 || TARGET_MIX_SSE_I387)
15034 && flag_unsafe_math_optimizations"
15038 if (optimize_insn_for_size_p ())
15041 op0 = gen_reg_rtx (XFmode);
15042 op1 = gen_reg_rtx (XFmode);
15044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15045 emit_insn (gen_expm1xf2 (op0, op1));
15046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15050 (define_expand "ldexpxf3"
15051 [(match_operand:XF 0 "register_operand")
15052 (match_operand:XF 1 "register_operand")
15053 (match_operand:SI 2 "register_operand")]
15054 "TARGET_USE_FANCY_MATH_387
15055 && flag_unsafe_math_optimizations"
15058 if (optimize_insn_for_size_p ())
15061 tmp1 = gen_reg_rtx (XFmode);
15062 tmp2 = gen_reg_rtx (XFmode);
15064 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15065 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15066 operands[1], tmp1));
15070 (define_expand "ldexp<mode>3"
15071 [(use (match_operand:MODEF 0 "register_operand"))
15072 (use (match_operand:MODEF 1 "general_operand"))
15073 (use (match_operand:SI 2 "register_operand"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15076 || TARGET_MIX_SSE_I387)
15077 && flag_unsafe_math_optimizations"
15081 if (optimize_insn_for_size_p ())
15084 op0 = gen_reg_rtx (XFmode);
15085 op1 = gen_reg_rtx (XFmode);
15087 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15088 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15093 (define_expand "scalbxf3"
15094 [(parallel [(set (match_operand:XF 0 " register_operand")
15095 (unspec:XF [(match_operand:XF 1 "register_operand")
15096 (match_operand:XF 2 "register_operand")]
15097 UNSPEC_FSCALE_FRACT))
15099 (unspec:XF [(match_dup 1) (match_dup 2)]
15100 UNSPEC_FSCALE_EXP))])]
15101 "TARGET_USE_FANCY_MATH_387
15102 && flag_unsafe_math_optimizations"
15104 if (optimize_insn_for_size_p ())
15107 operands[3] = gen_reg_rtx (XFmode);
15110 (define_expand "scalb<mode>3"
15111 [(use (match_operand:MODEF 0 "register_operand"))
15112 (use (match_operand:MODEF 1 "general_operand"))
15113 (use (match_operand:MODEF 2 "general_operand"))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116 || TARGET_MIX_SSE_I387)
15117 && flag_unsafe_math_optimizations"
15121 if (optimize_insn_for_size_p ())
15124 op0 = gen_reg_rtx (XFmode);
15125 op1 = gen_reg_rtx (XFmode);
15126 op2 = gen_reg_rtx (XFmode);
15128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15129 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15130 emit_insn (gen_scalbxf3 (op0, op1, op2));
15131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15135 (define_expand "significandxf2"
15136 [(parallel [(set (match_operand:XF 0 "register_operand")
15137 (unspec:XF [(match_operand:XF 1 "register_operand")]
15138 UNSPEC_XTRACT_FRACT))
15140 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15141 "TARGET_USE_FANCY_MATH_387
15142 && flag_unsafe_math_optimizations"
15143 "operands[2] = gen_reg_rtx (XFmode);")
15145 (define_expand "significand<mode>2"
15146 [(use (match_operand:MODEF 0 "register_operand"))
15147 (use (match_operand:MODEF 1 "register_operand"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15150 || TARGET_MIX_SSE_I387)
15151 && flag_unsafe_math_optimizations"
15153 rtx op0 = gen_reg_rtx (XFmode);
15154 rtx op1 = gen_reg_rtx (XFmode);
15156 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15162 (define_insn "sse4_1_round<mode>2"
15163 [(set (match_operand:MODEF 0 "register_operand" "=x")
15164 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15165 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15168 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15169 [(set_attr "type" "ssecvt")
15170 (set_attr "prefix_extra" "1")
15171 (set_attr "prefix" "maybe_vex")
15172 (set_attr "mode" "<MODE>")])
15174 (define_insn "rintxf2"
15175 [(set (match_operand:XF 0 "register_operand" "=f")
15176 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15178 "TARGET_USE_FANCY_MATH_387
15179 && flag_unsafe_math_optimizations"
15181 [(set_attr "type" "fpspc")
15182 (set_attr "mode" "XF")])
15184 (define_expand "rint<mode>2"
15185 [(use (match_operand:MODEF 0 "register_operand"))
15186 (use (match_operand:MODEF 1 "register_operand"))]
15187 "(TARGET_USE_FANCY_MATH_387
15188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15189 || TARGET_MIX_SSE_I387)
15190 && flag_unsafe_math_optimizations)
15191 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15192 && !flag_trapping_math)"
15194 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15195 && !flag_trapping_math)
15198 emit_insn (gen_sse4_1_round<mode>2
15199 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15200 else if (optimize_insn_for_size_p ())
15203 ix86_expand_rint (operands[0], operands[1]);
15207 rtx op0 = gen_reg_rtx (XFmode);
15208 rtx op1 = gen_reg_rtx (XFmode);
15210 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15211 emit_insn (gen_rintxf2 (op0, op1));
15213 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15218 (define_expand "round<mode>2"
15219 [(match_operand:X87MODEF 0 "register_operand")
15220 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15221 "(TARGET_USE_FANCY_MATH_387
15222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15223 || TARGET_MIX_SSE_I387)
15224 && flag_unsafe_math_optimizations)
15225 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15226 && !flag_trapping_math && !flag_rounding_math)"
15228 if (optimize_insn_for_size_p ())
15231 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15232 && !flag_trapping_math && !flag_rounding_math)
15236 operands[1] = force_reg (<MODE>mode, operands[1]);
15237 ix86_expand_round_sse4 (operands[0], operands[1]);
15239 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15240 ix86_expand_round (operands[0], operands[1]);
15242 ix86_expand_rounddf_32 (operands[0], operands[1]);
15246 operands[1] = force_reg (<MODE>mode, operands[1]);
15247 ix86_emit_i387_round (operands[0], operands[1]);
15252 (define_insn_and_split "*fistdi2_1"
15253 [(set (match_operand:DI 0 "nonimmediate_operand")
15254 (unspec:DI [(match_operand:XF 1 "register_operand")]
15256 "TARGET_USE_FANCY_MATH_387
15257 && can_create_pseudo_p ()"
15262 if (memory_operand (operands[0], VOIDmode))
15263 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15266 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15267 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15272 [(set_attr "type" "fpspc")
15273 (set_attr "mode" "DI")])
15275 (define_insn "fistdi2"
15276 [(set (match_operand:DI 0 "memory_operand" "=m")
15277 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15279 (clobber (match_scratch:XF 2 "=&1f"))]
15280 "TARGET_USE_FANCY_MATH_387"
15281 "* return output_fix_trunc (insn, operands, false);"
15282 [(set_attr "type" "fpspc")
15283 (set_attr "mode" "DI")])
15285 (define_insn "fistdi2_with_temp"
15286 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15287 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15289 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15290 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15291 "TARGET_USE_FANCY_MATH_387"
15293 [(set_attr "type" "fpspc")
15294 (set_attr "mode" "DI")])
15297 [(set (match_operand:DI 0 "register_operand")
15298 (unspec:DI [(match_operand:XF 1 "register_operand")]
15300 (clobber (match_operand:DI 2 "memory_operand"))
15301 (clobber (match_scratch 3))]
15303 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15304 (clobber (match_dup 3))])
15305 (set (match_dup 0) (match_dup 2))])
15308 [(set (match_operand:DI 0 "memory_operand")
15309 (unspec:DI [(match_operand:XF 1 "register_operand")]
15311 (clobber (match_operand:DI 2 "memory_operand"))
15312 (clobber (match_scratch 3))]
15314 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15315 (clobber (match_dup 3))])])
15317 (define_insn_and_split "*fist<mode>2_1"
15318 [(set (match_operand:SWI24 0 "register_operand")
15319 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15321 "TARGET_USE_FANCY_MATH_387
15322 && can_create_pseudo_p ()"
15327 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15328 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15332 [(set_attr "type" "fpspc")
15333 (set_attr "mode" "<MODE>")])
15335 (define_insn "fist<mode>2"
15336 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15337 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15339 "TARGET_USE_FANCY_MATH_387"
15340 "* return output_fix_trunc (insn, operands, false);"
15341 [(set_attr "type" "fpspc")
15342 (set_attr "mode" "<MODE>")])
15344 (define_insn "fist<mode>2_with_temp"
15345 [(set (match_operand:SWI24 0 "register_operand" "=r")
15346 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15348 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15349 "TARGET_USE_FANCY_MATH_387"
15351 [(set_attr "type" "fpspc")
15352 (set_attr "mode" "<MODE>")])
15355 [(set (match_operand:SWI24 0 "register_operand")
15356 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15358 (clobber (match_operand:SWI24 2 "memory_operand"))]
15360 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15361 (set (match_dup 0) (match_dup 2))])
15364 [(set (match_operand:SWI24 0 "memory_operand")
15365 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15367 (clobber (match_operand:SWI24 2 "memory_operand"))]
15369 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15371 (define_expand "lrintxf<mode>2"
15372 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15373 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15375 "TARGET_USE_FANCY_MATH_387")
15377 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15378 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15379 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15380 UNSPEC_FIX_NOTRUNC))]
15381 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15383 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15384 [(match_operand:SWI248x 0 "nonimmediate_operand")
15385 (match_operand:X87MODEF 1 "register_operand")]
15386 "(TARGET_USE_FANCY_MATH_387
15387 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15388 || TARGET_MIX_SSE_I387)
15389 && flag_unsafe_math_optimizations)
15390 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15391 && <SWI248x:MODE>mode != HImode
15392 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15393 && !flag_trapping_math && !flag_rounding_math)"
15395 if (optimize_insn_for_size_p ())
15398 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15399 && <SWI248x:MODE>mode != HImode
15400 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15401 && !flag_trapping_math && !flag_rounding_math)
15402 ix86_expand_lround (operands[0], operands[1]);
15404 ix86_emit_i387_round (operands[0], operands[1]);
15408 (define_int_iterator FRNDINT_ROUNDING
15409 [UNSPEC_FRNDINT_FLOOR
15410 UNSPEC_FRNDINT_CEIL
15411 UNSPEC_FRNDINT_TRUNC])
15413 (define_int_iterator FIST_ROUNDING
15417 ;; Base name for define_insn
15418 (define_int_attr rounding_insn
15419 [(UNSPEC_FRNDINT_FLOOR "floor")
15420 (UNSPEC_FRNDINT_CEIL "ceil")
15421 (UNSPEC_FRNDINT_TRUNC "btrunc")
15422 (UNSPEC_FIST_FLOOR "floor")
15423 (UNSPEC_FIST_CEIL "ceil")])
15425 (define_int_attr rounding
15426 [(UNSPEC_FRNDINT_FLOOR "floor")
15427 (UNSPEC_FRNDINT_CEIL "ceil")
15428 (UNSPEC_FRNDINT_TRUNC "trunc")
15429 (UNSPEC_FIST_FLOOR "floor")
15430 (UNSPEC_FIST_CEIL "ceil")])
15432 (define_int_attr ROUNDING
15433 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15434 (UNSPEC_FRNDINT_CEIL "CEIL")
15435 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15436 (UNSPEC_FIST_FLOOR "FLOOR")
15437 (UNSPEC_FIST_CEIL "CEIL")])
15439 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15440 (define_insn_and_split "frndintxf2_<rounding>"
15441 [(set (match_operand:XF 0 "register_operand")
15442 (unspec:XF [(match_operand:XF 1 "register_operand")]
15444 (clobber (reg:CC FLAGS_REG))]
15445 "TARGET_USE_FANCY_MATH_387
15446 && flag_unsafe_math_optimizations
15447 && can_create_pseudo_p ()"
15452 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15454 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15455 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15457 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15458 operands[2], operands[3]));
15461 [(set_attr "type" "frndint")
15462 (set_attr "i387_cw" "<rounding>")
15463 (set_attr "mode" "XF")])
15465 (define_insn "frndintxf2_<rounding>_i387"
15466 [(set (match_operand:XF 0 "register_operand" "=f")
15467 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15469 (use (match_operand:HI 2 "memory_operand" "m"))
15470 (use (match_operand:HI 3 "memory_operand" "m"))]
15471 "TARGET_USE_FANCY_MATH_387
15472 && flag_unsafe_math_optimizations"
15473 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15474 [(set_attr "type" "frndint")
15475 (set_attr "i387_cw" "<rounding>")
15476 (set_attr "mode" "XF")])
15478 (define_expand "<rounding_insn>xf2"
15479 [(parallel [(set (match_operand:XF 0 "register_operand")
15480 (unspec:XF [(match_operand:XF 1 "register_operand")]
15482 (clobber (reg:CC FLAGS_REG))])]
15483 "TARGET_USE_FANCY_MATH_387
15484 && flag_unsafe_math_optimizations
15485 && !optimize_insn_for_size_p ()")
15487 (define_expand "<rounding_insn><mode>2"
15488 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15489 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15491 (clobber (reg:CC FLAGS_REG))])]
15492 "(TARGET_USE_FANCY_MATH_387
15493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494 || TARGET_MIX_SSE_I387)
15495 && flag_unsafe_math_optimizations)
15496 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15497 && !flag_trapping_math)"
15499 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15500 && !flag_trapping_math)
15503 emit_insn (gen_sse4_1_round<mode>2
15504 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15505 else if (optimize_insn_for_size_p ())
15507 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15509 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15510 ix86_expand_floorceil (operands[0], operands[1], true);
15511 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15512 ix86_expand_floorceil (operands[0], operands[1], false);
15513 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15514 ix86_expand_trunc (operands[0], operands[1]);
15516 gcc_unreachable ();
15520 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15521 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15522 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15523 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15524 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15525 ix86_expand_truncdf_32 (operands[0], operands[1]);
15527 gcc_unreachable ();
15534 if (optimize_insn_for_size_p ())
15537 op0 = gen_reg_rtx (XFmode);
15538 op1 = gen_reg_rtx (XFmode);
15539 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15540 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15542 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15547 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15548 (define_insn_and_split "frndintxf2_mask_pm"
15549 [(set (match_operand:XF 0 "register_operand")
15550 (unspec:XF [(match_operand:XF 1 "register_operand")]
15551 UNSPEC_FRNDINT_MASK_PM))
15552 (clobber (reg:CC FLAGS_REG))]
15553 "TARGET_USE_FANCY_MATH_387
15554 && flag_unsafe_math_optimizations
15555 && can_create_pseudo_p ()"
15560 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15562 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15563 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15565 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15566 operands[2], operands[3]));
15569 [(set_attr "type" "frndint")
15570 (set_attr "i387_cw" "mask_pm")
15571 (set_attr "mode" "XF")])
15573 (define_insn "frndintxf2_mask_pm_i387"
15574 [(set (match_operand:XF 0 "register_operand" "=f")
15575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15576 UNSPEC_FRNDINT_MASK_PM))
15577 (use (match_operand:HI 2 "memory_operand" "m"))
15578 (use (match_operand:HI 3 "memory_operand" "m"))]
15579 "TARGET_USE_FANCY_MATH_387
15580 && flag_unsafe_math_optimizations"
15581 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15582 [(set_attr "type" "frndint")
15583 (set_attr "i387_cw" "mask_pm")
15584 (set_attr "mode" "XF")])
15586 (define_expand "nearbyintxf2"
15587 [(parallel [(set (match_operand:XF 0 "register_operand")
15588 (unspec:XF [(match_operand:XF 1 "register_operand")]
15589 UNSPEC_FRNDINT_MASK_PM))
15590 (clobber (reg:CC FLAGS_REG))])]
15591 "TARGET_USE_FANCY_MATH_387
15592 && flag_unsafe_math_optimizations")
15594 (define_expand "nearbyint<mode>2"
15595 [(use (match_operand:MODEF 0 "register_operand"))
15596 (use (match_operand:MODEF 1 "register_operand"))]
15597 "TARGET_USE_FANCY_MATH_387
15598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15599 || TARGET_MIX_SSE_I387)
15600 && flag_unsafe_math_optimizations"
15602 rtx op0 = gen_reg_rtx (XFmode);
15603 rtx op1 = gen_reg_rtx (XFmode);
15605 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15606 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15608 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15612 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15613 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15614 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15615 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15617 (clobber (reg:CC FLAGS_REG))]
15618 "TARGET_USE_FANCY_MATH_387
15619 && flag_unsafe_math_optimizations
15620 && can_create_pseudo_p ()"
15625 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15627 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15628 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15629 if (memory_operand (operands[0], VOIDmode))
15630 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15631 operands[2], operands[3]));
15634 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15635 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15636 (operands[0], operands[1], operands[2],
15637 operands[3], operands[4]));
15641 [(set_attr "type" "fistp")
15642 (set_attr "i387_cw" "<rounding>")
15643 (set_attr "mode" "<MODE>")])
15645 (define_insn "fistdi2_<rounding>"
15646 [(set (match_operand:DI 0 "memory_operand" "=m")
15647 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15649 (use (match_operand:HI 2 "memory_operand" "m"))
15650 (use (match_operand:HI 3 "memory_operand" "m"))
15651 (clobber (match_scratch:XF 4 "=&1f"))]
15652 "TARGET_USE_FANCY_MATH_387
15653 && flag_unsafe_math_optimizations"
15654 "* return output_fix_trunc (insn, operands, false);"
15655 [(set_attr "type" "fistp")
15656 (set_attr "i387_cw" "<rounding>")
15657 (set_attr "mode" "DI")])
15659 (define_insn "fistdi2_<rounding>_with_temp"
15660 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15661 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15663 (use (match_operand:HI 2 "memory_operand" "m,m"))
15664 (use (match_operand:HI 3 "memory_operand" "m,m"))
15665 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15666 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && flag_unsafe_math_optimizations"
15670 [(set_attr "type" "fistp")
15671 (set_attr "i387_cw" "<rounding>")
15672 (set_attr "mode" "DI")])
15675 [(set (match_operand:DI 0 "register_operand")
15676 (unspec:DI [(match_operand:XF 1 "register_operand")]
15678 (use (match_operand:HI 2 "memory_operand"))
15679 (use (match_operand:HI 3 "memory_operand"))
15680 (clobber (match_operand:DI 4 "memory_operand"))
15681 (clobber (match_scratch 5))]
15683 [(parallel [(set (match_dup 4)
15684 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15685 (use (match_dup 2))
15686 (use (match_dup 3))
15687 (clobber (match_dup 5))])
15688 (set (match_dup 0) (match_dup 4))])
15691 [(set (match_operand:DI 0 "memory_operand")
15692 (unspec:DI [(match_operand:XF 1 "register_operand")]
15694 (use (match_operand:HI 2 "memory_operand"))
15695 (use (match_operand:HI 3 "memory_operand"))
15696 (clobber (match_operand:DI 4 "memory_operand"))
15697 (clobber (match_scratch 5))]
15699 [(parallel [(set (match_dup 0)
15700 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15701 (use (match_dup 2))
15702 (use (match_dup 3))
15703 (clobber (match_dup 5))])])
15705 (define_insn "fist<mode>2_<rounding>"
15706 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15707 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15709 (use (match_operand:HI 2 "memory_operand" "m"))
15710 (use (match_operand:HI 3 "memory_operand" "m"))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && flag_unsafe_math_optimizations"
15713 "* return output_fix_trunc (insn, operands, false);"
15714 [(set_attr "type" "fistp")
15715 (set_attr "i387_cw" "<rounding>")
15716 (set_attr "mode" "<MODE>")])
15718 (define_insn "fist<mode>2_<rounding>_with_temp"
15719 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15720 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15722 (use (match_operand:HI 2 "memory_operand" "m,m"))
15723 (use (match_operand:HI 3 "memory_operand" "m,m"))
15724 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && flag_unsafe_math_optimizations"
15728 [(set_attr "type" "fistp")
15729 (set_attr "i387_cw" "<rounding>")
15730 (set_attr "mode" "<MODE>")])
15733 [(set (match_operand:SWI24 0 "register_operand")
15734 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15736 (use (match_operand:HI 2 "memory_operand"))
15737 (use (match_operand:HI 3 "memory_operand"))
15738 (clobber (match_operand:SWI24 4 "memory_operand"))]
15740 [(parallel [(set (match_dup 4)
15741 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15742 (use (match_dup 2))
15743 (use (match_dup 3))])
15744 (set (match_dup 0) (match_dup 4))])
15747 [(set (match_operand:SWI24 0 "memory_operand")
15748 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15750 (use (match_operand:HI 2 "memory_operand"))
15751 (use (match_operand:HI 3 "memory_operand"))
15752 (clobber (match_operand:SWI24 4 "memory_operand"))]
15754 [(parallel [(set (match_dup 0)
15755 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15756 (use (match_dup 2))
15757 (use (match_dup 3))])])
15759 (define_expand "l<rounding_insn>xf<mode>2"
15760 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15761 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15763 (clobber (reg:CC FLAGS_REG))])]
15764 "TARGET_USE_FANCY_MATH_387
15765 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15766 && flag_unsafe_math_optimizations")
15768 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15769 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15770 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15772 (clobber (reg:CC FLAGS_REG))])]
15773 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15774 && !flag_trapping_math"
15776 if (TARGET_64BIT && optimize_insn_for_size_p ())
15779 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15780 ix86_expand_lfloorceil (operands[0], operands[1], true);
15781 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15782 ix86_expand_lfloorceil (operands[0], operands[1], false);
15784 gcc_unreachable ();
15789 (define_insn "fxam<mode>2_i387"
15790 [(set (match_operand:HI 0 "register_operand" "=a")
15792 [(match_operand:X87MODEF 1 "register_operand" "f")]
15794 "TARGET_USE_FANCY_MATH_387"
15795 "fxam\n\tfnstsw\t%0"
15796 [(set_attr "type" "multi")
15797 (set_attr "length" "4")
15798 (set_attr "unit" "i387")
15799 (set_attr "mode" "<MODE>")])
15801 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15802 [(set (match_operand:HI 0 "register_operand")
15804 [(match_operand:MODEF 1 "memory_operand")]
15806 "TARGET_USE_FANCY_MATH_387
15807 && can_create_pseudo_p ()"
15810 [(set (match_dup 2)(match_dup 1))
15812 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15814 operands[2] = gen_reg_rtx (<MODE>mode);
15816 MEM_VOLATILE_P (operands[1]) = 1;
15818 [(set_attr "type" "multi")
15819 (set_attr "unit" "i387")
15820 (set_attr "mode" "<MODE>")])
15822 (define_expand "isinfxf2"
15823 [(use (match_operand:SI 0 "register_operand"))
15824 (use (match_operand:XF 1 "register_operand"))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && ix86_libc_has_function (function_c99_misc)"
15828 rtx mask = GEN_INT (0x45);
15829 rtx val = GEN_INT (0x05);
15833 rtx scratch = gen_reg_rtx (HImode);
15834 rtx res = gen_reg_rtx (QImode);
15836 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15838 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15839 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15840 cond = gen_rtx_fmt_ee (EQ, QImode,
15841 gen_rtx_REG (CCmode, FLAGS_REG),
15843 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15844 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15848 (define_expand "isinf<mode>2"
15849 [(use (match_operand:SI 0 "register_operand"))
15850 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && ix86_libc_has_function (function_c99_misc)
15853 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15855 rtx mask = GEN_INT (0x45);
15856 rtx val = GEN_INT (0x05);
15860 rtx scratch = gen_reg_rtx (HImode);
15861 rtx res = gen_reg_rtx (QImode);
15863 /* Remove excess precision by forcing value through memory. */
15864 if (memory_operand (operands[1], VOIDmode))
15865 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15868 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15870 emit_move_insn (temp, operands[1]);
15871 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15874 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15875 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15876 cond = gen_rtx_fmt_ee (EQ, QImode,
15877 gen_rtx_REG (CCmode, FLAGS_REG),
15879 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15880 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15884 (define_expand "signbitxf2"
15885 [(use (match_operand:SI 0 "register_operand"))
15886 (use (match_operand:XF 1 "register_operand"))]
15887 "TARGET_USE_FANCY_MATH_387"
15889 rtx scratch = gen_reg_rtx (HImode);
15891 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15892 emit_insn (gen_andsi3 (operands[0],
15893 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15897 (define_insn "movmsk_df"
15898 [(set (match_operand:SI 0 "register_operand" "=r")
15900 [(match_operand:DF 1 "register_operand" "x")]
15902 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15903 "%vmovmskpd\t{%1, %0|%0, %1}"
15904 [(set_attr "type" "ssemov")
15905 (set_attr "prefix" "maybe_vex")
15906 (set_attr "mode" "DF")])
15908 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15909 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15910 (define_expand "signbitdf2"
15911 [(use (match_operand:SI 0 "register_operand"))
15912 (use (match_operand:DF 1 "register_operand"))]
15913 "TARGET_USE_FANCY_MATH_387
15914 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15916 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15918 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15919 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15923 rtx scratch = gen_reg_rtx (HImode);
15925 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15926 emit_insn (gen_andsi3 (operands[0],
15927 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15932 (define_expand "signbitsf2"
15933 [(use (match_operand:SI 0 "register_operand"))
15934 (use (match_operand:SF 1 "register_operand"))]
15935 "TARGET_USE_FANCY_MATH_387
15936 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15938 rtx scratch = gen_reg_rtx (HImode);
15940 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15941 emit_insn (gen_andsi3 (operands[0],
15942 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15946 ;; Block operation instructions
15949 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15952 [(set_attr "length" "1")
15953 (set_attr "length_immediate" "0")
15954 (set_attr "modrm" "0")])
15956 (define_expand "movmem<mode>"
15957 [(use (match_operand:BLK 0 "memory_operand"))
15958 (use (match_operand:BLK 1 "memory_operand"))
15959 (use (match_operand:SWI48 2 "nonmemory_operand"))
15960 (use (match_operand:SWI48 3 "const_int_operand"))
15961 (use (match_operand:SI 4 "const_int_operand"))
15962 (use (match_operand:SI 5 "const_int_operand"))
15963 (use (match_operand:SI 6 ""))
15964 (use (match_operand:SI 7 ""))
15965 (use (match_operand:SI 8 ""))]
15968 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15969 operands[2], NULL, operands[3],
15970 operands[4], operands[5],
15971 operands[6], operands[7],
15972 operands[8], false))
15978 ;; Most CPUs don't like single string operations
15979 ;; Handle this case here to simplify previous expander.
15981 (define_expand "strmov"
15982 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15983 (set (match_operand 1 "memory_operand") (match_dup 4))
15984 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15985 (clobber (reg:CC FLAGS_REG))])
15986 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15987 (clobber (reg:CC FLAGS_REG))])]
15990 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15992 /* If .md ever supports :P for Pmode, these can be directly
15993 in the pattern above. */
15994 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15995 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15997 /* Can't use this if the user has appropriated esi or edi. */
15998 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15999 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16001 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16002 operands[2], operands[3],
16003 operands[5], operands[6]));
16007 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16010 (define_expand "strmov_singleop"
16011 [(parallel [(set (match_operand 1 "memory_operand")
16012 (match_operand 3 "memory_operand"))
16013 (set (match_operand 0 "register_operand")
16015 (set (match_operand 2 "register_operand")
16016 (match_operand 5))])]
16018 "ix86_current_function_needs_cld = 1;")
16020 (define_insn "*strmovdi_rex_1"
16021 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16022 (mem:DI (match_operand:P 3 "register_operand" "1")))
16023 (set (match_operand:P 0 "register_operand" "=D")
16024 (plus:P (match_dup 2)
16026 (set (match_operand:P 1 "register_operand" "=S")
16027 (plus:P (match_dup 3)
16030 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16032 [(set_attr "type" "str")
16033 (set_attr "memory" "both")
16034 (set_attr "mode" "DI")])
16036 (define_insn "*strmovsi_1"
16037 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16038 (mem:SI (match_operand:P 3 "register_operand" "1")))
16039 (set (match_operand:P 0 "register_operand" "=D")
16040 (plus:P (match_dup 2)
16042 (set (match_operand:P 1 "register_operand" "=S")
16043 (plus:P (match_dup 3)
16045 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16047 [(set_attr "type" "str")
16048 (set_attr "memory" "both")
16049 (set_attr "mode" "SI")])
16051 (define_insn "*strmovhi_1"
16052 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16053 (mem:HI (match_operand:P 3 "register_operand" "1")))
16054 (set (match_operand:P 0 "register_operand" "=D")
16055 (plus:P (match_dup 2)
16057 (set (match_operand:P 1 "register_operand" "=S")
16058 (plus:P (match_dup 3)
16060 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16062 [(set_attr "type" "str")
16063 (set_attr "memory" "both")
16064 (set_attr "mode" "HI")])
16066 (define_insn "*strmovqi_1"
16067 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16068 (mem:QI (match_operand:P 3 "register_operand" "1")))
16069 (set (match_operand:P 0 "register_operand" "=D")
16070 (plus:P (match_dup 2)
16072 (set (match_operand:P 1 "register_operand" "=S")
16073 (plus:P (match_dup 3)
16075 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16077 [(set_attr "type" "str")
16078 (set_attr "memory" "both")
16079 (set (attr "prefix_rex")
16081 (match_test "<P:MODE>mode == DImode")
16083 (const_string "*")))
16084 (set_attr "mode" "QI")])
16086 (define_expand "rep_mov"
16087 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16088 (set (match_operand 0 "register_operand")
16090 (set (match_operand 2 "register_operand")
16092 (set (match_operand 1 "memory_operand")
16093 (match_operand 3 "memory_operand"))
16094 (use (match_dup 4))])]
16096 "ix86_current_function_needs_cld = 1;")
16098 (define_insn "*rep_movdi_rex64"
16099 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16100 (set (match_operand:P 0 "register_operand" "=D")
16101 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16103 (match_operand:P 3 "register_operand" "0")))
16104 (set (match_operand:P 1 "register_operand" "=S")
16105 (plus:P (ashift:P (match_dup 5) (const_int 3))
16106 (match_operand:P 4 "register_operand" "1")))
16107 (set (mem:BLK (match_dup 3))
16108 (mem:BLK (match_dup 4)))
16109 (use (match_dup 5))]
16111 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16113 [(set_attr "type" "str")
16114 (set_attr "prefix_rep" "1")
16115 (set_attr "memory" "both")
16116 (set_attr "mode" "DI")])
16118 (define_insn "*rep_movsi"
16119 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16120 (set (match_operand:P 0 "register_operand" "=D")
16121 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16123 (match_operand:P 3 "register_operand" "0")))
16124 (set (match_operand:P 1 "register_operand" "=S")
16125 (plus:P (ashift:P (match_dup 5) (const_int 2))
16126 (match_operand:P 4 "register_operand" "1")))
16127 (set (mem:BLK (match_dup 3))
16128 (mem:BLK (match_dup 4)))
16129 (use (match_dup 5))]
16130 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16131 "%^rep{%;} movs{l|d}"
16132 [(set_attr "type" "str")
16133 (set_attr "prefix_rep" "1")
16134 (set_attr "memory" "both")
16135 (set_attr "mode" "SI")])
16137 (define_insn "*rep_movqi"
16138 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16139 (set (match_operand:P 0 "register_operand" "=D")
16140 (plus:P (match_operand:P 3 "register_operand" "0")
16141 (match_operand:P 5 "register_operand" "2")))
16142 (set (match_operand:P 1 "register_operand" "=S")
16143 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16144 (set (mem:BLK (match_dup 3))
16145 (mem:BLK (match_dup 4)))
16146 (use (match_dup 5))]
16147 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16149 [(set_attr "type" "str")
16150 (set_attr "prefix_rep" "1")
16151 (set_attr "memory" "both")
16152 (set_attr "mode" "QI")])
16154 (define_expand "setmem<mode>"
16155 [(use (match_operand:BLK 0 "memory_operand"))
16156 (use (match_operand:SWI48 1 "nonmemory_operand"))
16157 (use (match_operand:QI 2 "nonmemory_operand"))
16158 (use (match_operand 3 "const_int_operand"))
16159 (use (match_operand:SI 4 "const_int_operand"))
16160 (use (match_operand:SI 5 "const_int_operand"))
16161 (use (match_operand:SI 6 ""))
16162 (use (match_operand:SI 7 ""))
16163 (use (match_operand:SI 8 ""))]
16166 if (ix86_expand_set_or_movmem (operands[0], NULL,
16167 operands[1], operands[2],
16168 operands[3], operands[4],
16169 operands[5], operands[6],
16170 operands[7], operands[8], true))
16176 ;; Most CPUs don't like single string operations
16177 ;; Handle this case here to simplify previous expander.
16179 (define_expand "strset"
16180 [(set (match_operand 1 "memory_operand")
16181 (match_operand 2 "register_operand"))
16182 (parallel [(set (match_operand 0 "register_operand")
16184 (clobber (reg:CC FLAGS_REG))])]
16187 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16188 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16190 /* If .md ever supports :P for Pmode, this can be directly
16191 in the pattern above. */
16192 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16193 GEN_INT (GET_MODE_SIZE (GET_MODE
16195 /* Can't use this if the user has appropriated eax or edi. */
16196 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16197 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16199 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16205 (define_expand "strset_singleop"
16206 [(parallel [(set (match_operand 1 "memory_operand")
16207 (match_operand 2 "register_operand"))
16208 (set (match_operand 0 "register_operand")
16210 (unspec [(const_int 0)] UNSPEC_STOS)])]
16212 "ix86_current_function_needs_cld = 1;")
16214 (define_insn "*strsetdi_rex_1"
16215 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16216 (match_operand:DI 2 "register_operand" "a"))
16217 (set (match_operand:P 0 "register_operand" "=D")
16218 (plus:P (match_dup 1)
16220 (unspec [(const_int 0)] UNSPEC_STOS)]
16222 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16224 [(set_attr "type" "str")
16225 (set_attr "memory" "store")
16226 (set_attr "mode" "DI")])
16228 (define_insn "*strsetsi_1"
16229 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16230 (match_operand:SI 2 "register_operand" "a"))
16231 (set (match_operand:P 0 "register_operand" "=D")
16232 (plus:P (match_dup 1)
16234 (unspec [(const_int 0)] UNSPEC_STOS)]
16235 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16237 [(set_attr "type" "str")
16238 (set_attr "memory" "store")
16239 (set_attr "mode" "SI")])
16241 (define_insn "*strsethi_1"
16242 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16243 (match_operand:HI 2 "register_operand" "a"))
16244 (set (match_operand:P 0 "register_operand" "=D")
16245 (plus:P (match_dup 1)
16247 (unspec [(const_int 0)] UNSPEC_STOS)]
16248 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16250 [(set_attr "type" "str")
16251 (set_attr "memory" "store")
16252 (set_attr "mode" "HI")])
16254 (define_insn "*strsetqi_1"
16255 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16256 (match_operand:QI 2 "register_operand" "a"))
16257 (set (match_operand:P 0 "register_operand" "=D")
16258 (plus:P (match_dup 1)
16260 (unspec [(const_int 0)] UNSPEC_STOS)]
16261 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16263 [(set_attr "type" "str")
16264 (set_attr "memory" "store")
16265 (set (attr "prefix_rex")
16267 (match_test "<P:MODE>mode == DImode")
16269 (const_string "*")))
16270 (set_attr "mode" "QI")])
16272 (define_expand "rep_stos"
16273 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16274 (set (match_operand 0 "register_operand")
16276 (set (match_operand 2 "memory_operand") (const_int 0))
16277 (use (match_operand 3 "register_operand"))
16278 (use (match_dup 1))])]
16280 "ix86_current_function_needs_cld = 1;")
16282 (define_insn "*rep_stosdi_rex64"
16283 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16284 (set (match_operand:P 0 "register_operand" "=D")
16285 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16287 (match_operand:P 3 "register_operand" "0")))
16288 (set (mem:BLK (match_dup 3))
16290 (use (match_operand:DI 2 "register_operand" "a"))
16291 (use (match_dup 4))]
16293 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16295 [(set_attr "type" "str")
16296 (set_attr "prefix_rep" "1")
16297 (set_attr "memory" "store")
16298 (set_attr "mode" "DI")])
16300 (define_insn "*rep_stossi"
16301 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16302 (set (match_operand:P 0 "register_operand" "=D")
16303 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16305 (match_operand:P 3 "register_operand" "0")))
16306 (set (mem:BLK (match_dup 3))
16308 (use (match_operand:SI 2 "register_operand" "a"))
16309 (use (match_dup 4))]
16310 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16311 "%^rep{%;} stos{l|d}"
16312 [(set_attr "type" "str")
16313 (set_attr "prefix_rep" "1")
16314 (set_attr "memory" "store")
16315 (set_attr "mode" "SI")])
16317 (define_insn "*rep_stosqi"
16318 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16319 (set (match_operand:P 0 "register_operand" "=D")
16320 (plus:P (match_operand:P 3 "register_operand" "0")
16321 (match_operand:P 4 "register_operand" "1")))
16322 (set (mem:BLK (match_dup 3))
16324 (use (match_operand:QI 2 "register_operand" "a"))
16325 (use (match_dup 4))]
16326 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16328 [(set_attr "type" "str")
16329 (set_attr "prefix_rep" "1")
16330 (set_attr "memory" "store")
16331 (set (attr "prefix_rex")
16333 (match_test "<P:MODE>mode == DImode")
16335 (const_string "*")))
16336 (set_attr "mode" "QI")])
16338 (define_expand "cmpstrnsi"
16339 [(set (match_operand:SI 0 "register_operand")
16340 (compare:SI (match_operand:BLK 1 "general_operand")
16341 (match_operand:BLK 2 "general_operand")))
16342 (use (match_operand 3 "general_operand"))
16343 (use (match_operand 4 "immediate_operand"))]
16346 rtx addr1, addr2, out, outlow, count, countreg, align;
16348 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16351 /* Can't use this if the user has appropriated ecx, esi or edi. */
16352 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16357 out = gen_reg_rtx (SImode);
16359 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16360 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16361 if (addr1 != XEXP (operands[1], 0))
16362 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16363 if (addr2 != XEXP (operands[2], 0))
16364 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16366 count = operands[3];
16367 countreg = ix86_zero_extend_to_Pmode (count);
16369 /* %%% Iff we are testing strict equality, we can use known alignment
16370 to good advantage. This may be possible with combine, particularly
16371 once cc0 is dead. */
16372 align = operands[4];
16374 if (CONST_INT_P (count))
16376 if (INTVAL (count) == 0)
16378 emit_move_insn (operands[0], const0_rtx);
16381 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16382 operands[1], operands[2]));
16386 rtx (*gen_cmp) (rtx, rtx);
16388 gen_cmp = (TARGET_64BIT
16389 ? gen_cmpdi_1 : gen_cmpsi_1);
16391 emit_insn (gen_cmp (countreg, countreg));
16392 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16393 operands[1], operands[2]));
16396 outlow = gen_lowpart (QImode, out);
16397 emit_insn (gen_cmpintqi (outlow));
16398 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16400 if (operands[0] != out)
16401 emit_move_insn (operands[0], out);
16406 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16408 (define_expand "cmpintqi"
16409 [(set (match_dup 1)
16410 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16412 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16413 (parallel [(set (match_operand:QI 0 "register_operand")
16414 (minus:QI (match_dup 1)
16416 (clobber (reg:CC FLAGS_REG))])]
16419 operands[1] = gen_reg_rtx (QImode);
16420 operands[2] = gen_reg_rtx (QImode);
16423 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16424 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16426 (define_expand "cmpstrnqi_nz_1"
16427 [(parallel [(set (reg:CC FLAGS_REG)
16428 (compare:CC (match_operand 4 "memory_operand")
16429 (match_operand 5 "memory_operand")))
16430 (use (match_operand 2 "register_operand"))
16431 (use (match_operand:SI 3 "immediate_operand"))
16432 (clobber (match_operand 0 "register_operand"))
16433 (clobber (match_operand 1 "register_operand"))
16434 (clobber (match_dup 2))])]
16436 "ix86_current_function_needs_cld = 1;")
16438 (define_insn "*cmpstrnqi_nz_1"
16439 [(set (reg:CC FLAGS_REG)
16440 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16441 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16442 (use (match_operand:P 6 "register_operand" "2"))
16443 (use (match_operand:SI 3 "immediate_operand" "i"))
16444 (clobber (match_operand:P 0 "register_operand" "=S"))
16445 (clobber (match_operand:P 1 "register_operand" "=D"))
16446 (clobber (match_operand:P 2 "register_operand" "=c"))]
16447 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16449 [(set_attr "type" "str")
16450 (set_attr "mode" "QI")
16451 (set (attr "prefix_rex")
16453 (match_test "<P:MODE>mode == DImode")
16455 (const_string "*")))
16456 (set_attr "prefix_rep" "1")])
16458 ;; The same, but the count is not known to not be zero.
16460 (define_expand "cmpstrnqi_1"
16461 [(parallel [(set (reg:CC FLAGS_REG)
16462 (if_then_else:CC (ne (match_operand 2 "register_operand")
16464 (compare:CC (match_operand 4 "memory_operand")
16465 (match_operand 5 "memory_operand"))
16467 (use (match_operand:SI 3 "immediate_operand"))
16468 (use (reg:CC FLAGS_REG))
16469 (clobber (match_operand 0 "register_operand"))
16470 (clobber (match_operand 1 "register_operand"))
16471 (clobber (match_dup 2))])]
16473 "ix86_current_function_needs_cld = 1;")
16475 (define_insn "*cmpstrnqi_1"
16476 [(set (reg:CC FLAGS_REG)
16477 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16479 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16480 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16482 (use (match_operand:SI 3 "immediate_operand" "i"))
16483 (use (reg:CC FLAGS_REG))
16484 (clobber (match_operand:P 0 "register_operand" "=S"))
16485 (clobber (match_operand:P 1 "register_operand" "=D"))
16486 (clobber (match_operand:P 2 "register_operand" "=c"))]
16487 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16489 [(set_attr "type" "str")
16490 (set_attr "mode" "QI")
16491 (set (attr "prefix_rex")
16493 (match_test "<P:MODE>mode == DImode")
16495 (const_string "*")))
16496 (set_attr "prefix_rep" "1")])
16498 (define_expand "strlen<mode>"
16499 [(set (match_operand:P 0 "register_operand")
16500 (unspec:P [(match_operand:BLK 1 "general_operand")
16501 (match_operand:QI 2 "immediate_operand")
16502 (match_operand 3 "immediate_operand")]
16506 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16512 (define_expand "strlenqi_1"
16513 [(parallel [(set (match_operand 0 "register_operand")
16515 (clobber (match_operand 1 "register_operand"))
16516 (clobber (reg:CC FLAGS_REG))])]
16518 "ix86_current_function_needs_cld = 1;")
16520 (define_insn "*strlenqi_1"
16521 [(set (match_operand:P 0 "register_operand" "=&c")
16522 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16523 (match_operand:QI 2 "register_operand" "a")
16524 (match_operand:P 3 "immediate_operand" "i")
16525 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16526 (clobber (match_operand:P 1 "register_operand" "=D"))
16527 (clobber (reg:CC FLAGS_REG))]
16528 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16529 "%^repnz{%;} scasb"
16530 [(set_attr "type" "str")
16531 (set_attr "mode" "QI")
16532 (set (attr "prefix_rex")
16534 (match_test "<P:MODE>mode == DImode")
16536 (const_string "*")))
16537 (set_attr "prefix_rep" "1")])
16539 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16540 ;; handled in combine, but it is not currently up to the task.
16541 ;; When used for their truth value, the cmpstrn* expanders generate
16550 ;; The intermediate three instructions are unnecessary.
16552 ;; This one handles cmpstrn*_nz_1...
16555 (set (reg:CC FLAGS_REG)
16556 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16557 (mem:BLK (match_operand 5 "register_operand"))))
16558 (use (match_operand 6 "register_operand"))
16559 (use (match_operand:SI 3 "immediate_operand"))
16560 (clobber (match_operand 0 "register_operand"))
16561 (clobber (match_operand 1 "register_operand"))
16562 (clobber (match_operand 2 "register_operand"))])
16563 (set (match_operand:QI 7 "register_operand")
16564 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16565 (set (match_operand:QI 8 "register_operand")
16566 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16567 (set (reg FLAGS_REG)
16568 (compare (match_dup 7) (match_dup 8)))
16570 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16572 (set (reg:CC FLAGS_REG)
16573 (compare:CC (mem:BLK (match_dup 4))
16574 (mem:BLK (match_dup 5))))
16575 (use (match_dup 6))
16576 (use (match_dup 3))
16577 (clobber (match_dup 0))
16578 (clobber (match_dup 1))
16579 (clobber (match_dup 2))])])
16581 ;; ...and this one handles cmpstrn*_1.
16584 (set (reg:CC FLAGS_REG)
16585 (if_then_else:CC (ne (match_operand 6 "register_operand")
16587 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16588 (mem:BLK (match_operand 5 "register_operand")))
16590 (use (match_operand:SI 3 "immediate_operand"))
16591 (use (reg:CC FLAGS_REG))
16592 (clobber (match_operand 0 "register_operand"))
16593 (clobber (match_operand 1 "register_operand"))
16594 (clobber (match_operand 2 "register_operand"))])
16595 (set (match_operand:QI 7 "register_operand")
16596 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16597 (set (match_operand:QI 8 "register_operand")
16598 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16599 (set (reg FLAGS_REG)
16600 (compare (match_dup 7) (match_dup 8)))
16602 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16604 (set (reg:CC FLAGS_REG)
16605 (if_then_else:CC (ne (match_dup 6)
16607 (compare:CC (mem:BLK (match_dup 4))
16608 (mem:BLK (match_dup 5)))
16610 (use (match_dup 3))
16611 (use (reg:CC FLAGS_REG))
16612 (clobber (match_dup 0))
16613 (clobber (match_dup 1))
16614 (clobber (match_dup 2))])])
16616 ;; Conditional move instructions.
16618 (define_expand "mov<mode>cc"
16619 [(set (match_operand:SWIM 0 "register_operand")
16620 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16621 (match_operand:SWIM 2 "<general_operand>")
16622 (match_operand:SWIM 3 "<general_operand>")))]
16624 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16626 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16627 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16628 ;; So just document what we're doing explicitly.
16630 (define_expand "x86_mov<mode>cc_0_m1"
16632 [(set (match_operand:SWI48 0 "register_operand")
16633 (if_then_else:SWI48
16634 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16635 [(match_operand 1 "flags_reg_operand")
16639 (clobber (reg:CC FLAGS_REG))])])
16641 (define_insn "*x86_mov<mode>cc_0_m1"
16642 [(set (match_operand:SWI48 0 "register_operand" "=r")
16643 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16644 [(reg FLAGS_REG) (const_int 0)])
16647 (clobber (reg:CC FLAGS_REG))]
16649 "sbb{<imodesuffix>}\t%0, %0"
16650 ; Since we don't have the proper number of operands for an alu insn,
16651 ; fill in all the blanks.
16652 [(set_attr "type" "alu")
16653 (set_attr "use_carry" "1")
16654 (set_attr "pent_pair" "pu")
16655 (set_attr "memory" "none")
16656 (set_attr "imm_disp" "false")
16657 (set_attr "mode" "<MODE>")
16658 (set_attr "length_immediate" "0")])
16660 (define_insn "*x86_mov<mode>cc_0_m1_se"
16661 [(set (match_operand:SWI48 0 "register_operand" "=r")
16662 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16663 [(reg FLAGS_REG) (const_int 0)])
16666 (clobber (reg:CC FLAGS_REG))]
16668 "sbb{<imodesuffix>}\t%0, %0"
16669 [(set_attr "type" "alu")
16670 (set_attr "use_carry" "1")
16671 (set_attr "pent_pair" "pu")
16672 (set_attr "memory" "none")
16673 (set_attr "imm_disp" "false")
16674 (set_attr "mode" "<MODE>")
16675 (set_attr "length_immediate" "0")])
16677 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16678 [(set (match_operand:SWI48 0 "register_operand" "=r")
16679 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16680 [(reg FLAGS_REG) (const_int 0)])))
16681 (clobber (reg:CC FLAGS_REG))]
16683 "sbb{<imodesuffix>}\t%0, %0"
16684 [(set_attr "type" "alu")
16685 (set_attr "use_carry" "1")
16686 (set_attr "pent_pair" "pu")
16687 (set_attr "memory" "none")
16688 (set_attr "imm_disp" "false")
16689 (set_attr "mode" "<MODE>")
16690 (set_attr "length_immediate" "0")])
16692 (define_insn "*mov<mode>cc_noc"
16693 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16694 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16695 [(reg FLAGS_REG) (const_int 0)])
16696 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16697 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16698 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16700 cmov%O2%C1\t{%2, %0|%0, %2}
16701 cmov%O2%c1\t{%3, %0|%0, %3}"
16702 [(set_attr "type" "icmov")
16703 (set_attr "mode" "<MODE>")])
16705 ;; Don't do conditional moves with memory inputs. This splitter helps
16706 ;; register starved x86_32 by forcing inputs into registers before reload.
16708 [(set (match_operand:SWI248 0 "register_operand")
16709 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16710 [(reg FLAGS_REG) (const_int 0)])
16711 (match_operand:SWI248 2 "nonimmediate_operand")
16712 (match_operand:SWI248 3 "nonimmediate_operand")))]
16713 "!TARGET_64BIT && TARGET_CMOVE
16714 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16715 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16716 && can_create_pseudo_p ()
16717 && optimize_insn_for_speed_p ()"
16718 [(set (match_dup 0)
16719 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16721 if (MEM_P (operands[2]))
16722 operands[2] = force_reg (<MODE>mode, operands[2]);
16723 if (MEM_P (operands[3]))
16724 operands[3] = force_reg (<MODE>mode, operands[3]);
16727 (define_insn "*movqicc_noc"
16728 [(set (match_operand:QI 0 "register_operand" "=r,r")
16729 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16730 [(reg FLAGS_REG) (const_int 0)])
16731 (match_operand:QI 2 "register_operand" "r,0")
16732 (match_operand:QI 3 "register_operand" "0,r")))]
16733 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16735 [(set_attr "type" "icmov")
16736 (set_attr "mode" "QI")])
16739 [(set (match_operand:SWI12 0 "register_operand")
16740 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16741 [(reg FLAGS_REG) (const_int 0)])
16742 (match_operand:SWI12 2 "register_operand")
16743 (match_operand:SWI12 3 "register_operand")))]
16744 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16745 && reload_completed"
16746 [(set (match_dup 0)
16747 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16749 operands[0] = gen_lowpart (SImode, operands[0]);
16750 operands[2] = gen_lowpart (SImode, operands[2]);
16751 operands[3] = gen_lowpart (SImode, operands[3]);
16754 ;; Don't do conditional moves with memory inputs
16756 [(match_scratch:SWI248 2 "r")
16757 (set (match_operand:SWI248 0 "register_operand")
16758 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16759 [(reg FLAGS_REG) (const_int 0)])
16761 (match_operand:SWI248 3 "memory_operand")))]
16762 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16763 && optimize_insn_for_speed_p ()"
16764 [(set (match_dup 2) (match_dup 3))
16766 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16769 [(match_scratch:SWI248 2 "r")
16770 (set (match_operand:SWI248 0 "register_operand")
16771 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16772 [(reg FLAGS_REG) (const_int 0)])
16773 (match_operand:SWI248 3 "memory_operand")
16775 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16776 && optimize_insn_for_speed_p ()"
16777 [(set (match_dup 2) (match_dup 3))
16779 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16781 (define_expand "mov<mode>cc"
16782 [(set (match_operand:X87MODEF 0 "register_operand")
16783 (if_then_else:X87MODEF
16784 (match_operand 1 "comparison_operator")
16785 (match_operand:X87MODEF 2 "register_operand")
16786 (match_operand:X87MODEF 3 "register_operand")))]
16787 "(TARGET_80387 && TARGET_CMOVE)
16788 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16789 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16791 (define_insn "*movxfcc_1"
16792 [(set (match_operand:XF 0 "register_operand" "=f,f")
16793 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16794 [(reg FLAGS_REG) (const_int 0)])
16795 (match_operand:XF 2 "register_operand" "f,0")
16796 (match_operand:XF 3 "register_operand" "0,f")))]
16797 "TARGET_80387 && TARGET_CMOVE"
16799 fcmov%F1\t{%2, %0|%0, %2}
16800 fcmov%f1\t{%3, %0|%0, %3}"
16801 [(set_attr "type" "fcmov")
16802 (set_attr "mode" "XF")])
16804 (define_insn "*movdfcc_1"
16805 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16806 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16807 [(reg FLAGS_REG) (const_int 0)])
16808 (match_operand:DF 2 "nonimmediate_operand"
16810 (match_operand:DF 3 "nonimmediate_operand"
16811 "0 ,f,0 ,rm,0, rm")))]
16812 "TARGET_80387 && TARGET_CMOVE
16813 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16815 fcmov%F1\t{%2, %0|%0, %2}
16816 fcmov%f1\t{%3, %0|%0, %3}
16819 cmov%O2%C1\t{%2, %0|%0, %2}
16820 cmov%O2%c1\t{%3, %0|%0, %3}"
16821 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16822 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16823 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16826 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16827 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16828 [(reg FLAGS_REG) (const_int 0)])
16829 (match_operand:DF 2 "nonimmediate_operand")
16830 (match_operand:DF 3 "nonimmediate_operand")))]
16831 "!TARGET_64BIT && reload_completed"
16832 [(set (match_dup 2)
16833 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16835 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16837 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16838 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16841 (define_insn "*movsfcc_1_387"
16842 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16843 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16844 [(reg FLAGS_REG) (const_int 0)])
16845 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16846 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16847 "TARGET_80387 && TARGET_CMOVE
16848 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16850 fcmov%F1\t{%2, %0|%0, %2}
16851 fcmov%f1\t{%3, %0|%0, %3}
16852 cmov%O2%C1\t{%2, %0|%0, %2}
16853 cmov%O2%c1\t{%3, %0|%0, %3}"
16854 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16855 (set_attr "mode" "SF,SF,SI,SI")])
16857 ;; Don't do conditional moves with memory inputs. This splitter helps
16858 ;; register starved x86_32 by forcing inputs into registers before reload.
16860 [(set (match_operand:MODEF 0 "register_operand")
16861 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16862 [(reg FLAGS_REG) (const_int 0)])
16863 (match_operand:MODEF 2 "nonimmediate_operand")
16864 (match_operand:MODEF 3 "nonimmediate_operand")))]
16865 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16866 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16867 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16868 && can_create_pseudo_p ()
16869 && optimize_insn_for_speed_p ()"
16870 [(set (match_dup 0)
16871 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16873 if (MEM_P (operands[2]))
16874 operands[2] = force_reg (<MODE>mode, operands[2]);
16875 if (MEM_P (operands[3]))
16876 operands[3] = force_reg (<MODE>mode, operands[3]);
16879 ;; Don't do conditional moves with memory inputs
16881 [(match_scratch:MODEF 2 "r")
16882 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16883 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16884 [(reg FLAGS_REG) (const_int 0)])
16886 (match_operand:MODEF 3 "memory_operand")))]
16887 "(<MODE>mode != DFmode || TARGET_64BIT)
16888 && TARGET_80387 && TARGET_CMOVE
16889 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16890 && optimize_insn_for_speed_p ()"
16891 [(set (match_dup 2) (match_dup 3))
16893 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16896 [(match_scratch:MODEF 2 "r")
16897 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16898 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16899 [(reg FLAGS_REG) (const_int 0)])
16900 (match_operand:MODEF 3 "memory_operand")
16902 "(<MODE>mode != DFmode || TARGET_64BIT)
16903 && TARGET_80387 && TARGET_CMOVE
16904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16905 && optimize_insn_for_speed_p ()"
16906 [(set (match_dup 2) (match_dup 3))
16908 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16910 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16911 ;; the scalar versions to have only XMM registers as operands.
16913 ;; XOP conditional move
16914 (define_insn "*xop_pcmov_<mode>"
16915 [(set (match_operand:MODEF 0 "register_operand" "=x")
16916 (if_then_else:MODEF
16917 (match_operand:MODEF 1 "register_operand" "x")
16918 (match_operand:MODEF 2 "register_operand" "x")
16919 (match_operand:MODEF 3 "register_operand" "x")))]
16921 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16922 [(set_attr "type" "sse4arg")])
16924 ;; These versions of the min/max patterns are intentionally ignorant of
16925 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16926 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16927 ;; are undefined in this condition, we're certain this is correct.
16929 (define_insn "<code><mode>3"
16930 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16932 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16933 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16934 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16936 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16937 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16938 [(set_attr "isa" "noavx,avx")
16939 (set_attr "prefix" "orig,vex")
16940 (set_attr "type" "sseadd")
16941 (set_attr "mode" "<MODE>")])
16943 ;; These versions of the min/max patterns implement exactly the operations
16944 ;; min = (op1 < op2 ? op1 : op2)
16945 ;; max = (!(op1 < op2) ? op1 : op2)
16946 ;; Their operands are not commutative, and thus they may be used in the
16947 ;; presence of -0.0 and NaN.
16949 (define_int_iterator IEEE_MAXMIN
16953 (define_int_attr ieee_maxmin
16954 [(UNSPEC_IEEE_MAX "max")
16955 (UNSPEC_IEEE_MIN "min")])
16957 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16958 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16960 [(match_operand:MODEF 1 "register_operand" "0,v")
16961 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16963 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16965 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16966 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16967 [(set_attr "isa" "noavx,avx")
16968 (set_attr "prefix" "orig,maybe_evex")
16969 (set_attr "type" "sseadd")
16970 (set_attr "mode" "<MODE>")])
16972 ;; Make two stack loads independent:
16974 ;; fld %st(0) -> fld bb
16975 ;; fmul bb fmul %st(1), %st
16977 ;; Actually we only match the last two instructions for simplicity.
16979 [(set (match_operand 0 "fp_register_operand")
16980 (match_operand 1 "fp_register_operand"))
16982 (match_operator 2 "binary_fp_operator"
16984 (match_operand 3 "memory_operand")]))]
16985 "REGNO (operands[0]) != REGNO (operands[1])"
16986 [(set (match_dup 0) (match_dup 3))
16987 (set (match_dup 0) (match_dup 4))]
16989 ;; The % modifier is not operational anymore in peephole2's, so we have to
16990 ;; swap the operands manually in the case of addition and multiplication.
16994 if (COMMUTATIVE_ARITH_P (operands[2]))
16995 op0 = operands[0], op1 = operands[1];
16997 op0 = operands[1], op1 = operands[0];
16999 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17000 GET_MODE (operands[2]),
17004 ;; Conditional addition patterns
17005 (define_expand "add<mode>cc"
17006 [(match_operand:SWI 0 "register_operand")
17007 (match_operand 1 "ordered_comparison_operator")
17008 (match_operand:SWI 2 "register_operand")
17009 (match_operand:SWI 3 "const_int_operand")]
17011 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17013 ;; Misc patterns (?)
17015 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17016 ;; Otherwise there will be nothing to keep
17018 ;; [(set (reg ebp) (reg esp))]
17019 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17020 ;; (clobber (eflags)]
17021 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17023 ;; in proper program order.
17025 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17026 [(set (match_operand:P 0 "register_operand" "=r,r")
17027 (plus:P (match_operand:P 1 "register_operand" "0,r")
17028 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17029 (clobber (reg:CC FLAGS_REG))
17030 (clobber (mem:BLK (scratch)))]
17033 switch (get_attr_type (insn))
17036 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17039 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17040 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17041 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17043 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17046 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17047 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17050 [(set (attr "type")
17051 (cond [(and (eq_attr "alternative" "0")
17052 (not (match_test "TARGET_OPT_AGU")))
17053 (const_string "alu")
17054 (match_operand:<MODE> 2 "const0_operand")
17055 (const_string "imov")
17057 (const_string "lea")))
17058 (set (attr "length_immediate")
17059 (cond [(eq_attr "type" "imov")
17061 (and (eq_attr "type" "alu")
17062 (match_operand 2 "const128_operand"))
17065 (const_string "*")))
17066 (set_attr "mode" "<MODE>")])
17068 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17069 [(set (match_operand:P 0 "register_operand" "=r")
17070 (minus:P (match_operand:P 1 "register_operand" "0")
17071 (match_operand:P 2 "register_operand" "r")))
17072 (clobber (reg:CC FLAGS_REG))
17073 (clobber (mem:BLK (scratch)))]
17075 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17076 [(set_attr "type" "alu")
17077 (set_attr "mode" "<MODE>")])
17079 (define_insn "allocate_stack_worker_probe_<mode>"
17080 [(set (match_operand:P 0 "register_operand" "=a")
17081 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17082 UNSPECV_STACK_PROBE))
17083 (clobber (reg:CC FLAGS_REG))]
17084 "ix86_target_stack_probe ()"
17085 "call\t___chkstk_ms"
17086 [(set_attr "type" "multi")
17087 (set_attr "length" "5")])
17089 (define_expand "allocate_stack"
17090 [(match_operand 0 "register_operand")
17091 (match_operand 1 "general_operand")]
17092 "ix86_target_stack_probe ()"
17096 #ifndef CHECK_STACK_LIMIT
17097 #define CHECK_STACK_LIMIT 0
17100 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17101 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17105 rtx (*insn) (rtx, rtx);
17107 x = copy_to_mode_reg (Pmode, operands[1]);
17109 insn = (TARGET_64BIT
17110 ? gen_allocate_stack_worker_probe_di
17111 : gen_allocate_stack_worker_probe_si);
17113 emit_insn (insn (x, x));
17116 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17117 stack_pointer_rtx, 0, OPTAB_DIRECT);
17119 if (x != stack_pointer_rtx)
17120 emit_move_insn (stack_pointer_rtx, x);
17122 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17126 ;; Use IOR for stack probes, this is shorter.
17127 (define_expand "probe_stack"
17128 [(match_operand 0 "memory_operand")]
17131 rtx (*gen_ior3) (rtx, rtx, rtx);
17133 gen_ior3 = (GET_MODE (operands[0]) == DImode
17134 ? gen_iordi3 : gen_iorsi3);
17136 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17140 (define_insn "adjust_stack_and_probe<mode>"
17141 [(set (match_operand:P 0 "register_operand" "=r")
17142 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17143 UNSPECV_PROBE_STACK_RANGE))
17144 (set (reg:P SP_REG)
17145 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17146 (clobber (reg:CC FLAGS_REG))
17147 (clobber (mem:BLK (scratch)))]
17149 "* return output_adjust_stack_and_probe (operands[0]);"
17150 [(set_attr "type" "multi")])
17152 (define_insn "probe_stack_range<mode>"
17153 [(set (match_operand:P 0 "register_operand" "=r")
17154 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17155 (match_operand:P 2 "const_int_operand" "n")]
17156 UNSPECV_PROBE_STACK_RANGE))
17157 (clobber (reg:CC FLAGS_REG))]
17159 "* return output_probe_stack_range (operands[0], operands[2]);"
17160 [(set_attr "type" "multi")])
17162 (define_expand "builtin_setjmp_receiver"
17163 [(label_ref (match_operand 0))]
17164 "!TARGET_64BIT && flag_pic"
17170 rtx_code_label *label_rtx = gen_label_rtx ();
17171 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17172 xops[0] = xops[1] = pic_offset_table_rtx;
17173 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17174 ix86_expand_binary_operator (MINUS, SImode, xops);
17178 emit_insn (gen_set_got (pic_offset_table_rtx));
17182 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17183 ;; Do not split instructions with mask registers.
17185 [(set (match_operand 0 "general_reg_operand")
17186 (match_operator 3 "promotable_binary_operator"
17187 [(match_operand 1 "general_reg_operand")
17188 (match_operand 2 "aligned_operand")]))
17189 (clobber (reg:CC FLAGS_REG))]
17190 "! TARGET_PARTIAL_REG_STALL && reload_completed
17191 && ((GET_MODE (operands[0]) == HImode
17192 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17193 /* ??? next two lines just !satisfies_constraint_K (...) */
17194 || !CONST_INT_P (operands[2])
17195 || satisfies_constraint_K (operands[2])))
17196 || (GET_MODE (operands[0]) == QImode
17197 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17198 [(parallel [(set (match_dup 0)
17199 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17200 (clobber (reg:CC FLAGS_REG))])]
17202 operands[0] = gen_lowpart (SImode, operands[0]);
17203 operands[1] = gen_lowpart (SImode, operands[1]);
17204 if (GET_CODE (operands[3]) != ASHIFT)
17205 operands[2] = gen_lowpart (SImode, operands[2]);
17206 PUT_MODE (operands[3], SImode);
17209 ; Promote the QImode tests, as i386 has encoding of the AND
17210 ; instruction with 32-bit sign-extended immediate and thus the
17211 ; instruction size is unchanged, except in the %eax case for
17212 ; which it is increased by one byte, hence the ! optimize_size.
17214 [(set (match_operand 0 "flags_reg_operand")
17215 (match_operator 2 "compare_operator"
17216 [(and (match_operand 3 "aligned_operand")
17217 (match_operand 4 "const_int_operand"))
17219 (set (match_operand 1 "register_operand")
17220 (and (match_dup 3) (match_dup 4)))]
17221 "! TARGET_PARTIAL_REG_STALL && reload_completed
17222 && optimize_insn_for_speed_p ()
17223 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17224 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17225 /* Ensure that the operand will remain sign-extended immediate. */
17226 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17227 [(parallel [(set (match_dup 0)
17228 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17231 (and:SI (match_dup 3) (match_dup 4)))])]
17234 = gen_int_mode (INTVAL (operands[4])
17235 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17236 operands[1] = gen_lowpart (SImode, operands[1]);
17237 operands[3] = gen_lowpart (SImode, operands[3]);
17240 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17241 ; the TEST instruction with 32-bit sign-extended immediate and thus
17242 ; the instruction size would at least double, which is not what we
17243 ; want even with ! optimize_size.
17245 [(set (match_operand 0 "flags_reg_operand")
17246 (match_operator 1 "compare_operator"
17247 [(and (match_operand:HI 2 "aligned_operand")
17248 (match_operand:HI 3 "const_int_operand"))
17250 "! TARGET_PARTIAL_REG_STALL && reload_completed
17251 && ! TARGET_FAST_PREFIX
17252 && optimize_insn_for_speed_p ()
17253 /* Ensure that the operand will remain sign-extended immediate. */
17254 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17255 [(set (match_dup 0)
17256 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17260 = gen_int_mode (INTVAL (operands[3])
17261 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17262 operands[2] = gen_lowpart (SImode, operands[2]);
17266 [(set (match_operand 0 "register_operand")
17267 (neg (match_operand 1 "register_operand")))
17268 (clobber (reg:CC FLAGS_REG))]
17269 "! TARGET_PARTIAL_REG_STALL && reload_completed
17270 && (GET_MODE (operands[0]) == HImode
17271 || (GET_MODE (operands[0]) == QImode
17272 && (TARGET_PROMOTE_QImode
17273 || optimize_insn_for_size_p ())))"
17274 [(parallel [(set (match_dup 0)
17275 (neg:SI (match_dup 1)))
17276 (clobber (reg:CC FLAGS_REG))])]
17278 operands[0] = gen_lowpart (SImode, operands[0]);
17279 operands[1] = gen_lowpart (SImode, operands[1]);
17282 ;; Do not split instructions with mask regs.
17284 [(set (match_operand 0 "general_reg_operand")
17285 (not (match_operand 1 "general_reg_operand")))]
17286 "! TARGET_PARTIAL_REG_STALL && reload_completed
17287 && (GET_MODE (operands[0]) == HImode
17288 || (GET_MODE (operands[0]) == QImode
17289 && (TARGET_PROMOTE_QImode
17290 || optimize_insn_for_size_p ())))"
17291 [(set (match_dup 0)
17292 (not:SI (match_dup 1)))]
17294 operands[0] = gen_lowpart (SImode, operands[0]);
17295 operands[1] = gen_lowpart (SImode, operands[1]);
17298 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17299 ;; transform a complex memory operation into two memory to register operations.
17301 ;; Don't push memory operands
17303 [(set (match_operand:SWI 0 "push_operand")
17304 (match_operand:SWI 1 "memory_operand"))
17305 (match_scratch:SWI 2 "<r>")]
17306 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17307 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17308 [(set (match_dup 2) (match_dup 1))
17309 (set (match_dup 0) (match_dup 2))])
17311 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17314 [(set (match_operand:SF 0 "push_operand")
17315 (match_operand:SF 1 "memory_operand"))
17316 (match_scratch:SF 2 "r")]
17317 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17318 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17319 [(set (match_dup 2) (match_dup 1))
17320 (set (match_dup 0) (match_dup 2))])
17322 ;; Don't move an immediate directly to memory when the instruction
17323 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17325 [(match_scratch:SWI124 1 "<r>")
17326 (set (match_operand:SWI124 0 "memory_operand")
17328 "optimize_insn_for_speed_p ()
17329 && ((<MODE>mode == HImode
17330 && TARGET_LCP_STALL)
17331 || (!TARGET_USE_MOV0
17332 && TARGET_SPLIT_LONG_MOVES
17333 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17334 && peep2_regno_dead_p (0, FLAGS_REG)"
17335 [(parallel [(set (match_dup 2) (const_int 0))
17336 (clobber (reg:CC FLAGS_REG))])
17337 (set (match_dup 0) (match_dup 1))]
17338 "operands[2] = gen_lowpart (SImode, operands[1]);")
17341 [(match_scratch:SWI124 2 "<r>")
17342 (set (match_operand:SWI124 0 "memory_operand")
17343 (match_operand:SWI124 1 "immediate_operand"))]
17344 "optimize_insn_for_speed_p ()
17345 && ((<MODE>mode == HImode
17346 && TARGET_LCP_STALL)
17347 || (TARGET_SPLIT_LONG_MOVES
17348 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17349 [(set (match_dup 2) (match_dup 1))
17350 (set (match_dup 0) (match_dup 2))])
17352 ;; Don't compare memory with zero, load and use a test instead.
17354 [(set (match_operand 0 "flags_reg_operand")
17355 (match_operator 1 "compare_operator"
17356 [(match_operand:SI 2 "memory_operand")
17358 (match_scratch:SI 3 "r")]
17359 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17360 [(set (match_dup 3) (match_dup 2))
17361 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17363 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17364 ;; Don't split NOTs with a displacement operand, because resulting XOR
17365 ;; will not be pairable anyway.
17367 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17368 ;; represented using a modRM byte. The XOR replacement is long decoded,
17369 ;; so this split helps here as well.
17371 ;; Note: Can't do this as a regular split because we can't get proper
17372 ;; lifetime information then.
17375 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17376 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17377 "optimize_insn_for_speed_p ()
17378 && ((TARGET_NOT_UNPAIRABLE
17379 && (!MEM_P (operands[0])
17380 || !memory_displacement_operand (operands[0], <MODE>mode)))
17381 || (TARGET_NOT_VECTORMODE
17382 && long_memory_operand (operands[0], <MODE>mode)))
17383 && peep2_regno_dead_p (0, FLAGS_REG)"
17384 [(parallel [(set (match_dup 0)
17385 (xor:SWI124 (match_dup 1) (const_int -1)))
17386 (clobber (reg:CC FLAGS_REG))])])
17388 ;; Non pairable "test imm, reg" instructions can be translated to
17389 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17390 ;; byte opcode instead of two, have a short form for byte operands),
17391 ;; so do it for other CPUs as well. Given that the value was dead,
17392 ;; this should not create any new dependencies. Pass on the sub-word
17393 ;; versions if we're concerned about partial register stalls.
17396 [(set (match_operand 0 "flags_reg_operand")
17397 (match_operator 1 "compare_operator"
17398 [(and:SI (match_operand:SI 2 "register_operand")
17399 (match_operand:SI 3 "immediate_operand"))
17401 "ix86_match_ccmode (insn, CCNOmode)
17402 && (true_regnum (operands[2]) != AX_REG
17403 || satisfies_constraint_K (operands[3]))
17404 && peep2_reg_dead_p (1, operands[2])"
17406 [(set (match_dup 0)
17407 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17410 (and:SI (match_dup 2) (match_dup 3)))])])
17412 ;; We don't need to handle HImode case, because it will be promoted to SImode
17413 ;; on ! TARGET_PARTIAL_REG_STALL
17416 [(set (match_operand 0 "flags_reg_operand")
17417 (match_operator 1 "compare_operator"
17418 [(and:QI (match_operand:QI 2 "register_operand")
17419 (match_operand:QI 3 "immediate_operand"))
17421 "! TARGET_PARTIAL_REG_STALL
17422 && ix86_match_ccmode (insn, CCNOmode)
17423 && true_regnum (operands[2]) != AX_REG
17424 && peep2_reg_dead_p (1, operands[2])"
17426 [(set (match_dup 0)
17427 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17430 (and:QI (match_dup 2) (match_dup 3)))])])
17433 [(set (match_operand 0 "flags_reg_operand")
17434 (match_operator 1 "compare_operator"
17437 (match_operand 2 "QIreg_operand")
17440 (match_operand 3 "const_int_operand"))
17442 "! TARGET_PARTIAL_REG_STALL
17443 && ix86_match_ccmode (insn, CCNOmode)
17444 && true_regnum (operands[2]) != AX_REG
17445 && peep2_reg_dead_p (1, operands[2])"
17446 [(parallel [(set (match_dup 0)
17455 (set (zero_extract:SI (match_dup 2)
17463 (match_dup 3)))])])
17465 ;; Don't do logical operations with memory inputs.
17467 [(match_scratch:SI 2 "r")
17468 (parallel [(set (match_operand:SI 0 "register_operand")
17469 (match_operator:SI 3 "arith_or_logical_operator"
17471 (match_operand:SI 1 "memory_operand")]))
17472 (clobber (reg:CC FLAGS_REG))])]
17473 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17474 [(set (match_dup 2) (match_dup 1))
17475 (parallel [(set (match_dup 0)
17476 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17477 (clobber (reg:CC FLAGS_REG))])])
17480 [(match_scratch:SI 2 "r")
17481 (parallel [(set (match_operand:SI 0 "register_operand")
17482 (match_operator:SI 3 "arith_or_logical_operator"
17483 [(match_operand:SI 1 "memory_operand")
17485 (clobber (reg:CC FLAGS_REG))])]
17486 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17487 [(set (match_dup 2) (match_dup 1))
17488 (parallel [(set (match_dup 0)
17489 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17490 (clobber (reg:CC FLAGS_REG))])])
17492 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17493 ;; refers to the destination of the load!
17496 [(set (match_operand:SI 0 "register_operand")
17497 (match_operand:SI 1 "register_operand"))
17498 (parallel [(set (match_dup 0)
17499 (match_operator:SI 3 "commutative_operator"
17501 (match_operand:SI 2 "memory_operand")]))
17502 (clobber (reg:CC FLAGS_REG))])]
17503 "REGNO (operands[0]) != REGNO (operands[1])
17504 && GENERAL_REGNO_P (REGNO (operands[0]))
17505 && GENERAL_REGNO_P (REGNO (operands[1]))"
17506 [(set (match_dup 0) (match_dup 4))
17507 (parallel [(set (match_dup 0)
17508 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17509 (clobber (reg:CC FLAGS_REG))])]
17510 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17513 [(set (match_operand 0 "register_operand")
17514 (match_operand 1 "register_operand"))
17516 (match_operator 3 "commutative_operator"
17518 (match_operand 2 "memory_operand")]))]
17519 "REGNO (operands[0]) != REGNO (operands[1])
17520 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17521 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17522 [(set (match_dup 0) (match_dup 2))
17524 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17526 ; Don't do logical operations with memory outputs
17528 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17529 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17530 ; the same decoder scheduling characteristics as the original.
17533 [(match_scratch:SI 2 "r")
17534 (parallel [(set (match_operand:SI 0 "memory_operand")
17535 (match_operator:SI 3 "arith_or_logical_operator"
17537 (match_operand:SI 1 "nonmemory_operand")]))
17538 (clobber (reg:CC FLAGS_REG))])]
17539 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17540 /* Do not split stack checking probes. */
17541 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17542 [(set (match_dup 2) (match_dup 0))
17543 (parallel [(set (match_dup 2)
17544 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17545 (clobber (reg:CC FLAGS_REG))])
17546 (set (match_dup 0) (match_dup 2))])
17549 [(match_scratch:SI 2 "r")
17550 (parallel [(set (match_operand:SI 0 "memory_operand")
17551 (match_operator:SI 3 "arith_or_logical_operator"
17552 [(match_operand:SI 1 "nonmemory_operand")
17554 (clobber (reg:CC FLAGS_REG))])]
17555 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17556 /* Do not split stack checking probes. */
17557 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17558 [(set (match_dup 2) (match_dup 0))
17559 (parallel [(set (match_dup 2)
17560 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17561 (clobber (reg:CC FLAGS_REG))])
17562 (set (match_dup 0) (match_dup 2))])
17564 ;; Attempt to use arith or logical operations with memory outputs with
17565 ;; setting of flags.
17567 [(set (match_operand:SWI 0 "register_operand")
17568 (match_operand:SWI 1 "memory_operand"))
17569 (parallel [(set (match_dup 0)
17570 (match_operator:SWI 3 "plusminuslogic_operator"
17572 (match_operand:SWI 2 "<nonmemory_operand>")]))
17573 (clobber (reg:CC FLAGS_REG))])
17574 (set (match_dup 1) (match_dup 0))
17575 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17576 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17577 && peep2_reg_dead_p (4, operands[0])
17578 && !reg_overlap_mentioned_p (operands[0], operands[1])
17579 && !reg_overlap_mentioned_p (operands[0], operands[2])
17580 && (<MODE>mode != QImode
17581 || immediate_operand (operands[2], QImode)
17582 || any_QIreg_operand (operands[2], QImode))
17583 && ix86_match_ccmode (peep2_next_insn (3),
17584 (GET_CODE (operands[3]) == PLUS
17585 || GET_CODE (operands[3]) == MINUS)
17586 ? CCGOCmode : CCNOmode)"
17587 [(parallel [(set (match_dup 4) (match_dup 5))
17588 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17589 (match_dup 2)]))])]
17591 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17592 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17593 copy_rtx (operands[1]),
17594 copy_rtx (operands[2]));
17595 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17596 operands[5], const0_rtx);
17600 [(parallel [(set (match_operand:SWI 0 "register_operand")
17601 (match_operator:SWI 2 "plusminuslogic_operator"
17603 (match_operand:SWI 1 "memory_operand")]))
17604 (clobber (reg:CC FLAGS_REG))])
17605 (set (match_dup 1) (match_dup 0))
17606 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17607 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17608 && GET_CODE (operands[2]) != MINUS
17609 && peep2_reg_dead_p (3, operands[0])
17610 && !reg_overlap_mentioned_p (operands[0], operands[1])
17611 && ix86_match_ccmode (peep2_next_insn (2),
17612 GET_CODE (operands[2]) == PLUS
17613 ? CCGOCmode : CCNOmode)"
17614 [(parallel [(set (match_dup 3) (match_dup 4))
17615 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17616 (match_dup 0)]))])]
17618 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17619 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17620 copy_rtx (operands[1]),
17621 copy_rtx (operands[0]));
17622 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17623 operands[4], const0_rtx);
17627 [(set (match_operand:SWI12 0 "register_operand")
17628 (match_operand:SWI12 1 "memory_operand"))
17629 (parallel [(set (match_operand:SI 4 "register_operand")
17630 (match_operator:SI 3 "plusminuslogic_operator"
17632 (match_operand:SI 2 "nonmemory_operand")]))
17633 (clobber (reg:CC FLAGS_REG))])
17634 (set (match_dup 1) (match_dup 0))
17635 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17636 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17637 && REG_P (operands[0]) && REG_P (operands[4])
17638 && REGNO (operands[0]) == REGNO (operands[4])
17639 && peep2_reg_dead_p (4, operands[0])
17640 && (<MODE>mode != QImode
17641 || immediate_operand (operands[2], SImode)
17642 || any_QIreg_operand (operands[2], SImode))
17643 && !reg_overlap_mentioned_p (operands[0], operands[1])
17644 && !reg_overlap_mentioned_p (operands[0], operands[2])
17645 && ix86_match_ccmode (peep2_next_insn (3),
17646 (GET_CODE (operands[3]) == PLUS
17647 || GET_CODE (operands[3]) == MINUS)
17648 ? CCGOCmode : CCNOmode)"
17649 [(parallel [(set (match_dup 4) (match_dup 5))
17650 (set (match_dup 1) (match_dup 6))])]
17652 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17653 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17654 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17655 copy_rtx (operands[1]), operands[2]);
17656 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17657 operands[5], const0_rtx);
17658 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17659 copy_rtx (operands[1]),
17660 copy_rtx (operands[2]));
17663 ;; Attempt to always use XOR for zeroing registers.
17665 [(set (match_operand 0 "register_operand")
17666 (match_operand 1 "const0_operand"))]
17667 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17668 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17669 && GENERAL_REG_P (operands[0])
17670 && peep2_regno_dead_p (0, FLAGS_REG)"
17671 [(parallel [(set (match_dup 0) (const_int 0))
17672 (clobber (reg:CC FLAGS_REG))])]
17673 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17676 [(set (strict_low_part (match_operand 0 "register_operand"))
17678 "(GET_MODE (operands[0]) == QImode
17679 || GET_MODE (operands[0]) == HImode)
17680 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17681 && peep2_regno_dead_p (0, FLAGS_REG)"
17682 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17683 (clobber (reg:CC FLAGS_REG))])])
17685 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17687 [(set (match_operand:SWI248 0 "register_operand")
17689 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17690 && peep2_regno_dead_p (0, FLAGS_REG)"
17691 [(parallel [(set (match_dup 0) (const_int -1))
17692 (clobber (reg:CC FLAGS_REG))])]
17694 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17695 operands[0] = gen_lowpart (SImode, operands[0]);
17698 ;; Attempt to convert simple lea to add/shift.
17699 ;; These can be created by move expanders.
17700 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17701 ;; relevant lea instructions were already split.
17704 [(set (match_operand:SWI48 0 "register_operand")
17705 (plus:SWI48 (match_dup 0)
17706 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17708 && peep2_regno_dead_p (0, FLAGS_REG)"
17709 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17710 (clobber (reg:CC FLAGS_REG))])])
17713 [(set (match_operand:SWI48 0 "register_operand")
17714 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17717 && peep2_regno_dead_p (0, FLAGS_REG)"
17718 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17719 (clobber (reg:CC FLAGS_REG))])])
17722 [(set (match_operand:DI 0 "register_operand")
17724 (plus:SI (match_operand:SI 1 "register_operand")
17725 (match_operand:SI 2 "nonmemory_operand"))))]
17726 "TARGET_64BIT && !TARGET_OPT_AGU
17727 && REGNO (operands[0]) == REGNO (operands[1])
17728 && peep2_regno_dead_p (0, FLAGS_REG)"
17729 [(parallel [(set (match_dup 0)
17730 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17731 (clobber (reg:CC FLAGS_REG))])])
17734 [(set (match_operand:DI 0 "register_operand")
17736 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17737 (match_operand:SI 2 "register_operand"))))]
17738 "TARGET_64BIT && !TARGET_OPT_AGU
17739 && REGNO (operands[0]) == REGNO (operands[2])
17740 && peep2_regno_dead_p (0, FLAGS_REG)"
17741 [(parallel [(set (match_dup 0)
17742 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17743 (clobber (reg:CC FLAGS_REG))])])
17746 [(set (match_operand:SWI48 0 "register_operand")
17747 (mult:SWI48 (match_dup 0)
17748 (match_operand:SWI48 1 "const_int_operand")))]
17749 "exact_log2 (INTVAL (operands[1])) >= 0
17750 && peep2_regno_dead_p (0, FLAGS_REG)"
17751 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17752 (clobber (reg:CC FLAGS_REG))])]
17753 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17756 [(set (match_operand:DI 0 "register_operand")
17758 (mult:SI (match_operand:SI 1 "register_operand")
17759 (match_operand:SI 2 "const_int_operand"))))]
17761 && exact_log2 (INTVAL (operands[2])) >= 0
17762 && REGNO (operands[0]) == REGNO (operands[1])
17763 && peep2_regno_dead_p (0, FLAGS_REG)"
17764 [(parallel [(set (match_dup 0)
17765 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17766 (clobber (reg:CC FLAGS_REG))])]
17767 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17769 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17770 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17771 ;; On many CPUs it is also faster, since special hardware to avoid esp
17772 ;; dependencies is present.
17774 ;; While some of these conversions may be done using splitters, we use
17775 ;; peepholes in order to allow combine_stack_adjustments pass to see
17776 ;; nonobfuscated RTL.
17778 ;; Convert prologue esp subtractions to push.
17779 ;; We need register to push. In order to keep verify_flow_info happy we have
17781 ;; - use scratch and clobber it in order to avoid dependencies
17782 ;; - use already live register
17783 ;; We can't use the second way right now, since there is no reliable way how to
17784 ;; verify that given register is live. First choice will also most likely in
17785 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17786 ;; call clobbered registers are dead. We may want to use base pointer as an
17787 ;; alternative when no register is available later.
17790 [(match_scratch:W 1 "r")
17791 (parallel [(set (reg:P SP_REG)
17792 (plus:P (reg:P SP_REG)
17793 (match_operand:P 0 "const_int_operand")))
17794 (clobber (reg:CC FLAGS_REG))
17795 (clobber (mem:BLK (scratch)))])]
17796 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17797 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17798 [(clobber (match_dup 1))
17799 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17800 (clobber (mem:BLK (scratch)))])])
17803 [(match_scratch:W 1 "r")
17804 (parallel [(set (reg:P SP_REG)
17805 (plus:P (reg:P SP_REG)
17806 (match_operand:P 0 "const_int_operand")))
17807 (clobber (reg:CC FLAGS_REG))
17808 (clobber (mem:BLK (scratch)))])]
17809 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17810 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17811 [(clobber (match_dup 1))
17812 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17813 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17814 (clobber (mem:BLK (scratch)))])])
17816 ;; Convert esp subtractions to push.
17818 [(match_scratch:W 1 "r")
17819 (parallel [(set (reg:P SP_REG)
17820 (plus:P (reg:P SP_REG)
17821 (match_operand:P 0 "const_int_operand")))
17822 (clobber (reg:CC FLAGS_REG))])]
17823 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17824 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17825 [(clobber (match_dup 1))
17826 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17829 [(match_scratch:W 1 "r")
17830 (parallel [(set (reg:P SP_REG)
17831 (plus:P (reg:P SP_REG)
17832 (match_operand:P 0 "const_int_operand")))
17833 (clobber (reg:CC FLAGS_REG))])]
17834 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17835 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17836 [(clobber (match_dup 1))
17837 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17838 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17840 ;; Convert epilogue deallocator to pop.
17842 [(match_scratch:W 1 "r")
17843 (parallel [(set (reg:P SP_REG)
17844 (plus:P (reg:P SP_REG)
17845 (match_operand:P 0 "const_int_operand")))
17846 (clobber (reg:CC FLAGS_REG))
17847 (clobber (mem:BLK (scratch)))])]
17848 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17849 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17850 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17851 (clobber (mem:BLK (scratch)))])])
17853 ;; Two pops case is tricky, since pop causes dependency
17854 ;; on destination register. We use two registers if available.
17856 [(match_scratch:W 1 "r")
17857 (match_scratch:W 2 "r")
17858 (parallel [(set (reg:P SP_REG)
17859 (plus:P (reg:P SP_REG)
17860 (match_operand:P 0 "const_int_operand")))
17861 (clobber (reg:CC FLAGS_REG))
17862 (clobber (mem:BLK (scratch)))])]
17863 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17864 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17865 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17866 (clobber (mem:BLK (scratch)))])
17867 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17870 [(match_scratch:W 1 "r")
17871 (parallel [(set (reg:P SP_REG)
17872 (plus:P (reg:P SP_REG)
17873 (match_operand:P 0 "const_int_operand")))
17874 (clobber (reg:CC FLAGS_REG))
17875 (clobber (mem:BLK (scratch)))])]
17876 "optimize_insn_for_size_p ()
17877 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17878 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17879 (clobber (mem:BLK (scratch)))])
17880 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17882 ;; Convert esp additions to pop.
17884 [(match_scratch:W 1 "r")
17885 (parallel [(set (reg:P SP_REG)
17886 (plus:P (reg:P SP_REG)
17887 (match_operand:P 0 "const_int_operand")))
17888 (clobber (reg:CC FLAGS_REG))])]
17889 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17890 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17892 ;; Two pops case is tricky, since pop causes dependency
17893 ;; on destination register. We use two registers if available.
17895 [(match_scratch:W 1 "r")
17896 (match_scratch:W 2 "r")
17897 (parallel [(set (reg:P SP_REG)
17898 (plus:P (reg:P SP_REG)
17899 (match_operand:P 0 "const_int_operand")))
17900 (clobber (reg:CC FLAGS_REG))])]
17901 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17902 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17903 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17906 [(match_scratch:W 1 "r")
17907 (parallel [(set (reg:P SP_REG)
17908 (plus:P (reg:P SP_REG)
17909 (match_operand:P 0 "const_int_operand")))
17910 (clobber (reg:CC FLAGS_REG))])]
17911 "optimize_insn_for_size_p ()
17912 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17913 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17914 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17916 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17917 ;; required and register dies. Similarly for 128 to -128.
17919 [(set (match_operand 0 "flags_reg_operand")
17920 (match_operator 1 "compare_operator"
17921 [(match_operand 2 "register_operand")
17922 (match_operand 3 "const_int_operand")]))]
17923 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17924 && incdec_operand (operands[3], GET_MODE (operands[3])))
17925 || (!TARGET_FUSE_CMP_AND_BRANCH
17926 && INTVAL (operands[3]) == 128))
17927 && ix86_match_ccmode (insn, CCGCmode)
17928 && peep2_reg_dead_p (1, operands[2])"
17929 [(parallel [(set (match_dup 0)
17930 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17931 (clobber (match_dup 2))])])
17933 ;; Convert imul by three, five and nine into lea
17936 [(set (match_operand:SWI48 0 "register_operand")
17937 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17938 (match_operand:SWI48 2 "const359_operand")))
17939 (clobber (reg:CC FLAGS_REG))])]
17940 "!TARGET_PARTIAL_REG_STALL
17941 || <MODE>mode == SImode
17942 || optimize_function_for_size_p (cfun)"
17943 [(set (match_dup 0)
17944 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17946 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17950 [(set (match_operand:SWI48 0 "register_operand")
17951 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17952 (match_operand:SWI48 2 "const359_operand")))
17953 (clobber (reg:CC FLAGS_REG))])]
17954 "optimize_insn_for_speed_p ()
17955 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17956 [(set (match_dup 0) (match_dup 1))
17958 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17960 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17962 ;; imul $32bit_imm, mem, reg is vector decoded, while
17963 ;; imul $32bit_imm, reg, reg is direct decoded.
17965 [(match_scratch:SWI48 3 "r")
17966 (parallel [(set (match_operand:SWI48 0 "register_operand")
17967 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17968 (match_operand:SWI48 2 "immediate_operand")))
17969 (clobber (reg:CC FLAGS_REG))])]
17970 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17971 && !satisfies_constraint_K (operands[2])"
17972 [(set (match_dup 3) (match_dup 1))
17973 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17974 (clobber (reg:CC FLAGS_REG))])])
17977 [(match_scratch:SI 3 "r")
17978 (parallel [(set (match_operand:DI 0 "register_operand")
17980 (mult:SI (match_operand:SI 1 "memory_operand")
17981 (match_operand:SI 2 "immediate_operand"))))
17982 (clobber (reg:CC FLAGS_REG))])]
17984 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17985 && !satisfies_constraint_K (operands[2])"
17986 [(set (match_dup 3) (match_dup 1))
17987 (parallel [(set (match_dup 0)
17988 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17989 (clobber (reg:CC FLAGS_REG))])])
17991 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17992 ;; Convert it into imul reg, reg
17993 ;; It would be better to force assembler to encode instruction using long
17994 ;; immediate, but there is apparently no way to do so.
17996 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17998 (match_operand:SWI248 1 "nonimmediate_operand")
17999 (match_operand:SWI248 2 "const_int_operand")))
18000 (clobber (reg:CC FLAGS_REG))])
18001 (match_scratch:SWI248 3 "r")]
18002 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18003 && satisfies_constraint_K (operands[2])"
18004 [(set (match_dup 3) (match_dup 2))
18005 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18006 (clobber (reg:CC FLAGS_REG))])]
18008 if (!rtx_equal_p (operands[0], operands[1]))
18009 emit_move_insn (operands[0], operands[1]);
18012 ;; After splitting up read-modify operations, array accesses with memory
18013 ;; operands might end up in form:
18015 ;; movl 4(%esp), %edx
18017 ;; instead of pre-splitting:
18019 ;; addl 4(%esp), %eax
18021 ;; movl 4(%esp), %edx
18022 ;; leal (%edx,%eax,4), %eax
18025 [(match_scratch:W 5 "r")
18026 (parallel [(set (match_operand 0 "register_operand")
18027 (ashift (match_operand 1 "register_operand")
18028 (match_operand 2 "const_int_operand")))
18029 (clobber (reg:CC FLAGS_REG))])
18030 (parallel [(set (match_operand 3 "register_operand")
18031 (plus (match_dup 0)
18032 (match_operand 4 "x86_64_general_operand")))
18033 (clobber (reg:CC FLAGS_REG))])]
18034 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18035 /* Validate MODE for lea. */
18036 && ((!TARGET_PARTIAL_REG_STALL
18037 && (GET_MODE (operands[0]) == QImode
18038 || GET_MODE (operands[0]) == HImode))
18039 || GET_MODE (operands[0]) == SImode
18040 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18041 && (rtx_equal_p (operands[0], operands[3])
18042 || peep2_reg_dead_p (2, operands[0]))
18043 /* We reorder load and the shift. */
18044 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18045 [(set (match_dup 5) (match_dup 4))
18046 (set (match_dup 0) (match_dup 1))]
18048 machine_mode op1mode = GET_MODE (operands[1]);
18049 machine_mode mode = op1mode == DImode ? DImode : SImode;
18050 int scale = 1 << INTVAL (operands[2]);
18051 rtx index = gen_lowpart (word_mode, operands[1]);
18052 rtx base = gen_lowpart (word_mode, operands[5]);
18053 rtx dest = gen_lowpart (mode, operands[3]);
18055 operands[1] = gen_rtx_PLUS (word_mode, base,
18056 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18057 operands[5] = base;
18058 if (mode != word_mode)
18059 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18060 if (op1mode != word_mode)
18061 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18062 operands[0] = dest;
18065 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18066 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18067 ;; caught for use by garbage collectors and the like. Using an insn that
18068 ;; maps to SIGILL makes it more likely the program will rightfully die.
18069 ;; Keeping with tradition, "6" is in honor of #UD.
18070 (define_insn "trap"
18071 [(trap_if (const_int 1) (const_int 6))]
18074 #ifdef HAVE_AS_IX86_UD2
18077 return ASM_SHORT "0x0b0f";
18080 [(set_attr "length" "2")])
18082 (define_expand "prefetch"
18083 [(prefetch (match_operand 0 "address_operand")
18084 (match_operand:SI 1 "const_int_operand")
18085 (match_operand:SI 2 "const_int_operand"))]
18086 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18088 bool write = INTVAL (operands[1]) != 0;
18089 int locality = INTVAL (operands[2]);
18091 gcc_assert (IN_RANGE (locality, 0, 3));
18093 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18094 supported by SSE counterpart or the SSE prefetch is not available
18095 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18097 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18098 operands[2] = const2_rtx;
18099 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18100 operands[2] = GEN_INT (3);
18102 operands[1] = const0_rtx;
18105 (define_insn "*prefetch_sse"
18106 [(prefetch (match_operand 0 "address_operand" "p")
18108 (match_operand:SI 1 "const_int_operand"))]
18109 "TARGET_PREFETCH_SSE"
18111 static const char * const patterns[4] = {
18112 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18115 int locality = INTVAL (operands[1]);
18116 gcc_assert (IN_RANGE (locality, 0, 3));
18118 return patterns[locality];
18120 [(set_attr "type" "sse")
18121 (set_attr "atom_sse_attr" "prefetch")
18122 (set (attr "length_address")
18123 (symbol_ref "memory_address_length (operands[0], false)"))
18124 (set_attr "memory" "none")])
18126 (define_insn "*prefetch_3dnow"
18127 [(prefetch (match_operand 0 "address_operand" "p")
18128 (match_operand:SI 1 "const_int_operand" "n")
18132 if (INTVAL (operands[1]) == 0)
18133 return "prefetch\t%a0";
18135 return "prefetchw\t%a0";
18137 [(set_attr "type" "mmx")
18138 (set (attr "length_address")
18139 (symbol_ref "memory_address_length (operands[0], false)"))
18140 (set_attr "memory" "none")])
18142 (define_insn "*prefetch_prefetchwt1"
18143 [(prefetch (match_operand 0 "address_operand" "p")
18146 "TARGET_PREFETCHWT1"
18147 "prefetchwt1\t%a0";
18148 [(set_attr "type" "sse")
18149 (set (attr "length_address")
18150 (symbol_ref "memory_address_length (operands[0], false)"))
18151 (set_attr "memory" "none")])
18153 (define_expand "stack_protect_set"
18154 [(match_operand 0 "memory_operand")
18155 (match_operand 1 "memory_operand")]
18156 "TARGET_SSP_TLS_GUARD"
18158 rtx (*insn)(rtx, rtx);
18160 #ifdef TARGET_THREAD_SSP_OFFSET
18161 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18162 insn = (TARGET_LP64
18163 ? gen_stack_tls_protect_set_di
18164 : gen_stack_tls_protect_set_si);
18166 insn = (TARGET_LP64
18167 ? gen_stack_protect_set_di
18168 : gen_stack_protect_set_si);
18171 emit_insn (insn (operands[0], operands[1]));
18175 (define_insn "stack_protect_set_<mode>"
18176 [(set (match_operand:PTR 0 "memory_operand" "=m")
18177 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18179 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18180 (clobber (reg:CC FLAGS_REG))]
18181 "TARGET_SSP_TLS_GUARD"
18182 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18183 [(set_attr "type" "multi")])
18185 (define_insn "stack_tls_protect_set_<mode>"
18186 [(set (match_operand:PTR 0 "memory_operand" "=m")
18187 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18188 UNSPEC_SP_TLS_SET))
18189 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18190 (clobber (reg:CC FLAGS_REG))]
18192 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18193 [(set_attr "type" "multi")])
18195 (define_expand "stack_protect_test"
18196 [(match_operand 0 "memory_operand")
18197 (match_operand 1 "memory_operand")
18199 "TARGET_SSP_TLS_GUARD"
18201 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18203 rtx (*insn)(rtx, rtx, rtx);
18205 #ifdef TARGET_THREAD_SSP_OFFSET
18206 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18207 insn = (TARGET_LP64
18208 ? gen_stack_tls_protect_test_di
18209 : gen_stack_tls_protect_test_si);
18211 insn = (TARGET_LP64
18212 ? gen_stack_protect_test_di
18213 : gen_stack_protect_test_si);
18216 emit_insn (insn (flags, operands[0], operands[1]));
18218 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18219 flags, const0_rtx, operands[2]));
18223 (define_insn "stack_protect_test_<mode>"
18224 [(set (match_operand:CCZ 0 "flags_reg_operand")
18225 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18226 (match_operand:PTR 2 "memory_operand" "m")]
18228 (clobber (match_scratch:PTR 3 "=&r"))]
18229 "TARGET_SSP_TLS_GUARD"
18230 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18231 [(set_attr "type" "multi")])
18233 (define_insn "stack_tls_protect_test_<mode>"
18234 [(set (match_operand:CCZ 0 "flags_reg_operand")
18235 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18236 (match_operand:PTR 2 "const_int_operand" "i")]
18237 UNSPEC_SP_TLS_TEST))
18238 (clobber (match_scratch:PTR 3 "=r"))]
18240 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18241 [(set_attr "type" "multi")])
18243 (define_insn "sse4_2_crc32<mode>"
18244 [(set (match_operand:SI 0 "register_operand" "=r")
18246 [(match_operand:SI 1 "register_operand" "0")
18247 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18249 "TARGET_SSE4_2 || TARGET_CRC32"
18250 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18251 [(set_attr "type" "sselog1")
18252 (set_attr "prefix_rep" "1")
18253 (set_attr "prefix_extra" "1")
18254 (set (attr "prefix_data16")
18255 (if_then_else (match_operand:HI 2)
18257 (const_string "*")))
18258 (set (attr "prefix_rex")
18259 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18261 (const_string "*")))
18262 (set_attr "mode" "SI")])
18264 (define_insn "sse4_2_crc32di"
18265 [(set (match_operand:DI 0 "register_operand" "=r")
18267 [(match_operand:DI 1 "register_operand" "0")
18268 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18270 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18271 "crc32{q}\t{%2, %0|%0, %2}"
18272 [(set_attr "type" "sselog1")
18273 (set_attr "prefix_rep" "1")
18274 (set_attr "prefix_extra" "1")
18275 (set_attr "mode" "DI")])
18277 (define_insn "rdpmc"
18278 [(set (match_operand:DI 0 "register_operand" "=A")
18279 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18283 [(set_attr "type" "other")
18284 (set_attr "length" "2")])
18286 (define_insn "rdpmc_rex64"
18287 [(set (match_operand:DI 0 "register_operand" "=a")
18288 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18290 (set (match_operand:DI 1 "register_operand" "=d")
18291 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18294 [(set_attr "type" "other")
18295 (set_attr "length" "2")])
18297 (define_insn "rdtsc"
18298 [(set (match_operand:DI 0 "register_operand" "=A")
18299 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18302 [(set_attr "type" "other")
18303 (set_attr "length" "2")])
18305 (define_insn "rdtsc_rex64"
18306 [(set (match_operand:DI 0 "register_operand" "=a")
18307 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18308 (set (match_operand:DI 1 "register_operand" "=d")
18309 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18312 [(set_attr "type" "other")
18313 (set_attr "length" "2")])
18315 (define_insn "rdtscp"
18316 [(set (match_operand:DI 0 "register_operand" "=A")
18317 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18318 (set (match_operand:SI 1 "register_operand" "=c")
18319 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18322 [(set_attr "type" "other")
18323 (set_attr "length" "3")])
18325 (define_insn "rdtscp_rex64"
18326 [(set (match_operand:DI 0 "register_operand" "=a")
18327 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18328 (set (match_operand:DI 1 "register_operand" "=d")
18329 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18330 (set (match_operand:SI 2 "register_operand" "=c")
18331 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18334 [(set_attr "type" "other")
18335 (set_attr "length" "3")])
18337 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18339 ;; FXSR, XSAVE and XSAVEOPT instructions
18341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18343 (define_insn "fxsave"
18344 [(set (match_operand:BLK 0 "memory_operand" "=m")
18345 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18348 [(set_attr "type" "other")
18349 (set_attr "memory" "store")
18350 (set (attr "length")
18351 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18353 (define_insn "fxsave64"
18354 [(set (match_operand:BLK 0 "memory_operand" "=m")
18355 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18356 "TARGET_64BIT && TARGET_FXSR"
18358 [(set_attr "type" "other")
18359 (set_attr "memory" "store")
18360 (set (attr "length")
18361 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18363 (define_insn "fxrstor"
18364 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18368 [(set_attr "type" "other")
18369 (set_attr "memory" "load")
18370 (set (attr "length")
18371 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18373 (define_insn "fxrstor64"
18374 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18375 UNSPECV_FXRSTOR64)]
18376 "TARGET_64BIT && TARGET_FXSR"
18378 [(set_attr "type" "other")
18379 (set_attr "memory" "load")
18380 (set (attr "length")
18381 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18383 (define_int_iterator ANY_XSAVE
18385 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18386 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18387 (UNSPECV_XSAVES "TARGET_XSAVES")])
18389 (define_int_iterator ANY_XSAVE64
18391 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18392 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18393 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18395 (define_int_attr xsave
18396 [(UNSPECV_XSAVE "xsave")
18397 (UNSPECV_XSAVE64 "xsave64")
18398 (UNSPECV_XSAVEOPT "xsaveopt")
18399 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18400 (UNSPECV_XSAVEC "xsavec")
18401 (UNSPECV_XSAVEC64 "xsavec64")
18402 (UNSPECV_XSAVES "xsaves")
18403 (UNSPECV_XSAVES64 "xsaves64")])
18405 (define_int_iterator ANY_XRSTOR
18407 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18409 (define_int_iterator ANY_XRSTOR64
18411 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18413 (define_int_attr xrstor
18414 [(UNSPECV_XRSTOR "xrstor")
18415 (UNSPECV_XRSTOR64 "xrstor")
18416 (UNSPECV_XRSTORS "xrstors")
18417 (UNSPECV_XRSTORS64 "xrstors")])
18419 (define_insn "<xsave>"
18420 [(set (match_operand:BLK 0 "memory_operand" "=m")
18421 (unspec_volatile:BLK
18422 [(match_operand:DI 1 "register_operand" "A")]
18424 "!TARGET_64BIT && TARGET_XSAVE"
18426 [(set_attr "type" "other")
18427 (set_attr "memory" "store")
18428 (set (attr "length")
18429 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18431 (define_insn "<xsave>_rex64"
18432 [(set (match_operand:BLK 0 "memory_operand" "=m")
18433 (unspec_volatile:BLK
18434 [(match_operand:SI 1 "register_operand" "a")
18435 (match_operand:SI 2 "register_operand" "d")]
18437 "TARGET_64BIT && TARGET_XSAVE"
18439 [(set_attr "type" "other")
18440 (set_attr "memory" "store")
18441 (set (attr "length")
18442 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18444 (define_insn "<xsave>"
18445 [(set (match_operand:BLK 0 "memory_operand" "=m")
18446 (unspec_volatile:BLK
18447 [(match_operand:SI 1 "register_operand" "a")
18448 (match_operand:SI 2 "register_operand" "d")]
18450 "TARGET_64BIT && TARGET_XSAVE"
18452 [(set_attr "type" "other")
18453 (set_attr "memory" "store")
18454 (set (attr "length")
18455 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18457 (define_insn "<xrstor>"
18458 [(unspec_volatile:BLK
18459 [(match_operand:BLK 0 "memory_operand" "m")
18460 (match_operand:DI 1 "register_operand" "A")]
18462 "!TARGET_64BIT && TARGET_XSAVE"
18464 [(set_attr "type" "other")
18465 (set_attr "memory" "load")
18466 (set (attr "length")
18467 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18469 (define_insn "<xrstor>_rex64"
18470 [(unspec_volatile:BLK
18471 [(match_operand:BLK 0 "memory_operand" "m")
18472 (match_operand:SI 1 "register_operand" "a")
18473 (match_operand:SI 2 "register_operand" "d")]
18475 "TARGET_64BIT && TARGET_XSAVE"
18477 [(set_attr "type" "other")
18478 (set_attr "memory" "load")
18479 (set (attr "length")
18480 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18482 (define_insn "<xrstor>64"
18483 [(unspec_volatile:BLK
18484 [(match_operand:BLK 0 "memory_operand" "m")
18485 (match_operand:SI 1 "register_operand" "a")
18486 (match_operand:SI 2 "register_operand" "d")]
18488 "TARGET_64BIT && TARGET_XSAVE"
18490 [(set_attr "type" "other")
18491 (set_attr "memory" "load")
18492 (set (attr "length")
18493 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18495 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18497 ;; Floating-point instructions for atomic compound assignments
18499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18501 ; Clobber all floating-point registers on environment save and restore
18502 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18503 (define_insn "fnstenv"
18504 [(set (match_operand:BLK 0 "memory_operand" "=m")
18505 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18506 (clobber (reg:HI FPCR_REG))
18507 (clobber (reg:XF ST0_REG))
18508 (clobber (reg:XF ST1_REG))
18509 (clobber (reg:XF ST2_REG))
18510 (clobber (reg:XF ST3_REG))
18511 (clobber (reg:XF ST4_REG))
18512 (clobber (reg:XF ST5_REG))
18513 (clobber (reg:XF ST6_REG))
18514 (clobber (reg:XF ST7_REG))]
18517 [(set_attr "type" "other")
18518 (set_attr "memory" "store")
18519 (set (attr "length")
18520 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18522 (define_insn "fldenv"
18523 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18525 (clobber (reg:CCFP FPSR_REG))
18526 (clobber (reg:HI FPCR_REG))
18527 (clobber (reg:XF ST0_REG))
18528 (clobber (reg:XF ST1_REG))
18529 (clobber (reg:XF ST2_REG))
18530 (clobber (reg:XF ST3_REG))
18531 (clobber (reg:XF ST4_REG))
18532 (clobber (reg:XF ST5_REG))
18533 (clobber (reg:XF ST6_REG))
18534 (clobber (reg:XF ST7_REG))]
18537 [(set_attr "type" "other")
18538 (set_attr "memory" "load")
18539 (set (attr "length")
18540 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18542 (define_insn "fnstsw"
18543 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18544 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18547 [(set_attr "type" "other,other")
18548 (set_attr "memory" "none,store")
18549 (set (attr "length")
18550 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18552 (define_insn "fnclex"
18553 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18556 [(set_attr "type" "other")
18557 (set_attr "memory" "none")
18558 (set_attr "length" "2")])
18560 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18562 ;; LWP instructions
18564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18566 (define_expand "lwp_llwpcb"
18567 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18568 UNSPECV_LLWP_INTRINSIC)]
18571 (define_insn "*lwp_llwpcb<mode>1"
18572 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18573 UNSPECV_LLWP_INTRINSIC)]
18576 [(set_attr "type" "lwp")
18577 (set_attr "mode" "<MODE>")
18578 (set_attr "length" "5")])
18580 (define_expand "lwp_slwpcb"
18581 [(set (match_operand 0 "register_operand" "=r")
18582 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18587 insn = (Pmode == DImode
18589 : gen_lwp_slwpcbsi);
18591 emit_insn (insn (operands[0]));
18595 (define_insn "lwp_slwpcb<mode>"
18596 [(set (match_operand:P 0 "register_operand" "=r")
18597 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18600 [(set_attr "type" "lwp")
18601 (set_attr "mode" "<MODE>")
18602 (set_attr "length" "5")])
18604 (define_expand "lwp_lwpval<mode>3"
18605 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18606 (match_operand:SI 2 "nonimmediate_operand" "rm")
18607 (match_operand:SI 3 "const_int_operand" "i")]
18608 UNSPECV_LWPVAL_INTRINSIC)]
18610 ;; Avoid unused variable warning.
18611 "(void) operands[0];")
18613 (define_insn "*lwp_lwpval<mode>3_1"
18614 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18615 (match_operand:SI 1 "nonimmediate_operand" "rm")
18616 (match_operand:SI 2 "const_int_operand" "i")]
18617 UNSPECV_LWPVAL_INTRINSIC)]
18619 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18620 [(set_attr "type" "lwp")
18621 (set_attr "mode" "<MODE>")
18622 (set (attr "length")
18623 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18625 (define_expand "lwp_lwpins<mode>3"
18626 [(set (reg:CCC FLAGS_REG)
18627 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18628 (match_operand:SI 2 "nonimmediate_operand" "rm")
18629 (match_operand:SI 3 "const_int_operand" "i")]
18630 UNSPECV_LWPINS_INTRINSIC))
18631 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18632 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18635 (define_insn "*lwp_lwpins<mode>3_1"
18636 [(set (reg:CCC FLAGS_REG)
18637 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18638 (match_operand:SI 1 "nonimmediate_operand" "rm")
18639 (match_operand:SI 2 "const_int_operand" "i")]
18640 UNSPECV_LWPINS_INTRINSIC))]
18642 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18643 [(set_attr "type" "lwp")
18644 (set_attr "mode" "<MODE>")
18645 (set (attr "length")
18646 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18648 (define_int_iterator RDFSGSBASE
18652 (define_int_iterator WRFSGSBASE
18656 (define_int_attr fsgs
18657 [(UNSPECV_RDFSBASE "fs")
18658 (UNSPECV_RDGSBASE "gs")
18659 (UNSPECV_WRFSBASE "fs")
18660 (UNSPECV_WRGSBASE "gs")])
18662 (define_insn "rd<fsgs>base<mode>"
18663 [(set (match_operand:SWI48 0 "register_operand" "=r")
18664 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18665 "TARGET_64BIT && TARGET_FSGSBASE"
18667 [(set_attr "type" "other")
18668 (set_attr "prefix_extra" "2")])
18670 (define_insn "wr<fsgs>base<mode>"
18671 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18673 "TARGET_64BIT && TARGET_FSGSBASE"
18675 [(set_attr "type" "other")
18676 (set_attr "prefix_extra" "2")])
18678 (define_insn "rdrand<mode>_1"
18679 [(set (match_operand:SWI248 0 "register_operand" "=r")
18680 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18681 (set (reg:CCC FLAGS_REG)
18682 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18685 [(set_attr "type" "other")
18686 (set_attr "prefix_extra" "1")])
18688 (define_insn "rdseed<mode>_1"
18689 [(set (match_operand:SWI248 0 "register_operand" "=r")
18690 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18691 (set (reg:CCC FLAGS_REG)
18692 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18695 [(set_attr "type" "other")
18696 (set_attr "prefix_extra" "1")])
18698 (define_expand "pause"
18699 [(set (match_dup 0)
18700 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18703 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18704 MEM_VOLATILE_P (operands[0]) = 1;
18707 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18708 ;; They have the same encoding.
18709 (define_insn "*pause"
18710 [(set (match_operand:BLK 0)
18711 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18714 [(set_attr "length" "2")
18715 (set_attr "memory" "unknown")])
18717 (define_expand "xbegin"
18718 [(set (match_operand:SI 0 "register_operand")
18719 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18722 rtx_code_label *label = gen_label_rtx ();
18724 /* xbegin is emitted as jump_insn, so reload won't be able
18725 to reload its operand. Force the value into AX hard register. */
18726 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18727 emit_move_insn (ax_reg, constm1_rtx);
18729 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18731 emit_label (label);
18732 LABEL_NUSES (label) = 1;
18734 emit_move_insn (operands[0], ax_reg);
18739 (define_insn "xbegin_1"
18741 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18743 (label_ref (match_operand 1))
18745 (set (match_operand:SI 0 "register_operand" "+a")
18746 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18749 [(set_attr "type" "other")
18750 (set_attr "length" "6")])
18752 (define_insn "xend"
18753 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18756 [(set_attr "type" "other")
18757 (set_attr "length" "3")])
18759 (define_insn "xabort"
18760 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18764 [(set_attr "type" "other")
18765 (set_attr "length" "3")])
18767 (define_expand "xtest"
18768 [(set (match_operand:QI 0 "register_operand")
18769 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18772 emit_insn (gen_xtest_1 ());
18774 ix86_expand_setcc (operands[0], NE,
18775 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18779 (define_insn "xtest_1"
18780 [(set (reg:CCZ FLAGS_REG)
18781 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18784 [(set_attr "type" "other")
18785 (set_attr "length" "3")])
18787 (define_insn "pcommit"
18788 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18791 [(set_attr "type" "other")
18792 (set_attr "length" "4")])
18794 (define_insn "clwb"
18795 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18799 [(set_attr "type" "sse")
18800 (set_attr "atom_sse_attr" "fence")
18801 (set_attr "memory" "unknown")])
18803 (define_insn "clflushopt"
18804 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18805 UNSPECV_CLFLUSHOPT)]
18806 "TARGET_CLFLUSHOPT"
18808 [(set_attr "type" "sse")
18809 (set_attr "atom_sse_attr" "fence")
18810 (set_attr "memory" "unknown")])
18812 ;; MPX instructions
18814 (define_expand "<mode>_mk"
18815 [(set (match_operand:BND 0 "register_operand")
18819 [(match_operand:<bnd_ptr> 1 "register_operand")
18820 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18824 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18826 UNSPEC_BNDMK_ADDR);
18829 (define_insn "*<mode>_mk"
18830 [(set (match_operand:BND 0 "register_operand" "=w")
18832 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18834 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18835 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18836 UNSPEC_BNDMK_ADDR)])]
18839 "bndmk\t{%3, %0|%0, %3}"
18840 [(set_attr "type" "mpxmk")])
18842 (define_expand "mov<mode>"
18843 [(set (match_operand:BND 0 "general_operand")
18844 (match_operand:BND 1 "general_operand"))]
18847 ix86_expand_move (<MODE>mode, operands);DONE;
18850 (define_insn "*mov<mode>_internal_mpx"
18851 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18852 (match_operand:BND 1 "general_operand" "wm,w"))]
18854 "bndmov\t{%1, %0|%0, %1}"
18855 [(set_attr "type" "mpxmov")])
18857 (define_expand "<mode>_<bndcheck>"
18858 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18859 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18861 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18864 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18865 MEM_VOLATILE_P (operands[2]) = 1;
18868 (define_insn "*<mode>_<bndcheck>"
18869 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18870 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18871 (set (match_operand:BLK 2 "bnd_mem_operator")
18872 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18874 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18875 [(set_attr "type" "mpxchk")])
18877 (define_expand "<mode>_ldx"
18878 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18882 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18883 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18885 (use (mem:BLK (match_dup 1)))])]
18888 /* Avoid registers which connot be used as index. */
18889 if (!index_register_operand (operands[2], Pmode))
18891 rtx temp = gen_reg_rtx (Pmode);
18892 emit_move_insn (temp, operands[2]);
18893 operands[2] = temp;
18896 /* If it was a register originally then it may have
18897 mode other than Pmode. We need to extend in such
18898 case because bndldx may work only with Pmode regs. */
18899 if (GET_MODE (operands[2]) != Pmode)
18900 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18902 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18904 UNSPEC_BNDLDX_ADDR);
18907 (define_insn "*<mode>_ldx"
18908 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18910 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18912 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18913 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18914 UNSPEC_BNDLDX_ADDR)])]
18916 (use (mem:BLK (match_dup 1)))])]
18918 "bndldx\t{%3, %0|%0, %3}"
18919 [(set_attr "type" "mpxld")])
18921 (define_expand "<mode>_stx"
18922 [(parallel [(unspec [(mem:<bnd_ptr>
18924 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18925 (match_operand:<bnd_ptr> 1 "register_operand")]))
18926 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18928 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18931 /* Avoid registers which connot be used as index. */
18932 if (!index_register_operand (operands[1], Pmode))
18934 rtx temp = gen_reg_rtx (Pmode);
18935 emit_move_insn (temp, operands[1]);
18936 operands[1] = temp;
18939 /* If it was a register originally then it may have
18940 mode other than Pmode. We need to extend in such
18941 case because bndstx may work only with Pmode regs. */
18942 if (GET_MODE (operands[1]) != Pmode)
18943 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18945 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18947 UNSPEC_BNDLDX_ADDR);
18948 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18949 MEM_VOLATILE_P (operands[4]) = 1;
18952 (define_insn "*<mode>_stx"
18953 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18955 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18956 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18957 UNSPEC_BNDLDX_ADDR)])
18958 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18959 (set (match_operand:BLK 4 "bnd_mem_operator")
18960 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18962 "bndstx\t{%2, %3|%3, %2}"
18963 [(set_attr "type" "mpxst")])
18965 (define_insn "move_size_reloc_<mode>"
18966 [(set (match_operand:SWI48 0 "register_operand" "=r")
18968 [(match_operand:SWI48 1 "symbol_operand")]
18972 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18973 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18975 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18977 [(set_attr "type" "imov")
18978 (set_attr "mode" "<MODE>")])
18982 (include "sync.md")