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.
390 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
393 ;; In C guard expressions, put expressions which may be compile-time
394 ;; constants first. This allows for better optimization. For
395 ;; example, write "TARGET_64BIT && reload_completed", not
396 ;; "reload_completed && TARGET_64BIT".
400 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
401 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
403 (const (symbol_ref "ix86_schedule")))
405 ;; A basic instruction type. Refinements due to arguments to be
406 ;; provided in other attributes.
409 alu,alu1,negnot,imov,imovx,lea,
410 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
411 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
412 push,pop,call,callv,leave,
414 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
415 fxch,fistp,fisttp,frndint,
416 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
417 ssemul,sseimul,ssediv,sselog,sselog1,
418 sseishft,sseishft1,ssecmp,ssecomi,
419 ssecvt,ssecvt1,sseicvt,sseins,
420 sseshuf,sseshuf1,ssemuladd,sse4arg,
422 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
423 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
424 (const_string "other"))
426 ;; Main data type used by the insn
428 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
430 (const_string "unknown"))
432 ;; The CPU unit operations uses.
433 (define_attr "unit" "integer,i387,sse,mmx,unknown"
434 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
435 fxch,fistp,fisttp,frndint")
436 (const_string "i387")
437 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
438 ssemul,sseimul,ssediv,sselog,sselog1,
439 sseishft,sseishft1,ssecmp,ssecomi,
440 ssecvt,ssecvt1,sseicvt,sseins,
441 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
443 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
445 (eq_attr "type" "other")
446 (const_string "unknown")]
447 (const_string "integer")))
449 ;; The minimum required alignment of vector mode memory operands of the SSE
450 ;; (non-VEX/EVEX) instruction in bits, if it is different from
451 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
452 ;; multiple alternatives, this should be conservative maximum of those minimum
453 ;; required alignments.
454 (define_attr "ssememalign" "" (const_int 0))
456 ;; The (bounding maximum) length of an instruction immediate.
457 (define_attr "length_immediate" ""
458 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
459 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
462 (eq_attr "unit" "i387,sse,mmx")
464 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
465 rotate,rotatex,rotate1,imul,icmp,push,pop")
466 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
467 (eq_attr "type" "imov,test")
468 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
469 (eq_attr "type" "call")
470 (if_then_else (match_operand 0 "constant_call_address_operand")
473 (eq_attr "type" "callv")
474 (if_then_else (match_operand 1 "constant_call_address_operand")
477 ;; We don't know the size before shorten_branches. Expect
478 ;; the instruction to fit for better scheduling.
479 (eq_attr "type" "ibr")
482 (symbol_ref "/* Update immediate_length and other attributes! */
483 gcc_unreachable (),1")))
485 ;; The (bounding maximum) length of an instruction address.
486 (define_attr "length_address" ""
487 (cond [(eq_attr "type" "str,other,multi,fxch")
489 (and (eq_attr "type" "call")
490 (match_operand 0 "constant_call_address_operand"))
492 (and (eq_attr "type" "callv")
493 (match_operand 1 "constant_call_address_operand"))
496 (symbol_ref "ix86_attr_length_address_default (insn)")))
498 ;; Set when length prefix is used.
499 (define_attr "prefix_data16" ""
500 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
502 (eq_attr "mode" "HI")
504 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
509 ;; Set when string REP prefix is used.
510 (define_attr "prefix_rep" ""
511 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
513 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
515 (and (eq_attr "type" "ibr,call,callv")
516 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
521 ;; Set when 0f opcode prefix is used.
522 (define_attr "prefix_0f" ""
524 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
525 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
526 (eq_attr "unit" "sse,mmx"))
530 ;; Set when REX opcode prefix is used.
531 (define_attr "prefix_rex" ""
532 (cond [(not (match_test "TARGET_64BIT"))
534 (and (eq_attr "mode" "DI")
535 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
536 (eq_attr "unit" "!mmx")))
538 (and (eq_attr "mode" "QI")
539 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
541 (match_test "x86_extended_reg_mentioned_p (insn)")
543 (and (eq_attr "type" "imovx")
544 (match_operand:QI 1 "ext_QIreg_operand"))
549 ;; There are also additional prefixes in 3DNOW, SSSE3.
550 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
551 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
552 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
553 (define_attr "prefix_extra" ""
554 (cond [(eq_attr "type" "ssemuladd,sse4arg")
556 (eq_attr "type" "sseiadd1,ssecvt1")
561 ;; Prefix used: original, VEX or maybe VEX.
562 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
563 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
565 (eq_attr "mode" "XI,V16SF,V8DF")
566 (const_string "evex")
568 (const_string "orig")))
570 ;; VEX W bit is used.
571 (define_attr "prefix_vex_w" "" (const_int 0))
573 ;; The length of VEX prefix
574 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
575 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
576 ;; still prefix_0f 1, with prefix_extra 1.
577 (define_attr "length_vex" ""
578 (if_then_else (and (eq_attr "prefix_0f" "1")
579 (eq_attr "prefix_extra" "0"))
580 (if_then_else (eq_attr "prefix_vex_w" "1")
581 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
582 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
583 (if_then_else (eq_attr "prefix_vex_w" "1")
584 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
585 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
587 ;; 4-bytes evex prefix and 1 byte opcode.
588 (define_attr "length_evex" "" (const_int 5))
590 ;; Set when modrm byte is used.
591 (define_attr "modrm" ""
592 (cond [(eq_attr "type" "str,leave")
594 (eq_attr "unit" "i387")
596 (and (eq_attr "type" "incdec")
597 (and (not (match_test "TARGET_64BIT"))
598 (ior (match_operand:SI 1 "register_operand")
599 (match_operand:HI 1 "register_operand"))))
601 (and (eq_attr "type" "push")
602 (not (match_operand 1 "memory_operand")))
604 (and (eq_attr "type" "pop")
605 (not (match_operand 0 "memory_operand")))
607 (and (eq_attr "type" "imov")
608 (and (not (eq_attr "mode" "DI"))
609 (ior (and (match_operand 0 "register_operand")
610 (match_operand 1 "immediate_operand"))
611 (ior (and (match_operand 0 "ax_reg_operand")
612 (match_operand 1 "memory_displacement_only_operand"))
613 (and (match_operand 0 "memory_displacement_only_operand")
614 (match_operand 1 "ax_reg_operand"))))))
616 (and (eq_attr "type" "call")
617 (match_operand 0 "constant_call_address_operand"))
619 (and (eq_attr "type" "callv")
620 (match_operand 1 "constant_call_address_operand"))
622 (and (eq_attr "type" "alu,alu1,icmp,test")
623 (match_operand 0 "ax_reg_operand"))
624 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
628 ;; When this attribute is set, calculate total insn length from
629 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
630 (define_attr "length_nobnd" "" (const_int 0))
632 ;; The (bounding maximum) length of an instruction in bytes.
633 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
634 ;; Later we may want to split them and compute proper length as for
636 (define_attr "length" ""
637 (cond [(eq_attr "length_nobnd" "!0")
638 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
639 (attr "length_nobnd"))
640 (eq_attr "type" "other,multi,fistp,frndint")
642 (eq_attr "type" "fcmp")
644 (eq_attr "unit" "i387")
646 (plus (attr "prefix_data16")
647 (attr "length_address")))
648 (ior (eq_attr "prefix" "evex")
649 (and (ior (eq_attr "prefix" "maybe_evex")
650 (eq_attr "prefix" "maybe_vex"))
651 (match_test "TARGET_AVX512F")))
652 (plus (attr "length_evex")
653 (plus (attr "length_immediate")
655 (attr "length_address"))))
656 (ior (eq_attr "prefix" "vex")
657 (and (ior (eq_attr "prefix" "maybe_vex")
658 (eq_attr "prefix" "maybe_evex"))
659 (match_test "TARGET_AVX")))
660 (plus (attr "length_vex")
661 (plus (attr "length_immediate")
663 (attr "length_address"))))]
664 (plus (plus (attr "modrm")
665 (plus (attr "prefix_0f")
666 (plus (attr "prefix_rex")
667 (plus (attr "prefix_extra")
669 (plus (attr "prefix_rep")
670 (plus (attr "prefix_data16")
671 (plus (attr "length_immediate")
672 (attr "length_address")))))))
674 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
675 ;; `store' if there is a simple memory reference therein, or `unknown'
676 ;; if the instruction is complex.
678 (define_attr "memory" "none,load,store,both,unknown"
679 (cond [(eq_attr "type" "other,multi,str,lwp")
680 (const_string "unknown")
681 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
682 (const_string "none")
683 (eq_attr "type" "fistp,leave")
684 (const_string "both")
685 (eq_attr "type" "frndint")
686 (const_string "load")
687 (eq_attr "type" "mpxld")
688 (const_string "load")
689 (eq_attr "type" "mpxst")
690 (const_string "store")
691 (eq_attr "type" "push")
692 (if_then_else (match_operand 1 "memory_operand")
693 (const_string "both")
694 (const_string "store"))
695 (eq_attr "type" "pop")
696 (if_then_else (match_operand 0 "memory_operand")
697 (const_string "both")
698 (const_string "load"))
699 (eq_attr "type" "setcc")
700 (if_then_else (match_operand 0 "memory_operand")
701 (const_string "store")
702 (const_string "none"))
703 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
704 (if_then_else (ior (match_operand 0 "memory_operand")
705 (match_operand 1 "memory_operand"))
706 (const_string "load")
707 (const_string "none"))
708 (eq_attr "type" "ibr")
709 (if_then_else (match_operand 0 "memory_operand")
710 (const_string "load")
711 (const_string "none"))
712 (eq_attr "type" "call")
713 (if_then_else (match_operand 0 "constant_call_address_operand")
714 (const_string "none")
715 (const_string "load"))
716 (eq_attr "type" "callv")
717 (if_then_else (match_operand 1 "constant_call_address_operand")
718 (const_string "none")
719 (const_string "load"))
720 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
721 (match_operand 1 "memory_operand"))
722 (const_string "both")
723 (and (match_operand 0 "memory_operand")
724 (match_operand 1 "memory_operand"))
725 (const_string "both")
726 (match_operand 0 "memory_operand")
727 (const_string "store")
728 (match_operand 1 "memory_operand")
729 (const_string "load")
731 "!alu1,negnot,ishift1,
732 imov,imovx,icmp,test,bitmanip,
734 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
735 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
736 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
737 (match_operand 2 "memory_operand"))
738 (const_string "load")
739 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
740 (match_operand 3 "memory_operand"))
741 (const_string "load")
743 (const_string "none")))
745 ;; Indicates if an instruction has both an immediate and a displacement.
747 (define_attr "imm_disp" "false,true,unknown"
748 (cond [(eq_attr "type" "other,multi")
749 (const_string "unknown")
750 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
751 (and (match_operand 0 "memory_displacement_operand")
752 (match_operand 1 "immediate_operand")))
753 (const_string "true")
754 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
755 (and (match_operand 0 "memory_displacement_operand")
756 (match_operand 2 "immediate_operand")))
757 (const_string "true")
759 (const_string "false")))
761 ;; Indicates if an FP operation has an integer source.
763 (define_attr "fp_int_src" "false,true"
764 (const_string "false"))
766 ;; Defines rounding mode of an FP operation.
768 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
769 (const_string "any"))
771 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
772 (define_attr "use_carry" "0,1" (const_string "0"))
774 ;; Define attribute to indicate unaligned ssemov insns
775 (define_attr "movu" "0,1" (const_string "0"))
777 ;; Used to control the "enabled" attribute on a per-instruction basis.
778 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
779 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
780 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
781 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
782 (const_string "base"))
784 (define_attr "enabled" ""
785 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
786 (eq_attr "isa" "x64_sse4")
787 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
788 (eq_attr "isa" "x64_sse4_noavx")
789 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
790 (eq_attr "isa" "x64_avx")
791 (symbol_ref "TARGET_64BIT && TARGET_AVX")
792 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
793 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
794 (eq_attr "isa" "sse2_noavx")
795 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
796 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
797 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
798 (eq_attr "isa" "sse4_noavx")
799 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
800 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
801 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
802 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
803 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
804 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
805 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
806 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
807 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
808 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
809 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
810 (eq_attr "isa" "fma_avx512f")
811 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
812 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
813 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
814 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
815 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
819 (define_attr "preferred_for_size" "" (const_int 1))
820 (define_attr "preferred_for_speed" "" (const_int 1))
822 ;; Describe a user's asm statement.
823 (define_asm_attributes
824 [(set_attr "length" "128")
825 (set_attr "type" "multi")])
827 (define_code_iterator plusminus [plus minus])
829 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
831 (define_code_iterator multdiv [mult div])
833 ;; Base name for define_insn
834 (define_code_attr plusminus_insn
835 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
836 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
838 ;; Base name for insn mnemonic.
839 (define_code_attr plusminus_mnemonic
840 [(plus "add") (ss_plus "adds") (us_plus "addus")
841 (minus "sub") (ss_minus "subs") (us_minus "subus")])
842 (define_code_attr plusminus_carry_mnemonic
843 [(plus "adc") (minus "sbb")])
844 (define_code_attr multdiv_mnemonic
845 [(mult "mul") (div "div")])
847 ;; Mark commutative operators as such in constraints.
848 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
849 (minus "") (ss_minus "") (us_minus "")])
851 ;; Mapping of max and min
852 (define_code_iterator maxmin [smax smin umax umin])
854 ;; Mapping of signed max and min
855 (define_code_iterator smaxmin [smax smin])
857 ;; Mapping of unsigned max and min
858 (define_code_iterator umaxmin [umax umin])
860 ;; Base name for integer and FP insn mnemonic
861 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
862 (umax "maxu") (umin "minu")])
863 (define_code_attr maxmin_float [(smax "max") (smin "min")])
865 ;; Mapping of logic operators
866 (define_code_iterator any_logic [and ior xor])
867 (define_code_iterator any_or [ior xor])
868 (define_code_iterator fpint_logic [and xor])
870 ;; Base name for insn mnemonic.
871 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
873 ;; Mapping of logic-shift operators
874 (define_code_iterator any_lshift [ashift lshiftrt])
876 ;; Mapping of shift-right operators
877 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
879 ;; Mapping of all shift operators
880 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
882 ;; Base name for define_insn
883 (define_code_attr shift_insn
884 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
886 ;; Base name for insn mnemonic.
887 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
888 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
890 ;; Mapping of rotate operators
891 (define_code_iterator any_rotate [rotate rotatert])
893 ;; Base name for define_insn
894 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
896 ;; Base name for insn mnemonic.
897 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
899 ;; Mapping of abs neg operators
900 (define_code_iterator absneg [abs neg])
902 ;; Base name for x87 insn mnemonic.
903 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
905 ;; Used in signed and unsigned widening multiplications.
906 (define_code_iterator any_extend [sign_extend zero_extend])
908 ;; Prefix for insn menmonic.
909 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
911 ;; Prefix for define_insn
912 (define_code_attr u [(sign_extend "") (zero_extend "u")])
913 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
914 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
916 ;; Used in signed and unsigned truncations.
917 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
918 ;; Instruction suffix for truncations.
919 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
921 ;; Used in signed and unsigned fix.
922 (define_code_iterator any_fix [fix unsigned_fix])
923 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
925 ;; Used in signed and unsigned float.
926 (define_code_iterator any_float [float unsigned_float])
927 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
929 ;; All integer modes.
930 (define_mode_iterator SWI1248x [QI HI SI DI])
932 ;; All integer modes with AVX512BW.
933 (define_mode_iterator SWI1248_AVX512BW
934 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
936 ;; All integer modes without QImode.
937 (define_mode_iterator SWI248x [HI SI DI])
939 ;; All integer modes without QImode and HImode.
940 (define_mode_iterator SWI48x [SI DI])
942 ;; All integer modes without SImode and DImode.
943 (define_mode_iterator SWI12 [QI HI])
945 ;; All integer modes without DImode.
946 (define_mode_iterator SWI124 [QI HI SI])
948 ;; All integer modes without QImode and DImode.
949 (define_mode_iterator SWI24 [HI SI])
951 ;; Single word integer modes.
952 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
954 ;; Single word integer modes without QImode.
955 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
957 ;; Single word integer modes without QImode and HImode.
958 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
960 ;; All math-dependant single and double word integer modes.
961 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
962 (HI "TARGET_HIMODE_MATH")
963 SI DI (TI "TARGET_64BIT")])
965 ;; Math-dependant single word integer modes.
966 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
967 (HI "TARGET_HIMODE_MATH")
968 SI (DI "TARGET_64BIT")])
970 ;; Math-dependant integer modes without DImode.
971 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
972 (HI "TARGET_HIMODE_MATH")
975 ;; Math-dependant single word integer modes without QImode.
976 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
977 SI (DI "TARGET_64BIT")])
979 ;; Double word integer modes.
980 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
981 (TI "TARGET_64BIT")])
983 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
984 ;; compile time constant, it is faster to use <MODE_SIZE> than
985 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
986 ;; command line options just use GET_MODE_SIZE macro.
987 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
988 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
989 (V16QI "16") (V32QI "32") (V64QI "64")
990 (V8HI "16") (V16HI "32") (V32HI "64")
991 (V4SI "16") (V8SI "32") (V16SI "64")
992 (V2DI "16") (V4DI "32") (V8DI "64")
993 (V1TI "16") (V2TI "32") (V4TI "64")
994 (V2DF "16") (V4DF "32") (V8DF "64")
995 (V4SF "16") (V8SF "32") (V16SF "64")])
997 ;; Double word integer modes as mode attribute.
998 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
999 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1001 ;; Half mode for double word integer modes.
1002 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1003 (DI "TARGET_64BIT")])
1006 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1007 (BND64 "TARGET_LP64")])
1009 ;; Pointer mode corresponding to bound mode.
1010 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1013 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1016 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1018 (UNSPEC_BNDCN "cn")])
1020 ;; Instruction suffix for integer modes.
1021 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1023 ;; Instruction suffix for masks.
1024 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1026 ;; Pointer size prefix for integer modes (Intel asm dialect)
1027 (define_mode_attr iptrsize [(QI "BYTE")
1032 ;; Register class for integer modes.
1033 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1035 ;; Immediate operand constraint for integer modes.
1036 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1038 ;; General operand constraint for word modes.
1039 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1041 ;; Immediate operand constraint for double integer modes.
1042 (define_mode_attr di [(SI "nF") (DI "e")])
1044 ;; Immediate operand constraint for shifts.
1045 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1047 ;; General operand predicate for integer modes.
1048 (define_mode_attr general_operand
1049 [(QI "general_operand")
1050 (HI "general_operand")
1051 (SI "x86_64_general_operand")
1052 (DI "x86_64_general_operand")
1053 (TI "x86_64_general_operand")])
1055 ;; General sign extend operand predicate for integer modes,
1056 ;; which disallows VOIDmode operands and thus it is suitable
1057 ;; for use inside sign_extend.
1058 (define_mode_attr general_sext_operand
1059 [(QI "sext_operand")
1061 (SI "x86_64_sext_operand")
1062 (DI "x86_64_sext_operand")])
1064 ;; General sign/zero extend operand predicate for integer modes.
1065 (define_mode_attr general_szext_operand
1066 [(QI "general_operand")
1067 (HI "general_operand")
1068 (SI "x86_64_szext_general_operand")
1069 (DI "x86_64_szext_general_operand")])
1071 ;; Immediate operand predicate for integer modes.
1072 (define_mode_attr immediate_operand
1073 [(QI "immediate_operand")
1074 (HI "immediate_operand")
1075 (SI "x86_64_immediate_operand")
1076 (DI "x86_64_immediate_operand")])
1078 ;; Nonmemory operand predicate for integer modes.
1079 (define_mode_attr nonmemory_operand
1080 [(QI "nonmemory_operand")
1081 (HI "nonmemory_operand")
1082 (SI "x86_64_nonmemory_operand")
1083 (DI "x86_64_nonmemory_operand")])
1085 ;; Operand predicate for shifts.
1086 (define_mode_attr shift_operand
1087 [(QI "nonimmediate_operand")
1088 (HI "nonimmediate_operand")
1089 (SI "nonimmediate_operand")
1090 (DI "shiftdi_operand")
1091 (TI "register_operand")])
1093 ;; Operand predicate for shift argument.
1094 (define_mode_attr shift_immediate_operand
1095 [(QI "const_1_to_31_operand")
1096 (HI "const_1_to_31_operand")
1097 (SI "const_1_to_31_operand")
1098 (DI "const_1_to_63_operand")])
1100 ;; Input operand predicate for arithmetic left shifts.
1101 (define_mode_attr ashl_input_operand
1102 [(QI "nonimmediate_operand")
1103 (HI "nonimmediate_operand")
1104 (SI "nonimmediate_operand")
1105 (DI "ashldi_input_operand")
1106 (TI "reg_or_pm1_operand")])
1108 ;; SSE and x87 SFmode and DFmode floating point modes
1109 (define_mode_iterator MODEF [SF DF])
1111 ;; All x87 floating point modes
1112 (define_mode_iterator X87MODEF [SF DF XF])
1114 ;; SSE instruction suffix for various modes
1115 (define_mode_attr ssemodesuffix
1116 [(SF "ss") (DF "sd")
1117 (V16SF "ps") (V8DF "pd")
1118 (V8SF "ps") (V4DF "pd")
1119 (V4SF "ps") (V2DF "pd")
1120 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1121 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1122 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1124 ;; SSE vector suffix for floating point modes
1125 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1127 ;; SSE vector mode corresponding to a scalar mode
1128 (define_mode_attr ssevecmode
1129 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1130 (define_mode_attr ssevecmodelower
1131 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1133 ;; Instruction suffix for REX 64bit operators.
1134 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1136 ;; This mode iterator allows :P to be used for patterns that operate on
1137 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1138 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1140 ;; This mode iterator allows :W to be used for patterns that operate on
1141 ;; word_mode sized quantities.
1142 (define_mode_iterator W
1143 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1145 ;; This mode iterator allows :PTR to be used for patterns that operate on
1146 ;; ptr_mode sized quantities.
1147 (define_mode_iterator PTR
1148 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1150 ;; Scheduling descriptions
1152 (include "pentium.md")
1155 (include "athlon.md")
1156 (include "bdver1.md")
1157 (include "bdver3.md")
1158 (include "btver2.md")
1159 (include "geode.md")
1162 (include "core2.md")
1165 ;; Operand and operator predicates and constraints
1167 (include "predicates.md")
1168 (include "constraints.md")
1171 ;; Compare and branch/compare and store instructions.
1173 (define_expand "cbranch<mode>4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1176 (match_operand:SDWIM 2 "<general_operand>")))
1177 (set (pc) (if_then_else
1178 (match_operator 0 "ordered_comparison_operator"
1179 [(reg:CC FLAGS_REG) (const_int 0)])
1180 (label_ref (match_operand 3))
1184 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1185 operands[1] = force_reg (<MODE>mode, operands[1]);
1186 ix86_expand_branch (GET_CODE (operands[0]),
1187 operands[1], operands[2], operands[3]);
1191 (define_expand "cstore<mode>4"
1192 [(set (reg:CC FLAGS_REG)
1193 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1194 (match_operand:SWIM 3 "<general_operand>")))
1195 (set (match_operand:QI 0 "register_operand")
1196 (match_operator 1 "ordered_comparison_operator"
1197 [(reg:CC FLAGS_REG) (const_int 0)]))]
1200 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1201 operands[2] = force_reg (<MODE>mode, operands[2]);
1202 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1203 operands[2], operands[3]);
1207 (define_expand "cmp<mode>_1"
1208 [(set (reg:CC FLAGS_REG)
1209 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1210 (match_operand:SWI48 1 "<general_operand>")))])
1212 (define_insn "*cmp<mode>_ccno_1"
1213 [(set (reg FLAGS_REG)
1214 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1215 (match_operand:SWI 1 "const0_operand")))]
1216 "ix86_match_ccmode (insn, CCNOmode)"
1218 test{<imodesuffix>}\t%0, %0
1219 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1220 [(set_attr "type" "test,icmp")
1221 (set_attr "length_immediate" "0,1")
1222 (set_attr "mode" "<MODE>")])
1224 (define_insn "*cmp<mode>_1"
1225 [(set (reg FLAGS_REG)
1226 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1227 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1228 "ix86_match_ccmode (insn, CCmode)"
1229 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1230 [(set_attr "type" "icmp")
1231 (set_attr "mode" "<MODE>")])
1233 (define_insn "*cmp<mode>_minus_1"
1234 [(set (reg FLAGS_REG)
1236 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1237 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1239 "ix86_match_ccmode (insn, CCGOCmode)"
1240 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1241 [(set_attr "type" "icmp")
1242 (set_attr "mode" "<MODE>")])
1244 (define_insn "*cmpqi_ext_1"
1245 [(set (reg FLAGS_REG)
1247 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1250 (match_operand 1 "ext_register_operand" "Q,Q")
1252 (const_int 8)) 0)))]
1253 "ix86_match_ccmode (insn, CCmode)"
1254 "cmp{b}\t{%h1, %0|%0, %h1}"
1255 [(set_attr "isa" "*,nox64")
1256 (set_attr "type" "icmp")
1257 (set_attr "mode" "QI")])
1259 (define_insn "*cmpqi_ext_2"
1260 [(set (reg FLAGS_REG)
1264 (match_operand 0 "ext_register_operand" "Q")
1267 (match_operand:QI 1 "const0_operand")))]
1268 "ix86_match_ccmode (insn, CCNOmode)"
1270 [(set_attr "type" "test")
1271 (set_attr "length_immediate" "0")
1272 (set_attr "mode" "QI")])
1274 (define_expand "cmpqi_ext_3"
1275 [(set (reg:CC FLAGS_REG)
1279 (match_operand 0 "ext_register_operand")
1282 (match_operand:QI 1 "const_int_operand")))])
1284 (define_insn "*cmpqi_ext_3"
1285 [(set (reg FLAGS_REG)
1289 (match_operand 0 "ext_register_operand" "Q,Q")
1292 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1293 "ix86_match_ccmode (insn, CCmode)"
1294 "cmp{b}\t{%1, %h0|%h0, %1}"
1295 [(set_attr "isa" "*,nox64")
1296 (set_attr "type" "icmp")
1297 (set_attr "modrm" "1")
1298 (set_attr "mode" "QI")])
1300 (define_insn "*cmpqi_ext_4"
1301 [(set (reg FLAGS_REG)
1305 (match_operand 0 "ext_register_operand" "Q")
1310 (match_operand 1 "ext_register_operand" "Q")
1312 (const_int 8)) 0)))]
1313 "ix86_match_ccmode (insn, CCmode)"
1314 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1315 [(set_attr "type" "icmp")
1316 (set_attr "mode" "QI")])
1318 ;; These implement float point compares.
1319 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1320 ;; which would allow mix and match FP modes on the compares. Which is what
1321 ;; the old patterns did, but with many more of them.
1323 (define_expand "cbranchxf4"
1324 [(set (reg:CC FLAGS_REG)
1325 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1326 (match_operand:XF 2 "nonmemory_operand")))
1327 (set (pc) (if_then_else
1328 (match_operator 0 "ix86_fp_comparison_operator"
1331 (label_ref (match_operand 3))
1335 ix86_expand_branch (GET_CODE (operands[0]),
1336 operands[1], operands[2], operands[3]);
1340 (define_expand "cstorexf4"
1341 [(set (reg:CC FLAGS_REG)
1342 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1343 (match_operand:XF 3 "nonmemory_operand")))
1344 (set (match_operand:QI 0 "register_operand")
1345 (match_operator 1 "ix86_fp_comparison_operator"
1350 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1351 operands[2], operands[3]);
1355 (define_expand "cbranch<mode>4"
1356 [(set (reg:CC FLAGS_REG)
1357 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1358 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1359 (set (pc) (if_then_else
1360 (match_operator 0 "ix86_fp_comparison_operator"
1363 (label_ref (match_operand 3))
1365 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1367 ix86_expand_branch (GET_CODE (operands[0]),
1368 operands[1], operands[2], operands[3]);
1372 (define_expand "cstore<mode>4"
1373 [(set (reg:CC FLAGS_REG)
1374 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1375 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1376 (set (match_operand:QI 0 "register_operand")
1377 (match_operator 1 "ix86_fp_comparison_operator"
1380 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1382 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1383 operands[2], operands[3]);
1387 (define_expand "cbranchcc4"
1388 [(set (pc) (if_then_else
1389 (match_operator 0 "comparison_operator"
1390 [(match_operand 1 "flags_reg_operand")
1391 (match_operand 2 "const0_operand")])
1392 (label_ref (match_operand 3))
1396 ix86_expand_branch (GET_CODE (operands[0]),
1397 operands[1], operands[2], operands[3]);
1401 (define_expand "cstorecc4"
1402 [(set (match_operand:QI 0 "register_operand")
1403 (match_operator 1 "comparison_operator"
1404 [(match_operand 2 "flags_reg_operand")
1405 (match_operand 3 "const0_operand")]))]
1408 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1409 operands[2], operands[3]);
1414 ;; FP compares, step 1:
1415 ;; Set the FP condition codes.
1417 ;; CCFPmode compare with exceptions
1418 ;; CCFPUmode compare with no exceptions
1420 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1421 ;; used to manage the reg stack popping would not be preserved.
1423 (define_insn "*cmp<mode>_0_i387"
1424 [(set (match_operand:HI 0 "register_operand" "=a")
1427 (match_operand:X87MODEF 1 "register_operand" "f")
1428 (match_operand:X87MODEF 2 "const0_operand"))]
1431 "* return output_fp_compare (insn, operands, false, false);"
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1434 (set_attr "mode" "<MODE>")])
1436 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1437 [(set (reg:CCFP FLAGS_REG)
1439 (match_operand:X87MODEF 1 "register_operand" "f")
1440 (match_operand:X87MODEF 2 "const0_operand")))
1441 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1442 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1444 "&& reload_completed"
1447 [(compare:CCFP (match_dup 1)(match_dup 2))]
1449 (set (reg:CC FLAGS_REG)
1450 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1452 [(set_attr "type" "multi")
1453 (set_attr "unit" "i387")
1454 (set_attr "mode" "<MODE>")])
1456 (define_insn "*cmpxf_i387"
1457 [(set (match_operand:HI 0 "register_operand" "=a")
1460 (match_operand:XF 1 "register_operand" "f")
1461 (match_operand:XF 2 "register_operand" "f"))]
1464 "* return output_fp_compare (insn, operands, false, false);"
1465 [(set_attr "type" "multi")
1466 (set_attr "unit" "i387")
1467 (set_attr "mode" "XF")])
1469 (define_insn_and_split "*cmpxf_cc_i387"
1470 [(set (reg:CCFP FLAGS_REG)
1472 (match_operand:XF 1 "register_operand" "f")
1473 (match_operand:XF 2 "register_operand" "f")))
1474 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1475 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1477 "&& reload_completed"
1480 [(compare:CCFP (match_dup 1)(match_dup 2))]
1482 (set (reg:CC FLAGS_REG)
1483 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1485 [(set_attr "type" "multi")
1486 (set_attr "unit" "i387")
1487 (set_attr "mode" "XF")])
1489 (define_insn "*cmp<mode>_i387"
1490 [(set (match_operand:HI 0 "register_operand" "=a")
1493 (match_operand:MODEF 1 "register_operand" "f")
1494 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1497 "* return output_fp_compare (insn, operands, false, false);"
1498 [(set_attr "type" "multi")
1499 (set_attr "unit" "i387")
1500 (set_attr "mode" "<MODE>")])
1502 (define_insn_and_split "*cmp<mode>_cc_i387"
1503 [(set (reg:CCFP FLAGS_REG)
1505 (match_operand:MODEF 1 "register_operand" "f")
1506 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1507 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1508 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1510 "&& reload_completed"
1513 [(compare:CCFP (match_dup 1)(match_dup 2))]
1515 (set (reg:CC FLAGS_REG)
1516 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1518 [(set_attr "type" "multi")
1519 (set_attr "unit" "i387")
1520 (set_attr "mode" "<MODE>")])
1522 (define_insn "*cmpu<mode>_i387"
1523 [(set (match_operand:HI 0 "register_operand" "=a")
1526 (match_operand:X87MODEF 1 "register_operand" "f")
1527 (match_operand:X87MODEF 2 "register_operand" "f"))]
1530 "* return output_fp_compare (insn, operands, false, true);"
1531 [(set_attr "type" "multi")
1532 (set_attr "unit" "i387")
1533 (set_attr "mode" "<MODE>")])
1535 (define_insn_and_split "*cmpu<mode>_cc_i387"
1536 [(set (reg:CCFPU FLAGS_REG)
1538 (match_operand:X87MODEF 1 "register_operand" "f")
1539 (match_operand:X87MODEF 2 "register_operand" "f")))
1540 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1541 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1543 "&& reload_completed"
1546 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1548 (set (reg:CC FLAGS_REG)
1549 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1551 [(set_attr "type" "multi")
1552 (set_attr "unit" "i387")
1553 (set_attr "mode" "<MODE>")])
1555 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1556 [(set (match_operand:HI 0 "register_operand" "=a")
1559 (match_operand:X87MODEF 1 "register_operand" "f")
1560 (match_operator:X87MODEF 3 "float_operator"
1561 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1564 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1565 || optimize_function_for_size_p (cfun))"
1566 "* return output_fp_compare (insn, operands, false, false);"
1567 [(set_attr "type" "multi")
1568 (set_attr "unit" "i387")
1569 (set_attr "fp_int_src" "true")
1570 (set_attr "mode" "<SWI24:MODE>")])
1572 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1573 [(set (reg:CCFP FLAGS_REG)
1575 (match_operand:X87MODEF 1 "register_operand" "f")
1576 (match_operator:X87MODEF 3 "float_operator"
1577 [(match_operand:SWI24 2 "memory_operand" "m")])))
1578 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1579 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1580 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1581 || optimize_function_for_size_p (cfun))"
1583 "&& reload_completed"
1588 (match_op_dup 3 [(match_dup 2)]))]
1590 (set (reg:CC FLAGS_REG)
1591 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1593 [(set_attr "type" "multi")
1594 (set_attr "unit" "i387")
1595 (set_attr "fp_int_src" "true")
1596 (set_attr "mode" "<SWI24:MODE>")])
1598 ;; FP compares, step 2
1599 ;; Move the fpsw to ax.
1601 (define_insn "x86_fnstsw_1"
1602 [(set (match_operand:HI 0 "register_operand" "=a")
1603 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1606 [(set_attr "length" "2")
1607 (set_attr "mode" "SI")
1608 (set_attr "unit" "i387")])
1610 ;; FP compares, step 3
1611 ;; Get ax into flags, general case.
1613 (define_insn "x86_sahf_1"
1614 [(set (reg:CC FLAGS_REG)
1615 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1619 #ifndef HAVE_AS_IX86_SAHF
1621 return ASM_BYTE "0x9e";
1626 [(set_attr "length" "1")
1627 (set_attr "athlon_decode" "vector")
1628 (set_attr "amdfam10_decode" "direct")
1629 (set_attr "bdver1_decode" "direct")
1630 (set_attr "mode" "SI")])
1632 ;; Pentium Pro can do steps 1 through 3 in one go.
1633 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1634 ;; (these i387 instructions set flags directly)
1636 (define_mode_iterator FPCMP [CCFP CCFPU])
1637 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1639 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1640 [(set (reg:FPCMP FLAGS_REG)
1642 (match_operand:MODEF 0 "register_operand" "f,x")
1643 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1644 "TARGET_MIX_SSE_I387
1645 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1646 "* return output_fp_compare (insn, operands, true,
1647 <FPCMP:MODE>mode == CCFPUmode);"
1648 [(set_attr "type" "fcmp,ssecomi")
1649 (set_attr "prefix" "orig,maybe_vex")
1650 (set_attr "mode" "<MODEF:MODE>")
1651 (set (attr "prefix_rep")
1652 (if_then_else (eq_attr "type" "ssecomi")
1654 (const_string "*")))
1655 (set (attr "prefix_data16")
1656 (cond [(eq_attr "type" "fcmp")
1658 (eq_attr "mode" "DF")
1661 (const_string "0")))
1662 (set_attr "athlon_decode" "vector")
1663 (set_attr "amdfam10_decode" "direct")
1664 (set_attr "bdver1_decode" "double")])
1666 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1667 [(set (reg:FPCMP FLAGS_REG)
1669 (match_operand:MODEF 0 "register_operand" "x")
1670 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1672 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1673 "* return output_fp_compare (insn, operands, true,
1674 <FPCMP:MODE>mode == CCFPUmode);"
1675 [(set_attr "type" "ssecomi")
1676 (set_attr "prefix" "maybe_vex")
1677 (set_attr "mode" "<MODEF:MODE>")
1678 (set_attr "prefix_rep" "0")
1679 (set (attr "prefix_data16")
1680 (if_then_else (eq_attr "mode" "DF")
1682 (const_string "0")))
1683 (set_attr "athlon_decode" "vector")
1684 (set_attr "amdfam10_decode" "direct")
1685 (set_attr "bdver1_decode" "double")])
1687 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1688 [(set (reg:FPCMP FLAGS_REG)
1690 (match_operand:X87MODEF 0 "register_operand" "f")
1691 (match_operand:X87MODEF 1 "register_operand" "f")))]
1692 "TARGET_80387 && TARGET_CMOVE
1693 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1694 "* return output_fp_compare (insn, operands, true,
1695 <FPCMP:MODE>mode == CCFPUmode);"
1696 [(set_attr "type" "fcmp")
1697 (set_attr "mode" "<X87MODEF:MODE>")
1698 (set_attr "athlon_decode" "vector")
1699 (set_attr "amdfam10_decode" "direct")
1700 (set_attr "bdver1_decode" "double")])
1702 ;; Push/pop instructions.
1704 (define_insn "*push<mode>2"
1705 [(set (match_operand:DWI 0 "push_operand" "=<")
1706 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1709 [(set_attr "type" "multi")
1710 (set_attr "mode" "<MODE>")])
1713 [(set (match_operand:TI 0 "push_operand")
1714 (match_operand:TI 1 "general_operand"))]
1715 "TARGET_64BIT && reload_completed
1716 && !SSE_REG_P (operands[1])"
1718 "ix86_split_long_move (operands); DONE;")
1720 (define_insn "*pushdi2_rex64"
1721 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1722 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1727 [(set_attr "type" "push,multi")
1728 (set_attr "mode" "DI")])
1730 ;; Convert impossible pushes of immediate to existing instructions.
1731 ;; First try to get scratch register and go through it. In case this
1732 ;; fails, push sign extended lower part first and then overwrite
1733 ;; upper part by 32bit move.
1735 [(match_scratch:DI 2 "r")
1736 (set (match_operand:DI 0 "push_operand")
1737 (match_operand:DI 1 "immediate_operand"))]
1738 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1739 && !x86_64_immediate_operand (operands[1], DImode)"
1740 [(set (match_dup 2) (match_dup 1))
1741 (set (match_dup 0) (match_dup 2))])
1743 ;; We need to define this as both peepholer and splitter for case
1744 ;; peephole2 pass is not run.
1745 ;; "&& 1" is needed to keep it from matching the previous pattern.
1747 [(set (match_operand:DI 0 "push_operand")
1748 (match_operand:DI 1 "immediate_operand"))]
1749 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1750 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1751 [(set (match_dup 0) (match_dup 1))
1752 (set (match_dup 2) (match_dup 3))]
1754 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1756 operands[1] = gen_lowpart (DImode, operands[2]);
1757 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1762 [(set (match_operand:DI 0 "push_operand")
1763 (match_operand:DI 1 "immediate_operand"))]
1764 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1765 ? epilogue_completed : reload_completed)
1766 && !symbolic_operand (operands[1], DImode)
1767 && !x86_64_immediate_operand (operands[1], DImode)"
1768 [(set (match_dup 0) (match_dup 1))
1769 (set (match_dup 2) (match_dup 3))]
1771 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1773 operands[1] = gen_lowpart (DImode, operands[2]);
1774 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1779 [(set (match_operand:DI 0 "push_operand")
1780 (match_operand:DI 1 "general_operand"))]
1781 "!TARGET_64BIT && reload_completed
1782 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1784 "ix86_split_long_move (operands); DONE;")
1786 (define_insn "*pushsi2"
1787 [(set (match_operand:SI 0 "push_operand" "=<")
1788 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1791 [(set_attr "type" "push")
1792 (set_attr "mode" "SI")])
1794 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1795 ;; "push a byte/word". But actually we use pushl, which has the effect
1796 ;; of rounding the amount pushed up to a word.
1798 ;; For TARGET_64BIT we always round up to 8 bytes.
1799 (define_insn "*push<mode>2_rex64"
1800 [(set (match_operand:SWI124 0 "push_operand" "=X")
1801 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1804 [(set_attr "type" "push")
1805 (set_attr "mode" "DI")])
1807 (define_insn "*push<mode>2"
1808 [(set (match_operand:SWI12 0 "push_operand" "=X")
1809 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1812 [(set_attr "type" "push")
1813 (set_attr "mode" "SI")])
1815 (define_insn "*push<mode>2_prologue"
1816 [(set (match_operand:W 0 "push_operand" "=<")
1817 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1818 (clobber (mem:BLK (scratch)))]
1820 "push{<imodesuffix>}\t%1"
1821 [(set_attr "type" "push")
1822 (set_attr "mode" "<MODE>")])
1824 (define_insn "*pop<mode>1"
1825 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1826 (match_operand:W 1 "pop_operand" ">"))]
1828 "pop{<imodesuffix>}\t%0"
1829 [(set_attr "type" "pop")
1830 (set_attr "mode" "<MODE>")])
1832 (define_insn "*pop<mode>1_epilogue"
1833 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1834 (match_operand:W 1 "pop_operand" ">"))
1835 (clobber (mem:BLK (scratch)))]
1837 "pop{<imodesuffix>}\t%0"
1838 [(set_attr "type" "pop")
1839 (set_attr "mode" "<MODE>")])
1841 (define_insn "*pushfl<mode>2"
1842 [(set (match_operand:W 0 "push_operand" "=<")
1843 (match_operand:W 1 "flags_reg_operand"))]
1845 "pushf{<imodesuffix>}"
1846 [(set_attr "type" "push")
1847 (set_attr "mode" "<MODE>")])
1849 (define_insn "*popfl<mode>1"
1850 [(set (match_operand:W 0 "flags_reg_operand")
1851 (match_operand:W 1 "pop_operand" ">"))]
1853 "popf{<imodesuffix>}"
1854 [(set_attr "type" "pop")
1855 (set_attr "mode" "<MODE>")])
1858 ;; Move instructions.
1860 (define_expand "movxi"
1861 [(set (match_operand:XI 0 "nonimmediate_operand")
1862 (match_operand:XI 1 "general_operand"))]
1864 "ix86_expand_move (XImode, operands); DONE;")
1866 ;; Reload patterns to support multi-word load/store
1867 ;; with non-offsetable address.
1868 (define_expand "reload_noff_store"
1869 [(parallel [(match_operand 0 "memory_operand" "=m")
1870 (match_operand 1 "register_operand" "r")
1871 (match_operand:DI 2 "register_operand" "=&r")])]
1874 rtx mem = operands[0];
1875 rtx addr = XEXP (mem, 0);
1877 emit_move_insn (operands[2], addr);
1878 mem = replace_equiv_address_nv (mem, operands[2]);
1880 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1884 (define_expand "reload_noff_load"
1885 [(parallel [(match_operand 0 "register_operand" "=r")
1886 (match_operand 1 "memory_operand" "m")
1887 (match_operand:DI 2 "register_operand" "=r")])]
1890 rtx mem = operands[1];
1891 rtx addr = XEXP (mem, 0);
1893 emit_move_insn (operands[2], addr);
1894 mem = replace_equiv_address_nv (mem, operands[2]);
1896 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1900 (define_expand "movoi"
1901 [(set (match_operand:OI 0 "nonimmediate_operand")
1902 (match_operand:OI 1 "general_operand"))]
1904 "ix86_expand_move (OImode, operands); DONE;")
1906 (define_expand "movti"
1907 [(set (match_operand:TI 0 "nonimmediate_operand")
1908 (match_operand:TI 1 "nonimmediate_operand"))]
1909 "TARGET_64BIT || TARGET_SSE"
1912 ix86_expand_move (TImode, operands);
1914 ix86_expand_vector_move (TImode, operands);
1918 ;; This expands to what emit_move_complex would generate if we didn't
1919 ;; have a movti pattern. Having this avoids problems with reload on
1920 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1921 ;; to have around all the time.
1922 (define_expand "movcdi"
1923 [(set (match_operand:CDI 0 "nonimmediate_operand")
1924 (match_operand:CDI 1 "general_operand"))]
1927 if (push_operand (operands[0], CDImode))
1928 emit_move_complex_push (CDImode, operands[0], operands[1]);
1930 emit_move_complex_parts (operands[0], operands[1]);
1934 (define_expand "mov<mode>"
1935 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1936 (match_operand:SWI1248x 1 "general_operand"))]
1938 "ix86_expand_move (<MODE>mode, operands); DONE;")
1940 (define_insn "*mov<mode>_xor"
1941 [(set (match_operand:SWI48 0 "register_operand" "=r")
1942 (match_operand:SWI48 1 "const0_operand"))
1943 (clobber (reg:CC FLAGS_REG))]
1946 [(set_attr "type" "alu1")
1947 (set_attr "mode" "SI")
1948 (set_attr "length_immediate" "0")])
1950 (define_insn "*mov<mode>_or"
1951 [(set (match_operand:SWI48 0 "register_operand" "=r")
1952 (match_operand:SWI48 1 "const_int_operand"))
1953 (clobber (reg:CC FLAGS_REG))]
1955 && operands[1] == constm1_rtx"
1956 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1957 [(set_attr "type" "alu1")
1958 (set_attr "mode" "<MODE>")
1959 (set_attr "length_immediate" "1")])
1961 (define_insn "*movxi_internal_avx512f"
1962 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1963 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1964 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1966 switch (which_alternative)
1969 return standard_sse_constant_opcode (insn, operands[1]);
1972 if (misaligned_operand (operands[0], XImode)
1973 || misaligned_operand (operands[1], XImode))
1974 return "vmovdqu32\t{%1, %0|%0, %1}";
1976 return "vmovdqa32\t{%1, %0|%0, %1}";
1981 [(set_attr "type" "sselog1,ssemov,ssemov")
1982 (set_attr "prefix" "evex")
1983 (set_attr "mode" "XI")])
1985 (define_insn "*movoi_internal_avx"
1986 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1987 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1988 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990 switch (get_attr_type (insn))
1993 return standard_sse_constant_opcode (insn, operands[1]);
1996 if (misaligned_operand (operands[0], OImode)
1997 || misaligned_operand (operands[1], OImode))
1999 if (get_attr_mode (insn) == MODE_V8SF)
2000 return "vmovups\t{%1, %0|%0, %1}";
2001 else if (get_attr_mode (insn) == MODE_XI)
2002 return "vmovdqu32\t{%1, %0|%0, %1}";
2004 return "vmovdqu\t{%1, %0|%0, %1}";
2008 if (get_attr_mode (insn) == MODE_V8SF)
2009 return "vmovaps\t{%1, %0|%0, %1}";
2010 else if (get_attr_mode (insn) == MODE_XI)
2011 return "vmovdqa32\t{%1, %0|%0, %1}";
2013 return "vmovdqa\t{%1, %0|%0, %1}";
2020 [(set_attr "type" "sselog1,ssemov,ssemov")
2021 (set_attr "prefix" "vex")
2023 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2024 (match_operand 1 "ext_sse_reg_operand"))
2026 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2027 (const_string "V8SF")
2028 (and (eq_attr "alternative" "2")
2029 (match_test "TARGET_SSE_TYPELESS_STORES"))
2030 (const_string "V8SF")
2032 (const_string "OI")))])
2034 (define_insn "*movti_internal"
2035 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2036 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2037 "(TARGET_64BIT || TARGET_SSE)
2038 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2040 switch (get_attr_type (insn))
2046 return standard_sse_constant_opcode (insn, operands[1]);
2049 /* TDmode values are passed as TImode on the stack. Moving them
2050 to stack may result in unaligned memory access. */
2051 if (misaligned_operand (operands[0], TImode)
2052 || misaligned_operand (operands[1], TImode))
2054 if (get_attr_mode (insn) == MODE_V4SF)
2055 return "%vmovups\t{%1, %0|%0, %1}";
2056 else if (get_attr_mode (insn) == MODE_XI)
2057 return "vmovdqu32\t{%1, %0|%0, %1}";
2059 return "%vmovdqu\t{%1, %0|%0, %1}";
2063 if (get_attr_mode (insn) == MODE_V4SF)
2064 return "%vmovaps\t{%1, %0|%0, %1}";
2065 else if (get_attr_mode (insn) == MODE_XI)
2066 return "vmovdqa32\t{%1, %0|%0, %1}";
2068 return "%vmovdqa\t{%1, %0|%0, %1}";
2075 [(set_attr "isa" "x64,x64,*,*,*")
2076 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2077 (set (attr "prefix")
2078 (if_then_else (eq_attr "type" "sselog1,ssemov")
2079 (const_string "maybe_vex")
2080 (const_string "orig")))
2082 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2083 (match_operand 1 "ext_sse_reg_operand"))
2085 (eq_attr "alternative" "0,1")
2087 (ior (not (match_test "TARGET_SSE2"))
2088 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2089 (const_string "V4SF")
2090 (and (eq_attr "alternative" "4")
2091 (match_test "TARGET_SSE_TYPELESS_STORES"))
2092 (const_string "V4SF")
2093 (match_test "TARGET_AVX")
2095 (match_test "optimize_function_for_size_p (cfun)")
2096 (const_string "V4SF")
2098 (const_string "TI")))])
2101 [(set (match_operand:TI 0 "nonimmediate_operand")
2102 (match_operand:TI 1 "general_operand"))]
2104 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2106 "ix86_split_long_move (operands); DONE;")
2108 (define_insn "*movdi_internal"
2109 [(set (match_operand:DI 0 "nonimmediate_operand"
2110 "=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")
2111 (match_operand:DI 1 "general_operand"
2112 "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"))]
2113 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115 switch (get_attr_type (insn))
2118 return "kmovq\t{%1, %0|%0, %1}";
2124 return "pxor\t%0, %0";
2127 /* Handle broken assemblers that require movd instead of movq. */
2128 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2129 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2130 return "movd\t{%1, %0|%0, %1}";
2131 return "movq\t{%1, %0|%0, %1}";
2134 if (GENERAL_REG_P (operands[0]))
2135 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2137 return standard_sse_constant_opcode (insn, operands[1]);
2140 switch (get_attr_mode (insn))
2143 /* Handle broken assemblers that require movd instead of movq. */
2144 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2145 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2146 return "%vmovd\t{%1, %0|%0, %1}";
2147 return "%vmovq\t{%1, %0|%0, %1}";
2149 return "%vmovdqa\t{%1, %0|%0, %1}";
2151 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2154 gcc_assert (!TARGET_AVX);
2155 return "movlps\t{%1, %0|%0, %1}";
2157 return "%vmovaps\t{%1, %0|%0, %1}";
2164 if (SSE_REG_P (operands[0]))
2165 return "movq2dq\t{%1, %0|%0, %1}";
2167 return "movdq2q\t{%1, %0|%0, %1}";
2170 return "lea{q}\t{%E1, %0|%0, %E1}";
2173 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2174 if (get_attr_mode (insn) == MODE_SI)
2175 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2176 else if (which_alternative == 4)
2177 return "movabs{q}\t{%1, %0|%0, %1}";
2178 else if (ix86_use_lea_for_mov (insn, operands))
2179 return "lea{q}\t{%E1, %0|%0, %E1}";
2181 return "mov{q}\t{%1, %0|%0, %1}";
2188 (cond [(eq_attr "alternative" "0,1")
2189 (const_string "nox64")
2190 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2191 (const_string "x64")
2192 (eq_attr "alternative" "17")
2193 (const_string "x64_sse4")
2195 (const_string "*")))
2197 (cond [(eq_attr "alternative" "0,1")
2198 (const_string "multi")
2199 (eq_attr "alternative" "6")
2200 (const_string "mmx")
2201 (eq_attr "alternative" "7,8,9,10,11")
2202 (const_string "mmxmov")
2203 (eq_attr "alternative" "12,17")
2204 (const_string "sselog1")
2205 (eq_attr "alternative" "13,14,15,16,18")
2206 (const_string "ssemov")
2207 (eq_attr "alternative" "19,20")
2208 (const_string "ssecvt")
2209 (eq_attr "alternative" "21,22,23,24")
2210 (const_string "mskmov")
2211 (and (match_operand 0 "register_operand")
2212 (match_operand 1 "pic_32bit_operand"))
2213 (const_string "lea")
2215 (const_string "imov")))
2218 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2220 (const_string "*")))
2221 (set (attr "length_immediate")
2222 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2224 (eq_attr "alternative" "17")
2227 (const_string "*")))
2228 (set (attr "prefix_rex")
2229 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2231 (const_string "*")))
2232 (set (attr "prefix_extra")
2233 (if_then_else (eq_attr "alternative" "17")
2235 (const_string "*")))
2236 (set (attr "prefix")
2237 (if_then_else (eq_attr "type" "sselog1,ssemov")
2238 (const_string "maybe_vex")
2239 (const_string "orig")))
2240 (set (attr "prefix_data16")
2241 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2243 (const_string "*")))
2245 (cond [(eq_attr "alternative" "2")
2247 (eq_attr "alternative" "12,13")
2248 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2249 (match_operand 1 "ext_sse_reg_operand"))
2251 (ior (not (match_test "TARGET_SSE2"))
2252 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2253 (const_string "V4SF")
2254 (match_test "TARGET_AVX")
2256 (match_test "optimize_function_for_size_p (cfun)")
2257 (const_string "V4SF")
2259 (const_string "TI"))
2261 (and (eq_attr "alternative" "14,15")
2262 (not (match_test "TARGET_SSE2")))
2263 (const_string "V2SF")
2264 (eq_attr "alternative" "17")
2267 (const_string "DI")))])
2270 [(set (match_operand:DI 0 "nonimmediate_operand")
2271 (match_operand:DI 1 "general_operand"))]
2272 "!TARGET_64BIT && reload_completed
2273 && !(MMX_REG_P (operands[0])
2274 || SSE_REG_P (operands[0])
2275 || MASK_REG_P (operands[0]))
2276 && !(MMX_REG_P (operands[1])
2277 || SSE_REG_P (operands[1])
2278 || MASK_REG_P (operands[1]))"
2280 "ix86_split_long_move (operands); DONE;")
2282 (define_insn "*movsi_internal"
2283 [(set (match_operand:SI 0 "nonimmediate_operand"
2284 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2285 (match_operand:SI 1 "general_operand"
2286 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2287 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2289 switch (get_attr_type (insn))
2292 if (GENERAL_REG_P (operands[0]))
2293 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2295 return standard_sse_constant_opcode (insn, operands[1]);
2298 return "kmovd\t{%1, %0|%0, %1}";
2301 switch (get_attr_mode (insn))
2304 return "%vmovd\t{%1, %0|%0, %1}";
2306 return "%vmovdqa\t{%1, %0|%0, %1}";
2308 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2311 return "%vmovaps\t{%1, %0|%0, %1}";
2314 gcc_assert (!TARGET_AVX);
2315 return "movss\t{%1, %0|%0, %1}";
2322 return "pxor\t%0, %0";
2325 switch (get_attr_mode (insn))
2328 return "movq\t{%1, %0|%0, %1}";
2330 return "movd\t{%1, %0|%0, %1}";
2337 return "lea{l}\t{%E1, %0|%0, %E1}";
2340 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2341 if (ix86_use_lea_for_mov (insn, operands))
2342 return "lea{l}\t{%E1, %0|%0, %E1}";
2344 return "mov{l}\t{%1, %0|%0, %1}";
2351 (if_then_else (eq_attr "alternative" "11")
2352 (const_string "sse4")
2353 (const_string "*")))
2355 (cond [(eq_attr "alternative" "2")
2356 (const_string "mmx")
2357 (eq_attr "alternative" "3,4,5")
2358 (const_string "mmxmov")
2359 (eq_attr "alternative" "6,11")
2360 (const_string "sselog1")
2361 (eq_attr "alternative" "7,8,9,10,12")
2362 (const_string "ssemov")
2363 (eq_attr "alternative" "13,14")
2364 (const_string "mskmov")
2365 (and (match_operand 0 "register_operand")
2366 (match_operand 1 "pic_32bit_operand"))
2367 (const_string "lea")
2369 (const_string "imov")))
2370 (set (attr "length_immediate")
2371 (if_then_else (eq_attr "alternative" "11")
2373 (const_string "*")))
2374 (set (attr "prefix_extra")
2375 (if_then_else (eq_attr "alternative" "11")
2377 (const_string "*")))
2378 (set (attr "prefix")
2379 (if_then_else (eq_attr "type" "sselog1,ssemov")
2380 (const_string "maybe_vex")
2381 (const_string "orig")))
2382 (set (attr "prefix_data16")
2383 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2385 (const_string "*")))
2387 (cond [(eq_attr "alternative" "2,3")
2389 (eq_attr "alternative" "6,7")
2390 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2391 (match_operand 1 "ext_sse_reg_operand"))
2393 (ior (not (match_test "TARGET_SSE2"))
2394 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2395 (const_string "V4SF")
2396 (match_test "TARGET_AVX")
2398 (match_test "optimize_function_for_size_p (cfun)")
2399 (const_string "V4SF")
2401 (const_string "TI"))
2403 (and (eq_attr "alternative" "8,9")
2404 (not (match_test "TARGET_SSE2")))
2406 (eq_attr "alternative" "11")
2409 (const_string "SI")))])
2411 (define_insn "kmovw"
2412 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2414 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2416 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2418 kmovw\t{%k1, %0|%0, %k1}
2419 kmovw\t{%1, %0|%0, %1}";
2420 [(set_attr "mode" "HI")
2421 (set_attr "type" "mskmov")
2422 (set_attr "prefix" "vex")])
2425 (define_insn "*movhi_internal"
2426 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2427 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2428 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2430 switch (get_attr_type (insn))
2433 /* movzwl is faster than movw on p2 due to partial word stalls,
2434 though not as fast as an aligned movl. */
2435 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2438 switch (which_alternative)
2440 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2441 case 5: return "kmovw\t{%1, %0|%0, %1}";
2442 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2443 default: gcc_unreachable ();
2447 if (get_attr_mode (insn) == MODE_SI)
2448 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2450 return "mov{w}\t{%1, %0|%0, %1}";
2454 (cond [(eq_attr "alternative" "4,5,6")
2455 (const_string "mskmov")
2456 (match_test "optimize_function_for_size_p (cfun)")
2457 (const_string "imov")
2458 (and (eq_attr "alternative" "0")
2459 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2460 (not (match_test "TARGET_HIMODE_MATH"))))
2461 (const_string "imov")
2462 (and (eq_attr "alternative" "1,2")
2463 (match_operand:HI 1 "aligned_operand"))
2464 (const_string "imov")
2465 (and (match_test "TARGET_MOVX")
2466 (eq_attr "alternative" "0,2"))
2467 (const_string "imovx")
2469 (const_string "imov")))
2470 (set (attr "prefix")
2471 (if_then_else (eq_attr "alternative" "4,5,6")
2472 (const_string "vex")
2473 (const_string "orig")))
2475 (cond [(eq_attr "type" "imovx")
2477 (and (eq_attr "alternative" "1,2")
2478 (match_operand:HI 1 "aligned_operand"))
2480 (and (eq_attr "alternative" "0")
2481 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2482 (not (match_test "TARGET_HIMODE_MATH"))))
2485 (const_string "HI")))])
2487 ;; Situation is quite tricky about when to choose full sized (SImode) move
2488 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2489 ;; partial register dependency machines (such as AMD Athlon), where QImode
2490 ;; moves issue extra dependency and for partial register stalls machines
2491 ;; that don't use QImode patterns (and QImode move cause stall on the next
2494 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2495 ;; register stall machines with, where we use QImode instructions, since
2496 ;; partial register stall can be caused there. Then we use movzx.
2498 (define_insn "*movqi_internal"
2499 [(set (match_operand:QI 0 "nonimmediate_operand"
2500 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2501 (match_operand:QI 1 "general_operand"
2502 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2503 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2505 switch (get_attr_type (insn))
2508 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2509 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2512 switch (which_alternative)
2514 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2515 : "kmovw\t{%k1, %0|%0, %k1}";
2516 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2517 : "kmovw\t{%1, %0|%0, %1}";
2518 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2519 : "kmovw\t{%1, %k0|%k0, %1}";
2522 gcc_assert (TARGET_AVX512DQ);
2523 return "kmovb\t{%1, %0|%0, %1}";
2524 default: gcc_unreachable ();
2528 if (get_attr_mode (insn) == MODE_SI)
2529 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2531 return "mov{b}\t{%1, %0|%0, %1}";
2534 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2536 (cond [(eq_attr "alternative" "3,5")
2537 (const_string "imovx")
2538 (eq_attr "alternative" "7,8,9,10,11")
2539 (const_string "mskmov")
2540 (and (eq_attr "alternative" "5")
2541 (not (match_operand:QI 1 "aligned_operand")))
2542 (const_string "imovx")
2543 (match_test "optimize_function_for_size_p (cfun)")
2544 (const_string "imov")
2545 (and (eq_attr "alternative" "3")
2546 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2547 (not (match_test "TARGET_QIMODE_MATH"))))
2548 (const_string "imov")
2549 (and (match_test "TARGET_MOVX")
2550 (eq_attr "alternative" "2"))
2551 (const_string "imovx")
2553 (const_string "imov")))
2554 (set (attr "prefix")
2555 (if_then_else (eq_attr "alternative" "7,8,9")
2556 (const_string "vex")
2557 (const_string "orig")))
2559 (cond [(eq_attr "alternative" "3,4,5")
2561 (eq_attr "alternative" "6")
2563 (eq_attr "type" "imovx")
2565 (and (eq_attr "type" "imov")
2566 (and (eq_attr "alternative" "0,1")
2567 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2568 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2569 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2571 ;; Avoid partial register stalls when not using QImode arithmetic
2572 (and (eq_attr "type" "imov")
2573 (and (eq_attr "alternative" "0,1")
2574 (and (match_test "TARGET_PARTIAL_REG_STALL")
2575 (not (match_test "TARGET_QIMODE_MATH")))))
2578 (const_string "QI")))])
2580 ;; Stores and loads of ax to arbitrary constant address.
2581 ;; We fake an second form of instruction to force reload to load address
2582 ;; into register when rax is not available
2583 (define_insn "*movabs<mode>_1"
2584 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2585 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2586 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2588 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2589 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2590 [(set_attr "type" "imov")
2591 (set_attr "modrm" "0,*")
2592 (set_attr "length_address" "8,0")
2593 (set_attr "length_immediate" "0,*")
2594 (set_attr "memory" "store")
2595 (set_attr "mode" "<MODE>")])
2597 (define_insn "*movabs<mode>_2"
2598 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2599 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2600 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2602 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2603 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "modrm" "0,*")
2606 (set_attr "length_address" "8,0")
2607 (set_attr "length_immediate" "0")
2608 (set_attr "memory" "load")
2609 (set_attr "mode" "<MODE>")])
2611 (define_insn "*swap<mode>"
2612 [(set (match_operand:SWI48 0 "register_operand" "+r")
2613 (match_operand:SWI48 1 "register_operand" "+r"))
2617 "xchg{<imodesuffix>}\t%1, %0"
2618 [(set_attr "type" "imov")
2619 (set_attr "mode" "<MODE>")
2620 (set_attr "pent_pair" "np")
2621 (set_attr "athlon_decode" "vector")
2622 (set_attr "amdfam10_decode" "double")
2623 (set_attr "bdver1_decode" "double")])
2625 (define_insn "*swap<mode>_1"
2626 [(set (match_operand:SWI12 0 "register_operand" "+r")
2627 (match_operand:SWI12 1 "register_operand" "+r"))
2630 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2632 [(set_attr "type" "imov")
2633 (set_attr "mode" "SI")
2634 (set_attr "pent_pair" "np")
2635 (set_attr "athlon_decode" "vector")
2636 (set_attr "amdfam10_decode" "double")
2637 (set_attr "bdver1_decode" "double")])
2639 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2640 ;; is disabled for AMDFAM10
2641 (define_insn "*swap<mode>_2"
2642 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2643 (match_operand:SWI12 1 "register_operand" "+<r>"))
2646 "TARGET_PARTIAL_REG_STALL"
2647 "xchg{<imodesuffix>}\t%1, %0"
2648 [(set_attr "type" "imov")
2649 (set_attr "mode" "<MODE>")
2650 (set_attr "pent_pair" "np")
2651 (set_attr "athlon_decode" "vector")])
2653 (define_expand "movstrict<mode>"
2654 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2655 (match_operand:SWI12 1 "general_operand"))]
2658 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2660 if (GET_CODE (operands[0]) == SUBREG
2661 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2663 /* Don't generate memory->memory moves, go through a register */
2664 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2665 operands[1] = force_reg (<MODE>mode, operands[1]);
2668 (define_insn "*movstrict<mode>_1"
2669 [(set (strict_low_part
2670 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2671 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2672 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2673 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2675 [(set_attr "type" "imov")
2676 (set_attr "mode" "<MODE>")])
2678 (define_insn "*movstrict<mode>_xor"
2679 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2680 (match_operand:SWI12 1 "const0_operand"))
2681 (clobber (reg:CC FLAGS_REG))]
2683 "xor{<imodesuffix>}\t%0, %0"
2684 [(set_attr "type" "alu1")
2685 (set_attr "mode" "<MODE>")
2686 (set_attr "length_immediate" "0")])
2688 (define_insn "*mov<mode>_extv_1"
2689 [(set (match_operand:SWI24 0 "register_operand" "=R")
2690 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2694 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2695 [(set_attr "type" "imovx")
2696 (set_attr "mode" "SI")])
2698 (define_insn "*movqi_extv_1"
2699 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2700 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2705 switch (get_attr_type (insn))
2708 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2710 return "mov{b}\t{%h1, %0|%0, %h1}";
2713 [(set_attr "isa" "*,*,nox64")
2715 (if_then_else (and (match_operand:QI 0 "register_operand")
2716 (ior (not (match_operand:QI 0 "QIreg_operand"))
2717 (match_test "TARGET_MOVX")))
2718 (const_string "imovx")
2719 (const_string "imov")))
2721 (if_then_else (eq_attr "type" "imovx")
2723 (const_string "QI")))])
2725 (define_insn "*mov<mode>_extzv_1"
2726 [(set (match_operand:SWI48 0 "register_operand" "=R")
2727 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2731 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2732 [(set_attr "type" "imovx")
2733 (set_attr "mode" "SI")])
2735 (define_insn "*movqi_extzv_2"
2736 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2738 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2743 switch (get_attr_type (insn))
2746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2748 return "mov{b}\t{%h1, %0|%0, %h1}";
2751 [(set_attr "isa" "*,*,nox64")
2753 (if_then_else (and (match_operand:QI 0 "register_operand")
2754 (ior (not (match_operand:QI 0 "QIreg_operand"))
2755 (match_test "TARGET_MOVX")))
2756 (const_string "imovx")
2757 (const_string "imov")))
2759 (if_then_else (eq_attr "type" "imovx")
2761 (const_string "QI")))])
2763 (define_insn "mov<mode>_insv_1"
2764 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2767 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2770 if (CONST_INT_P (operands[1]))
2771 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2772 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2774 [(set_attr "isa" "*,nox64")
2775 (set_attr "type" "imov")
2776 (set_attr "mode" "QI")])
2778 (define_insn "*movqi_insv_2"
2779 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2782 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2785 "mov{b}\t{%h1, %h0|%h0, %h1}"
2786 [(set_attr "type" "imov")
2787 (set_attr "mode" "QI")])
2789 ;; Floating point push instructions.
2791 (define_insn "*pushtf"
2792 [(set (match_operand:TF 0 "push_operand" "=<,<")
2793 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2794 "TARGET_64BIT || TARGET_SSE"
2796 /* This insn should be already split before reg-stack. */
2799 [(set_attr "isa" "*,x64")
2800 (set_attr "type" "multi")
2801 (set_attr "unit" "sse,*")
2802 (set_attr "mode" "TF,DI")])
2804 ;; %%% Kill this when call knows how to work this out.
2806 [(set (match_operand:TF 0 "push_operand")
2807 (match_operand:TF 1 "sse_reg_operand"))]
2808 "TARGET_SSE && reload_completed"
2809 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2810 (set (match_dup 0) (match_dup 1))]
2812 /* Preserve memory attributes. */
2813 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2816 (define_insn "*pushxf"
2817 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2818 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2821 /* This insn should be already split before reg-stack. */
2824 [(set_attr "type" "multi")
2825 (set_attr "unit" "i387,*,*,*")
2827 (cond [(eq_attr "alternative" "1,2,3")
2828 (if_then_else (match_test "TARGET_64BIT")
2830 (const_string "SI"))
2832 (const_string "XF")))
2833 (set (attr "preferred_for_size")
2834 (cond [(eq_attr "alternative" "1")
2835 (symbol_ref "false")]
2836 (symbol_ref "true")))])
2838 ;; %%% Kill this when call knows how to work this out.
2840 [(set (match_operand:XF 0 "push_operand")
2841 (match_operand:XF 1 "fp_register_operand"))]
2843 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2844 (set (match_dup 0) (match_dup 1))]
2846 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2847 /* Preserve memory attributes. */
2848 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2851 (define_insn "*pushdf"
2852 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2853 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2856 /* This insn should be already split before reg-stack. */
2859 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2860 (set_attr "type" "multi")
2861 (set_attr "unit" "i387,*,*,*,*,sse")
2862 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2863 (set (attr "preferred_for_size")
2864 (cond [(eq_attr "alternative" "1")
2865 (symbol_ref "false")]
2866 (symbol_ref "true")))
2867 (set (attr "preferred_for_speed")
2868 (cond [(eq_attr "alternative" "1")
2869 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2870 (symbol_ref "true")))])
2872 ;; %%% Kill this when call knows how to work this out.
2874 [(set (match_operand:DF 0 "push_operand")
2875 (match_operand:DF 1 "any_fp_register_operand"))]
2877 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2878 (set (match_dup 0) (match_dup 1))]
2880 /* Preserve memory attributes. */
2881 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2884 (define_insn "*pushsf_rex64"
2885 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2886 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2889 /* Anything else should be already split before reg-stack. */
2890 gcc_assert (which_alternative == 1);
2891 return "push{q}\t%q1";
2893 [(set_attr "type" "multi,push,multi")
2894 (set_attr "unit" "i387,*,*")
2895 (set_attr "mode" "SF,DI,SF")])
2897 (define_insn "*pushsf"
2898 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2899 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2902 /* Anything else should be already split before reg-stack. */
2903 gcc_assert (which_alternative == 1);
2904 return "push{l}\t%1";
2906 [(set_attr "type" "multi,push,multi")
2907 (set_attr "unit" "i387,*,*")
2908 (set_attr "mode" "SF,SI,SF")])
2910 ;; %%% Kill this when call knows how to work this out.
2912 [(set (match_operand:SF 0 "push_operand")
2913 (match_operand:SF 1 "any_fp_register_operand"))]
2915 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2916 (set (match_dup 0) (match_dup 1))]
2918 rtx op = XEXP (operands[0], 0);
2919 if (GET_CODE (op) == PRE_DEC)
2921 gcc_assert (!TARGET_64BIT);
2926 op = XEXP (XEXP (op, 1), 1);
2927 gcc_assert (CONST_INT_P (op));
2930 /* Preserve memory attributes. */
2931 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2935 [(set (match_operand:SF 0 "push_operand")
2936 (match_operand:SF 1 "memory_operand"))]
2938 && (operands[2] = find_constant_src (insn))"
2939 [(set (match_dup 0) (match_dup 2))])
2942 [(set (match_operand 0 "push_operand")
2943 (match_operand 1 "general_operand"))]
2945 && (GET_MODE (operands[0]) == TFmode
2946 || GET_MODE (operands[0]) == XFmode
2947 || GET_MODE (operands[0]) == DFmode)
2948 && !ANY_FP_REG_P (operands[1])"
2950 "ix86_split_long_move (operands); DONE;")
2952 ;; Floating point move instructions.
2954 (define_expand "movtf"
2955 [(set (match_operand:TF 0 "nonimmediate_operand")
2956 (match_operand:TF 1 "nonimmediate_operand"))]
2957 "TARGET_64BIT || TARGET_SSE"
2958 "ix86_expand_move (TFmode, operands); DONE;")
2960 (define_expand "mov<mode>"
2961 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2962 (match_operand:X87MODEF 1 "general_operand"))]
2964 "ix86_expand_move (<MODE>mode, operands); DONE;")
2966 (define_insn "*movtf_internal"
2967 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2968 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2969 "(TARGET_64BIT || TARGET_SSE)
2970 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2971 && (!can_create_pseudo_p ()
2972 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2973 || GET_CODE (operands[1]) != CONST_DOUBLE
2974 || (optimize_function_for_size_p (cfun)
2975 && standard_sse_constant_p (operands[1])
2976 && !memory_operand (operands[0], TFmode))
2977 || (!TARGET_MEMORY_MISMATCH_STALL
2978 && memory_operand (operands[0], TFmode)))"
2980 switch (get_attr_type (insn))
2983 return standard_sse_constant_opcode (insn, operands[1]);
2986 /* Handle misaligned load/store since we
2987 don't have movmisaligntf pattern. */
2988 if (misaligned_operand (operands[0], TFmode)
2989 || misaligned_operand (operands[1], TFmode))
2991 if (get_attr_mode (insn) == MODE_V4SF)
2992 return "%vmovups\t{%1, %0|%0, %1}";
2994 return "%vmovdqu\t{%1, %0|%0, %1}";
2998 if (get_attr_mode (insn) == MODE_V4SF)
2999 return "%vmovaps\t{%1, %0|%0, %1}";
3001 return "%vmovdqa\t{%1, %0|%0, %1}";
3011 [(set_attr "isa" "*,*,*,x64,x64")
3012 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3013 (set (attr "prefix")
3014 (if_then_else (eq_attr "type" "sselog1,ssemov")
3015 (const_string "maybe_vex")
3016 (const_string "orig")))
3018 (cond [(eq_attr "alternative" "3,4")
3020 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3021 (const_string "V4SF")
3022 (and (eq_attr "alternative" "2")
3023 (match_test "TARGET_SSE_TYPELESS_STORES"))
3024 (const_string "V4SF")
3025 (match_test "TARGET_AVX")
3027 (ior (not (match_test "TARGET_SSE2"))
3028 (match_test "optimize_function_for_size_p (cfun)"))
3029 (const_string "V4SF")
3031 (const_string "TI")))])
3033 ;; Possible store forwarding (partial memory) stall
3034 ;; in alternatives 4, 6, 7 and 8.
3035 (define_insn "*movxf_internal"
3036 [(set (match_operand:XF 0 "nonimmediate_operand"
3037 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3038 (match_operand:XF 1 "general_operand"
3039 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3040 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3041 && (!can_create_pseudo_p ()
3042 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3043 || GET_CODE (operands[1]) != CONST_DOUBLE
3044 || (optimize_function_for_size_p (cfun)
3045 && standard_80387_constant_p (operands[1]) > 0
3046 && !memory_operand (operands[0], XFmode))
3047 || (!TARGET_MEMORY_MISMATCH_STALL
3048 && memory_operand (operands[0], XFmode)))"
3050 switch (get_attr_type (insn))
3053 if (which_alternative == 2)
3054 return standard_80387_constant_opcode (operands[1]);
3055 return output_387_reg_move (insn, operands);
3065 (cond [(eq_attr "alternative" "7")
3066 (const_string "nox64")
3067 (eq_attr "alternative" "8")
3068 (const_string "x64")
3070 (const_string "*")))
3072 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3073 (const_string "multi")
3075 (const_string "fmov")))
3077 (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3078 (if_then_else (match_test "TARGET_64BIT")
3080 (const_string "SI"))
3082 (const_string "XF")))
3083 (set (attr "preferred_for_size")
3084 (cond [(eq_attr "alternative" "3,4")
3085 (symbol_ref "false")]
3086 (symbol_ref "true")))])
3088 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3089 (define_insn "*movdf_internal"
3090 [(set (match_operand:DF 0 "nonimmediate_operand"
3091 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3092 (match_operand:DF 1 "general_operand"
3093 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3094 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3095 && (!can_create_pseudo_p ()
3096 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3097 || GET_CODE (operands[1]) != CONST_DOUBLE
3098 || (optimize_function_for_size_p (cfun)
3099 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3100 && standard_80387_constant_p (operands[1]) > 0)
3101 || (TARGET_SSE2 && TARGET_SSE_MATH
3102 && standard_sse_constant_p (operands[1])))
3103 && !memory_operand (operands[0], DFmode))
3104 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3105 && memory_operand (operands[0], DFmode)))"
3107 switch (get_attr_type (insn))
3110 if (which_alternative == 2)
3111 return standard_80387_constant_opcode (operands[1]);
3112 return output_387_reg_move (insn, operands);
3118 if (get_attr_mode (insn) == MODE_SI)
3119 return "mov{l}\t{%1, %k0|%k0, %1}";
3120 else if (which_alternative == 11)
3121 return "movabs{q}\t{%1, %0|%0, %1}";
3123 return "mov{q}\t{%1, %0|%0, %1}";
3126 return standard_sse_constant_opcode (insn, operands[1]);
3129 switch (get_attr_mode (insn))
3132 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3133 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3134 return "%vmovsd\t{%1, %0|%0, %1}";
3137 return "%vmovaps\t{%1, %0|%0, %1}";
3139 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3141 return "%vmovapd\t{%1, %0|%0, %1}";
3144 gcc_assert (!TARGET_AVX);
3145 return "movlps\t{%1, %0|%0, %1}";
3147 gcc_assert (!TARGET_AVX);
3148 return "movlpd\t{%1, %0|%0, %1}";
3151 /* Handle broken assemblers that require movd instead of movq. */
3152 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3153 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3154 return "%vmovd\t{%1, %0|%0, %1}";
3155 return "%vmovq\t{%1, %0|%0, %1}";
3166 (cond [(eq_attr "alternative" "3,4,5,6,7")
3167 (const_string "nox64")
3168 (eq_attr "alternative" "8,9,10,11,20,21")
3169 (const_string "x64")
3170 (eq_attr "alternative" "12,13,14,15")
3171 (const_string "sse2")
3173 (const_string "*")))
3175 (cond [(eq_attr "alternative" "0,1,2")
3176 (const_string "fmov")
3177 (eq_attr "alternative" "3,4,5,6,7")
3178 (const_string "multi")
3179 (eq_attr "alternative" "8,9,10,11")
3180 (const_string "imov")
3181 (eq_attr "alternative" "12,16")
3182 (const_string "sselog1")
3184 (const_string "ssemov")))
3186 (if_then_else (eq_attr "alternative" "11")
3188 (const_string "*")))
3189 (set (attr "length_immediate")
3190 (if_then_else (eq_attr "alternative" "11")
3192 (const_string "*")))
3193 (set (attr "prefix")
3194 (if_then_else (eq_attr "type" "sselog1,ssemov")
3195 (const_string "maybe_vex")
3196 (const_string "orig")))
3197 (set (attr "prefix_data16")
3199 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3200 (eq_attr "mode" "V1DF"))
3202 (const_string "*")))
3204 (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3206 (eq_attr "alternative" "8,9,11,20,21")
3209 /* xorps is one byte shorter for non-AVX targets. */
3210 (eq_attr "alternative" "12,16")
3211 (cond [(not (match_test "TARGET_SSE2"))
3212 (const_string "V4SF")
3213 (match_test "TARGET_AVX512F")
3215 (match_test "TARGET_AVX")
3216 (const_string "V2DF")
3217 (match_test "optimize_function_for_size_p (cfun)")
3218 (const_string "V4SF")
3219 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3222 (const_string "V2DF"))
3224 /* For architectures resolving dependencies on
3225 whole SSE registers use movapd to break dependency
3226 chains, otherwise use short move to avoid extra work. */
3228 /* movaps is one byte shorter for non-AVX targets. */
3229 (eq_attr "alternative" "13,17")
3230 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3231 (match_operand 1 "ext_sse_reg_operand"))
3232 (const_string "V8DF")
3233 (ior (not (match_test "TARGET_SSE2"))
3234 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3235 (const_string "V4SF")
3236 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3237 (const_string "V2DF")
3238 (match_test "TARGET_AVX")
3240 (match_test "optimize_function_for_size_p (cfun)")
3241 (const_string "V4SF")
3243 (const_string "DF"))
3245 /* For architectures resolving dependencies on register
3246 parts we may avoid extra work to zero out upper part
3248 (eq_attr "alternative" "14,18")
3249 (cond [(not (match_test "TARGET_SSE2"))
3250 (const_string "V2SF")
3251 (match_test "TARGET_AVX")
3253 (match_test "TARGET_SSE_SPLIT_REGS")
3254 (const_string "V1DF")
3256 (const_string "DF"))
3258 (and (eq_attr "alternative" "15,19")
3259 (not (match_test "TARGET_SSE2")))
3260 (const_string "V2SF")
3262 (const_string "DF")))
3263 (set (attr "preferred_for_size")
3264 (cond [(eq_attr "alternative" "3,4")
3265 (symbol_ref "false")]
3266 (symbol_ref "true")))
3267 (set (attr "preferred_for_speed")
3268 (cond [(eq_attr "alternative" "3,4")
3269 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3270 (symbol_ref "true")))])
3272 (define_insn "*movsf_internal"
3273 [(set (match_operand:SF 0 "nonimmediate_operand"
3274 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3275 (match_operand:SF 1 "general_operand"
3276 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3277 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3278 && (!can_create_pseudo_p ()
3279 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3280 || GET_CODE (operands[1]) != CONST_DOUBLE
3281 || (optimize_function_for_size_p (cfun)
3282 && ((!TARGET_SSE_MATH
3283 && standard_80387_constant_p (operands[1]) > 0)
3285 && standard_sse_constant_p (operands[1]))))
3286 || memory_operand (operands[0], SFmode))"
3288 switch (get_attr_type (insn))
3291 if (which_alternative == 2)
3292 return standard_80387_constant_opcode (operands[1]);
3293 return output_387_reg_move (insn, operands);
3296 return "mov{l}\t{%1, %0|%0, %1}";
3299 return standard_sse_constant_opcode (insn, operands[1]);
3302 switch (get_attr_mode (insn))
3305 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3306 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3307 return "%vmovss\t{%1, %0|%0, %1}";
3310 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3312 return "%vmovaps\t{%1, %0|%0, %1}";
3315 return "%vmovd\t{%1, %0|%0, %1}";
3322 switch (get_attr_mode (insn))
3325 return "movq\t{%1, %0|%0, %1}";
3327 return "movd\t{%1, %0|%0, %1}";
3338 (cond [(eq_attr "alternative" "0,1,2")
3339 (const_string "fmov")
3340 (eq_attr "alternative" "3,4")
3341 (const_string "imov")
3342 (eq_attr "alternative" "5")
3343 (const_string "sselog1")
3344 (eq_attr "alternative" "11,12,13,14,15")
3345 (const_string "mmxmov")
3347 (const_string "ssemov")))
3348 (set (attr "prefix")
3349 (if_then_else (eq_attr "type" "sselog1,ssemov")
3350 (const_string "maybe_vex")
3351 (const_string "orig")))
3352 (set (attr "prefix_data16")
3353 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3355 (const_string "*")))
3357 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3359 (eq_attr "alternative" "11")
3361 (eq_attr "alternative" "5")
3362 (cond [(not (match_test "TARGET_SSE2"))
3363 (const_string "V4SF")
3364 (match_test "TARGET_AVX512F")
3365 (const_string "V16SF")
3366 (match_test "TARGET_AVX")
3367 (const_string "V4SF")
3368 (match_test "optimize_function_for_size_p (cfun)")
3369 (const_string "V4SF")
3370 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3373 (const_string "V4SF"))
3375 /* For architectures resolving dependencies on
3376 whole SSE registers use APS move to break dependency
3377 chains, otherwise use short move to avoid extra work.
3379 Do the same for architectures resolving dependencies on
3380 the parts. While in DF mode it is better to always handle
3381 just register parts, the SF mode is different due to lack
3382 of instructions to load just part of the register. It is
3383 better to maintain the whole registers in single format
3384 to avoid problems on using packed logical operations. */
3385 (eq_attr "alternative" "6")
3386 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3387 (match_operand 1 "ext_sse_reg_operand"))
3388 (const_string "V16SF")
3389 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3390 (match_test "TARGET_SSE_SPLIT_REGS"))
3391 (const_string "V4SF")
3393 (const_string "SF"))
3395 (const_string "SF")))])
3398 [(set (match_operand 0 "any_fp_register_operand")
3399 (match_operand 1 "memory_operand"))]
3401 && (GET_MODE (operands[0]) == TFmode
3402 || GET_MODE (operands[0]) == XFmode
3403 || GET_MODE (operands[0]) == DFmode
3404 || GET_MODE (operands[0]) == SFmode)
3405 && (operands[2] = find_constant_src (insn))"
3406 [(set (match_dup 0) (match_dup 2))]
3408 rtx c = operands[2];
3409 int r = REGNO (operands[0]);
3411 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3412 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3417 [(set (match_operand 0 "any_fp_register_operand")
3418 (float_extend (match_operand 1 "memory_operand")))]
3420 && (GET_MODE (operands[0]) == TFmode
3421 || GET_MODE (operands[0]) == XFmode
3422 || GET_MODE (operands[0]) == DFmode)
3423 && (operands[2] = find_constant_src (insn))"
3424 [(set (match_dup 0) (match_dup 2))]
3426 rtx c = operands[2];
3427 int r = REGNO (operands[0]);
3429 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3430 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3434 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3436 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3437 (match_operand:X87MODEF 1 "immediate_operand"))]
3439 && (standard_80387_constant_p (operands[1]) == 8
3440 || standard_80387_constant_p (operands[1]) == 9)"
3441 [(set (match_dup 0)(match_dup 1))
3443 (neg:X87MODEF (match_dup 0)))]
3447 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3448 if (real_isnegzero (&r))
3449 operands[1] = CONST0_RTX (<MODE>mode);
3451 operands[1] = CONST1_RTX (<MODE>mode);
3455 [(set (match_operand 0 "nonimmediate_operand")
3456 (match_operand 1 "general_operand"))]
3458 && (GET_MODE (operands[0]) == TFmode
3459 || GET_MODE (operands[0]) == XFmode
3460 || GET_MODE (operands[0]) == DFmode)
3461 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3463 "ix86_split_long_move (operands); DONE;")
3465 (define_insn "swapxf"
3466 [(set (match_operand:XF 0 "register_operand" "+f")
3467 (match_operand:XF 1 "register_operand" "+f"))
3472 if (STACK_TOP_P (operands[0]))
3477 [(set_attr "type" "fxch")
3478 (set_attr "mode" "XF")])
3480 (define_insn "*swap<mode>"
3481 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3482 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3485 "TARGET_80387 || reload_completed"
3487 if (STACK_TOP_P (operands[0]))
3492 [(set_attr "type" "fxch")
3493 (set_attr "mode" "<MODE>")])
3495 ;; Zero extension instructions
3497 (define_expand "zero_extendsidi2"
3498 [(set (match_operand:DI 0 "nonimmediate_operand")
3499 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3501 (define_insn "*zero_extendsidi2"
3502 [(set (match_operand:DI 0 "nonimmediate_operand"
3503 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3505 (match_operand:SI 1 "x86_64_zext_operand"
3506 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3509 switch (get_attr_type (insn))
3512 if (ix86_use_lea_for_mov (insn, operands))
3513 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3515 return "mov{l}\t{%1, %k0|%k0, %1}";
3521 return "movd\t{%1, %0|%0, %1}";
3524 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3527 if (GENERAL_REG_P (operands[0]))
3528 return "%vmovd\t{%1, %k0|%k0, %1}";
3530 return "%vmovd\t{%1, %0|%0, %1}";
3537 (cond [(eq_attr "alternative" "0,1,2")
3538 (const_string "nox64")
3539 (eq_attr "alternative" "3,7")
3540 (const_string "x64")
3541 (eq_attr "alternative" "8")
3542 (const_string "x64_sse4")
3543 (eq_attr "alternative" "10")
3544 (const_string "sse2")
3546 (const_string "*")))
3548 (cond [(eq_attr "alternative" "0,1,2,4")
3549 (const_string "multi")
3550 (eq_attr "alternative" "5,6")
3551 (const_string "mmxmov")
3552 (eq_attr "alternative" "7,9,10")
3553 (const_string "ssemov")
3554 (eq_attr "alternative" "8")
3555 (const_string "sselog1")
3557 (const_string "imovx")))
3558 (set (attr "prefix_extra")
3559 (if_then_else (eq_attr "alternative" "8")
3561 (const_string "*")))
3562 (set (attr "length_immediate")
3563 (if_then_else (eq_attr "alternative" "8")
3565 (const_string "*")))
3566 (set (attr "prefix")
3567 (if_then_else (eq_attr "type" "ssemov,sselog1")
3568 (const_string "maybe_vex")
3569 (const_string "orig")))
3570 (set (attr "prefix_0f")
3571 (if_then_else (eq_attr "type" "imovx")
3573 (const_string "*")))
3575 (cond [(eq_attr "alternative" "5,6")
3577 (eq_attr "alternative" "7,8,9")
3580 (const_string "SI")))])
3583 [(set (match_operand:DI 0 "memory_operand")
3584 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3586 [(set (match_dup 4) (const_int 0))]
3587 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3590 [(set (match_operand:DI 0 "register_operand")
3591 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3592 "!TARGET_64BIT && reload_completed
3593 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3594 && true_regnum (operands[0]) == true_regnum (operands[1])"
3595 [(set (match_dup 4) (const_int 0))]
3596 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3599 [(set (match_operand:DI 0 "nonimmediate_operand")
3600 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3601 "!TARGET_64BIT && reload_completed
3602 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3603 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3604 [(set (match_dup 3) (match_dup 1))
3605 (set (match_dup 4) (const_int 0))]
3606 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3608 (define_insn "zero_extend<mode>di2"
3609 [(set (match_operand:DI 0 "register_operand" "=r")
3611 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3613 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3614 [(set_attr "type" "imovx")
3615 (set_attr "mode" "SI")])
3617 (define_expand "zero_extend<mode>si2"
3618 [(set (match_operand:SI 0 "register_operand")
3619 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3622 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3624 operands[1] = force_reg (<MODE>mode, operands[1]);
3625 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3630 (define_insn_and_split "zero_extend<mode>si2_and"
3631 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3633 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3634 (clobber (reg:CC FLAGS_REG))]
3635 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3637 "&& reload_completed"
3638 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3639 (clobber (reg:CC FLAGS_REG))])]
3641 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3643 ix86_expand_clear (operands[0]);
3645 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3646 emit_insn (gen_movstrict<mode>
3647 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3651 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3653 [(set_attr "type" "alu1")
3654 (set_attr "mode" "SI")])
3656 (define_insn "*zero_extend<mode>si2"
3657 [(set (match_operand:SI 0 "register_operand" "=r")
3659 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3660 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3661 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3662 [(set_attr "type" "imovx")
3663 (set_attr "mode" "SI")])
3665 (define_expand "zero_extendqihi2"
3666 [(set (match_operand:HI 0 "register_operand")
3667 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3670 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3672 operands[1] = force_reg (QImode, operands[1]);
3673 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3678 (define_insn_and_split "zero_extendqihi2_and"
3679 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3680 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3681 (clobber (reg:CC FLAGS_REG))]
3682 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3684 "&& reload_completed"
3685 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3686 (clobber (reg:CC FLAGS_REG))])]
3688 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3690 ix86_expand_clear (operands[0]);
3692 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3693 emit_insn (gen_movstrictqi
3694 (gen_lowpart (QImode, operands[0]), operands[1]));
3698 operands[0] = gen_lowpart (SImode, operands[0]);
3700 [(set_attr "type" "alu1")
3701 (set_attr "mode" "SI")])
3703 ; zero extend to SImode to avoid partial register stalls
3704 (define_insn "*zero_extendqihi2"
3705 [(set (match_operand:HI 0 "register_operand" "=r")
3706 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3707 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3708 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3709 [(set_attr "type" "imovx")
3710 (set_attr "mode" "SI")])
3712 ;; Sign extension instructions
3714 (define_expand "extendsidi2"
3715 [(set (match_operand:DI 0 "register_operand")
3716 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3721 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3726 (define_insn "*extendsidi2_rex64"
3727 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3728 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3732 movs{lq|x}\t{%1, %0|%0, %1}"
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "DI")
3735 (set_attr "prefix_0f" "0")
3736 (set_attr "modrm" "0,1")])
3738 (define_insn "extendsidi2_1"
3739 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3740 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3741 (clobber (reg:CC FLAGS_REG))
3742 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3746 ;; Split the memory case. If the source register doesn't die, it will stay
3747 ;; this way, if it does die, following peephole2s take care of it.
3749 [(set (match_operand:DI 0 "memory_operand")
3750 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3751 (clobber (reg:CC FLAGS_REG))
3752 (clobber (match_operand:SI 2 "register_operand"))]
3756 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3758 emit_move_insn (operands[3], operands[1]);
3760 /* Generate a cltd if possible and doing so it profitable. */
3761 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3762 && true_regnum (operands[1]) == AX_REG
3763 && true_regnum (operands[2]) == DX_REG)
3765 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3769 emit_move_insn (operands[2], operands[1]);
3770 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3772 emit_move_insn (operands[4], operands[2]);
3776 ;; Peepholes for the case where the source register does die, after
3777 ;; being split with the above splitter.
3779 [(set (match_operand:SI 0 "memory_operand")
3780 (match_operand:SI 1 "register_operand"))
3781 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3782 (parallel [(set (match_dup 2)
3783 (ashiftrt:SI (match_dup 2) (const_int 31)))
3784 (clobber (reg:CC FLAGS_REG))])
3785 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3786 "REGNO (operands[1]) != REGNO (operands[2])
3787 && peep2_reg_dead_p (2, operands[1])
3788 && peep2_reg_dead_p (4, operands[2])
3789 && !reg_mentioned_p (operands[2], operands[3])"
3790 [(set (match_dup 0) (match_dup 1))
3791 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3792 (clobber (reg:CC FLAGS_REG))])
3793 (set (match_dup 3) (match_dup 1))])
3796 [(set (match_operand:SI 0 "memory_operand")
3797 (match_operand:SI 1 "register_operand"))
3798 (parallel [(set (match_operand:SI 2 "register_operand")
3799 (ashiftrt:SI (match_dup 1) (const_int 31)))
3800 (clobber (reg:CC FLAGS_REG))])
3801 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3802 "/* cltd is shorter than sarl $31, %eax */
3803 !optimize_function_for_size_p (cfun)
3804 && true_regnum (operands[1]) == AX_REG
3805 && true_regnum (operands[2]) == DX_REG
3806 && peep2_reg_dead_p (2, operands[1])
3807 && peep2_reg_dead_p (3, operands[2])
3808 && !reg_mentioned_p (operands[2], operands[3])"
3809 [(set (match_dup 0) (match_dup 1))
3810 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3811 (clobber (reg:CC FLAGS_REG))])
3812 (set (match_dup 3) (match_dup 1))])
3814 ;; Extend to register case. Optimize case where source and destination
3815 ;; registers match and cases where we can use cltd.
3817 [(set (match_operand:DI 0 "register_operand")
3818 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3819 (clobber (reg:CC FLAGS_REG))
3820 (clobber (match_scratch:SI 2))]
3824 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3826 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3827 emit_move_insn (operands[3], operands[1]);
3829 /* Generate a cltd if possible and doing so it profitable. */
3830 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3831 && true_regnum (operands[3]) == AX_REG
3832 && true_regnum (operands[4]) == DX_REG)
3834 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3838 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3839 emit_move_insn (operands[4], operands[1]);
3841 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3845 (define_insn "extend<mode>di2"
3846 [(set (match_operand:DI 0 "register_operand" "=r")
3848 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3850 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3851 [(set_attr "type" "imovx")
3852 (set_attr "mode" "DI")])
3854 (define_insn "extendhisi2"
3855 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3856 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3859 switch (get_attr_prefix_0f (insn))
3862 return "{cwtl|cwde}";
3864 return "movs{wl|x}\t{%1, %0|%0, %1}";
3867 [(set_attr "type" "imovx")
3868 (set_attr "mode" "SI")
3869 (set (attr "prefix_0f")
3870 ;; movsx is short decodable while cwtl is vector decoded.
3871 (if_then_else (and (eq_attr "cpu" "!k6")
3872 (eq_attr "alternative" "0"))
3874 (const_string "1")))
3876 (if_then_else (eq_attr "prefix_0f" "0")
3878 (const_string "1")))])
3880 (define_insn "*extendhisi2_zext"
3881 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3884 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3887 switch (get_attr_prefix_0f (insn))
3890 return "{cwtl|cwde}";
3892 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3895 [(set_attr "type" "imovx")
3896 (set_attr "mode" "SI")
3897 (set (attr "prefix_0f")
3898 ;; movsx is short decodable while cwtl is vector decoded.
3899 (if_then_else (and (eq_attr "cpu" "!k6")
3900 (eq_attr "alternative" "0"))
3902 (const_string "1")))
3904 (if_then_else (eq_attr "prefix_0f" "0")
3906 (const_string "1")))])
3908 (define_insn "extendqisi2"
3909 [(set (match_operand:SI 0 "register_operand" "=r")
3910 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3912 "movs{bl|x}\t{%1, %0|%0, %1}"
3913 [(set_attr "type" "imovx")
3914 (set_attr "mode" "SI")])
3916 (define_insn "*extendqisi2_zext"
3917 [(set (match_operand:DI 0 "register_operand" "=r")
3919 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3921 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3922 [(set_attr "type" "imovx")
3923 (set_attr "mode" "SI")])
3925 (define_insn "extendqihi2"
3926 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3927 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3930 switch (get_attr_prefix_0f (insn))
3933 return "{cbtw|cbw}";
3935 return "movs{bw|x}\t{%1, %0|%0, %1}";
3938 [(set_attr "type" "imovx")
3939 (set_attr "mode" "HI")
3940 (set (attr "prefix_0f")
3941 ;; movsx is short decodable while cwtl is vector decoded.
3942 (if_then_else (and (eq_attr "cpu" "!k6")
3943 (eq_attr "alternative" "0"))
3945 (const_string "1")))
3947 (if_then_else (eq_attr "prefix_0f" "0")
3949 (const_string "1")))])
3951 ;; Conversions between float and double.
3953 ;; These are all no-ops in the model used for the 80387.
3954 ;; So just emit moves.
3956 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3958 [(set (match_operand:DF 0 "push_operand")
3959 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3961 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3962 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3965 [(set (match_operand:XF 0 "push_operand")
3966 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3968 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3969 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3970 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3972 (define_expand "extendsfdf2"
3973 [(set (match_operand:DF 0 "nonimmediate_operand")
3974 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3975 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3977 /* ??? Needed for compress_float_constant since all fp constants
3978 are TARGET_LEGITIMATE_CONSTANT_P. */
3979 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3981 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3982 && standard_80387_constant_p (operands[1]) > 0)
3984 operands[1] = simplify_const_unary_operation
3985 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3986 emit_move_insn_1 (operands[0], operands[1]);
3989 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3993 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3995 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3997 We do the conversion post reload to avoid producing of 128bit spills
3998 that might lead to ICE on 32bit target. The sequence unlikely combine
4001 [(set (match_operand:DF 0 "register_operand")
4003 (match_operand:SF 1 "nonimmediate_operand")))]
4004 "TARGET_USE_VECTOR_FP_CONVERTS
4005 && optimize_insn_for_speed_p ()
4006 && reload_completed && SSE_REG_P (operands[0])"
4011 (parallel [(const_int 0) (const_int 1)]))))]
4013 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4014 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4015 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4016 Try to avoid move when unpacking can be done in source. */
4017 if (REG_P (operands[1]))
4019 /* If it is unsafe to overwrite upper half of source, we need
4020 to move to destination and unpack there. */
4021 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4022 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4023 && true_regnum (operands[0]) != true_regnum (operands[1]))
4025 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4026 emit_move_insn (tmp, operands[1]);
4029 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4030 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4034 emit_insn (gen_vec_setv4sf_0 (operands[3],
4035 CONST0_RTX (V4SFmode), operands[1]));
4038 ;; It's more profitable to split and then extend in the same register.
4040 [(set (match_operand:DF 0 "register_operand")
4042 (match_operand:SF 1 "memory_operand")))]
4043 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4044 && optimize_insn_for_speed_p ()
4045 && SSE_REG_P (operands[0])"
4046 [(set (match_dup 2) (match_dup 1))
4047 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4048 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4050 (define_insn "*extendsfdf2_mixed"
4051 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4053 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4054 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4056 switch (which_alternative)
4060 return output_387_reg_move (insn, operands);
4063 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4069 [(set_attr "type" "fmov,fmov,ssecvt")
4070 (set_attr "prefix" "orig,orig,maybe_vex")
4071 (set_attr "mode" "SF,XF,DF")])
4073 (define_insn "*extendsfdf2_sse"
4074 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4075 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4076 "TARGET_SSE2 && TARGET_SSE_MATH"
4077 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4078 [(set_attr "type" "ssecvt")
4079 (set_attr "prefix" "maybe_vex")
4080 (set_attr "mode" "DF")])
4082 (define_insn "*extendsfdf2_i387"
4083 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4084 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4086 "* return output_387_reg_move (insn, operands);"
4087 [(set_attr "type" "fmov")
4088 (set_attr "mode" "SF,XF")])
4090 (define_expand "extend<mode>xf2"
4091 [(set (match_operand:XF 0 "nonimmediate_operand")
4092 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4095 /* ??? Needed for compress_float_constant since all fp constants
4096 are TARGET_LEGITIMATE_CONSTANT_P. */
4097 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4099 if (standard_80387_constant_p (operands[1]) > 0)
4101 operands[1] = simplify_const_unary_operation
4102 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4103 emit_move_insn_1 (operands[0], operands[1]);
4106 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4110 (define_insn "*extend<mode>xf2_i387"
4111 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4113 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4115 "* return output_387_reg_move (insn, operands);"
4116 [(set_attr "type" "fmov")
4117 (set_attr "mode" "<MODE>,XF")])
4119 ;; %%% This seems bad bad news.
4120 ;; This cannot output into an f-reg because there is no way to be sure
4121 ;; of truncating in that case. Otherwise this is just like a simple move
4122 ;; insn. So we pretend we can output to a reg in order to get better
4123 ;; register preferencing, but we really use a stack slot.
4125 ;; Conversion from DFmode to SFmode.
4127 (define_expand "truncdfsf2"
4128 [(set (match_operand:SF 0 "nonimmediate_operand")
4130 (match_operand:DF 1 "nonimmediate_operand")))]
4131 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4133 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4135 else if (flag_unsafe_math_optimizations)
4139 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4140 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4145 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4147 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4149 We do the conversion post reload to avoid producing of 128bit spills
4150 that might lead to ICE on 32bit target. The sequence unlikely combine
4153 [(set (match_operand:SF 0 "register_operand")
4155 (match_operand:DF 1 "nonimmediate_operand")))]
4156 "TARGET_USE_VECTOR_FP_CONVERTS
4157 && optimize_insn_for_speed_p ()
4158 && reload_completed && SSE_REG_P (operands[0])"
4161 (float_truncate:V2SF
4165 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4166 operands[3] = CONST0_RTX (V2SFmode);
4167 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4168 /* Use movsd for loading from memory, unpcklpd for registers.
4169 Try to avoid move when unpacking can be done in source, or SSE3
4170 movddup is available. */
4171 if (REG_P (operands[1]))
4174 && true_regnum (operands[0]) != true_regnum (operands[1])
4175 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4176 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4178 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4179 emit_move_insn (tmp, operands[1]);
4182 else if (!TARGET_SSE3)
4183 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4184 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4187 emit_insn (gen_sse2_loadlpd (operands[4],
4188 CONST0_RTX (V2DFmode), operands[1]));
4191 ;; It's more profitable to split and then extend in the same register.
4193 [(set (match_operand:SF 0 "register_operand")
4195 (match_operand:DF 1 "memory_operand")))]
4196 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4197 && optimize_insn_for_speed_p ()
4198 && SSE_REG_P (operands[0])"
4199 [(set (match_dup 2) (match_dup 1))
4200 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4201 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4203 (define_expand "truncdfsf2_with_temp"
4204 [(parallel [(set (match_operand:SF 0)
4205 (float_truncate:SF (match_operand:DF 1)))
4206 (clobber (match_operand:SF 2))])])
4208 (define_insn "*truncdfsf_fast_mixed"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4212 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 switch (which_alternative)
4217 return output_387_reg_move (insn, operands);
4219 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4224 [(set_attr "type" "fmov,ssecvt")
4225 (set_attr "prefix" "orig,maybe_vex")
4226 (set_attr "mode" "SF")])
4228 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4229 ;; because nothing we do here is unsafe.
4230 (define_insn "*truncdfsf_fast_sse"
4231 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4233 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4234 "TARGET_SSE2 && TARGET_SSE_MATH"
4235 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4236 [(set_attr "type" "ssecvt")
4237 (set_attr "prefix" "maybe_vex")
4238 (set_attr "mode" "SF")])
4240 (define_insn "*truncdfsf_fast_i387"
4241 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4243 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4244 "TARGET_80387 && flag_unsafe_math_optimizations"
4245 "* return output_387_reg_move (insn, operands);"
4246 [(set_attr "type" "fmov")
4247 (set_attr "mode" "SF")])
4249 (define_insn "*truncdfsf_mixed"
4250 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4252 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4253 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4254 "TARGET_MIX_SSE_I387"
4256 switch (which_alternative)
4259 return output_387_reg_move (insn, operands);
4261 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4267 [(set_attr "isa" "*,sse2,*,*,*")
4268 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4269 (set_attr "unit" "*,*,i387,i387,i387")
4270 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4271 (set_attr "mode" "SF")])
4273 (define_insn "*truncdfsf_i387"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4276 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4280 switch (which_alternative)
4283 return output_387_reg_move (insn, operands);
4289 [(set_attr "type" "fmov,multi,multi,multi")
4290 (set_attr "unit" "*,i387,i387,i387")
4291 (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4296 (match_operand:DF 1 "register_operand" "f")))]
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4305 [(set (match_operand:SF 0 "register_operand")
4307 (match_operand:DF 1 "fp_register_operand")))
4308 (clobber (match_operand 2))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4312 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4314 ;; Conversion from XFmode to {SF,DF}mode
4316 (define_expand "truncxf<mode>2"
4317 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4318 (float_truncate:MODEF
4319 (match_operand:XF 1 "register_operand")))
4320 (clobber (match_dup 2))])]
4323 if (flag_unsafe_math_optimizations)
4325 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4326 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4327 if (reg != operands[0])
4328 emit_move_insn (operands[0], reg);
4332 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4335 (define_insn "*truncxfsf2_mixed"
4336 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4338 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4339 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4342 gcc_assert (!which_alternative);
4343 return output_387_reg_move (insn, operands);
4345 [(set_attr "type" "fmov,multi,multi,multi")
4346 (set_attr "unit" "*,i387,i387,i387")
4347 (set_attr "mode" "SF")])
4349 (define_insn "*truncxfdf2_mixed"
4350 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4352 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4353 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4356 gcc_assert (!which_alternative);
4357 return output_387_reg_move (insn, operands);
4359 [(set_attr "isa" "*,*,sse2,*")
4360 (set_attr "type" "fmov,multi,multi,multi")
4361 (set_attr "unit" "*,i387,i387,i387")
4362 (set_attr "mode" "DF")])
4364 (define_insn "truncxf<mode>2_i387_noop"
4365 [(set (match_operand:MODEF 0 "register_operand" "=f")
4366 (float_truncate:MODEF
4367 (match_operand:XF 1 "register_operand" "f")))]
4368 "TARGET_80387 && flag_unsafe_math_optimizations"
4369 "* return output_387_reg_move (insn, operands);"
4370 [(set_attr "type" "fmov")
4371 (set_attr "mode" "<MODE>")])
4373 (define_insn "*truncxf<mode>2_i387"
4374 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4375 (float_truncate:MODEF
4376 (match_operand:XF 1 "register_operand" "f")))]
4378 "* return output_387_reg_move (insn, operands);"
4379 [(set_attr "type" "fmov")
4380 (set_attr "mode" "<MODE>")])
4383 [(set (match_operand:MODEF 0 "register_operand")
4384 (float_truncate:MODEF
4385 (match_operand:XF 1 "register_operand")))
4386 (clobber (match_operand:MODEF 2 "memory_operand"))]
4387 "TARGET_80387 && reload_completed"
4388 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4389 (set (match_dup 0) (match_dup 2))])
4392 [(set (match_operand:MODEF 0 "memory_operand")
4393 (float_truncate:MODEF
4394 (match_operand:XF 1 "register_operand")))
4395 (clobber (match_operand:MODEF 2 "memory_operand"))]
4397 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4399 ;; Signed conversion to DImode.
4401 (define_expand "fix_truncxfdi2"
4402 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4403 (fix:DI (match_operand:XF 1 "register_operand")))
4404 (clobber (reg:CC FLAGS_REG))])]
4409 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4414 (define_expand "fix_trunc<mode>di2"
4415 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4416 (fix:DI (match_operand:MODEF 1 "register_operand")))
4417 (clobber (reg:CC FLAGS_REG))])]
4418 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4421 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4423 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4426 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4428 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4429 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4430 if (out != operands[0])
4431 emit_move_insn (operands[0], out);
4436 ;; Signed conversion to SImode.
4438 (define_expand "fix_truncxfsi2"
4439 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4440 (fix:SI (match_operand:XF 1 "register_operand")))
4441 (clobber (reg:CC FLAGS_REG))])]
4446 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4451 (define_expand "fix_trunc<mode>si2"
4452 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4453 (fix:SI (match_operand:MODEF 1 "register_operand")))
4454 (clobber (reg:CC FLAGS_REG))])]
4455 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4458 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4460 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4463 if (SSE_FLOAT_MODE_P (<MODE>mode))
4465 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4466 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4467 if (out != operands[0])
4468 emit_move_insn (operands[0], out);
4473 ;; Signed conversion to HImode.
4475 (define_expand "fix_trunc<mode>hi2"
4476 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4477 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4478 (clobber (reg:CC FLAGS_REG))])]
4480 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4484 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4489 ;; Unsigned conversion to SImode.
4491 (define_expand "fixuns_trunc<mode>si2"
4493 [(set (match_operand:SI 0 "register_operand")
4495 (match_operand:MODEF 1 "nonimmediate_operand")))
4497 (clobber (match_scratch:<ssevecmode> 3))
4498 (clobber (match_scratch:<ssevecmode> 4))])]
4499 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4501 machine_mode mode = <MODE>mode;
4502 machine_mode vecmode = <ssevecmode>mode;
4503 REAL_VALUE_TYPE TWO31r;
4506 if (optimize_insn_for_size_p ())
4509 real_ldexp (&TWO31r, &dconst1, 31);
4510 two31 = const_double_from_real_value (TWO31r, mode);
4511 two31 = ix86_build_const_vector (vecmode, true, two31);
4512 operands[2] = force_reg (vecmode, two31);
4515 (define_insn_and_split "*fixuns_trunc<mode>_1"
4516 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4518 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4519 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4520 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4521 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4522 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4523 && optimize_function_for_speed_p (cfun)"
4525 "&& reload_completed"
4528 ix86_split_convert_uns_si_sse (operands);
4532 ;; Unsigned conversion to HImode.
4533 ;; Without these patterns, we'll try the unsigned SI conversion which
4534 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4536 (define_expand "fixuns_trunc<mode>hi2"
4538 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4539 (set (match_operand:HI 0 "nonimmediate_operand")
4540 (subreg:HI (match_dup 2) 0))]
4541 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4542 "operands[2] = gen_reg_rtx (SImode);")
4544 ;; When SSE is available, it is always faster to use it!
4545 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4546 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4547 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4548 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4549 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4550 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "sseicvt")
4552 (set_attr "prefix" "maybe_vex")
4553 (set (attr "prefix_rex")
4555 (match_test "<SWI48:MODE>mode == DImode")
4557 (const_string "*")))
4558 (set_attr "mode" "<MODEF:MODE>")
4559 (set_attr "athlon_decode" "double,vector")
4560 (set_attr "amdfam10_decode" "double,double")
4561 (set_attr "bdver1_decode" "double,double")])
4563 ;; Avoid vector decoded forms of the instruction.
4565 [(match_scratch:MODEF 2 "x")
4566 (set (match_operand:SWI48 0 "register_operand")
4567 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4568 "TARGET_AVOID_VECTOR_DECODE
4569 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4570 && optimize_insn_for_speed_p ()"
4571 [(set (match_dup 2) (match_dup 1))
4572 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4574 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4575 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4576 (fix:SWI248x (match_operand 1 "register_operand")))]
4577 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4580 && (TARGET_64BIT || <MODE>mode != DImode))
4582 && can_create_pseudo_p ()"
4587 if (memory_operand (operands[0], VOIDmode))
4588 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4591 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4592 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4598 [(set_attr "type" "fisttp")
4599 (set_attr "mode" "<MODE>")])
4601 (define_insn "fix_trunc<mode>_i387_fisttp"
4602 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4603 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4604 (clobber (match_scratch:XF 2 "=&1f"))]
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && (TARGET_64BIT || <MODE>mode != DImode))
4609 && TARGET_SSE_MATH)"
4610 "* return output_fix_trunc (insn, operands, true);"
4611 [(set_attr "type" "fisttp")
4612 (set_attr "mode" "<MODE>")])
4614 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4615 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4616 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4617 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4618 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4619 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4621 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4622 && (TARGET_64BIT || <MODE>mode != DImode))
4623 && TARGET_SSE_MATH)"
4625 [(set_attr "type" "fisttp")
4626 (set_attr "mode" "<MODE>")])
4629 [(set (match_operand:SWI248x 0 "register_operand")
4630 (fix:SWI248x (match_operand 1 "register_operand")))
4631 (clobber (match_operand:SWI248x 2 "memory_operand"))
4632 (clobber (match_scratch 3))]
4634 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4635 (clobber (match_dup 3))])
4636 (set (match_dup 0) (match_dup 2))])
4639 [(set (match_operand:SWI248x 0 "memory_operand")
4640 (fix:SWI248x (match_operand 1 "register_operand")))
4641 (clobber (match_operand:SWI248x 2 "memory_operand"))
4642 (clobber (match_scratch 3))]
4644 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4645 (clobber (match_dup 3))])])
4647 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4648 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4649 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4650 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4651 ;; function in i386.c.
4652 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4653 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4654 (fix:SWI248x (match_operand 1 "register_operand")))
4655 (clobber (reg:CC FLAGS_REG))]
4656 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4658 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4659 && (TARGET_64BIT || <MODE>mode != DImode))
4660 && can_create_pseudo_p ()"
4665 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4667 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4668 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4669 if (memory_operand (operands[0], VOIDmode))
4670 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4671 operands[2], operands[3]));
4674 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4675 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4676 operands[2], operands[3],
4681 [(set_attr "type" "fistp")
4682 (set_attr "i387_cw" "trunc")
4683 (set_attr "mode" "<MODE>")])
4685 (define_insn "fix_truncdi_i387"
4686 [(set (match_operand:DI 0 "memory_operand" "=m")
4687 (fix:DI (match_operand 1 "register_operand" "f")))
4688 (use (match_operand:HI 2 "memory_operand" "m"))
4689 (use (match_operand:HI 3 "memory_operand" "m"))
4690 (clobber (match_scratch:XF 4 "=&1f"))]
4691 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4693 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4694 "* return output_fix_trunc (insn, operands, false);"
4695 [(set_attr "type" "fistp")
4696 (set_attr "i387_cw" "trunc")
4697 (set_attr "mode" "DI")])
4699 (define_insn "fix_truncdi_i387_with_temp"
4700 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4701 (fix:DI (match_operand 1 "register_operand" "f,f")))
4702 (use (match_operand:HI 2 "memory_operand" "m,m"))
4703 (use (match_operand:HI 3 "memory_operand" "m,m"))
4704 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4705 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4706 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4708 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4710 [(set_attr "type" "fistp")
4711 (set_attr "i387_cw" "trunc")
4712 (set_attr "mode" "DI")])
4715 [(set (match_operand:DI 0 "register_operand")
4716 (fix:DI (match_operand 1 "register_operand")))
4717 (use (match_operand:HI 2 "memory_operand"))
4718 (use (match_operand:HI 3 "memory_operand"))
4719 (clobber (match_operand:DI 4 "memory_operand"))
4720 (clobber (match_scratch 5))]
4722 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4725 (clobber (match_dup 5))])
4726 (set (match_dup 0) (match_dup 4))])
4729 [(set (match_operand:DI 0 "memory_operand")
4730 (fix:DI (match_operand 1 "register_operand")))
4731 (use (match_operand:HI 2 "memory_operand"))
4732 (use (match_operand:HI 3 "memory_operand"))
4733 (clobber (match_operand:DI 4 "memory_operand"))
4734 (clobber (match_scratch 5))]
4736 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4739 (clobber (match_dup 5))])])
4741 (define_insn "fix_trunc<mode>_i387"
4742 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4743 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4744 (use (match_operand:HI 2 "memory_operand" "m"))
4745 (use (match_operand:HI 3 "memory_operand" "m"))]
4746 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4748 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4749 "* return output_fix_trunc (insn, operands, false);"
4750 [(set_attr "type" "fistp")
4751 (set_attr "i387_cw" "trunc")
4752 (set_attr "mode" "<MODE>")])
4754 (define_insn "fix_trunc<mode>_i387_with_temp"
4755 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4756 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4757 (use (match_operand:HI 2 "memory_operand" "m,m"))
4758 (use (match_operand:HI 3 "memory_operand" "m,m"))
4759 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4760 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4762 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4764 [(set_attr "type" "fistp")
4765 (set_attr "i387_cw" "trunc")
4766 (set_attr "mode" "<MODE>")])
4769 [(set (match_operand:SWI24 0 "register_operand")
4770 (fix:SWI24 (match_operand 1 "register_operand")))
4771 (use (match_operand:HI 2 "memory_operand"))
4772 (use (match_operand:HI 3 "memory_operand"))
4773 (clobber (match_operand:SWI24 4 "memory_operand"))]
4775 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4777 (use (match_dup 3))])
4778 (set (match_dup 0) (match_dup 4))])
4781 [(set (match_operand:SWI24 0 "memory_operand")
4782 (fix:SWI24 (match_operand 1 "register_operand")))
4783 (use (match_operand:HI 2 "memory_operand"))
4784 (use (match_operand:HI 3 "memory_operand"))
4785 (clobber (match_operand:SWI24 4 "memory_operand"))]
4787 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4789 (use (match_dup 3))])])
4791 (define_insn "x86_fnstcw_1"
4792 [(set (match_operand:HI 0 "memory_operand" "=m")
4793 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4796 [(set (attr "length")
4797 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4798 (set_attr "mode" "HI")
4799 (set_attr "unit" "i387")
4800 (set_attr "bdver1_decode" "vector")])
4802 (define_insn "x86_fldcw_1"
4803 [(set (reg:HI FPCR_REG)
4804 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4807 [(set (attr "length")
4808 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4809 (set_attr "mode" "HI")
4810 (set_attr "unit" "i387")
4811 (set_attr "athlon_decode" "vector")
4812 (set_attr "amdfam10_decode" "vector")
4813 (set_attr "bdver1_decode" "vector")])
4815 ;; Conversion between fixed point and floating point.
4817 ;; Even though we only accept memory inputs, the backend _really_
4818 ;; wants to be able to do this between registers. Thankfully, LRA
4819 ;; will fix this up for us during register allocation.
4821 (define_insn "floathi<mode>2"
4822 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4823 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4826 || TARGET_MIX_SSE_I387)"
4828 [(set_attr "type" "fmov")
4829 (set_attr "mode" "<MODE>")
4830 (set_attr "fp_int_src" "true")])
4832 (define_insn "float<SWI48x:mode>xf2"
4833 [(set (match_operand:XF 0 "register_operand" "=f")
4834 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4837 [(set_attr "type" "fmov")
4838 (set_attr "mode" "XF")
4839 (set_attr "fp_int_src" "true")])
4841 (define_expand "float<SWI48:mode><MODEF:mode>2"
4842 [(set (match_operand:MODEF 0 "register_operand")
4843 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4844 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4846 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4847 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4849 rtx reg = gen_reg_rtx (XFmode);
4850 rtx (*insn)(rtx, rtx);
4852 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4854 if (<MODEF:MODE>mode == SFmode)
4855 insn = gen_truncxfsf2;
4856 else if (<MODEF:MODE>mode == DFmode)
4857 insn = gen_truncxfdf2;
4861 emit_insn (insn (operands[0], reg));
4866 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4869 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4870 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4873 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4875 [(set_attr "type" "fmov,sseicvt,sseicvt")
4876 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4877 (set_attr "mode" "<MODEF:MODE>")
4878 (set (attr "prefix_rex")
4880 (and (eq_attr "prefix" "maybe_vex")
4881 (match_test "<SWI48:MODE>mode == DImode"))
4883 (const_string "*")))
4884 (set_attr "unit" "i387,*,*")
4885 (set_attr "athlon_decode" "*,double,direct")
4886 (set_attr "amdfam10_decode" "*,vector,double")
4887 (set_attr "bdver1_decode" "*,double,direct")
4888 (set_attr "fp_int_src" "true")
4889 (set (attr "enabled")
4890 (cond [(eq_attr "alternative" "0")
4891 (symbol_ref "TARGET_MIX_SSE_I387
4892 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4895 (symbol_ref "true")))
4896 (set (attr "preferred_for_speed")
4897 (cond [(eq_attr "alternative" "1")
4898 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4899 (symbol_ref "true")))])
4901 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4902 [(set (match_operand:MODEF 0 "register_operand" "=f")
4903 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4904 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4906 [(set_attr "type" "fmov")
4907 (set_attr "mode" "<MODEF:MODE>")
4908 (set_attr "fp_int_src" "true")])
4910 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4911 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4912 ;; alternative in sse2_loadld.
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4916 "TARGET_SSE2 && TARGET_SSE_MATH
4917 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4918 && reload_completed && SSE_REG_P (operands[0])
4919 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4922 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4924 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4926 emit_insn (gen_sse2_loadld (operands[4],
4927 CONST0_RTX (V4SImode), operands[1]));
4929 if (<ssevecmode>mode == V4SFmode)
4930 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4932 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4936 ;; Avoid partial SSE register dependency stalls
4938 [(set (match_operand:MODEF 0 "register_operand")
4939 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4940 "TARGET_SSE2 && TARGET_SSE_MATH
4941 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4942 && optimize_function_for_speed_p (cfun)
4943 && reload_completed && SSE_REG_P (operands[0])"
4946 const machine_mode vmode = <MODEF:ssevecmode>mode;
4947 const machine_mode mode = <MODEF:MODE>mode;
4948 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4950 emit_move_insn (op0, CONST0_RTX (vmode));
4952 t = gen_rtx_FLOAT (mode, operands[1]);
4953 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4954 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4955 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4959 ;; Break partial reg stall for cvtsd2ss.
4962 [(set (match_operand:SF 0 "register_operand")
4964 (match_operand:DF 1 "nonimmediate_operand")))]
4965 "TARGET_SSE2 && TARGET_SSE_MATH
4966 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4967 && optimize_function_for_speed_p (cfun)
4968 && SSE_REG_P (operands[0])
4969 && (!SSE_REG_P (operands[1])
4970 || REGNO (operands[0]) != REGNO (operands[1]))"
4974 (float_truncate:V2SF
4979 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4981 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4983 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4986 ;; Break partial reg stall for cvtss2sd.
4989 [(set (match_operand:DF 0 "register_operand")
4991 (match_operand:SF 1 "nonimmediate_operand")))]
4992 "TARGET_SSE2 && TARGET_SSE_MATH
4993 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4994 && optimize_function_for_speed_p (cfun)
4995 && SSE_REG_P (operands[0])
4996 && (!SSE_REG_P (operands[1])
4997 || REGNO (operands[0]) != REGNO (operands[1]))"
5003 (parallel [(const_int 0) (const_int 1)])))
5007 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5009 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5011 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5014 ;; Avoid store forwarding (partial memory) stall penalty
5015 ;; by passing DImode value through XMM registers. */
5017 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5018 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5020 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5021 (clobber (match_scratch:V4SI 3 "=X,x"))
5022 (clobber (match_scratch:V4SI 4 "=X,x"))
5023 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
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)"
5028 [(set_attr "type" "multi")
5029 (set_attr "mode" "<X87MODEF:MODE>")
5030 (set_attr "unit" "i387")
5031 (set_attr "fp_int_src" "true")])
5034 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5035 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5036 (clobber (match_scratch:V4SI 3))
5037 (clobber (match_scratch:V4SI 4))
5038 (clobber (match_operand:DI 2 "memory_operand"))]
5039 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5040 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5041 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5042 && reload_completed"
5043 [(set (match_dup 2) (match_dup 3))
5044 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5046 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5047 Assemble the 64-bit DImode value in an xmm register. */
5048 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5049 gen_rtx_SUBREG (SImode, operands[1], 0)));
5050 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5051 gen_rtx_SUBREG (SImode, operands[1], 4)));
5052 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5055 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5059 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5060 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5061 (clobber (match_scratch:V4SI 3))
5062 (clobber (match_scratch:V4SI 4))
5063 (clobber (match_operand:DI 2 "memory_operand"))]
5064 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5065 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5066 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5067 && reload_completed"
5068 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5070 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5071 [(set (match_operand:MODEF 0 "register_operand")
5072 (unsigned_float:MODEF
5073 (match_operand:SWI12 1 "nonimmediate_operand")))]
5075 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5077 operands[1] = convert_to_mode (SImode, operands[1], 1);
5078 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5082 ;; Avoid store forwarding (partial memory) stall penalty by extending
5083 ;; SImode value to DImode through XMM register instead of pushing two
5084 ;; SImode values to stack. Also note that fild loads from memory only.
5086 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5087 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5088 (unsigned_float:X87MODEF
5089 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5090 (clobber (match_scratch:DI 3 "=x"))
5091 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5093 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5094 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5096 "&& reload_completed"
5097 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5098 (set (match_dup 2) (match_dup 3))
5100 (float:X87MODEF (match_dup 2)))]
5102 [(set_attr "type" "multi")
5103 (set_attr "mode" "<MODE>")])
5105 (define_expand "floatunssi<mode>2"
5107 [(set (match_operand:X87MODEF 0 "register_operand")
5108 (unsigned_float:X87MODEF
5109 (match_operand:SI 1 "nonimmediate_operand")))
5110 (clobber (match_scratch:DI 3))
5111 (clobber (match_dup 2))])]
5113 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5114 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5115 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5117 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5119 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5123 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5126 (define_expand "floatunsdisf2"
5127 [(use (match_operand:SF 0 "register_operand"))
5128 (use (match_operand:DI 1 "nonimmediate_operand"))]
5129 "TARGET_64BIT && TARGET_SSE_MATH"
5130 "x86_emit_floatuns (operands); DONE;")
5132 (define_expand "floatunsdidf2"
5133 [(use (match_operand:DF 0 "register_operand"))
5134 (use (match_operand:DI 1 "nonimmediate_operand"))]
5135 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5136 && TARGET_SSE2 && TARGET_SSE_MATH"
5139 x86_emit_floatuns (operands);
5141 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5145 ;; Load effective address instructions
5147 (define_insn_and_split "*lea<mode>"
5148 [(set (match_operand:SWI48 0 "register_operand" "=r")
5149 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5152 if (SImode_address_operand (operands[1], VOIDmode))
5154 gcc_assert (TARGET_64BIT);
5155 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5158 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5160 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5163 machine_mode mode = <MODE>mode;
5166 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5167 change operands[] array behind our back. */
5168 pat = PATTERN (curr_insn);
5170 operands[0] = SET_DEST (pat);
5171 operands[1] = SET_SRC (pat);
5173 /* Emit all operations in SImode for zero-extended addresses. */
5174 if (SImode_address_operand (operands[1], VOIDmode))
5177 ix86_split_lea_for_addr (curr_insn, operands, mode);
5179 /* Zero-extend return register to DImode for zero-extended addresses. */
5180 if (mode != <MODE>mode)
5181 emit_insn (gen_zero_extendsidi2
5182 (operands[0], gen_lowpart (mode, operands[0])));
5186 [(set_attr "type" "lea")
5189 (match_operand 1 "SImode_address_operand")
5191 (const_string "<MODE>")))])
5195 (define_expand "add<mode>3"
5196 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5197 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5198 (match_operand:SDWIM 2 "<general_operand>")))]
5200 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5202 (define_insn_and_split "*add<dwi>3_doubleword"
5203 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5205 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5206 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5207 (clobber (reg:CC FLAGS_REG))]
5208 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5211 [(parallel [(set (reg:CC FLAGS_REG)
5212 (unspec:CC [(match_dup 1) (match_dup 2)]
5215 (plus:DWIH (match_dup 1) (match_dup 2)))])
5216 (parallel [(set (match_dup 3)
5220 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5222 (clobber (reg:CC FLAGS_REG))])]
5223 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5225 (define_insn "*add<mode>3_cc"
5226 [(set (reg:CC FLAGS_REG)
5228 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5229 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5231 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5232 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5233 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5234 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5235 [(set_attr "type" "alu")
5236 (set_attr "mode" "<MODE>")])
5238 (define_insn "addqi3_cc"
5239 [(set (reg:CC FLAGS_REG)
5241 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5242 (match_operand:QI 2 "general_operand" "qn,qm")]
5244 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5245 (plus:QI (match_dup 1) (match_dup 2)))]
5246 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5247 "add{b}\t{%2, %0|%0, %2}"
5248 [(set_attr "type" "alu")
5249 (set_attr "mode" "QI")])
5251 (define_insn "*add<mode>_1"
5252 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5254 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5255 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5256 (clobber (reg:CC FLAGS_REG))]
5257 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5259 switch (get_attr_type (insn))
5265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266 if (operands[2] == const1_rtx)
5267 return "inc{<imodesuffix>}\t%0";
5270 gcc_assert (operands[2] == constm1_rtx);
5271 return "dec{<imodesuffix>}\t%0";
5275 /* For most processors, ADD is faster than LEA. This alternative
5276 was added to use ADD as much as possible. */
5277 if (which_alternative == 2)
5278 std::swap (operands[1], operands[2]);
5280 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5281 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5282 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5284 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5288 (cond [(eq_attr "alternative" "3")
5289 (const_string "lea")
5290 (match_operand:SWI48 2 "incdec_operand")
5291 (const_string "incdec")
5293 (const_string "alu")))
5294 (set (attr "length_immediate")
5296 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5298 (const_string "*")))
5299 (set_attr "mode" "<MODE>")])
5301 ;; It may seem that nonimmediate operand is proper one for operand 1.
5302 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5303 ;; we take care in ix86_binary_operator_ok to not allow two memory
5304 ;; operands so proper swapping will be done in reload. This allow
5305 ;; patterns constructed from addsi_1 to match.
5307 (define_insn "addsi_1_zext"
5308 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5310 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5311 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5312 (clobber (reg:CC FLAGS_REG))]
5313 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5315 switch (get_attr_type (insn))
5321 if (operands[2] == const1_rtx)
5322 return "inc{l}\t%k0";
5325 gcc_assert (operands[2] == constm1_rtx);
5326 return "dec{l}\t%k0";
5330 /* For most processors, ADD is faster than LEA. This alternative
5331 was added to use ADD as much as possible. */
5332 if (which_alternative == 1)
5333 std::swap (operands[1], operands[2]);
5335 if (x86_maybe_negate_const_int (&operands[2], SImode))
5336 return "sub{l}\t{%2, %k0|%k0, %2}";
5338 return "add{l}\t{%2, %k0|%k0, %2}";
5342 (cond [(eq_attr "alternative" "2")
5343 (const_string "lea")
5344 (match_operand:SI 2 "incdec_operand")
5345 (const_string "incdec")
5347 (const_string "alu")))
5348 (set (attr "length_immediate")
5350 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5352 (const_string "*")))
5353 (set_attr "mode" "SI")])
5355 (define_insn "*addhi_1"
5356 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5357 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5358 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5359 (clobber (reg:CC FLAGS_REG))]
5360 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5362 switch (get_attr_type (insn))
5368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369 if (operands[2] == const1_rtx)
5370 return "inc{w}\t%0";
5373 gcc_assert (operands[2] == constm1_rtx);
5374 return "dec{w}\t%0";
5378 /* For most processors, ADD is faster than LEA. This alternative
5379 was added to use ADD as much as possible. */
5380 if (which_alternative == 2)
5381 std::swap (operands[1], operands[2]);
5383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5384 if (x86_maybe_negate_const_int (&operands[2], HImode))
5385 return "sub{w}\t{%2, %0|%0, %2}";
5387 return "add{w}\t{%2, %0|%0, %2}";
5391 (cond [(eq_attr "alternative" "3")
5392 (const_string "lea")
5393 (match_operand:HI 2 "incdec_operand")
5394 (const_string "incdec")
5396 (const_string "alu")))
5397 (set (attr "length_immediate")
5399 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5401 (const_string "*")))
5402 (set_attr "mode" "HI,HI,HI,SI")])
5404 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5405 (define_insn "*addqi_1"
5406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5407 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5408 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5409 (clobber (reg:CC FLAGS_REG))]
5410 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5412 bool widen = (which_alternative == 3 || which_alternative == 4);
5414 switch (get_attr_type (insn))
5420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5421 if (operands[2] == const1_rtx)
5422 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5425 gcc_assert (operands[2] == constm1_rtx);
5426 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5430 /* For most processors, ADD is faster than LEA. These alternatives
5431 were added to use ADD as much as possible. */
5432 if (which_alternative == 2 || which_alternative == 4)
5433 std::swap (operands[1], operands[2]);
5435 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5436 if (x86_maybe_negate_const_int (&operands[2], QImode))
5439 return "sub{l}\t{%2, %k0|%k0, %2}";
5441 return "sub{b}\t{%2, %0|%0, %2}";
5444 return "add{l}\t{%k2, %k0|%k0, %k2}";
5446 return "add{b}\t{%2, %0|%0, %2}";
5450 (cond [(eq_attr "alternative" "5")
5451 (const_string "lea")
5452 (match_operand:QI 2 "incdec_operand")
5453 (const_string "incdec")
5455 (const_string "alu")))
5456 (set (attr "length_immediate")
5458 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5460 (const_string "*")))
5461 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5463 (define_insn "*addqi_1_slp"
5464 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5465 (plus:QI (match_dup 0)
5466 (match_operand:QI 1 "general_operand" "qn,qm")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5469 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5471 switch (get_attr_type (insn))
5474 if (operands[1] == const1_rtx)
5475 return "inc{b}\t%0";
5478 gcc_assert (operands[1] == constm1_rtx);
5479 return "dec{b}\t%0";
5483 if (x86_maybe_negate_const_int (&operands[1], QImode))
5484 return "sub{b}\t{%1, %0|%0, %1}";
5486 return "add{b}\t{%1, %0|%0, %1}";
5490 (if_then_else (match_operand:QI 1 "incdec_operand")
5491 (const_string "incdec")
5492 (const_string "alu1")))
5493 (set (attr "memory")
5494 (if_then_else (match_operand 1 "memory_operand")
5495 (const_string "load")
5496 (const_string "none")))
5497 (set_attr "mode" "QI")])
5499 ;; Split non destructive adds if we cannot use lea.
5501 [(set (match_operand:SWI48 0 "register_operand")
5502 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5503 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5504 (clobber (reg:CC FLAGS_REG))]
5505 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5506 [(set (match_dup 0) (match_dup 1))
5507 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5508 (clobber (reg:CC FLAGS_REG))])])
5510 ;; Convert add to the lea pattern to avoid flags dependency.
5512 [(set (match_operand:SWI 0 "register_operand")
5513 (plus:SWI (match_operand:SWI 1 "register_operand")
5514 (match_operand:SWI 2 "<nonmemory_operand>")))
5515 (clobber (reg:CC FLAGS_REG))]
5516 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5519 machine_mode mode = <MODE>mode;
5522 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5525 operands[0] = gen_lowpart (mode, operands[0]);
5526 operands[1] = gen_lowpart (mode, operands[1]);
5527 operands[2] = gen_lowpart (mode, operands[2]);
5530 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5532 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5536 ;; Split non destructive adds if we cannot use lea.
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))]
5544 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5545 [(set (match_dup 3) (match_dup 1))
5546 (parallel [(set (match_dup 0)
5547 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5548 (clobber (reg:CC FLAGS_REG))])]
5549 "operands[3] = gen_lowpart (SImode, operands[0]);")
5551 ;; Convert add to the lea pattern to avoid flags dependency.
5553 [(set (match_operand:DI 0 "register_operand")
5555 (plus:SI (match_operand:SI 1 "register_operand")
5556 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5557 (clobber (reg:CC FLAGS_REG))]
5558 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5560 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5562 (define_insn "*add<mode>_2"
5563 [(set (reg FLAGS_REG)
5566 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5567 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5569 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5570 (plus:SWI (match_dup 1) (match_dup 2)))]
5571 "ix86_match_ccmode (insn, CCGOCmode)
5572 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5574 switch (get_attr_type (insn))
5577 if (operands[2] == const1_rtx)
5578 return "inc{<imodesuffix>}\t%0";
5581 gcc_assert (operands[2] == constm1_rtx);
5582 return "dec{<imodesuffix>}\t%0";
5586 if (which_alternative == 2)
5587 std::swap (operands[1], operands[2]);
5589 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5590 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5591 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5593 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5597 (if_then_else (match_operand:SWI 2 "incdec_operand")
5598 (const_string "incdec")
5599 (const_string "alu")))
5600 (set (attr "length_immediate")
5602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604 (const_string "*")))
5605 (set_attr "mode" "<MODE>")])
5607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5608 (define_insn "*addsi_2_zext"
5609 [(set (reg FLAGS_REG)
5611 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5612 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5614 (set (match_operand:DI 0 "register_operand" "=r,r")
5615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5616 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5617 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5619 switch (get_attr_type (insn))
5622 if (operands[2] == const1_rtx)
5623 return "inc{l}\t%k0";
5626 gcc_assert (operands[2] == constm1_rtx);
5627 return "dec{l}\t%k0";
5631 if (which_alternative == 1)
5632 std::swap (operands[1], operands[2]);
5634 if (x86_maybe_negate_const_int (&operands[2], SImode))
5635 return "sub{l}\t{%2, %k0|%k0, %2}";
5637 return "add{l}\t{%2, %k0|%k0, %2}";
5641 (if_then_else (match_operand:SI 2 "incdec_operand")
5642 (const_string "incdec")
5643 (const_string "alu")))
5644 (set (attr "length_immediate")
5646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "*")))
5649 (set_attr "mode" "SI")])
5651 (define_insn "*add<mode>_3"
5652 [(set (reg FLAGS_REG)
5654 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5655 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5656 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5657 "ix86_match_ccmode (insn, CCZmode)
5658 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5660 switch (get_attr_type (insn))
5663 if (operands[2] == const1_rtx)
5664 return "inc{<imodesuffix>}\t%0";
5667 gcc_assert (operands[2] == constm1_rtx);
5668 return "dec{<imodesuffix>}\t%0";
5672 if (which_alternative == 1)
5673 std::swap (operands[1], operands[2]);
5675 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5677 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5679 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5683 (if_then_else (match_operand:SWI 2 "incdec_operand")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set (attr "length_immediate")
5688 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5690 (const_string "*")))
5691 (set_attr "mode" "<MODE>")])
5693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5694 (define_insn "*addsi_3_zext"
5695 [(set (reg FLAGS_REG)
5697 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5698 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5699 (set (match_operand:DI 0 "register_operand" "=r,r")
5700 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5701 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5702 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5704 switch (get_attr_type (insn))
5707 if (operands[2] == const1_rtx)
5708 return "inc{l}\t%k0";
5711 gcc_assert (operands[2] == constm1_rtx);
5712 return "dec{l}\t%k0";
5716 if (which_alternative == 1)
5717 std::swap (operands[1], operands[2]);
5719 if (x86_maybe_negate_const_int (&operands[2], SImode))
5720 return "sub{l}\t{%2, %k0|%k0, %2}";
5722 return "add{l}\t{%2, %k0|%k0, %2}";
5726 (if_then_else (match_operand:SI 2 "incdec_operand")
5727 (const_string "incdec")
5728 (const_string "alu")))
5729 (set (attr "length_immediate")
5731 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5733 (const_string "*")))
5734 (set_attr "mode" "SI")])
5736 ; For comparisons against 1, -1 and 128, we may generate better code
5737 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5738 ; is matched then. We can't accept general immediate, because for
5739 ; case of overflows, the result is messed up.
5740 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5741 ; only for comparisons not depending on it.
5743 (define_insn "*adddi_4"
5744 [(set (reg FLAGS_REG)
5746 (match_operand:DI 1 "nonimmediate_operand" "0")
5747 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5748 (clobber (match_scratch:DI 0 "=rm"))]
5750 && ix86_match_ccmode (insn, CCGCmode)"
5752 switch (get_attr_type (insn))
5755 if (operands[2] == constm1_rtx)
5756 return "inc{q}\t%0";
5759 gcc_assert (operands[2] == const1_rtx);
5760 return "dec{q}\t%0";
5764 if (x86_maybe_negate_const_int (&operands[2], DImode))
5765 return "add{q}\t{%2, %0|%0, %2}";
5767 return "sub{q}\t{%2, %0|%0, %2}";
5771 (if_then_else (match_operand:DI 2 "incdec_operand")
5772 (const_string "incdec")
5773 (const_string "alu")))
5774 (set (attr "length_immediate")
5776 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5778 (const_string "*")))
5779 (set_attr "mode" "DI")])
5781 ; For comparisons against 1, -1 and 128, we may generate better code
5782 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5783 ; is matched then. We can't accept general immediate, because for
5784 ; case of overflows, the result is messed up.
5785 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5786 ; only for comparisons not depending on it.
5788 (define_insn "*add<mode>_4"
5789 [(set (reg FLAGS_REG)
5791 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5792 (match_operand:SWI124 2 "const_int_operand" "n")))
5793 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5794 "ix86_match_ccmode (insn, CCGCmode)"
5796 switch (get_attr_type (insn))
5799 if (operands[2] == constm1_rtx)
5800 return "inc{<imodesuffix>}\t%0";
5803 gcc_assert (operands[2] == const1_rtx);
5804 return "dec{<imodesuffix>}\t%0";
5808 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5809 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5811 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5815 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5816 (const_string "incdec")
5817 (const_string "alu")))
5818 (set (attr "length_immediate")
5820 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822 (const_string "*")))
5823 (set_attr "mode" "<MODE>")])
5825 (define_insn "*add<mode>_5"
5826 [(set (reg FLAGS_REG)
5829 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5830 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5832 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5833 "ix86_match_ccmode (insn, CCGOCmode)
5834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5836 switch (get_attr_type (insn))
5839 if (operands[2] == const1_rtx)
5840 return "inc{<imodesuffix>}\t%0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{<imodesuffix>}\t%0";
5848 if (which_alternative == 1)
5849 std::swap (operands[1], operands[2]);
5851 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5852 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5859 (if_then_else (match_operand:SWI 2 "incdec_operand")
5860 (const_string "incdec")
5861 (const_string "alu")))
5862 (set (attr "length_immediate")
5864 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5866 (const_string "*")))
5867 (set_attr "mode" "<MODE>")])
5869 (define_insn "addqi_ext_1"
5870 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5875 (match_operand 1 "ext_register_operand" "0,0")
5878 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5879 (clobber (reg:CC FLAGS_REG))]
5882 switch (get_attr_type (insn))
5885 if (operands[2] == const1_rtx)
5886 return "inc{b}\t%h0";
5889 gcc_assert (operands[2] == constm1_rtx);
5890 return "dec{b}\t%h0";
5894 return "add{b}\t{%2, %h0|%h0, %2}";
5897 [(set_attr "isa" "*,nox64")
5899 (if_then_else (match_operand:QI 2 "incdec_operand")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set_attr "modrm" "1")
5903 (set_attr "mode" "QI")])
5905 (define_insn "*addqi_ext_2"
5906 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5911 (match_operand 1 "ext_register_operand" "%0")
5915 (match_operand 2 "ext_register_operand" "Q")
5918 (clobber (reg:CC FLAGS_REG))]
5920 "add{b}\t{%h2, %h0|%h0, %h2}"
5921 [(set_attr "type" "alu")
5922 (set_attr "mode" "QI")])
5924 ;; Add with jump on overflow.
5925 (define_expand "addv<mode>4"
5926 [(parallel [(set (reg:CCO FLAGS_REG)
5929 (match_operand:SWI 1 "nonimmediate_operand"))
5932 (plus:SWI (match_dup 1)
5933 (match_operand:SWI 2
5934 "<general_operand>")))))
5935 (set (match_operand:SWI 0 "register_operand")
5936 (plus:SWI (match_dup 1) (match_dup 2)))])
5937 (set (pc) (if_then_else
5938 (eq (reg:CCO FLAGS_REG) (const_int 0))
5939 (label_ref (match_operand 3))
5943 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5944 if (CONST_INT_P (operands[2]))
5945 operands[4] = operands[2];
5947 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5950 (define_insn "*addv<mode>4"
5951 [(set (reg:CCO FLAGS_REG)
5954 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5956 (match_operand:SWI 2 "<general_sext_operand>"
5959 (plus:SWI (match_dup 1) (match_dup 2)))))
5960 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5961 (plus:SWI (match_dup 1) (match_dup 2)))]
5962 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5963 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5964 [(set_attr "type" "alu")
5965 (set_attr "mode" "<MODE>")])
5967 (define_insn "*addv<mode>4_1"
5968 [(set (reg:CCO FLAGS_REG)
5971 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5972 (match_operand:<DWI> 3 "const_int_operand" "i"))
5974 (plus:SWI (match_dup 1)
5975 (match_operand:SWI 2 "x86_64_immediate_operand"
5977 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5978 (plus:SWI (match_dup 1) (match_dup 2)))]
5979 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5980 && CONST_INT_P (operands[2])
5981 && INTVAL (operands[2]) == INTVAL (operands[3])"
5982 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5983 [(set_attr "type" "alu")
5984 (set_attr "mode" "<MODE>")
5985 (set (attr "length_immediate")
5986 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5988 (match_test "<MODE_SIZE> == 8")
5990 (const_string "<MODE_SIZE>")))])
5992 ;; The lea patterns for modes less than 32 bits need to be matched by
5993 ;; several insns converted to real lea by splitters.
5995 (define_insn_and_split "*lea_general_1"
5996 [(set (match_operand 0 "register_operand" "=r")
5997 (plus (plus (match_operand 1 "index_register_operand" "l")
5998 (match_operand 2 "register_operand" "r"))
5999 (match_operand 3 "immediate_operand" "i")))]
6000 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6001 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6002 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6003 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6004 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6005 || GET_MODE (operands[3]) == VOIDmode)"
6007 "&& reload_completed"
6010 machine_mode mode = SImode;
6013 operands[0] = gen_lowpart (mode, operands[0]);
6014 operands[1] = gen_lowpart (mode, operands[1]);
6015 operands[2] = gen_lowpart (mode, operands[2]);
6016 operands[3] = gen_lowpart (mode, operands[3]);
6018 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6021 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6024 [(set_attr "type" "lea")
6025 (set_attr "mode" "SI")])
6027 (define_insn_and_split "*lea_general_2"
6028 [(set (match_operand 0 "register_operand" "=r")
6029 (plus (mult (match_operand 1 "index_register_operand" "l")
6030 (match_operand 2 "const248_operand" "n"))
6031 (match_operand 3 "nonmemory_operand" "ri")))]
6032 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6033 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6034 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6036 || GET_MODE (operands[3]) == VOIDmode)"
6038 "&& reload_completed"
6041 machine_mode mode = SImode;
6044 operands[0] = gen_lowpart (mode, operands[0]);
6045 operands[1] = gen_lowpart (mode, operands[1]);
6046 operands[3] = gen_lowpart (mode, operands[3]);
6048 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6054 [(set_attr "type" "lea")
6055 (set_attr "mode" "SI")])
6057 (define_insn_and_split "*lea_general_3"
6058 [(set (match_operand 0 "register_operand" "=r")
6059 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6060 (match_operand 2 "const248_operand" "n"))
6061 (match_operand 3 "register_operand" "r"))
6062 (match_operand 4 "immediate_operand" "i")))]
6063 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6064 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6066 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6068 "&& reload_completed"
6071 machine_mode mode = SImode;
6074 operands[0] = gen_lowpart (mode, operands[0]);
6075 operands[1] = gen_lowpart (mode, operands[1]);
6076 operands[3] = gen_lowpart (mode, operands[3]);
6077 operands[4] = gen_lowpart (mode, operands[4]);
6079 pat = gen_rtx_PLUS (mode,
6081 gen_rtx_MULT (mode, operands[1],
6086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6089 [(set_attr "type" "lea")
6090 (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_4"
6093 [(set (match_operand 0 "register_operand" "=r")
6095 (match_operand 1 "index_register_operand" "l")
6096 (match_operand 2 "const_int_operand" "n"))
6097 (match_operand 3 "const_int_operand" "n")))]
6098 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6099 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6100 || GET_MODE (operands[0]) == SImode
6101 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6102 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6103 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6104 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6105 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6107 "&& reload_completed"
6110 machine_mode mode = GET_MODE (operands[0]);
6113 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6116 operands[0] = gen_lowpart (mode, operands[0]);
6117 operands[1] = gen_lowpart (mode, operands[1]);
6120 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6122 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6123 INTVAL (operands[3]));
6125 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6128 [(set_attr "type" "lea")
6130 (if_then_else (match_operand:DI 0)
6132 (const_string "SI")))])
6134 ;; Subtract instructions
6136 (define_expand "sub<mode>3"
6137 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6138 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6139 (match_operand:SDWIM 2 "<general_operand>")))]
6141 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6143 (define_insn_and_split "*sub<dwi>3_doubleword"
6144 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6146 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6147 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6152 [(parallel [(set (reg:CC FLAGS_REG)
6153 (compare:CC (match_dup 1) (match_dup 2)))
6155 (minus:DWIH (match_dup 1) (match_dup 2)))])
6156 (parallel [(set (match_dup 3)
6160 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6162 (clobber (reg:CC FLAGS_REG))])]
6163 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6165 (define_insn "*sub<mode>_1"
6166 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6168 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6169 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6170 (clobber (reg:CC FLAGS_REG))]
6171 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6172 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6173 [(set_attr "type" "alu")
6174 (set_attr "mode" "<MODE>")])
6176 (define_insn "*subsi_1_zext"
6177 [(set (match_operand:DI 0 "register_operand" "=r")
6179 (minus:SI (match_operand:SI 1 "register_operand" "0")
6180 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6181 (clobber (reg:CC FLAGS_REG))]
6182 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6183 "sub{l}\t{%2, %k0|%k0, %2}"
6184 [(set_attr "type" "alu")
6185 (set_attr "mode" "SI")])
6187 (define_insn "*subqi_1_slp"
6188 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6189 (minus:QI (match_dup 0)
6190 (match_operand:QI 1 "general_operand" "qn,qm")))
6191 (clobber (reg:CC FLAGS_REG))]
6192 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6193 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6194 "sub{b}\t{%1, %0|%0, %1}"
6195 [(set_attr "type" "alu1")
6196 (set_attr "mode" "QI")])
6198 (define_insn "*sub<mode>_2"
6199 [(set (reg FLAGS_REG)
6202 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6203 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6205 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6206 (minus:SWI (match_dup 1) (match_dup 2)))]
6207 "ix86_match_ccmode (insn, CCGOCmode)
6208 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6209 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6210 [(set_attr "type" "alu")
6211 (set_attr "mode" "<MODE>")])
6213 (define_insn "*subsi_2_zext"
6214 [(set (reg FLAGS_REG)
6216 (minus:SI (match_operand:SI 1 "register_operand" "0")
6217 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6219 (set (match_operand:DI 0 "register_operand" "=r")
6221 (minus:SI (match_dup 1)
6223 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6224 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6225 "sub{l}\t{%2, %k0|%k0, %2}"
6226 [(set_attr "type" "alu")
6227 (set_attr "mode" "SI")])
6229 ;; Subtract with jump on overflow.
6230 (define_expand "subv<mode>4"
6231 [(parallel [(set (reg:CCO FLAGS_REG)
6232 (eq:CCO (minus:<DWI>
6234 (match_operand:SWI 1 "nonimmediate_operand"))
6237 (minus:SWI (match_dup 1)
6238 (match_operand:SWI 2
6239 "<general_operand>")))))
6240 (set (match_operand:SWI 0 "register_operand")
6241 (minus:SWI (match_dup 1) (match_dup 2)))])
6242 (set (pc) (if_then_else
6243 (eq (reg:CCO FLAGS_REG) (const_int 0))
6244 (label_ref (match_operand 3))
6248 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6249 if (CONST_INT_P (operands[2]))
6250 operands[4] = operands[2];
6252 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6255 (define_insn "*subv<mode>4"
6256 [(set (reg:CCO FLAGS_REG)
6257 (eq:CCO (minus:<DWI>
6259 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6261 (match_operand:SWI 2 "<general_sext_operand>"
6264 (minus:SWI (match_dup 1) (match_dup 2)))))
6265 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6266 (minus:SWI (match_dup 1) (match_dup 2)))]
6267 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6268 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6269 [(set_attr "type" "alu")
6270 (set_attr "mode" "<MODE>")])
6272 (define_insn "*subv<mode>4_1"
6273 [(set (reg:CCO FLAGS_REG)
6274 (eq:CCO (minus:<DWI>
6276 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6277 (match_operand:<DWI> 3 "const_int_operand" "i"))
6279 (minus:SWI (match_dup 1)
6280 (match_operand:SWI 2 "x86_64_immediate_operand"
6282 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6283 (minus:SWI (match_dup 1) (match_dup 2)))]
6284 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6285 && CONST_INT_P (operands[2])
6286 && INTVAL (operands[2]) == INTVAL (operands[3])"
6287 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6288 [(set_attr "type" "alu")
6289 (set_attr "mode" "<MODE>")
6290 (set (attr "length_immediate")
6291 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6293 (match_test "<MODE_SIZE> == 8")
6295 (const_string "<MODE_SIZE>")))])
6297 (define_insn "*sub<mode>_3"
6298 [(set (reg FLAGS_REG)
6299 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6300 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6301 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6302 (minus:SWI (match_dup 1) (match_dup 2)))]
6303 "ix86_match_ccmode (insn, CCmode)
6304 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6305 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6306 [(set_attr "type" "alu")
6307 (set_attr "mode" "<MODE>")])
6309 (define_insn "*subsi_3_zext"
6310 [(set (reg FLAGS_REG)
6311 (compare (match_operand:SI 1 "register_operand" "0")
6312 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6313 (set (match_operand:DI 0 "register_operand" "=r")
6315 (minus:SI (match_dup 1)
6317 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6318 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6319 "sub{l}\t{%2, %1|%1, %2}"
6320 [(set_attr "type" "alu")
6321 (set_attr "mode" "SI")])
6323 ;; Add with carry and subtract with borrow
6325 (define_expand "<plusminus_insn><mode>3_carry"
6327 [(set (match_operand:SWI 0 "nonimmediate_operand")
6329 (match_operand:SWI 1 "nonimmediate_operand")
6330 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6331 [(match_operand 3 "flags_reg_operand")
6333 (match_operand:SWI 2 "<general_operand>"))))
6334 (clobber (reg:CC FLAGS_REG))])]
6335 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6337 (define_insn "*<plusminus_insn><mode>3_carry"
6338 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6340 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6342 (match_operator 3 "ix86_carry_flag_operator"
6343 [(reg FLAGS_REG) (const_int 0)])
6344 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6345 (clobber (reg:CC FLAGS_REG))]
6346 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6347 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6348 [(set_attr "type" "alu")
6349 (set_attr "use_carry" "1")
6350 (set_attr "pent_pair" "pu")
6351 (set_attr "mode" "<MODE>")])
6353 (define_insn "*addsi3_carry_zext"
6354 [(set (match_operand:DI 0 "register_operand" "=r")
6356 (plus:SI (match_operand:SI 1 "nonimmediate_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 (PLUS, SImode, operands)"
6362 "adc{l}\t{%2, %k0|%k0, %2}"
6363 [(set_attr "type" "alu")
6364 (set_attr "use_carry" "1")
6365 (set_attr "pent_pair" "pu")
6366 (set_attr "mode" "SI")])
6368 (define_insn "*subsi3_carry_zext"
6369 [(set (match_operand:DI 0 "register_operand" "=r")
6371 (minus:SI (match_operand:SI 1 "register_operand" "0")
6372 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6373 [(reg FLAGS_REG) (const_int 0)])
6374 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6375 (clobber (reg:CC FLAGS_REG))]
6376 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6377 "sbb{l}\t{%2, %k0|%k0, %2}"
6378 [(set_attr "type" "alu")
6379 (set_attr "pent_pair" "pu")
6380 (set_attr "mode" "SI")])
6384 (define_insn "adcx<mode>3"
6385 [(set (reg:CCC FLAGS_REG)
6388 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6390 (match_operator 4 "ix86_carry_flag_operator"
6391 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6392 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6394 (set (match_operand:SWI48 0 "register_operand" "=r")
6395 (plus:SWI48 (match_dup 1)
6396 (plus:SWI48 (match_op_dup 4
6397 [(match_dup 3) (const_int 0)])
6399 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6400 "adcx\t{%2, %0|%0, %2}"
6401 [(set_attr "type" "alu")
6402 (set_attr "use_carry" "1")
6403 (set_attr "mode" "<MODE>")])
6405 ;; Overflow setting add instructions
6407 (define_insn "*add<mode>3_cconly_overflow"
6408 [(set (reg:CCC FLAGS_REG)
6411 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6412 (match_operand:SWI 2 "<general_operand>" "<g>"))
6414 (clobber (match_scratch:SWI 0 "=<r>"))]
6415 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6416 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "<MODE>")])
6420 (define_insn "*add<mode>3_cc_overflow"
6421 [(set (reg:CCC FLAGS_REG)
6424 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6425 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6427 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6428 (plus:SWI (match_dup 1) (match_dup 2)))]
6429 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6430 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "<MODE>")])
6434 (define_insn "*addsi3_zext_cc_overflow"
6435 [(set (reg:CCC FLAGS_REG)
6438 (match_operand:SI 1 "nonimmediate_operand" "%0")
6439 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6441 (set (match_operand:DI 0 "register_operand" "=r")
6442 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6443 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6444 "add{l}\t{%2, %k0|%k0, %2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "SI")])
6448 ;; The patterns that match these are at the end of this file.
6450 (define_expand "<plusminus_insn>xf3"
6451 [(set (match_operand:XF 0 "register_operand")
6453 (match_operand:XF 1 "register_operand")
6454 (match_operand:XF 2 "register_operand")))]
6457 (define_expand "<plusminus_insn><mode>3"
6458 [(set (match_operand:MODEF 0 "register_operand")
6460 (match_operand:MODEF 1 "register_operand")
6461 (match_operand:MODEF 2 "nonimmediate_operand")))]
6462 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6463 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6465 ;; Multiply instructions
6467 (define_expand "mul<mode>3"
6468 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6470 (match_operand:SWIM248 1 "register_operand")
6471 (match_operand:SWIM248 2 "<general_operand>")))
6472 (clobber (reg:CC FLAGS_REG))])])
6474 (define_expand "mulqi3"
6475 [(parallel [(set (match_operand:QI 0 "register_operand")
6477 (match_operand:QI 1 "register_operand")
6478 (match_operand:QI 2 "nonimmediate_operand")))
6479 (clobber (reg:CC FLAGS_REG))])]
6480 "TARGET_QIMODE_MATH")
6483 ;; IMUL reg32/64, reg32/64, imm8 Direct
6484 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6485 ;; IMUL reg32/64, reg32/64, imm32 Direct
6486 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6487 ;; IMUL reg32/64, reg32/64 Direct
6488 ;; IMUL reg32/64, mem32/64 Direct
6490 ;; On BDVER1, all above IMULs use DirectPath
6492 (define_insn "*mul<mode>3_1"
6493 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6495 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6496 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6497 (clobber (reg:CC FLAGS_REG))]
6498 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6500 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6501 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6502 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6503 [(set_attr "type" "imul")
6504 (set_attr "prefix_0f" "0,0,1")
6505 (set (attr "athlon_decode")
6506 (cond [(eq_attr "cpu" "athlon")
6507 (const_string "vector")
6508 (eq_attr "alternative" "1")
6509 (const_string "vector")
6510 (and (eq_attr "alternative" "2")
6511 (match_operand 1 "memory_operand"))
6512 (const_string "vector")]
6513 (const_string "direct")))
6514 (set (attr "amdfam10_decode")
6515 (cond [(and (eq_attr "alternative" "0,1")
6516 (match_operand 1 "memory_operand"))
6517 (const_string "vector")]
6518 (const_string "direct")))
6519 (set_attr "bdver1_decode" "direct")
6520 (set_attr "mode" "<MODE>")])
6522 (define_insn "*mulsi3_1_zext"
6523 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6525 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6526 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6527 (clobber (reg:CC FLAGS_REG))]
6529 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6532 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6533 imul{l}\t{%2, %k0|%k0, %2}"
6534 [(set_attr "type" "imul")
6535 (set_attr "prefix_0f" "0,0,1")
6536 (set (attr "athlon_decode")
6537 (cond [(eq_attr "cpu" "athlon")
6538 (const_string "vector")
6539 (eq_attr "alternative" "1")
6540 (const_string "vector")
6541 (and (eq_attr "alternative" "2")
6542 (match_operand 1 "memory_operand"))
6543 (const_string "vector")]
6544 (const_string "direct")))
6545 (set (attr "amdfam10_decode")
6546 (cond [(and (eq_attr "alternative" "0,1")
6547 (match_operand 1 "memory_operand"))
6548 (const_string "vector")]
6549 (const_string "direct")))
6550 (set_attr "bdver1_decode" "direct")
6551 (set_attr "mode" "SI")])
6554 ;; IMUL reg16, reg16, imm8 VectorPath
6555 ;; IMUL reg16, mem16, imm8 VectorPath
6556 ;; IMUL reg16, reg16, imm16 VectorPath
6557 ;; IMUL reg16, mem16, imm16 VectorPath
6558 ;; IMUL reg16, reg16 Direct
6559 ;; IMUL reg16, mem16 Direct
6561 ;; On BDVER1, all HI MULs use DoublePath
6563 (define_insn "*mulhi3_1"
6564 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6565 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6566 (match_operand:HI 2 "general_operand" "K,n,mr")))
6567 (clobber (reg:CC FLAGS_REG))]
6569 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6571 imul{w}\t{%2, %1, %0|%0, %1, %2}
6572 imul{w}\t{%2, %1, %0|%0, %1, %2}
6573 imul{w}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "imul")
6575 (set_attr "prefix_0f" "0,0,1")
6576 (set (attr "athlon_decode")
6577 (cond [(eq_attr "cpu" "athlon")
6578 (const_string "vector")
6579 (eq_attr "alternative" "1,2")
6580 (const_string "vector")]
6581 (const_string "direct")))
6582 (set (attr "amdfam10_decode")
6583 (cond [(eq_attr "alternative" "0,1")
6584 (const_string "vector")]
6585 (const_string "direct")))
6586 (set_attr "bdver1_decode" "double")
6587 (set_attr "mode" "HI")])
6589 ;;On AMDFAM10 and BDVER1
6593 (define_insn "*mulqi3_1"
6594 [(set (match_operand:QI 0 "register_operand" "=a")
6595 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6596 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6597 (clobber (reg:CC FLAGS_REG))]
6599 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6601 [(set_attr "type" "imul")
6602 (set_attr "length_immediate" "0")
6603 (set (attr "athlon_decode")
6604 (if_then_else (eq_attr "cpu" "athlon")
6605 (const_string "vector")
6606 (const_string "direct")))
6607 (set_attr "amdfam10_decode" "direct")
6608 (set_attr "bdver1_decode" "direct")
6609 (set_attr "mode" "QI")])
6611 ;; Multiply with jump on overflow.
6612 (define_expand "mulv<mode>4"
6613 [(parallel [(set (reg:CCO FLAGS_REG)
6616 (match_operand:SWI48 1 "register_operand"))
6619 (mult:SWI48 (match_dup 1)
6620 (match_operand:SWI48 2
6621 "<general_operand>")))))
6622 (set (match_operand:SWI48 0 "register_operand")
6623 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6624 (set (pc) (if_then_else
6625 (eq (reg:CCO FLAGS_REG) (const_int 0))
6626 (label_ref (match_operand 3))
6630 if (CONST_INT_P (operands[2]))
6631 operands[4] = operands[2];
6633 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6636 (define_insn "*mulv<mode>4"
6637 [(set (reg:CCO FLAGS_REG)
6640 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6642 (match_operand:SWI48 2 "<general_sext_operand>"
6645 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6646 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6647 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6648 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6652 [(set_attr "type" "imul")
6653 (set_attr "prefix_0f" "0,1")
6654 (set (attr "athlon_decode")
6655 (cond [(eq_attr "cpu" "athlon")
6656 (const_string "vector")
6657 (eq_attr "alternative" "0")
6658 (const_string "vector")
6659 (and (eq_attr "alternative" "1")
6660 (match_operand 1 "memory_operand"))
6661 (const_string "vector")]
6662 (const_string "direct")))
6663 (set (attr "amdfam10_decode")
6664 (cond [(and (eq_attr "alternative" "1")
6665 (match_operand 1 "memory_operand"))
6666 (const_string "vector")]
6667 (const_string "direct")))
6668 (set_attr "bdver1_decode" "direct")
6669 (set_attr "mode" "<MODE>")])
6671 (define_insn "*mulv<mode>4_1"
6672 [(set (reg:CCO FLAGS_REG)
6675 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6676 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6678 (mult:SWI48 (match_dup 1)
6679 (match_operand:SWI 2 "x86_64_immediate_operand"
6681 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6682 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6683 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6684 && CONST_INT_P (operands[2])
6685 && INTVAL (operands[2]) == INTVAL (operands[3])"
6687 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6688 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6689 [(set_attr "type" "imul")
6690 (set (attr "athlon_decode")
6691 (cond [(eq_attr "cpu" "athlon")
6692 (const_string "vector")
6693 (eq_attr "alternative" "1")
6694 (const_string "vector")]
6695 (const_string "direct")))
6696 (set (attr "amdfam10_decode")
6697 (cond [(match_operand 1 "memory_operand")
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "<MODE>")
6702 (set (attr "length_immediate")
6703 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6705 (match_test "<MODE_SIZE> == 8")
6707 (const_string "<MODE_SIZE>")))])
6709 (define_expand "umulv<mode>4"
6710 [(parallel [(set (reg:CCO FLAGS_REG)
6713 (match_operand:SWI48 1
6714 "nonimmediate_operand"))
6716 (match_operand:SWI48 2
6717 "nonimmediate_operand")))
6719 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6720 (set (match_operand:SWI48 0 "register_operand")
6721 (mult:SWI48 (match_dup 1) (match_dup 2)))
6722 (clobber (match_scratch:SWI48 4))])
6723 (set (pc) (if_then_else
6724 (eq (reg:CCO FLAGS_REG) (const_int 0))
6725 (label_ref (match_operand 3))
6729 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6730 operands[1] = force_reg (<MODE>mode, operands[1]);
6733 (define_insn "*umulv<mode>4"
6734 [(set (reg:CCO FLAGS_REG)
6737 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6739 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6741 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6742 (set (match_operand:SWI48 0 "register_operand" "=a")
6743 (mult:SWI48 (match_dup 1) (match_dup 2)))
6744 (clobber (match_scratch:SWI48 3 "=d"))]
6745 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6746 "mul{<imodesuffix>}\t%2"
6747 [(set_attr "type" "imul")
6748 (set_attr "length_immediate" "0")
6749 (set (attr "athlon_decode")
6750 (if_then_else (eq_attr "cpu" "athlon")
6751 (const_string "vector")
6752 (const_string "double")))
6753 (set_attr "amdfam10_decode" "double")
6754 (set_attr "bdver1_decode" "direct")
6755 (set_attr "mode" "<MODE>")])
6757 (define_expand "<u>mulvqi4"
6758 [(parallel [(set (reg:CCO FLAGS_REG)
6761 (match_operand:QI 1 "nonimmediate_operand"))
6763 (match_operand:QI 2 "nonimmediate_operand")))
6765 (mult:QI (match_dup 1) (match_dup 2)))))
6766 (set (match_operand:QI 0 "register_operand")
6767 (mult:QI (match_dup 1) (match_dup 2)))])
6768 (set (pc) (if_then_else
6769 (eq (reg:CCO FLAGS_REG) (const_int 0))
6770 (label_ref (match_operand 3))
6772 "TARGET_QIMODE_MATH"
6774 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6775 operands[1] = force_reg (QImode, operands[1]);
6778 (define_insn "*<u>mulvqi4"
6779 [(set (reg:CCO FLAGS_REG)
6782 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6784 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6786 (mult:QI (match_dup 1) (match_dup 2)))))
6787 (set (match_operand:QI 0 "register_operand" "=a")
6788 (mult:QI (match_dup 1) (match_dup 2)))]
6790 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6791 "<sgnprefix>mul{b}\t%2"
6792 [(set_attr "type" "imul")
6793 (set_attr "length_immediate" "0")
6794 (set (attr "athlon_decode")
6795 (if_then_else (eq_attr "cpu" "athlon")
6796 (const_string "vector")
6797 (const_string "direct")))
6798 (set_attr "amdfam10_decode" "direct")
6799 (set_attr "bdver1_decode" "direct")
6800 (set_attr "mode" "QI")])
6802 (define_expand "<u>mul<mode><dwi>3"
6803 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6806 (match_operand:DWIH 1 "nonimmediate_operand"))
6808 (match_operand:DWIH 2 "register_operand"))))
6809 (clobber (reg:CC FLAGS_REG))])])
6811 (define_expand "<u>mulqihi3"
6812 [(parallel [(set (match_operand:HI 0 "register_operand")
6815 (match_operand:QI 1 "nonimmediate_operand"))
6817 (match_operand:QI 2 "register_operand"))))
6818 (clobber (reg:CC FLAGS_REG))])]
6819 "TARGET_QIMODE_MATH")
6821 (define_insn "*bmi2_umulditi3_1"
6822 [(set (match_operand:DI 0 "register_operand" "=r")
6824 (match_operand:DI 2 "nonimmediate_operand" "%d")
6825 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6826 (set (match_operand:DI 1 "register_operand" "=r")
6829 (mult:TI (zero_extend:TI (match_dup 2))
6830 (zero_extend:TI (match_dup 3)))
6832 "TARGET_64BIT && TARGET_BMI2
6833 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6834 "mulx\t{%3, %0, %1|%1, %0, %3}"
6835 [(set_attr "type" "imulx")
6836 (set_attr "prefix" "vex")
6837 (set_attr "mode" "DI")])
6839 (define_insn "*bmi2_umulsidi3_1"
6840 [(set (match_operand:SI 0 "register_operand" "=r")
6842 (match_operand:SI 2 "nonimmediate_operand" "%d")
6843 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6844 (set (match_operand:SI 1 "register_operand" "=r")
6847 (mult:DI (zero_extend:DI (match_dup 2))
6848 (zero_extend:DI (match_dup 3)))
6850 "!TARGET_64BIT && TARGET_BMI2
6851 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6852 "mulx\t{%3, %0, %1|%1, %0, %3}"
6853 [(set_attr "type" "imulx")
6854 (set_attr "prefix" "vex")
6855 (set_attr "mode" "SI")])
6857 (define_insn "*umul<mode><dwi>3_1"
6858 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6861 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6863 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 mul{<imodesuffix>}\t%2"
6869 [(set_attr "isa" "bmi2,*")
6870 (set_attr "type" "imulx,imul")
6871 (set_attr "length_immediate" "*,0")
6872 (set (attr "athlon_decode")
6873 (cond [(eq_attr "alternative" "1")
6874 (if_then_else (eq_attr "cpu" "athlon")
6875 (const_string "vector")
6876 (const_string "double"))]
6877 (const_string "*")))
6878 (set_attr "amdfam10_decode" "*,double")
6879 (set_attr "bdver1_decode" "*,direct")
6880 (set_attr "prefix" "vex,orig")
6881 (set_attr "mode" "<MODE>")])
6883 ;; Convert mul to the mulx pattern to avoid flags dependency.
6885 [(set (match_operand:<DWI> 0 "register_operand")
6888 (match_operand:DWIH 1 "register_operand"))
6890 (match_operand:DWIH 2 "nonimmediate_operand"))))
6891 (clobber (reg:CC FLAGS_REG))]
6892 "TARGET_BMI2 && reload_completed
6893 && true_regnum (operands[1]) == DX_REG"
6894 [(parallel [(set (match_dup 3)
6895 (mult:DWIH (match_dup 1) (match_dup 2)))
6899 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6900 (zero_extend:<DWI> (match_dup 2)))
6903 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6905 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6908 (define_insn "*mul<mode><dwi>3_1"
6909 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6912 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6914 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6915 (clobber (reg:CC FLAGS_REG))]
6916 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "imul{<imodesuffix>}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "<MODE>")])
6928 (define_insn "*<u>mulqihi3_1"
6929 [(set (match_operand:HI 0 "register_operand" "=a")
6932 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6934 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6935 (clobber (reg:CC FLAGS_REG))]
6937 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938 "<sgnprefix>mul{b}\t%2"
6939 [(set_attr "type" "imul")
6940 (set_attr "length_immediate" "0")
6941 (set (attr "athlon_decode")
6942 (if_then_else (eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (const_string "direct")))
6945 (set_attr "amdfam10_decode" "direct")
6946 (set_attr "bdver1_decode" "direct")
6947 (set_attr "mode" "QI")])
6949 (define_expand "<s>mul<mode>3_highpart"
6950 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6955 (match_operand:SWI48 1 "nonimmediate_operand"))
6957 (match_operand:SWI48 2 "register_operand")))
6959 (clobber (match_scratch:SWI48 3))
6960 (clobber (reg:CC FLAGS_REG))])]
6962 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6964 (define_insn "*<s>muldi3_highpart_1"
6965 [(set (match_operand:DI 0 "register_operand" "=d")
6970 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6972 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6974 (clobber (match_scratch:DI 3 "=1"))
6975 (clobber (reg:CC FLAGS_REG))]
6977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978 "<sgnprefix>mul{q}\t%2"
6979 [(set_attr "type" "imul")
6980 (set_attr "length_immediate" "0")
6981 (set (attr "athlon_decode")
6982 (if_then_else (eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (const_string "double")))
6985 (set_attr "amdfam10_decode" "double")
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "DI")])
6989 (define_insn "*<s>mulsi3_highpart_1"
6990 [(set (match_operand:SI 0 "register_operand" "=d")
6995 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6997 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6999 (clobber (match_scratch:SI 3 "=1"))
7000 (clobber (reg:CC FLAGS_REG))]
7001 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002 "<sgnprefix>mul{l}\t%2"
7003 [(set_attr "type" "imul")
7004 (set_attr "length_immediate" "0")
7005 (set (attr "athlon_decode")
7006 (if_then_else (eq_attr "cpu" "athlon")
7007 (const_string "vector")
7008 (const_string "double")))
7009 (set_attr "amdfam10_decode" "double")
7010 (set_attr "bdver1_decode" "direct")
7011 (set_attr "mode" "SI")])
7013 (define_insn "*<s>mulsi3_highpart_zext"
7014 [(set (match_operand:DI 0 "register_operand" "=d")
7015 (zero_extend:DI (truncate:SI
7017 (mult:DI (any_extend:DI
7018 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7020 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7022 (clobber (match_scratch:SI 3 "=1"))
7023 (clobber (reg:CC FLAGS_REG))]
7025 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7026 "<sgnprefix>mul{l}\t%2"
7027 [(set_attr "type" "imul")
7028 (set_attr "length_immediate" "0")
7029 (set (attr "athlon_decode")
7030 (if_then_else (eq_attr "cpu" "athlon")
7031 (const_string "vector")
7032 (const_string "double")))
7033 (set_attr "amdfam10_decode" "double")
7034 (set_attr "bdver1_decode" "direct")
7035 (set_attr "mode" "SI")])
7037 ;; The patterns that match these are at the end of this file.
7039 (define_expand "mulxf3"
7040 [(set (match_operand:XF 0 "register_operand")
7041 (mult:XF (match_operand:XF 1 "register_operand")
7042 (match_operand:XF 2 "register_operand")))]
7045 (define_expand "mul<mode>3"
7046 [(set (match_operand:MODEF 0 "register_operand")
7047 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7048 (match_operand:MODEF 2 "nonimmediate_operand")))]
7049 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7050 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7052 ;; Divide instructions
7054 ;; The patterns that match these are at the end of this file.
7056 (define_expand "divxf3"
7057 [(set (match_operand:XF 0 "register_operand")
7058 (div:XF (match_operand:XF 1 "register_operand")
7059 (match_operand:XF 2 "register_operand")))]
7062 (define_expand "divdf3"
7063 [(set (match_operand:DF 0 "register_operand")
7064 (div:DF (match_operand:DF 1 "register_operand")
7065 (match_operand:DF 2 "nonimmediate_operand")))]
7066 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7067 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7069 (define_expand "divsf3"
7070 [(set (match_operand:SF 0 "register_operand")
7071 (div:SF (match_operand:SF 1 "register_operand")
7072 (match_operand:SF 2 "nonimmediate_operand")))]
7073 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7078 && optimize_insn_for_speed_p ()
7079 && flag_finite_math_only && !flag_trapping_math
7080 && flag_unsafe_math_optimizations)
7082 ix86_emit_swdivsf (operands[0], operands[1],
7083 operands[2], SFmode);
7088 ;; Divmod instructions.
7090 (define_expand "divmod<mode>4"
7091 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7093 (match_operand:SWIM248 1 "register_operand")
7094 (match_operand:SWIM248 2 "nonimmediate_operand")))
7095 (set (match_operand:SWIM248 3 "register_operand")
7096 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7097 (clobber (reg:CC FLAGS_REG))])])
7099 ;; Split with 8bit unsigned divide:
7100 ;; if (dividend an divisor are in [0-255])
7101 ;; use 8bit unsigned integer divide
7103 ;; use original integer divide
7105 [(set (match_operand:SWI48 0 "register_operand")
7106 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7107 (match_operand:SWI48 3 "nonimmediate_operand")))
7108 (set (match_operand:SWI48 1 "register_operand")
7109 (mod:SWI48 (match_dup 2) (match_dup 3)))
7110 (clobber (reg:CC FLAGS_REG))]
7111 "TARGET_USE_8BIT_IDIV
7112 && TARGET_QIMODE_MATH
7113 && can_create_pseudo_p ()
7114 && !optimize_insn_for_size_p ()"
7116 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7118 (define_insn_and_split "divmod<mode>4_1"
7119 [(set (match_operand:SWI48 0 "register_operand" "=a")
7120 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7121 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7122 (set (match_operand:SWI48 1 "register_operand" "=&d")
7123 (mod:SWI48 (match_dup 2) (match_dup 3)))
7124 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7125 (clobber (reg:CC FLAGS_REG))]
7129 [(parallel [(set (match_dup 1)
7130 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7131 (clobber (reg:CC FLAGS_REG))])
7132 (parallel [(set (match_dup 0)
7133 (div:SWI48 (match_dup 2) (match_dup 3)))
7135 (mod:SWI48 (match_dup 2) (match_dup 3)))
7137 (clobber (reg:CC FLAGS_REG))])]
7139 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7141 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7142 operands[4] = operands[2];
7145 /* Avoid use of cltd in favor of a mov+shift. */
7146 emit_move_insn (operands[1], operands[2]);
7147 operands[4] = operands[1];
7150 [(set_attr "type" "multi")
7151 (set_attr "mode" "<MODE>")])
7153 (define_insn_and_split "*divmod<mode>4"
7154 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7155 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7156 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7157 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7158 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7159 (clobber (reg:CC FLAGS_REG))]
7163 [(parallel [(set (match_dup 1)
7164 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7165 (clobber (reg:CC FLAGS_REG))])
7166 (parallel [(set (match_dup 0)
7167 (div:SWIM248 (match_dup 2) (match_dup 3)))
7169 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7171 (clobber (reg:CC FLAGS_REG))])]
7173 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7175 if (<MODE>mode != HImode
7176 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7177 operands[4] = operands[2];
7180 /* Avoid use of cltd in favor of a mov+shift. */
7181 emit_move_insn (operands[1], operands[2]);
7182 operands[4] = operands[1];
7185 [(set_attr "type" "multi")
7186 (set_attr "mode" "<MODE>")])
7188 (define_insn "*divmod<mode>4_noext"
7189 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7190 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7191 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7192 (set (match_operand:SWIM248 1 "register_operand" "=d")
7193 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7194 (use (match_operand:SWIM248 4 "register_operand" "1"))
7195 (clobber (reg:CC FLAGS_REG))]
7197 "idiv{<imodesuffix>}\t%3"
7198 [(set_attr "type" "idiv")
7199 (set_attr "mode" "<MODE>")])
7201 (define_expand "divmodqi4"
7202 [(parallel [(set (match_operand:QI 0 "register_operand")
7204 (match_operand:QI 1 "register_operand")
7205 (match_operand:QI 2 "nonimmediate_operand")))
7206 (set (match_operand:QI 3 "register_operand")
7207 (mod:QI (match_dup 1) (match_dup 2)))
7208 (clobber (reg:CC FLAGS_REG))])]
7209 "TARGET_QIMODE_MATH"
7214 tmp0 = gen_reg_rtx (HImode);
7215 tmp1 = gen_reg_rtx (HImode);
7217 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7219 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7220 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7222 /* Extract remainder from AH. */
7223 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7224 insn = emit_move_insn (operands[3], tmp1);
7226 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7227 set_unique_reg_note (insn, REG_EQUAL, mod);
7229 /* Extract quotient from AL. */
7230 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7232 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7233 set_unique_reg_note (insn, REG_EQUAL, div);
7238 ;; Divide AX by r/m8, with result stored in
7241 ;; Change div/mod to HImode and extend the second argument to HImode
7242 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7243 ;; combine may fail.
7244 (define_insn "divmodhiqi3"
7245 [(set (match_operand:HI 0 "register_operand" "=a")
7250 (mod:HI (match_operand:HI 1 "register_operand" "0")
7252 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7256 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "TARGET_QIMODE_MATH"
7260 [(set_attr "type" "idiv")
7261 (set_attr "mode" "QI")])
7263 (define_expand "udivmod<mode>4"
7264 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7266 (match_operand:SWIM248 1 "register_operand")
7267 (match_operand:SWIM248 2 "nonimmediate_operand")))
7268 (set (match_operand:SWIM248 3 "register_operand")
7269 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7270 (clobber (reg:CC FLAGS_REG))])])
7272 ;; Split with 8bit unsigned divide:
7273 ;; if (dividend an divisor are in [0-255])
7274 ;; use 8bit unsigned integer divide
7276 ;; use original integer divide
7278 [(set (match_operand:SWI48 0 "register_operand")
7279 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7280 (match_operand:SWI48 3 "nonimmediate_operand")))
7281 (set (match_operand:SWI48 1 "register_operand")
7282 (umod:SWI48 (match_dup 2) (match_dup 3)))
7283 (clobber (reg:CC FLAGS_REG))]
7284 "TARGET_USE_8BIT_IDIV
7285 && TARGET_QIMODE_MATH
7286 && can_create_pseudo_p ()
7287 && !optimize_insn_for_size_p ()"
7289 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7291 (define_insn_and_split "udivmod<mode>4_1"
7292 [(set (match_operand:SWI48 0 "register_operand" "=a")
7293 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7294 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7295 (set (match_operand:SWI48 1 "register_operand" "=&d")
7296 (umod:SWI48 (match_dup 2) (match_dup 3)))
7297 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7298 (clobber (reg:CC FLAGS_REG))]
7302 [(set (match_dup 1) (const_int 0))
7303 (parallel [(set (match_dup 0)
7304 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7306 (umod:SWI48 (match_dup 2) (match_dup 3)))
7308 (clobber (reg:CC FLAGS_REG))])]
7310 [(set_attr "type" "multi")
7311 (set_attr "mode" "<MODE>")])
7313 (define_insn_and_split "*udivmod<mode>4"
7314 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7315 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7316 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7317 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7318 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7319 (clobber (reg:CC FLAGS_REG))]
7323 [(set (match_dup 1) (const_int 0))
7324 (parallel [(set (match_dup 0)
7325 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7327 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7329 (clobber (reg:CC FLAGS_REG))])]
7331 [(set_attr "type" "multi")
7332 (set_attr "mode" "<MODE>")])
7334 ;; Optimize division or modulo by constant power of 2, if the constant
7335 ;; materializes only after expansion.
7336 (define_insn_and_split "*udivmod<mode>4_pow2"
7337 [(set (match_operand:SWI48 0 "register_operand" "=r")
7338 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7339 (match_operand:SWI48 3 "const_int_operand" "n")))
7340 (set (match_operand:SWI48 1 "register_operand" "=r")
7341 (umod:SWI48 (match_dup 2) (match_dup 3)))
7342 (clobber (reg:CC FLAGS_REG))]
7343 "UINTVAL (operands[3]) - 2 < <MODE_SIZE> * BITS_PER_UNIT
7344 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7347 [(set (match_dup 1) (match_dup 2))
7348 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7349 (clobber (reg:CC FLAGS_REG))])
7350 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7351 (clobber (reg:CC FLAGS_REG))])]
7353 int v = exact_log2 (UINTVAL (operands[3]));
7354 operands[4] = GEN_INT (v);
7355 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7357 [(set_attr "type" "multi")
7358 (set_attr "mode" "<MODE>")])
7360 (define_insn "*udivmod<mode>4_noext"
7361 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7362 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7363 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7364 (set (match_operand:SWIM248 1 "register_operand" "=d")
7365 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7366 (use (match_operand:SWIM248 4 "register_operand" "1"))
7367 (clobber (reg:CC FLAGS_REG))]
7369 "div{<imodesuffix>}\t%3"
7370 [(set_attr "type" "idiv")
7371 (set_attr "mode" "<MODE>")])
7373 (define_expand "udivmodqi4"
7374 [(parallel [(set (match_operand:QI 0 "register_operand")
7376 (match_operand:QI 1 "register_operand")
7377 (match_operand:QI 2 "nonimmediate_operand")))
7378 (set (match_operand:QI 3 "register_operand")
7379 (umod:QI (match_dup 1) (match_dup 2)))
7380 (clobber (reg:CC FLAGS_REG))])]
7381 "TARGET_QIMODE_MATH"
7386 tmp0 = gen_reg_rtx (HImode);
7387 tmp1 = gen_reg_rtx (HImode);
7389 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7391 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7392 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7394 /* Extract remainder from AH. */
7395 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7396 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7397 insn = emit_move_insn (operands[3], tmp1);
7399 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7400 set_unique_reg_note (insn, REG_EQUAL, mod);
7402 /* Extract quotient from AL. */
7403 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7405 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7406 set_unique_reg_note (insn, REG_EQUAL, div);
7411 (define_insn "udivmodhiqi3"
7412 [(set (match_operand:HI 0 "register_operand" "=a")
7417 (mod:HI (match_operand:HI 1 "register_operand" "0")
7419 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7423 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7424 (clobber (reg:CC FLAGS_REG))]
7425 "TARGET_QIMODE_MATH"
7427 [(set_attr "type" "idiv")
7428 (set_attr "mode" "QI")])
7430 ;; We cannot use div/idiv for double division, because it causes
7431 ;; "division by zero" on the overflow and that's not what we expect
7432 ;; from truncate. Because true (non truncating) double division is
7433 ;; never generated, we can't create this insn anyway.
7436 ; [(set (match_operand:SI 0 "register_operand" "=a")
7438 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7440 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7441 ; (set (match_operand:SI 3 "register_operand" "=d")
7443 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7444 ; (clobber (reg:CC FLAGS_REG))]
7446 ; "div{l}\t{%2, %0|%0, %2}"
7447 ; [(set_attr "type" "idiv")])
7449 ;;- Logical AND instructions
7451 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7452 ;; Note that this excludes ah.
7454 (define_expand "testsi_ccno_1"
7455 [(set (reg:CCNO FLAGS_REG)
7457 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7458 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7461 (define_expand "testqi_ccz_1"
7462 [(set (reg:CCZ FLAGS_REG)
7463 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7464 (match_operand:QI 1 "nonmemory_operand"))
7467 (define_expand "testdi_ccno_1"
7468 [(set (reg:CCNO FLAGS_REG)
7470 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7471 (match_operand:DI 1 "x86_64_szext_general_operand"))
7473 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7475 (define_insn "*testdi_1"
7476 [(set (reg FLAGS_REG)
7479 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7480 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7482 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7483 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7485 test{l}\t{%k1, %k0|%k0, %k1}
7486 test{l}\t{%k1, %k0|%k0, %k1}
7487 test{q}\t{%1, %0|%0, %1}
7488 test{q}\t{%1, %0|%0, %1}
7489 test{q}\t{%1, %0|%0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "modrm" "0,1,0,1,1")
7492 (set_attr "mode" "SI,SI,DI,DI,DI")])
7494 (define_insn "*testqi_1_maybe_si"
7495 [(set (reg FLAGS_REG)
7498 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7499 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7501 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7502 && ix86_match_ccmode (insn,
7503 CONST_INT_P (operands[1])
7504 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7506 if (which_alternative == 3)
7508 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7509 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7510 return "test{l}\t{%1, %k0|%k0, %1}";
7512 return "test{b}\t{%1, %0|%0, %1}";
7514 [(set_attr "type" "test")
7515 (set_attr "modrm" "0,1,1,1")
7516 (set_attr "mode" "QI,QI,QI,SI")
7517 (set_attr "pent_pair" "uv,np,uv,np")])
7519 (define_insn "*test<mode>_1"
7520 [(set (reg FLAGS_REG)
7523 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7524 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7526 "ix86_match_ccmode (insn, CCNOmode)
7527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7528 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7529 [(set_attr "type" "test")
7530 (set_attr "modrm" "0,1,1")
7531 (set_attr "mode" "<MODE>")
7532 (set_attr "pent_pair" "uv,np,uv")])
7534 (define_expand "testqi_ext_ccno_0"
7535 [(set (reg:CCNO FLAGS_REG)
7539 (match_operand 0 "ext_register_operand")
7542 (match_operand 1 "const_int_operand"))
7545 (define_insn "*testqi_ext_0"
7546 [(set (reg FLAGS_REG)
7550 (match_operand 0 "ext_register_operand" "Q")
7553 (match_operand 1 "const_int_operand" "n"))
7555 "ix86_match_ccmode (insn, CCNOmode)"
7556 "test{b}\t{%1, %h0|%h0, %1}"
7557 [(set_attr "type" "test")
7558 (set_attr "mode" "QI")
7559 (set_attr "length_immediate" "1")
7560 (set_attr "modrm" "1")
7561 (set_attr "pent_pair" "np")])
7563 (define_insn "*testqi_ext_1"
7564 [(set (reg FLAGS_REG)
7568 (match_operand 0 "ext_register_operand" "Q,Q")
7572 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7574 "ix86_match_ccmode (insn, CCNOmode)"
7575 "test{b}\t{%1, %h0|%h0, %1}"
7576 [(set_attr "isa" "*,nox64")
7577 (set_attr "type" "test")
7578 (set_attr "mode" "QI")])
7580 (define_insn "*testqi_ext_2"
7581 [(set (reg FLAGS_REG)
7585 (match_operand 0 "ext_register_operand" "Q")
7589 (match_operand 1 "ext_register_operand" "Q")
7593 "ix86_match_ccmode (insn, CCNOmode)"
7594 "test{b}\t{%h1, %h0|%h0, %h1}"
7595 [(set_attr "type" "test")
7596 (set_attr "mode" "QI")])
7598 ;; Combine likes to form bit extractions for some tests. Humor it.
7599 (define_insn "*testqi_ext_3"
7600 [(set (reg FLAGS_REG)
7601 (compare (zero_extract:SWI48
7602 (match_operand 0 "nonimmediate_operand" "rm")
7603 (match_operand:SWI48 1 "const_int_operand")
7604 (match_operand:SWI48 2 "const_int_operand"))
7606 "ix86_match_ccmode (insn, CCNOmode)
7607 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7608 || GET_MODE (operands[0]) == SImode
7609 || GET_MODE (operands[0]) == HImode
7610 || GET_MODE (operands[0]) == QImode)
7611 /* Ensure that resulting mask is zero or sign extended operand. */
7612 && INTVAL (operands[2]) >= 0
7613 && ((INTVAL (operands[1]) > 0
7614 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7615 || (<MODE>mode == DImode
7616 && INTVAL (operands[1]) > 32
7617 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7621 [(set (match_operand 0 "flags_reg_operand")
7622 (match_operator 1 "compare_operator"
7624 (match_operand 2 "nonimmediate_operand")
7625 (match_operand 3 "const_int_operand")
7626 (match_operand 4 "const_int_operand"))
7628 "ix86_match_ccmode (insn, CCNOmode)"
7629 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7631 rtx val = operands[2];
7632 HOST_WIDE_INT len = INTVAL (operands[3]);
7633 HOST_WIDE_INT pos = INTVAL (operands[4]);
7635 machine_mode mode, submode;
7637 mode = GET_MODE (val);
7640 /* ??? Combine likes to put non-volatile mem extractions in QImode
7641 no matter the size of the test. So find a mode that works. */
7642 if (! MEM_VOLATILE_P (val))
7644 mode = smallest_mode_for_size (pos + len, MODE_INT);
7645 val = adjust_address (val, mode, 0);
7648 else if (GET_CODE (val) == SUBREG
7649 && (submode = GET_MODE (SUBREG_REG (val)),
7650 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7651 && pos + len <= GET_MODE_BITSIZE (submode)
7652 && GET_MODE_CLASS (submode) == MODE_INT)
7654 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7656 val = SUBREG_REG (val);
7658 else if (mode == HImode && pos + len <= 8)
7660 /* Small HImode tests can be converted to QImode. */
7662 val = gen_lowpart (QImode, val);
7665 if (len == HOST_BITS_PER_WIDE_INT)
7668 mask = ((HOST_WIDE_INT)1 << len) - 1;
7671 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7674 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7675 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7676 ;; this is relatively important trick.
7677 ;; Do the conversion only post-reload to avoid limiting of the register class
7680 [(set (match_operand 0 "flags_reg_operand")
7681 (match_operator 1 "compare_operator"
7682 [(and (match_operand 2 "register_operand")
7683 (match_operand 3 "const_int_operand"))
7686 && QI_REG_P (operands[2])
7687 && GET_MODE (operands[2]) != QImode
7688 && ((ix86_match_ccmode (insn, CCZmode)
7689 && !(INTVAL (operands[3]) & ~(255 << 8)))
7690 || (ix86_match_ccmode (insn, CCNOmode)
7691 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7694 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7698 operands[2] = gen_lowpart (SImode, operands[2]);
7699 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7703 [(set (match_operand 0 "flags_reg_operand")
7704 (match_operator 1 "compare_operator"
7705 [(and (match_operand 2 "nonimmediate_operand")
7706 (match_operand 3 "const_int_operand"))
7709 && GET_MODE (operands[2]) != QImode
7710 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7711 && ((ix86_match_ccmode (insn, CCZmode)
7712 && !(INTVAL (operands[3]) & ~255))
7713 || (ix86_match_ccmode (insn, CCNOmode)
7714 && !(INTVAL (operands[3]) & ~127)))"
7716 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7719 operands[2] = gen_lowpart (QImode, operands[2]);
7720 operands[3] = gen_lowpart (QImode, operands[3]);
7724 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7725 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7726 (match_operand:SWI1248x 2 "mask_reg_operand")))
7727 (clobber (reg:CC FLAGS_REG))]
7728 "TARGET_AVX512F && reload_completed"
7730 (any_logic:SWI1248x (match_dup 1)
7733 (define_insn "*k<logic><mode>"
7734 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7735 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7736 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7739 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7740 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7742 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7744 [(set_attr "mode" "<MODE>")
7745 (set_attr "type" "msklog")
7746 (set_attr "prefix" "vex")])
7748 ;; %%% This used to optimize known byte-wide and operations to memory,
7749 ;; and sometimes to QImode registers. If this is considered useful,
7750 ;; it should be done with splitters.
7752 (define_expand "and<mode>3"
7753 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7754 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7755 (match_operand:SWIM 2 "<general_szext_operand>")))]
7758 machine_mode mode = <MODE>mode;
7759 rtx (*insn) (rtx, rtx);
7761 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7763 HOST_WIDE_INT ival = INTVAL (operands[2]);
7765 if (ival == (HOST_WIDE_INT) 0xffffffff)
7767 else if (ival == 0xffff)
7769 else if (ival == 0xff)
7773 if (mode == <MODE>mode)
7775 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7779 if (<MODE>mode == DImode)
7780 insn = (mode == SImode)
7781 ? gen_zero_extendsidi2
7783 ? gen_zero_extendhidi2
7784 : gen_zero_extendqidi2;
7785 else if (<MODE>mode == SImode)
7786 insn = (mode == HImode)
7787 ? gen_zero_extendhisi2
7788 : gen_zero_extendqisi2;
7789 else if (<MODE>mode == HImode)
7790 insn = gen_zero_extendqihi2;
7794 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7798 (define_insn "*anddi_1"
7799 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7801 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7802 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7803 (clobber (reg:CC FLAGS_REG))]
7804 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7806 switch (get_attr_type (insn))
7812 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816 if (get_attr_mode (insn) == MODE_SI)
7817 return "and{l}\t{%k2, %k0|%k0, %k2}";
7819 return "and{q}\t{%2, %0|%0, %2}";
7822 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7823 (set_attr "length_immediate" "*,*,*,0,0")
7824 (set (attr "prefix_rex")
7826 (and (eq_attr "type" "imovx")
7827 (and (match_test "INTVAL (operands[2]) == 0xff")
7828 (match_operand 1 "ext_QIreg_operand")))
7830 (const_string "*")))
7831 (set_attr "mode" "SI,DI,DI,SI,DI")])
7833 (define_insn "*andsi_1"
7834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7835 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7836 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7837 (clobber (reg:CC FLAGS_REG))]
7838 "ix86_binary_operator_ok (AND, SImode, operands)"
7840 switch (get_attr_type (insn))
7846 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7849 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7850 return "and{l}\t{%2, %0|%0, %2}";
7853 [(set_attr "type" "alu,alu,imovx,msklog")
7854 (set (attr "prefix_rex")
7856 (and (eq_attr "type" "imovx")
7857 (and (match_test "INTVAL (operands[2]) == 0xff")
7858 (match_operand 1 "ext_QIreg_operand")))
7860 (const_string "*")))
7861 (set_attr "length_immediate" "*,*,0,0")
7862 (set_attr "mode" "SI")])
7864 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7865 (define_insn "*andsi_1_zext"
7866 [(set (match_operand:DI 0 "register_operand" "=r")
7868 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7869 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7870 (clobber (reg:CC FLAGS_REG))]
7871 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7872 "and{l}\t{%2, %k0|%k0, %2}"
7873 [(set_attr "type" "alu")
7874 (set_attr "mode" "SI")])
7876 (define_insn "*andhi_1"
7877 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7878 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7879 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "ix86_binary_operator_ok (AND, HImode, operands)"
7883 switch (get_attr_type (insn))
7889 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7892 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7893 return "and{w}\t{%2, %0|%0, %2}";
7896 [(set_attr "type" "alu,alu,imovx,msklog")
7897 (set_attr "length_immediate" "*,*,0,*")
7898 (set (attr "prefix_rex")
7900 (and (eq_attr "type" "imovx")
7901 (match_operand 1 "ext_QIreg_operand"))
7903 (const_string "*")))
7904 (set_attr "mode" "HI,HI,SI,HI")])
7906 ;; %%% Potential partial reg stall on alternative 2. What to do?
7907 (define_insn "*andqi_1"
7908 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7909 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7910 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "ix86_binary_operator_ok (AND, QImode, operands)"
7914 switch (which_alternative)
7918 return "and{b}\t{%2, %0|%0, %2}";
7920 return "and{l}\t{%k2, %k0|%k0, %k2}";
7922 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7923 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7928 [(set_attr "type" "alu,alu,alu,msklog")
7929 (set_attr "mode" "QI,QI,SI,HI")])
7931 (define_insn "*andqi_1_slp"
7932 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7933 (and:QI (match_dup 0)
7934 (match_operand:QI 1 "general_operand" "qn,qmn")))
7935 (clobber (reg:CC FLAGS_REG))]
7936 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7937 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7938 "and{b}\t{%1, %0|%0, %1}"
7939 [(set_attr "type" "alu1")
7940 (set_attr "mode" "QI")])
7942 (define_insn "kandn<mode>"
7943 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7946 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7947 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7948 (clobber (reg:CC FLAGS_REG))]
7951 switch (which_alternative)
7954 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7958 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7959 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7961 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7966 [(set_attr "isa" "bmi,*,avx512f")
7967 (set_attr "type" "bitmanip,*,msklog")
7968 (set_attr "prefix" "*,*,vex")
7969 (set_attr "btver2_decode" "direct,*,*")
7970 (set_attr "mode" "<MODE>")])
7973 [(set (match_operand:SWI12 0 "general_reg_operand")
7977 (match_operand:SWI12 1 "general_reg_operand")))
7978 (clobber (reg:CC FLAGS_REG))]
7979 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7981 (not:HI (match_dup 0)))
7982 (parallel [(set (match_dup 0)
7983 (and:HI (match_dup 0)
7985 (clobber (reg:CC FLAGS_REG))])])
7987 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7989 [(set (match_operand:DI 0 "register_operand")
7990 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7991 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7992 (clobber (reg:CC FLAGS_REG))]
7994 [(parallel [(set (match_dup 0)
7995 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7996 (clobber (reg:CC FLAGS_REG))])]
7997 "operands[2] = gen_lowpart (SImode, operands[2]);")
8000 [(set (match_operand:SWI248 0 "register_operand")
8001 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8002 (match_operand:SWI248 2 "const_int_operand")))
8003 (clobber (reg:CC FLAGS_REG))]
8005 && true_regnum (operands[0]) != true_regnum (operands[1])"
8008 HOST_WIDE_INT ival = INTVAL (operands[2]);
8010 rtx (*insn) (rtx, rtx);
8012 if (ival == (HOST_WIDE_INT) 0xffffffff)
8014 else if (ival == 0xffff)
8018 gcc_assert (ival == 0xff);
8022 if (<MODE>mode == DImode)
8023 insn = (mode == SImode)
8024 ? gen_zero_extendsidi2
8026 ? gen_zero_extendhidi2
8027 : gen_zero_extendqidi2;
8030 if (<MODE>mode != SImode)
8031 /* Zero extend to SImode to avoid partial register stalls. */
8032 operands[0] = gen_lowpart (SImode, operands[0]);
8034 insn = (mode == HImode)
8035 ? gen_zero_extendhisi2
8036 : gen_zero_extendqisi2;
8038 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8043 [(set (match_operand 0 "register_operand")
8045 (const_int -65536)))
8046 (clobber (reg:CC FLAGS_REG))]
8047 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8048 || optimize_function_for_size_p (cfun)"
8049 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8050 "operands[1] = gen_lowpart (HImode, operands[0]);")
8053 [(set (match_operand 0 "ext_register_operand")
8056 (clobber (reg:CC FLAGS_REG))]
8057 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8058 && reload_completed"
8059 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8060 "operands[1] = gen_lowpart (QImode, operands[0]);")
8063 [(set (match_operand 0 "ext_register_operand")
8065 (const_int -65281)))
8066 (clobber (reg:CC FLAGS_REG))]
8067 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8068 && reload_completed"
8069 [(parallel [(set (zero_extract:SI (match_dup 0)
8073 (zero_extract:SI (match_dup 0)
8076 (zero_extract:SI (match_dup 0)
8079 (clobber (reg:CC FLAGS_REG))])]
8080 "operands[0] = gen_lowpart (SImode, operands[0]);")
8082 (define_insn "*anddi_2"
8083 [(set (reg FLAGS_REG)
8086 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8087 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8089 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8090 (and:DI (match_dup 1) (match_dup 2)))]
8092 && ix86_match_ccmode
8094 /* If we are going to emit andl instead of andq, and the operands[2]
8095 constant might have the SImode sign bit set, make sure the sign
8096 flag isn't tested, because the instruction will set the sign flag
8097 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8098 conservatively assume it might have bit 31 set. */
8099 (satisfies_constraint_Z (operands[2])
8100 && (!CONST_INT_P (operands[2])
8101 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8102 ? CCZmode : CCNOmode)
8103 && ix86_binary_operator_ok (AND, DImode, operands)"
8105 and{l}\t{%k2, %k0|%k0, %k2}
8106 and{q}\t{%2, %0|%0, %2}
8107 and{q}\t{%2, %0|%0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "mode" "SI,DI,DI")])
8111 (define_insn "*andqi_2_maybe_si"
8112 [(set (reg FLAGS_REG)
8114 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8115 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8117 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8118 (and:QI (match_dup 1) (match_dup 2)))]
8119 "ix86_binary_operator_ok (AND, QImode, operands)
8120 && ix86_match_ccmode (insn,
8121 CONST_INT_P (operands[2])
8122 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8124 if (which_alternative == 2)
8126 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8127 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8128 return "and{l}\t{%2, %k0|%k0, %2}";
8130 return "and{b}\t{%2, %0|%0, %2}";
8132 [(set_attr "type" "alu")
8133 (set_attr "mode" "QI,QI,SI")])
8135 (define_insn "*and<mode>_2"
8136 [(set (reg FLAGS_REG)
8137 (compare (and:SWI124
8138 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8139 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8141 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8142 (and:SWI124 (match_dup 1) (match_dup 2)))]
8143 "ix86_match_ccmode (insn, CCNOmode)
8144 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8145 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8146 [(set_attr "type" "alu")
8147 (set_attr "mode" "<MODE>")])
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_2_zext"
8151 [(set (reg FLAGS_REG)
8153 (match_operand:SI 1 "nonimmediate_operand" "%0")
8154 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8156 (set (match_operand:DI 0 "register_operand" "=r")
8157 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8158 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8159 && ix86_binary_operator_ok (AND, SImode, operands)"
8160 "and{l}\t{%2, %k0|%k0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "mode" "SI")])
8164 (define_insn "*andqi_2_slp"
8165 [(set (reg FLAGS_REG)
8167 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8168 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8170 (set (strict_low_part (match_dup 0))
8171 (and:QI (match_dup 0) (match_dup 1)))]
8172 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8173 && ix86_match_ccmode (insn, CCNOmode)
8174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8175 "and{b}\t{%1, %0|%0, %1}"
8176 [(set_attr "type" "alu1")
8177 (set_attr "mode" "QI")])
8179 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8180 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8181 ;; for a QImode operand, which of course failed.
8182 (define_insn "andqi_ext_0"
8183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (match_operand 1 "ext_register_operand" "0")
8191 (match_operand 2 "const_int_operand" "n")))
8192 (clobber (reg:CC FLAGS_REG))]
8194 "and{b}\t{%2, %h0|%h0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "length_immediate" "1")
8197 (set_attr "modrm" "1")
8198 (set_attr "mode" "QI")])
8200 ;; Generated by peephole translating test to and. This shows up
8201 ;; often in fp comparisons.
8202 (define_insn "*andqi_ext_0_cc"
8203 [(set (reg FLAGS_REG)
8207 (match_operand 1 "ext_register_operand" "0")
8210 (match_operand 2 "const_int_operand" "n"))
8212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8221 "ix86_match_ccmode (insn, CCNOmode)"
8222 "and{b}\t{%2, %h0|%h0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "length_immediate" "1")
8225 (set_attr "modrm" "1")
8226 (set_attr "mode" "QI")])
8228 (define_insn "*andqi_ext_1"
8229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8234 (match_operand 1 "ext_register_operand" "0,0")
8238 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8239 (clobber (reg:CC FLAGS_REG))]
8241 "and{b}\t{%2, %h0|%h0, %2}"
8242 [(set_attr "isa" "*,nox64")
8243 (set_attr "type" "alu")
8244 (set_attr "length_immediate" "0")
8245 (set_attr "mode" "QI")])
8247 (define_insn "*andqi_ext_2"
8248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (match_operand 1 "ext_register_operand" "%0")
8257 (match_operand 2 "ext_register_operand" "Q")
8260 (clobber (reg:CC FLAGS_REG))]
8262 "and{b}\t{%h2, %h0|%h0, %h2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "length_immediate" "0")
8265 (set_attr "mode" "QI")])
8267 ;; Convert wide AND instructions with immediate operand to shorter QImode
8268 ;; equivalents when possible.
8269 ;; Don't do the splitting with memory operands, since it introduces risk
8270 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8271 ;; for size, but that can (should?) be handled by generic code instead.
8273 [(set (match_operand 0 "register_operand")
8274 (and (match_operand 1 "register_operand")
8275 (match_operand 2 "const_int_operand")))
8276 (clobber (reg:CC FLAGS_REG))]
8278 && QI_REG_P (operands[0])
8279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8280 && !(~INTVAL (operands[2]) & ~(255 << 8))
8281 && GET_MODE (operands[0]) != QImode"
8282 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8283 (and:SI (zero_extract:SI (match_dup 1)
8284 (const_int 8) (const_int 8))
8286 (clobber (reg:CC FLAGS_REG))])]
8288 operands[0] = gen_lowpart (SImode, operands[0]);
8289 operands[1] = gen_lowpart (SImode, operands[1]);
8290 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8293 ;; Since AND can be encoded with sign extended immediate, this is only
8294 ;; profitable when 7th bit is not set.
8296 [(set (match_operand 0 "register_operand")
8297 (and (match_operand 1 "general_operand")
8298 (match_operand 2 "const_int_operand")))
8299 (clobber (reg:CC FLAGS_REG))]
8301 && ANY_QI_REG_P (operands[0])
8302 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8303 && !(~INTVAL (operands[2]) & ~255)
8304 && !(INTVAL (operands[2]) & 128)
8305 && GET_MODE (operands[0]) != QImode"
8306 [(parallel [(set (strict_low_part (match_dup 0))
8307 (and:QI (match_dup 1)
8309 (clobber (reg:CC FLAGS_REG))])]
8311 operands[0] = gen_lowpart (QImode, operands[0]);
8312 operands[1] = gen_lowpart (QImode, operands[1]);
8313 operands[2] = gen_lowpart (QImode, operands[2]);
8316 ;; Logical inclusive and exclusive OR instructions
8318 ;; %%% This used to optimize known byte-wide and operations to memory.
8319 ;; If this is considered useful, it should be done with splitters.
8321 (define_expand "<code><mode>3"
8322 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8323 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8324 (match_operand:SWIM 2 "<general_operand>")))]
8326 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8328 (define_insn "*<code><mode>_1"
8329 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8331 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8332 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8336 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8337 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8338 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8339 [(set_attr "type" "alu,alu,msklog")
8340 (set_attr "mode" "<MODE>")])
8342 (define_insn "*<code>hi_1"
8343 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8345 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8346 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8347 (clobber (reg:CC FLAGS_REG))]
8348 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8350 <logic>{w}\t{%2, %0|%0, %2}
8351 <logic>{w}\t{%2, %0|%0, %2}
8352 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8353 [(set_attr "type" "alu,alu,msklog")
8354 (set_attr "mode" "HI")])
8356 ;; %%% Potential partial reg stall on alternative 2. What to do?
8357 (define_insn "*<code>qi_1"
8358 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8359 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8360 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8361 (clobber (reg:CC FLAGS_REG))]
8362 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8364 <logic>{b}\t{%2, %0|%0, %2}
8365 <logic>{b}\t{%2, %0|%0, %2}
8366 <logic>{l}\t{%k2, %k0|%k0, %k2}
8367 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8368 [(set_attr "type" "alu,alu,alu,msklog")
8369 (set_attr "mode" "QI,QI,SI,HI")])
8371 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8372 (define_insn "*<code>si_1_zext"
8373 [(set (match_operand:DI 0 "register_operand" "=r")
8375 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8376 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8377 (clobber (reg:CC FLAGS_REG))]
8378 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8379 "<logic>{l}\t{%2, %k0|%k0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "SI")])
8383 (define_insn "*<code>si_1_zext_imm"
8384 [(set (match_operand:DI 0 "register_operand" "=r")
8386 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8387 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8388 (clobber (reg:CC FLAGS_REG))]
8389 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8390 "<logic>{l}\t{%2, %k0|%k0, %2}"
8391 [(set_attr "type" "alu")
8392 (set_attr "mode" "SI")])
8394 (define_insn "*<code>qi_1_slp"
8395 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8396 (any_or:QI (match_dup 0)
8397 (match_operand:QI 1 "general_operand" "qmn,qn")))
8398 (clobber (reg:CC FLAGS_REG))]
8399 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8400 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8401 "<logic>{b}\t{%1, %0|%0, %1}"
8402 [(set_attr "type" "alu1")
8403 (set_attr "mode" "QI")])
8405 (define_insn "*<code><mode>_2"
8406 [(set (reg FLAGS_REG)
8407 (compare (any_or:SWI
8408 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8409 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8411 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8412 (any_or:SWI (match_dup 1) (match_dup 2)))]
8413 "ix86_match_ccmode (insn, CCNOmode)
8414 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8415 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8416 [(set_attr "type" "alu")
8417 (set_attr "mode" "<MODE>")])
8419 (define_insn "kxnor<mode>"
8420 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8423 (match_operand:SWI12 1 "register_operand" "0,k")
8424 (match_operand:SWI12 2 "register_operand" "r,k"))))
8425 (clobber (reg:CC FLAGS_REG))]
8428 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8429 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8430 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8432 [(set_attr "type" "*,msklog")
8433 (set_attr "prefix" "*,vex")
8434 (set_attr "mode" "<MODE>")])
8436 (define_insn "kxnor<mode>"
8437 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8440 (match_operand:SWI48x 1 "register_operand" "0,k")
8441 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8442 (clobber (reg:CC FLAGS_REG))]
8446 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8447 [(set_attr "type" "*,msklog")
8448 (set_attr "prefix" "*,vex")
8449 (set_attr "mode" "<MODE>")])
8452 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8456 (match_operand:SWI1248x 1 "general_reg_operand"))))
8457 (clobber (reg:CC FLAGS_REG))]
8458 "TARGET_AVX512F && reload_completed"
8459 [(parallel [(set (match_dup 0)
8460 (xor:HI (match_dup 0)
8462 (clobber (reg:CC FLAGS_REG))])
8464 (not:HI (match_dup 0)))])
8466 ;;There are kortrest[bdq] but no intrinsics for them.
8467 ;;We probably don't need to implement them.
8468 (define_insn "kortestzhi"
8469 [(set (reg:CCZ FLAGS_REG)
8472 (match_operand:HI 0 "register_operand" "k")
8473 (match_operand:HI 1 "register_operand" "k"))
8475 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8476 "kortestw\t{%1, %0|%0, %1}"
8477 [(set_attr "mode" "HI")
8478 (set_attr "type" "msklog")
8479 (set_attr "prefix" "vex")])
8481 (define_insn "kortestchi"
8482 [(set (reg:CCC FLAGS_REG)
8485 (match_operand:HI 0 "register_operand" "k")
8486 (match_operand:HI 1 "register_operand" "k"))
8488 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8489 "kortestw\t{%1, %0|%0, %1}"
8490 [(set_attr "mode" "HI")
8491 (set_attr "type" "msklog")
8492 (set_attr "prefix" "vex")])
8494 (define_insn "kunpckhi"
8495 [(set (match_operand:HI 0 "register_operand" "=k")
8498 (match_operand:HI 1 "register_operand" "k")
8500 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8502 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8503 [(set_attr "mode" "HI")
8504 (set_attr "type" "msklog")
8505 (set_attr "prefix" "vex")])
8507 (define_insn "kunpcksi"
8508 [(set (match_operand:SI 0 "register_operand" "=k")
8511 (match_operand:SI 1 "register_operand" "k")
8513 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8515 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8516 [(set_attr "mode" "SI")])
8518 (define_insn "kunpckdi"
8519 [(set (match_operand:DI 0 "register_operand" "=k")
8522 (match_operand:DI 1 "register_operand" "k")
8524 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8526 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8527 [(set_attr "mode" "DI")])
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 ;; ??? Special case for immediate operand is missing - it is tricky.
8531 (define_insn "*<code>si_2_zext"
8532 [(set (reg FLAGS_REG)
8533 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8536 (set (match_operand:DI 0 "register_operand" "=r")
8537 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8539 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8540 "<logic>{l}\t{%2, %k0|%k0, %2}"
8541 [(set_attr "type" "alu")
8542 (set_attr "mode" "SI")])
8544 (define_insn "*<code>si_2_zext_imm"
8545 [(set (reg FLAGS_REG)
8547 (match_operand:SI 1 "nonimmediate_operand" "%0")
8548 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8550 (set (match_operand:DI 0 "register_operand" "=r")
8551 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8552 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8553 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8554 "<logic>{l}\t{%2, %k0|%k0, %2}"
8555 [(set_attr "type" "alu")
8556 (set_attr "mode" "SI")])
8558 (define_insn "*<code>qi_2_slp"
8559 [(set (reg FLAGS_REG)
8560 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8561 (match_operand:QI 1 "general_operand" "qmn,qn"))
8563 (set (strict_low_part (match_dup 0))
8564 (any_or:QI (match_dup 0) (match_dup 1)))]
8565 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8566 && ix86_match_ccmode (insn, CCNOmode)
8567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8568 "<logic>{b}\t{%1, %0|%0, %1}"
8569 [(set_attr "type" "alu1")
8570 (set_attr "mode" "QI")])
8572 (define_insn "*<code><mode>_3"
8573 [(set (reg FLAGS_REG)
8574 (compare (any_or:SWI
8575 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8576 (match_operand:SWI 2 "<general_operand>" "<g>"))
8578 (clobber (match_scratch:SWI 0 "=<r>"))]
8579 "ix86_match_ccmode (insn, CCNOmode)
8580 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8581 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8582 [(set_attr "type" "alu")
8583 (set_attr "mode" "<MODE>")])
8585 (define_insn "*<code>qi_ext_0"
8586 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8591 (match_operand 1 "ext_register_operand" "0")
8594 (match_operand 2 "const_int_operand" "n")))
8595 (clobber (reg:CC FLAGS_REG))]
8596 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8597 "<logic>{b}\t{%2, %h0|%h0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "length_immediate" "1")
8600 (set_attr "modrm" "1")
8601 (set_attr "mode" "QI")])
8603 (define_insn "*<code>qi_ext_1"
8604 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8609 (match_operand 1 "ext_register_operand" "0,0")
8613 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8616 "<logic>{b}\t{%2, %h0|%h0, %2}"
8617 [(set_attr "isa" "*,nox64")
8618 (set_attr "type" "alu")
8619 (set_attr "length_immediate" "0")
8620 (set_attr "mode" "QI")])
8622 (define_insn "*<code>qi_ext_2"
8623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8627 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8630 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8633 (clobber (reg:CC FLAGS_REG))]
8634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8635 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "length_immediate" "0")
8638 (set_attr "mode" "QI")])
8641 [(set (match_operand 0 "register_operand")
8642 (any_or (match_operand 1 "register_operand")
8643 (match_operand 2 "const_int_operand")))
8644 (clobber (reg:CC FLAGS_REG))]
8646 && QI_REG_P (operands[0])
8647 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8648 && !(INTVAL (operands[2]) & ~(255 << 8))
8649 && GET_MODE (operands[0]) != QImode"
8650 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8651 (any_or:SI (zero_extract:SI (match_dup 1)
8652 (const_int 8) (const_int 8))
8654 (clobber (reg:CC FLAGS_REG))])]
8656 operands[0] = gen_lowpart (SImode, operands[0]);
8657 operands[1] = gen_lowpart (SImode, operands[1]);
8658 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8661 ;; Since OR can be encoded with sign extended immediate, this is only
8662 ;; profitable when 7th bit is set.
8664 [(set (match_operand 0 "register_operand")
8665 (any_or (match_operand 1 "general_operand")
8666 (match_operand 2 "const_int_operand")))
8667 (clobber (reg:CC FLAGS_REG))]
8669 && ANY_QI_REG_P (operands[0])
8670 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8671 && !(INTVAL (operands[2]) & ~255)
8672 && (INTVAL (operands[2]) & 128)
8673 && GET_MODE (operands[0]) != QImode"
8674 [(parallel [(set (strict_low_part (match_dup 0))
8675 (any_or:QI (match_dup 1)
8677 (clobber (reg:CC FLAGS_REG))])]
8679 operands[0] = gen_lowpart (QImode, operands[0]);
8680 operands[1] = gen_lowpart (QImode, operands[1]);
8681 operands[2] = gen_lowpart (QImode, operands[2]);
8684 (define_expand "xorqi_cc_ext_1"
8686 (set (reg:CCNO FLAGS_REG)
8690 (match_operand 1 "ext_register_operand")
8693 (match_operand:QI 2 "const_int_operand"))
8695 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8705 (define_insn "*xorqi_cc_ext_1"
8706 [(set (reg FLAGS_REG)
8710 (match_operand 1 "ext_register_operand" "0,0")
8713 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8715 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8724 "ix86_match_ccmode (insn, CCNOmode)"
8725 "xor{b}\t{%2, %h0|%h0, %2}"
8726 [(set_attr "isa" "*,nox64")
8727 (set_attr "type" "alu")
8728 (set_attr "modrm" "1")
8729 (set_attr "mode" "QI")])
8731 ;; Negation instructions
8733 (define_expand "neg<mode>2"
8734 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8735 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8737 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8739 (define_insn_and_split "*neg<dwi>2_doubleword"
8740 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8741 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8747 [(set (reg:CCZ FLAGS_REG)
8748 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8749 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8752 (plus:DWIH (match_dup 3)
8753 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8755 (clobber (reg:CC FLAGS_REG))])
8758 (neg:DWIH (match_dup 2)))
8759 (clobber (reg:CC FLAGS_REG))])]
8760 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8762 (define_insn "*neg<mode>2_1"
8763 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8764 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8765 (clobber (reg:CC FLAGS_REG))]
8766 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8767 "neg{<imodesuffix>}\t%0"
8768 [(set_attr "type" "negnot")
8769 (set_attr "mode" "<MODE>")])
8771 ;; Combine is quite creative about this pattern.
8772 (define_insn "*negsi2_1_zext"
8773 [(set (match_operand:DI 0 "register_operand" "=r")
8775 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8778 (clobber (reg:CC FLAGS_REG))]
8779 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8781 [(set_attr "type" "negnot")
8782 (set_attr "mode" "SI")])
8784 ;; The problem with neg is that it does not perform (compare x 0),
8785 ;; it really performs (compare 0 x), which leaves us with the zero
8786 ;; flag being the only useful item.
8788 (define_insn "*neg<mode>2_cmpz"
8789 [(set (reg:CCZ FLAGS_REG)
8791 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8793 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8794 (neg:SWI (match_dup 1)))]
8795 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8796 "neg{<imodesuffix>}\t%0"
8797 [(set_attr "type" "negnot")
8798 (set_attr "mode" "<MODE>")])
8800 (define_insn "*negsi2_cmpz_zext"
8801 [(set (reg:CCZ FLAGS_REG)
8805 (match_operand:DI 1 "register_operand" "0")
8809 (set (match_operand:DI 0 "register_operand" "=r")
8810 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8813 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8815 [(set_attr "type" "negnot")
8816 (set_attr "mode" "SI")])
8818 ;; Negate with jump on overflow.
8819 (define_expand "negv<mode>3"
8820 [(parallel [(set (reg:CCO FLAGS_REG)
8821 (ne:CCO (match_operand:SWI 1 "register_operand")
8823 (set (match_operand:SWI 0 "register_operand")
8824 (neg:SWI (match_dup 1)))])
8825 (set (pc) (if_then_else
8826 (eq (reg:CCO FLAGS_REG) (const_int 0))
8827 (label_ref (match_operand 2))
8832 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8836 (define_insn "*negv<mode>3"
8837 [(set (reg:CCO FLAGS_REG)
8838 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8839 (match_operand:SWI 2 "const_int_operand")))
8840 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8841 (neg:SWI (match_dup 1)))]
8842 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8843 && mode_signbit_p (<MODE>mode, operands[2])"
8844 "neg{<imodesuffix>}\t%0"
8845 [(set_attr "type" "negnot")
8846 (set_attr "mode" "<MODE>")])
8848 ;; Changing of sign for FP values is doable using integer unit too.
8850 (define_expand "<code><mode>2"
8851 [(set (match_operand:X87MODEF 0 "register_operand")
8852 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8853 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8854 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8856 (define_insn "*absneg<mode>2_mixed"
8857 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8858 (match_operator:MODEF 3 "absneg_operator"
8859 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8860 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8865 (define_insn "*absneg<mode>2_sse"
8866 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8867 (match_operator:MODEF 3 "absneg_operator"
8868 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8869 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8874 (define_insn "*absneg<mode>2_i387"
8875 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8876 (match_operator:X87MODEF 3 "absneg_operator"
8877 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8878 (use (match_operand 2))
8879 (clobber (reg:CC FLAGS_REG))]
8880 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8883 (define_expand "<code>tf2"
8884 [(set (match_operand:TF 0 "register_operand")
8885 (absneg:TF (match_operand:TF 1 "register_operand")))]
8887 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8889 (define_insn "*absnegtf2_sse"
8890 [(set (match_operand:TF 0 "register_operand" "=x,x")
8891 (match_operator:TF 3 "absneg_operator"
8892 [(match_operand:TF 1 "register_operand" "0,x")]))
8893 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8894 (clobber (reg:CC FLAGS_REG))]
8898 ;; Splitters for fp abs and neg.
8901 [(set (match_operand 0 "fp_register_operand")
8902 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8903 (use (match_operand 2))
8904 (clobber (reg:CC FLAGS_REG))]
8906 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8909 [(set (match_operand 0 "register_operand")
8910 (match_operator 3 "absneg_operator"
8911 [(match_operand 1 "register_operand")]))
8912 (use (match_operand 2 "nonimmediate_operand"))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "reload_completed && SSE_REG_P (operands[0])"
8915 [(set (match_dup 0) (match_dup 3))]
8917 machine_mode mode = GET_MODE (operands[0]);
8918 machine_mode vmode = GET_MODE (operands[2]);
8921 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8922 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8923 if (operands_match_p (operands[0], operands[2]))
8924 std::swap (operands[1], operands[2]);
8925 if (GET_CODE (operands[3]) == ABS)
8926 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8928 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8933 [(set (match_operand:SF 0 "register_operand")
8934 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8935 (use (match_operand:V4SF 2))
8936 (clobber (reg:CC FLAGS_REG))]
8938 [(parallel [(set (match_dup 0) (match_dup 1))
8939 (clobber (reg:CC FLAGS_REG))])]
8942 operands[0] = gen_lowpart (SImode, operands[0]);
8943 if (GET_CODE (operands[1]) == ABS)
8945 tmp = gen_int_mode (0x7fffffff, SImode);
8946 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8950 tmp = gen_int_mode (0x80000000, SImode);
8951 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8957 [(set (match_operand:DF 0 "register_operand")
8958 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8959 (use (match_operand 2))
8960 (clobber (reg:CC FLAGS_REG))]
8962 [(parallel [(set (match_dup 0) (match_dup 1))
8963 (clobber (reg:CC FLAGS_REG))])]
8968 tmp = gen_lowpart (DImode, operands[0]);
8969 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8972 if (GET_CODE (operands[1]) == ABS)
8975 tmp = gen_rtx_NOT (DImode, tmp);
8979 operands[0] = gen_highpart (SImode, operands[0]);
8980 if (GET_CODE (operands[1]) == ABS)
8982 tmp = gen_int_mode (0x7fffffff, SImode);
8983 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8987 tmp = gen_int_mode (0x80000000, SImode);
8988 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8995 [(set (match_operand:XF 0 "register_operand")
8996 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8997 (use (match_operand 2))
8998 (clobber (reg:CC FLAGS_REG))]
9000 [(parallel [(set (match_dup 0) (match_dup 1))
9001 (clobber (reg:CC FLAGS_REG))])]
9004 operands[0] = gen_rtx_REG (SImode,
9005 true_regnum (operands[0])
9006 + (TARGET_64BIT ? 1 : 2));
9007 if (GET_CODE (operands[1]) == ABS)
9009 tmp = GEN_INT (0x7fff);
9010 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9014 tmp = GEN_INT (0x8000);
9015 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9020 ;; Conditionalize these after reload. If they match before reload, we
9021 ;; lose the clobber and ability to use integer instructions.
9023 (define_insn "*<code><mode>2_1"
9024 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9025 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9027 && (reload_completed
9028 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9029 "f<absneg_mnemonic>"
9030 [(set_attr "type" "fsgn")
9031 (set_attr "mode" "<MODE>")])
9033 (define_insn "*<code>extendsfdf2"
9034 [(set (match_operand:DF 0 "register_operand" "=f")
9035 (absneg:DF (float_extend:DF
9036 (match_operand:SF 1 "register_operand" "0"))))]
9037 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9038 "f<absneg_mnemonic>"
9039 [(set_attr "type" "fsgn")
9040 (set_attr "mode" "DF")])
9042 (define_insn "*<code>extendsfxf2"
9043 [(set (match_operand:XF 0 "register_operand" "=f")
9044 (absneg:XF (float_extend:XF
9045 (match_operand:SF 1 "register_operand" "0"))))]
9047 "f<absneg_mnemonic>"
9048 [(set_attr "type" "fsgn")
9049 (set_attr "mode" "XF")])
9051 (define_insn "*<code>extenddfxf2"
9052 [(set (match_operand:XF 0 "register_operand" "=f")
9053 (absneg:XF (float_extend:XF
9054 (match_operand:DF 1 "register_operand" "0"))))]
9056 "f<absneg_mnemonic>"
9057 [(set_attr "type" "fsgn")
9058 (set_attr "mode" "XF")])
9060 ;; Copysign instructions
9062 (define_mode_iterator CSGNMODE [SF DF TF])
9063 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9065 (define_expand "copysign<mode>3"
9066 [(match_operand:CSGNMODE 0 "register_operand")
9067 (match_operand:CSGNMODE 1 "nonmemory_operand")
9068 (match_operand:CSGNMODE 2 "register_operand")]
9069 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9070 || (TARGET_SSE && (<MODE>mode == TFmode))"
9071 "ix86_expand_copysign (operands); DONE;")
9073 (define_insn_and_split "copysign<mode>3_const"
9074 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9076 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9077 (match_operand:CSGNMODE 2 "register_operand" "0")
9078 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9080 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9081 || (TARGET_SSE && (<MODE>mode == TFmode))"
9083 "&& reload_completed"
9085 "ix86_split_copysign_const (operands); DONE;")
9087 (define_insn "copysign<mode>3_var"
9088 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9090 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9091 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9092 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9093 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9095 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9096 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9097 || (TARGET_SSE && (<MODE>mode == TFmode))"
9101 [(set (match_operand:CSGNMODE 0 "register_operand")
9103 [(match_operand:CSGNMODE 2 "register_operand")
9104 (match_operand:CSGNMODE 3 "register_operand")
9105 (match_operand:<CSGNVMODE> 4)
9106 (match_operand:<CSGNVMODE> 5)]
9108 (clobber (match_scratch:<CSGNVMODE> 1))]
9109 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9110 || (TARGET_SSE && (<MODE>mode == TFmode)))
9111 && reload_completed"
9113 "ix86_split_copysign_var (operands); DONE;")
9115 ;; One complement instructions
9117 (define_expand "one_cmpl<mode>2"
9118 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9119 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9121 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9123 (define_insn "*one_cmpl<mode>2_1"
9124 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9125 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9126 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9128 not{<imodesuffix>}\t%0
9129 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9130 [(set_attr "isa" "*,avx512bw")
9131 (set_attr "type" "negnot,msklog")
9132 (set_attr "prefix" "*,vex")
9133 (set_attr "mode" "<MODE>")])
9135 (define_insn "*one_cmplhi2_1"
9136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9138 "ix86_unary_operator_ok (NOT, HImode, operands)"
9141 knotw\t{%1, %0|%0, %1}"
9142 [(set_attr "isa" "*,avx512f")
9143 (set_attr "type" "negnot,msklog")
9144 (set_attr "prefix" "*,vex")
9145 (set_attr "mode" "HI")])
9147 ;; %%% Potential partial reg stall on alternative 1. What to do?
9148 (define_insn "*one_cmplqi2_1"
9149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9150 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9151 "ix86_unary_operator_ok (NOT, QImode, operands)"
9153 switch (which_alternative)
9156 return "not{b}\t%0";
9158 return "not{l}\t%k0";
9160 if (TARGET_AVX512DQ)
9161 return "knotb\t{%1, %0|%0, %1}";
9162 return "knotw\t{%1, %0|%0, %1}";
9167 [(set_attr "isa" "*,*,avx512f")
9168 (set_attr "type" "negnot,negnot,msklog")
9169 (set_attr "prefix" "*,*,vex")
9170 (set_attr "mode" "QI,SI,QI")])
9172 ;; ??? Currently never generated - xor is used instead.
9173 (define_insn "*one_cmplsi2_1_zext"
9174 [(set (match_operand:DI 0 "register_operand" "=r")
9176 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9177 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9179 [(set_attr "type" "negnot")
9180 (set_attr "mode" "SI")])
9182 (define_insn "*one_cmpl<mode>2_2"
9183 [(set (reg FLAGS_REG)
9184 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9186 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9187 (not:SWI (match_dup 1)))]
9188 "ix86_match_ccmode (insn, CCNOmode)
9189 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9191 [(set_attr "type" "alu1")
9192 (set_attr "mode" "<MODE>")])
9195 [(set (match_operand 0 "flags_reg_operand")
9196 (match_operator 2 "compare_operator"
9197 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9199 (set (match_operand:SWI 1 "nonimmediate_operand")
9200 (not:SWI (match_dup 3)))]
9201 "ix86_match_ccmode (insn, CCNOmode)"
9202 [(parallel [(set (match_dup 0)
9203 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9206 (xor:SWI (match_dup 3) (const_int -1)))])])
9208 ;; ??? Currently never generated - xor is used instead.
9209 (define_insn "*one_cmplsi2_2_zext"
9210 [(set (reg FLAGS_REG)
9211 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9213 (set (match_operand:DI 0 "register_operand" "=r")
9214 (zero_extend:DI (not:SI (match_dup 1))))]
9215 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9216 && ix86_unary_operator_ok (NOT, SImode, operands)"
9218 [(set_attr "type" "alu1")
9219 (set_attr "mode" "SI")])
9222 [(set (match_operand 0 "flags_reg_operand")
9223 (match_operator 2 "compare_operator"
9224 [(not:SI (match_operand:SI 3 "register_operand"))
9226 (set (match_operand:DI 1 "register_operand")
9227 (zero_extend:DI (not:SI (match_dup 3))))]
9228 "ix86_match_ccmode (insn, CCNOmode)"
9229 [(parallel [(set (match_dup 0)
9230 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9233 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9235 ;; Shift instructions
9237 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9238 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9239 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9240 ;; from the assembler input.
9242 ;; This instruction shifts the target reg/mem as usual, but instead of
9243 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9244 ;; is a left shift double, bits are taken from the high order bits of
9245 ;; reg, else if the insn is a shift right double, bits are taken from the
9246 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9247 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9249 ;; Since sh[lr]d does not change the `reg' operand, that is done
9250 ;; separately, making all shifts emit pairs of shift double and normal
9251 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9252 ;; support a 63 bit shift, each shift where the count is in a reg expands
9253 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9255 ;; If the shift count is a constant, we need never emit more than one
9256 ;; shift pair, instead using moves and sign extension for counts greater
9259 (define_expand "ashl<mode>3"
9260 [(set (match_operand:SDWIM 0 "<shift_operand>")
9261 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9262 (match_operand:QI 2 "nonmemory_operand")))]
9264 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9266 (define_insn "*ashl<mode>3_doubleword"
9267 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9268 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9269 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9270 (clobber (reg:CC FLAGS_REG))]
9273 [(set_attr "type" "multi")])
9276 [(set (match_operand:DWI 0 "register_operand")
9277 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9278 (match_operand:QI 2 "nonmemory_operand")))
9279 (clobber (reg:CC FLAGS_REG))]
9280 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9282 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9284 ;; By default we don't ask for a scratch register, because when DWImode
9285 ;; values are manipulated, registers are already at a premium. But if
9286 ;; we have one handy, we won't turn it away.
9289 [(match_scratch:DWIH 3 "r")
9290 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9292 (match_operand:<DWI> 1 "nonmemory_operand")
9293 (match_operand:QI 2 "nonmemory_operand")))
9294 (clobber (reg:CC FLAGS_REG))])
9298 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9300 (define_insn "x86_64_shld"
9301 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9302 (ior:DI (ashift:DI (match_dup 0)
9303 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9304 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9305 (minus:QI (const_int 64) (match_dup 2)))))
9306 (clobber (reg:CC FLAGS_REG))]
9308 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9309 [(set_attr "type" "ishift")
9310 (set_attr "prefix_0f" "1")
9311 (set_attr "mode" "DI")
9312 (set_attr "athlon_decode" "vector")
9313 (set_attr "amdfam10_decode" "vector")
9314 (set_attr "bdver1_decode" "vector")])
9316 (define_insn "x86_shld"
9317 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9318 (ior:SI (ashift:SI (match_dup 0)
9319 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9320 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9321 (minus:QI (const_int 32) (match_dup 2)))))
9322 (clobber (reg:CC FLAGS_REG))]
9324 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9325 [(set_attr "type" "ishift")
9326 (set_attr "prefix_0f" "1")
9327 (set_attr "mode" "SI")
9328 (set_attr "pent_pair" "np")
9329 (set_attr "athlon_decode" "vector")
9330 (set_attr "amdfam10_decode" "vector")
9331 (set_attr "bdver1_decode" "vector")])
9333 (define_expand "x86_shift<mode>_adj_1"
9334 [(set (reg:CCZ FLAGS_REG)
9335 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9338 (set (match_operand:SWI48 0 "register_operand")
9339 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9340 (match_operand:SWI48 1 "register_operand")
9343 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9344 (match_operand:SWI48 3 "register_operand")
9347 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9349 (define_expand "x86_shift<mode>_adj_2"
9350 [(use (match_operand:SWI48 0 "register_operand"))
9351 (use (match_operand:SWI48 1 "register_operand"))
9352 (use (match_operand:QI 2 "register_operand"))]
9355 rtx_code_label *label = gen_label_rtx ();
9358 emit_insn (gen_testqi_ccz_1 (operands[2],
9359 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9361 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9362 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9363 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9364 gen_rtx_LABEL_REF (VOIDmode, label),
9366 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9367 JUMP_LABEL (tmp) = label;
9369 emit_move_insn (operands[0], operands[1]);
9370 ix86_expand_clear (operands[1]);
9373 LABEL_NUSES (label) = 1;
9378 ;; Avoid useless masking of count operand.
9379 (define_insn "*ashl<mode>3_mask"
9380 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9382 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9385 (match_operand:SI 2 "register_operand" "c")
9386 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9389 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9390 == GET_MODE_BITSIZE (<MODE>mode)-1"
9392 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9394 [(set_attr "type" "ishift")
9395 (set_attr "mode" "<MODE>")])
9397 (define_insn "*bmi2_ashl<mode>3_1"
9398 [(set (match_operand:SWI48 0 "register_operand" "=r")
9399 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9400 (match_operand:SWI48 2 "register_operand" "r")))]
9402 "shlx\t{%2, %1, %0|%0, %1, %2}"
9403 [(set_attr "type" "ishiftx")
9404 (set_attr "mode" "<MODE>")])
9406 (define_insn "*ashl<mode>3_1"
9407 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9408 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9409 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9413 switch (get_attr_type (insn))
9420 gcc_assert (operands[2] == const1_rtx);
9421 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9422 return "add{<imodesuffix>}\t%0, %0";
9425 if (operands[2] == const1_rtx
9426 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427 return "sal{<imodesuffix>}\t%0";
9429 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9432 [(set_attr "isa" "*,*,bmi2")
9434 (cond [(eq_attr "alternative" "1")
9435 (const_string "lea")
9436 (eq_attr "alternative" "2")
9437 (const_string "ishiftx")
9438 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9439 (match_operand 0 "register_operand"))
9440 (match_operand 2 "const1_operand"))
9441 (const_string "alu")
9443 (const_string "ishift")))
9444 (set (attr "length_immediate")
9446 (ior (eq_attr "type" "alu")
9447 (and (eq_attr "type" "ishift")
9448 (and (match_operand 2 "const1_operand")
9449 (ior (match_test "TARGET_SHIFT1")
9450 (match_test "optimize_function_for_size_p (cfun)")))))
9452 (const_string "*")))
9453 (set_attr "mode" "<MODE>")])
9455 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9457 [(set (match_operand:SWI48 0 "register_operand")
9458 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9459 (match_operand:QI 2 "register_operand")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 "TARGET_BMI2 && reload_completed"
9463 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9464 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9466 (define_insn "*bmi2_ashlsi3_1_zext"
9467 [(set (match_operand:DI 0 "register_operand" "=r")
9469 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9470 (match_operand:SI 2 "register_operand" "r"))))]
9471 "TARGET_64BIT && TARGET_BMI2"
9472 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9473 [(set_attr "type" "ishiftx")
9474 (set_attr "mode" "SI")])
9476 (define_insn "*ashlsi3_1_zext"
9477 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9479 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9480 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9484 switch (get_attr_type (insn))
9491 gcc_assert (operands[2] == const1_rtx);
9492 return "add{l}\t%k0, %k0";
9495 if (operands[2] == const1_rtx
9496 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9497 return "sal{l}\t%k0";
9499 return "sal{l}\t{%2, %k0|%k0, %2}";
9502 [(set_attr "isa" "*,*,bmi2")
9504 (cond [(eq_attr "alternative" "1")
9505 (const_string "lea")
9506 (eq_attr "alternative" "2")
9507 (const_string "ishiftx")
9508 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9509 (match_operand 2 "const1_operand"))
9510 (const_string "alu")
9512 (const_string "ishift")))
9513 (set (attr "length_immediate")
9515 (ior (eq_attr "type" "alu")
9516 (and (eq_attr "type" "ishift")
9517 (and (match_operand 2 "const1_operand")
9518 (ior (match_test "TARGET_SHIFT1")
9519 (match_test "optimize_function_for_size_p (cfun)")))))
9521 (const_string "*")))
9522 (set_attr "mode" "SI")])
9524 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9526 [(set (match_operand:DI 0 "register_operand")
9528 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9529 (match_operand:QI 2 "register_operand"))))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9533 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9534 "operands[2] = gen_lowpart (SImode, operands[2]);")
9536 (define_insn "*ashlhi3_1"
9537 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9538 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9539 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9543 switch (get_attr_type (insn))
9549 gcc_assert (operands[2] == const1_rtx);
9550 return "add{w}\t%0, %0";
9553 if (operands[2] == const1_rtx
9554 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9555 return "sal{w}\t%0";
9557 return "sal{w}\t{%2, %0|%0, %2}";
9561 (cond [(eq_attr "alternative" "1")
9562 (const_string "lea")
9563 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9564 (match_operand 0 "register_operand"))
9565 (match_operand 2 "const1_operand"))
9566 (const_string "alu")
9568 (const_string "ishift")))
9569 (set (attr "length_immediate")
9571 (ior (eq_attr "type" "alu")
9572 (and (eq_attr "type" "ishift")
9573 (and (match_operand 2 "const1_operand")
9574 (ior (match_test "TARGET_SHIFT1")
9575 (match_test "optimize_function_for_size_p (cfun)")))))
9577 (const_string "*")))
9578 (set_attr "mode" "HI,SI")])
9580 ;; %%% Potential partial reg stall on alternative 1. What to do?
9581 (define_insn "*ashlqi3_1"
9582 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9583 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9584 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9588 switch (get_attr_type (insn))
9594 gcc_assert (operands[2] == const1_rtx);
9595 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9596 return "add{l}\t%k0, %k0";
9598 return "add{b}\t%0, %0";
9601 if (operands[2] == const1_rtx
9602 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9604 if (get_attr_mode (insn) == MODE_SI)
9605 return "sal{l}\t%k0";
9607 return "sal{b}\t%0";
9611 if (get_attr_mode (insn) == MODE_SI)
9612 return "sal{l}\t{%2, %k0|%k0, %2}";
9614 return "sal{b}\t{%2, %0|%0, %2}";
9619 (cond [(eq_attr "alternative" "2")
9620 (const_string "lea")
9621 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9622 (match_operand 0 "register_operand"))
9623 (match_operand 2 "const1_operand"))
9624 (const_string "alu")
9626 (const_string "ishift")))
9627 (set (attr "length_immediate")
9629 (ior (eq_attr "type" "alu")
9630 (and (eq_attr "type" "ishift")
9631 (and (match_operand 2 "const1_operand")
9632 (ior (match_test "TARGET_SHIFT1")
9633 (match_test "optimize_function_for_size_p (cfun)")))))
9635 (const_string "*")))
9636 (set_attr "mode" "QI,SI,SI")])
9638 (define_insn "*ashlqi3_1_slp"
9639 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9640 (ashift:QI (match_dup 0)
9641 (match_operand:QI 1 "nonmemory_operand" "cI")))
9642 (clobber (reg:CC FLAGS_REG))]
9643 "(optimize_function_for_size_p (cfun)
9644 || !TARGET_PARTIAL_FLAG_REG_STALL
9645 || (operands[1] == const1_rtx
9647 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9649 switch (get_attr_type (insn))
9652 gcc_assert (operands[1] == const1_rtx);
9653 return "add{b}\t%0, %0";
9656 if (operands[1] == const1_rtx
9657 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9658 return "sal{b}\t%0";
9660 return "sal{b}\t{%1, %0|%0, %1}";
9664 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9665 (match_operand 0 "register_operand"))
9666 (match_operand 1 "const1_operand"))
9667 (const_string "alu")
9669 (const_string "ishift1")))
9670 (set (attr "length_immediate")
9672 (ior (eq_attr "type" "alu")
9673 (and (eq_attr "type" "ishift1")
9674 (and (match_operand 1 "const1_operand")
9675 (ior (match_test "TARGET_SHIFT1")
9676 (match_test "optimize_function_for_size_p (cfun)")))))
9678 (const_string "*")))
9679 (set_attr "mode" "QI")])
9681 ;; Convert ashift to the lea pattern to avoid flags dependency.
9683 [(set (match_operand 0 "register_operand")
9684 (ashift (match_operand 1 "index_register_operand")
9685 (match_operand:QI 2 "const_int_operand")))
9686 (clobber (reg:CC FLAGS_REG))]
9687 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9689 && true_regnum (operands[0]) != true_regnum (operands[1])"
9692 machine_mode mode = GET_MODE (operands[0]);
9695 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9698 operands[0] = gen_lowpart (mode, operands[0]);
9699 operands[1] = gen_lowpart (mode, operands[1]);
9702 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9704 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9706 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9710 ;; Convert ashift to the lea pattern to avoid flags dependency.
9712 [(set (match_operand:DI 0 "register_operand")
9714 (ashift:SI (match_operand:SI 1 "index_register_operand")
9715 (match_operand:QI 2 "const_int_operand"))))
9716 (clobber (reg:CC FLAGS_REG))]
9717 "TARGET_64BIT && reload_completed
9718 && true_regnum (operands[0]) != true_regnum (operands[1])"
9720 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9722 operands[1] = gen_lowpart (SImode, operands[1]);
9723 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9726 ;; This pattern can't accept a variable shift count, since shifts by
9727 ;; zero don't affect the flags. We assume that shifts by constant
9728 ;; zero are optimized away.
9729 (define_insn "*ashl<mode>3_cmp"
9730 [(set (reg FLAGS_REG)
9732 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9733 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9735 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9736 (ashift:SWI (match_dup 1) (match_dup 2)))]
9737 "(optimize_function_for_size_p (cfun)
9738 || !TARGET_PARTIAL_FLAG_REG_STALL
9739 || (operands[2] == const1_rtx
9741 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9742 && ix86_match_ccmode (insn, CCGOCmode)
9743 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9745 switch (get_attr_type (insn))
9748 gcc_assert (operands[2] == const1_rtx);
9749 return "add{<imodesuffix>}\t%0, %0";
9752 if (operands[2] == const1_rtx
9753 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9754 return "sal{<imodesuffix>}\t%0";
9756 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9760 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9761 (match_operand 0 "register_operand"))
9762 (match_operand 2 "const1_operand"))
9763 (const_string "alu")
9765 (const_string "ishift")))
9766 (set (attr "length_immediate")
9768 (ior (eq_attr "type" "alu")
9769 (and (eq_attr "type" "ishift")
9770 (and (match_operand 2 "const1_operand")
9771 (ior (match_test "TARGET_SHIFT1")
9772 (match_test "optimize_function_for_size_p (cfun)")))))
9774 (const_string "*")))
9775 (set_attr "mode" "<MODE>")])
9777 (define_insn "*ashlsi3_cmp_zext"
9778 [(set (reg FLAGS_REG)
9780 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9781 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9783 (set (match_operand:DI 0 "register_operand" "=r")
9784 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9786 && (optimize_function_for_size_p (cfun)
9787 || !TARGET_PARTIAL_FLAG_REG_STALL
9788 || (operands[2] == const1_rtx
9790 || TARGET_DOUBLE_WITH_ADD)))
9791 && ix86_match_ccmode (insn, CCGOCmode)
9792 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9794 switch (get_attr_type (insn))
9797 gcc_assert (operands[2] == const1_rtx);
9798 return "add{l}\t%k0, %k0";
9801 if (operands[2] == const1_rtx
9802 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9803 return "sal{l}\t%k0";
9805 return "sal{l}\t{%2, %k0|%k0, %2}";
9809 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9810 (match_operand 2 "const1_operand"))
9811 (const_string "alu")
9813 (const_string "ishift")))
9814 (set (attr "length_immediate")
9816 (ior (eq_attr "type" "alu")
9817 (and (eq_attr "type" "ishift")
9818 (and (match_operand 2 "const1_operand")
9819 (ior (match_test "TARGET_SHIFT1")
9820 (match_test "optimize_function_for_size_p (cfun)")))))
9822 (const_string "*")))
9823 (set_attr "mode" "SI")])
9825 (define_insn "*ashl<mode>3_cconly"
9826 [(set (reg FLAGS_REG)
9828 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9829 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9831 (clobber (match_scratch:SWI 0 "=<r>"))]
9832 "(optimize_function_for_size_p (cfun)
9833 || !TARGET_PARTIAL_FLAG_REG_STALL
9834 || (operands[2] == const1_rtx
9836 || TARGET_DOUBLE_WITH_ADD)))
9837 && ix86_match_ccmode (insn, CCGOCmode)"
9839 switch (get_attr_type (insn))
9842 gcc_assert (operands[2] == const1_rtx);
9843 return "add{<imodesuffix>}\t%0, %0";
9846 if (operands[2] == const1_rtx
9847 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9848 return "sal{<imodesuffix>}\t%0";
9850 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9854 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9855 (match_operand 0 "register_operand"))
9856 (match_operand 2 "const1_operand"))
9857 (const_string "alu")
9859 (const_string "ishift")))
9860 (set (attr "length_immediate")
9862 (ior (eq_attr "type" "alu")
9863 (and (eq_attr "type" "ishift")
9864 (and (match_operand 2 "const1_operand")
9865 (ior (match_test "TARGET_SHIFT1")
9866 (match_test "optimize_function_for_size_p (cfun)")))))
9868 (const_string "*")))
9869 (set_attr "mode" "<MODE>")])
9871 ;; See comment above `ashl<mode>3' about how this works.
9873 (define_expand "<shift_insn><mode>3"
9874 [(set (match_operand:SDWIM 0 "<shift_operand>")
9875 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9876 (match_operand:QI 2 "nonmemory_operand")))]
9878 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9880 ;; Avoid useless masking of count operand.
9881 (define_insn "*<shift_insn><mode>3_mask"
9882 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9884 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9887 (match_operand:SI 2 "register_operand" "c")
9888 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9889 (clobber (reg:CC FLAGS_REG))]
9890 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9891 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9892 == GET_MODE_BITSIZE (<MODE>mode)-1"
9894 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9896 [(set_attr "type" "ishift")
9897 (set_attr "mode" "<MODE>")])
9899 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9900 [(set (match_operand:DWI 0 "register_operand" "=r")
9901 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9902 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9903 (clobber (reg:CC FLAGS_REG))]
9906 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9908 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9909 [(set_attr "type" "multi")])
9911 ;; By default we don't ask for a scratch register, because when DWImode
9912 ;; values are manipulated, registers are already at a premium. But if
9913 ;; we have one handy, we won't turn it away.
9916 [(match_scratch:DWIH 3 "r")
9917 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9919 (match_operand:<DWI> 1 "register_operand")
9920 (match_operand:QI 2 "nonmemory_operand")))
9921 (clobber (reg:CC FLAGS_REG))])
9925 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9927 (define_insn "x86_64_shrd"
9928 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9929 (ior:DI (lshiftrt:DI (match_dup 0)
9930 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9931 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9932 (minus:QI (const_int 64) (match_dup 2)))))
9933 (clobber (reg:CC FLAGS_REG))]
9935 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9936 [(set_attr "type" "ishift")
9937 (set_attr "prefix_0f" "1")
9938 (set_attr "mode" "DI")
9939 (set_attr "athlon_decode" "vector")
9940 (set_attr "amdfam10_decode" "vector")
9941 (set_attr "bdver1_decode" "vector")])
9943 (define_insn "x86_shrd"
9944 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9945 (ior:SI (lshiftrt:SI (match_dup 0)
9946 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9947 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9948 (minus:QI (const_int 32) (match_dup 2)))))
9949 (clobber (reg:CC FLAGS_REG))]
9951 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9952 [(set_attr "type" "ishift")
9953 (set_attr "prefix_0f" "1")
9954 (set_attr "mode" "SI")
9955 (set_attr "pent_pair" "np")
9956 (set_attr "athlon_decode" "vector")
9957 (set_attr "amdfam10_decode" "vector")
9958 (set_attr "bdver1_decode" "vector")])
9960 (define_insn "ashrdi3_cvt"
9961 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9962 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9963 (match_operand:QI 2 "const_int_operand")))
9964 (clobber (reg:CC FLAGS_REG))]
9965 "TARGET_64BIT && INTVAL (operands[2]) == 63
9966 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9967 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9970 sar{q}\t{%2, %0|%0, %2}"
9971 [(set_attr "type" "imovx,ishift")
9972 (set_attr "prefix_0f" "0,*")
9973 (set_attr "length_immediate" "0,*")
9974 (set_attr "modrm" "0,1")
9975 (set_attr "mode" "DI")])
9977 (define_insn "ashrsi3_cvt"
9978 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9979 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9980 (match_operand:QI 2 "const_int_operand")))
9981 (clobber (reg:CC FLAGS_REG))]
9982 "INTVAL (operands[2]) == 31
9983 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9984 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9987 sar{l}\t{%2, %0|%0, %2}"
9988 [(set_attr "type" "imovx,ishift")
9989 (set_attr "prefix_0f" "0,*")
9990 (set_attr "length_immediate" "0,*")
9991 (set_attr "modrm" "0,1")
9992 (set_attr "mode" "SI")])
9994 (define_insn "*ashrsi3_cvt_zext"
9995 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9997 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9998 (match_operand:QI 2 "const_int_operand"))))
9999 (clobber (reg:CC FLAGS_REG))]
10000 "TARGET_64BIT && INTVAL (operands[2]) == 31
10001 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10002 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10005 sar{l}\t{%2, %k0|%k0, %2}"
10006 [(set_attr "type" "imovx,ishift")
10007 (set_attr "prefix_0f" "0,*")
10008 (set_attr "length_immediate" "0,*")
10009 (set_attr "modrm" "0,1")
10010 (set_attr "mode" "SI")])
10012 (define_expand "x86_shift<mode>_adj_3"
10013 [(use (match_operand:SWI48 0 "register_operand"))
10014 (use (match_operand:SWI48 1 "register_operand"))
10015 (use (match_operand:QI 2 "register_operand"))]
10018 rtx_code_label *label = gen_label_rtx ();
10021 emit_insn (gen_testqi_ccz_1 (operands[2],
10022 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10024 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10025 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10026 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10027 gen_rtx_LABEL_REF (VOIDmode, label),
10029 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10030 JUMP_LABEL (tmp) = label;
10032 emit_move_insn (operands[0], operands[1]);
10033 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10034 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10035 emit_label (label);
10036 LABEL_NUSES (label) = 1;
10041 (define_insn "*bmi2_<shift_insn><mode>3_1"
10042 [(set (match_operand:SWI48 0 "register_operand" "=r")
10043 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10044 (match_operand:SWI48 2 "register_operand" "r")))]
10046 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10047 [(set_attr "type" "ishiftx")
10048 (set_attr "mode" "<MODE>")])
10050 (define_insn "*<shift_insn><mode>3_1"
10051 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10053 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10054 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10058 switch (get_attr_type (insn))
10064 if (operands[2] == const1_rtx
10065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066 return "<shift>{<imodesuffix>}\t%0";
10068 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10071 [(set_attr "isa" "*,bmi2")
10072 (set_attr "type" "ishift,ishiftx")
10073 (set (attr "length_immediate")
10075 (and (match_operand 2 "const1_operand")
10076 (ior (match_test "TARGET_SHIFT1")
10077 (match_test "optimize_function_for_size_p (cfun)")))
10079 (const_string "*")))
10080 (set_attr "mode" "<MODE>")])
10082 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10084 [(set (match_operand:SWI48 0 "register_operand")
10085 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10086 (match_operand:QI 2 "register_operand")))
10087 (clobber (reg:CC FLAGS_REG))]
10088 "TARGET_BMI2 && reload_completed"
10089 [(set (match_dup 0)
10090 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10091 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10093 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10094 [(set (match_operand:DI 0 "register_operand" "=r")
10096 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10097 (match_operand:SI 2 "register_operand" "r"))))]
10098 "TARGET_64BIT && TARGET_BMI2"
10099 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10100 [(set_attr "type" "ishiftx")
10101 (set_attr "mode" "SI")])
10103 (define_insn "*<shift_insn>si3_1_zext"
10104 [(set (match_operand:DI 0 "register_operand" "=r,r")
10106 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10107 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10111 switch (get_attr_type (insn))
10117 if (operands[2] == const1_rtx
10118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119 return "<shift>{l}\t%k0";
10121 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10124 [(set_attr "isa" "*,bmi2")
10125 (set_attr "type" "ishift,ishiftx")
10126 (set (attr "length_immediate")
10128 (and (match_operand 2 "const1_operand")
10129 (ior (match_test "TARGET_SHIFT1")
10130 (match_test "optimize_function_for_size_p (cfun)")))
10132 (const_string "*")))
10133 (set_attr "mode" "SI")])
10135 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10137 [(set (match_operand:DI 0 "register_operand")
10139 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10140 (match_operand:QI 2 "register_operand"))))
10141 (clobber (reg:CC FLAGS_REG))]
10142 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10143 [(set (match_dup 0)
10144 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10145 "operands[2] = gen_lowpart (SImode, operands[2]);")
10147 (define_insn "*<shift_insn><mode>3_1"
10148 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10150 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10151 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10155 if (operands[2] == const1_rtx
10156 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10157 return "<shift>{<imodesuffix>}\t%0";
10159 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10161 [(set_attr "type" "ishift")
10162 (set (attr "length_immediate")
10164 (and (match_operand 2 "const1_operand")
10165 (ior (match_test "TARGET_SHIFT1")
10166 (match_test "optimize_function_for_size_p (cfun)")))
10168 (const_string "*")))
10169 (set_attr "mode" "<MODE>")])
10171 (define_insn "*<shift_insn>qi3_1_slp"
10172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10173 (any_shiftrt:QI (match_dup 0)
10174 (match_operand:QI 1 "nonmemory_operand" "cI")))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "(optimize_function_for_size_p (cfun)
10177 || !TARGET_PARTIAL_REG_STALL
10178 || (operands[1] == const1_rtx
10179 && TARGET_SHIFT1))"
10181 if (operands[1] == const1_rtx
10182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10183 return "<shift>{b}\t%0";
10185 return "<shift>{b}\t{%1, %0|%0, %1}";
10187 [(set_attr "type" "ishift1")
10188 (set (attr "length_immediate")
10190 (and (match_operand 1 "const1_operand")
10191 (ior (match_test "TARGET_SHIFT1")
10192 (match_test "optimize_function_for_size_p (cfun)")))
10194 (const_string "*")))
10195 (set_attr "mode" "QI")])
10197 ;; This pattern can't accept a variable shift count, since shifts by
10198 ;; zero don't affect the flags. We assume that shifts by constant
10199 ;; zero are optimized away.
10200 (define_insn "*<shift_insn><mode>3_cmp"
10201 [(set (reg FLAGS_REG)
10204 (match_operand:SWI 1 "nonimmediate_operand" "0")
10205 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10207 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10208 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10209 "(optimize_function_for_size_p (cfun)
10210 || !TARGET_PARTIAL_FLAG_REG_STALL
10211 || (operands[2] == const1_rtx
10213 && ix86_match_ccmode (insn, CCGOCmode)
10214 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10216 if (operands[2] == const1_rtx
10217 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10218 return "<shift>{<imodesuffix>}\t%0";
10220 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10222 [(set_attr "type" "ishift")
10223 (set (attr "length_immediate")
10225 (and (match_operand 2 "const1_operand")
10226 (ior (match_test "TARGET_SHIFT1")
10227 (match_test "optimize_function_for_size_p (cfun)")))
10229 (const_string "*")))
10230 (set_attr "mode" "<MODE>")])
10232 (define_insn "*<shift_insn>si3_cmp_zext"
10233 [(set (reg FLAGS_REG)
10235 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10236 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10238 (set (match_operand:DI 0 "register_operand" "=r")
10239 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10241 && (optimize_function_for_size_p (cfun)
10242 || !TARGET_PARTIAL_FLAG_REG_STALL
10243 || (operands[2] == const1_rtx
10245 && ix86_match_ccmode (insn, CCGOCmode)
10246 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10248 if (operands[2] == const1_rtx
10249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10250 return "<shift>{l}\t%k0";
10252 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10254 [(set_attr "type" "ishift")
10255 (set (attr "length_immediate")
10257 (and (match_operand 2 "const1_operand")
10258 (ior (match_test "TARGET_SHIFT1")
10259 (match_test "optimize_function_for_size_p (cfun)")))
10261 (const_string "*")))
10262 (set_attr "mode" "SI")])
10264 (define_insn "*<shift_insn><mode>3_cconly"
10265 [(set (reg FLAGS_REG)
10268 (match_operand:SWI 1 "register_operand" "0")
10269 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10271 (clobber (match_scratch:SWI 0 "=<r>"))]
10272 "(optimize_function_for_size_p (cfun)
10273 || !TARGET_PARTIAL_FLAG_REG_STALL
10274 || (operands[2] == const1_rtx
10276 && ix86_match_ccmode (insn, CCGOCmode)"
10278 if (operands[2] == const1_rtx
10279 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10280 return "<shift>{<imodesuffix>}\t%0";
10282 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10284 [(set_attr "type" "ishift")
10285 (set (attr "length_immediate")
10287 (and (match_operand 2 "const1_operand")
10288 (ior (match_test "TARGET_SHIFT1")
10289 (match_test "optimize_function_for_size_p (cfun)")))
10291 (const_string "*")))
10292 (set_attr "mode" "<MODE>")])
10294 ;; Rotate instructions
10296 (define_expand "<rotate_insn>ti3"
10297 [(set (match_operand:TI 0 "register_operand")
10298 (any_rotate:TI (match_operand:TI 1 "register_operand")
10299 (match_operand:QI 2 "nonmemory_operand")))]
10302 if (const_1_to_63_operand (operands[2], VOIDmode))
10303 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10304 (operands[0], operands[1], operands[2]));
10311 (define_expand "<rotate_insn>di3"
10312 [(set (match_operand:DI 0 "shiftdi_operand")
10313 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10314 (match_operand:QI 2 "nonmemory_operand")))]
10318 ix86_expand_binary_operator (<CODE>, DImode, operands);
10319 else if (const_1_to_31_operand (operands[2], VOIDmode))
10320 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10321 (operands[0], operands[1], operands[2]));
10328 (define_expand "<rotate_insn><mode>3"
10329 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10330 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10331 (match_operand:QI 2 "nonmemory_operand")))]
10333 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10335 ;; Avoid useless masking of count operand.
10336 (define_insn "*<rotate_insn><mode>3_mask"
10337 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10339 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10342 (match_operand:SI 2 "register_operand" "c")
10343 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10346 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10347 == GET_MODE_BITSIZE (<MODE>mode)-1"
10349 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10351 [(set_attr "type" "rotate")
10352 (set_attr "mode" "<MODE>")])
10354 ;; Implement rotation using two double-precision
10355 ;; shift instructions and a scratch register.
10357 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10358 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10359 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10360 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10361 (clobber (reg:CC FLAGS_REG))
10362 (clobber (match_scratch:DWIH 3 "=&r"))]
10366 [(set (match_dup 3) (match_dup 4))
10368 [(set (match_dup 4)
10369 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10370 (lshiftrt:DWIH (match_dup 5)
10371 (minus:QI (match_dup 6) (match_dup 2)))))
10372 (clobber (reg:CC FLAGS_REG))])
10374 [(set (match_dup 5)
10375 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10376 (lshiftrt:DWIH (match_dup 3)
10377 (minus:QI (match_dup 6) (match_dup 2)))))
10378 (clobber (reg:CC FLAGS_REG))])]
10380 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10382 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10385 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10386 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10387 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10388 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10389 (clobber (reg:CC FLAGS_REG))
10390 (clobber (match_scratch:DWIH 3 "=&r"))]
10394 [(set (match_dup 3) (match_dup 4))
10396 [(set (match_dup 4)
10397 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10398 (ashift:DWIH (match_dup 5)
10399 (minus:QI (match_dup 6) (match_dup 2)))))
10400 (clobber (reg:CC FLAGS_REG))])
10402 [(set (match_dup 5)
10403 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10404 (ashift:DWIH (match_dup 3)
10405 (minus:QI (match_dup 6) (match_dup 2)))))
10406 (clobber (reg:CC FLAGS_REG))])]
10408 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10410 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10413 (define_insn "*bmi2_rorx<mode>3_1"
10414 [(set (match_operand:SWI48 0 "register_operand" "=r")
10415 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10416 (match_operand:QI 2 "immediate_operand" "<S>")))]
10418 "rorx\t{%2, %1, %0|%0, %1, %2}"
10419 [(set_attr "type" "rotatex")
10420 (set_attr "mode" "<MODE>")])
10422 (define_insn "*<rotate_insn><mode>3_1"
10423 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10425 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10426 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10430 switch (get_attr_type (insn))
10436 if (operands[2] == const1_rtx
10437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10438 return "<rotate>{<imodesuffix>}\t%0";
10440 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10443 [(set_attr "isa" "*,bmi2")
10444 (set_attr "type" "rotate,rotatex")
10445 (set (attr "length_immediate")
10447 (and (eq_attr "type" "rotate")
10448 (and (match_operand 2 "const1_operand")
10449 (ior (match_test "TARGET_SHIFT1")
10450 (match_test "optimize_function_for_size_p (cfun)"))))
10452 (const_string "*")))
10453 (set_attr "mode" "<MODE>")])
10455 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10457 [(set (match_operand:SWI48 0 "register_operand")
10458 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10459 (match_operand:QI 2 "immediate_operand")))
10460 (clobber (reg:CC FLAGS_REG))]
10461 "TARGET_BMI2 && reload_completed"
10462 [(set (match_dup 0)
10463 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10466 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10470 [(set (match_operand:SWI48 0 "register_operand")
10471 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10472 (match_operand:QI 2 "immediate_operand")))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "TARGET_BMI2 && reload_completed"
10475 [(set (match_dup 0)
10476 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10478 (define_insn "*bmi2_rorxsi3_1_zext"
10479 [(set (match_operand:DI 0 "register_operand" "=r")
10481 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10482 (match_operand:QI 2 "immediate_operand" "I"))))]
10483 "TARGET_64BIT && TARGET_BMI2"
10484 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10485 [(set_attr "type" "rotatex")
10486 (set_attr "mode" "SI")])
10488 (define_insn "*<rotate_insn>si3_1_zext"
10489 [(set (match_operand:DI 0 "register_operand" "=r,r")
10491 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10492 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10496 switch (get_attr_type (insn))
10502 if (operands[2] == const1_rtx
10503 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10504 return "<rotate>{l}\t%k0";
10506 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10509 [(set_attr "isa" "*,bmi2")
10510 (set_attr "type" "rotate,rotatex")
10511 (set (attr "length_immediate")
10513 (and (eq_attr "type" "rotate")
10514 (and (match_operand 2 "const1_operand")
10515 (ior (match_test "TARGET_SHIFT1")
10516 (match_test "optimize_function_for_size_p (cfun)"))))
10518 (const_string "*")))
10519 (set_attr "mode" "SI")])
10521 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10523 [(set (match_operand:DI 0 "register_operand")
10525 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10526 (match_operand:QI 2 "immediate_operand"))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10529 [(set (match_dup 0)
10530 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10533 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10537 [(set (match_operand:DI 0 "register_operand")
10539 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10540 (match_operand:QI 2 "immediate_operand"))))
10541 (clobber (reg:CC FLAGS_REG))]
10542 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10543 [(set (match_dup 0)
10544 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10546 (define_insn "*<rotate_insn><mode>3_1"
10547 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10548 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10549 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10553 if (operands[2] == const1_rtx
10554 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10555 return "<rotate>{<imodesuffix>}\t%0";
10557 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10559 [(set_attr "type" "rotate")
10560 (set (attr "length_immediate")
10562 (and (match_operand 2 "const1_operand")
10563 (ior (match_test "TARGET_SHIFT1")
10564 (match_test "optimize_function_for_size_p (cfun)")))
10566 (const_string "*")))
10567 (set_attr "mode" "<MODE>")])
10569 (define_insn "*<rotate_insn>qi3_1_slp"
10570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10571 (any_rotate:QI (match_dup 0)
10572 (match_operand:QI 1 "nonmemory_operand" "cI")))
10573 (clobber (reg:CC FLAGS_REG))]
10574 "(optimize_function_for_size_p (cfun)
10575 || !TARGET_PARTIAL_REG_STALL
10576 || (operands[1] == const1_rtx
10577 && TARGET_SHIFT1))"
10579 if (operands[1] == const1_rtx
10580 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10581 return "<rotate>{b}\t%0";
10583 return "<rotate>{b}\t{%1, %0|%0, %1}";
10585 [(set_attr "type" "rotate1")
10586 (set (attr "length_immediate")
10588 (and (match_operand 1 "const1_operand")
10589 (ior (match_test "TARGET_SHIFT1")
10590 (match_test "optimize_function_for_size_p (cfun)")))
10592 (const_string "*")))
10593 (set_attr "mode" "QI")])
10596 [(set (match_operand:HI 0 "register_operand")
10597 (any_rotate:HI (match_dup 0) (const_int 8)))
10598 (clobber (reg:CC FLAGS_REG))]
10600 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10601 [(parallel [(set (strict_low_part (match_dup 0))
10602 (bswap:HI (match_dup 0)))
10603 (clobber (reg:CC FLAGS_REG))])])
10605 ;; Bit set / bit test instructions
10607 (define_expand "extv"
10608 [(set (match_operand:SI 0 "register_operand")
10609 (sign_extract:SI (match_operand:SI 1 "register_operand")
10610 (match_operand:SI 2 "const8_operand")
10611 (match_operand:SI 3 "const8_operand")))]
10614 /* Handle extractions from %ah et al. */
10615 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10618 /* From mips.md: extract_bit_field doesn't verify that our source
10619 matches the predicate, so check it again here. */
10620 if (! ext_register_operand (operands[1], VOIDmode))
10624 (define_expand "extzv"
10625 [(set (match_operand:SI 0 "register_operand")
10626 (zero_extract:SI (match_operand 1 "ext_register_operand")
10627 (match_operand:SI 2 "const8_operand")
10628 (match_operand:SI 3 "const8_operand")))]
10631 /* Handle extractions from %ah et al. */
10632 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10635 /* From mips.md: extract_bit_field doesn't verify that our source
10636 matches the predicate, so check it again here. */
10637 if (! ext_register_operand (operands[1], VOIDmode))
10641 (define_expand "insv"
10642 [(set (zero_extract (match_operand 0 "register_operand")
10643 (match_operand 1 "const_int_operand")
10644 (match_operand 2 "const_int_operand"))
10645 (match_operand 3 "register_operand"))]
10648 rtx (*gen_mov_insv_1) (rtx, rtx);
10650 if (ix86_expand_pinsr (operands))
10653 /* Handle insertions to %ah et al. */
10654 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10657 /* From mips.md: insert_bit_field doesn't verify that our source
10658 matches the predicate, so check it again here. */
10659 if (! ext_register_operand (operands[0], VOIDmode))
10662 gen_mov_insv_1 = (TARGET_64BIT
10663 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10665 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10669 ;; %%% bts, btr, btc, bt.
10670 ;; In general these instructions are *slow* when applied to memory,
10671 ;; since they enforce atomic operation. When applied to registers,
10672 ;; it depends on the cpu implementation. They're never faster than
10673 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10674 ;; no point. But in 64-bit, we can't hold the relevant immediates
10675 ;; within the instruction itself, so operating on bits in the high
10676 ;; 32-bits of a register becomes easier.
10678 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10679 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10680 ;; negdf respectively, so they can never be disabled entirely.
10682 (define_insn "*btsq"
10683 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10685 (match_operand:DI 1 "const_0_to_63_operand"))
10687 (clobber (reg:CC FLAGS_REG))]
10688 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10689 "bts{q}\t{%1, %0|%0, %1}"
10690 [(set_attr "type" "alu1")
10691 (set_attr "prefix_0f" "1")
10692 (set_attr "mode" "DI")])
10694 (define_insn "*btrq"
10695 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10697 (match_operand:DI 1 "const_0_to_63_operand"))
10699 (clobber (reg:CC FLAGS_REG))]
10700 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10701 "btr{q}\t{%1, %0|%0, %1}"
10702 [(set_attr "type" "alu1")
10703 (set_attr "prefix_0f" "1")
10704 (set_attr "mode" "DI")])
10706 (define_insn "*btcq"
10707 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10709 (match_operand:DI 1 "const_0_to_63_operand"))
10710 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10711 (clobber (reg:CC FLAGS_REG))]
10712 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10713 "btc{q}\t{%1, %0|%0, %1}"
10714 [(set_attr "type" "alu1")
10715 (set_attr "prefix_0f" "1")
10716 (set_attr "mode" "DI")])
10718 ;; Allow Nocona to avoid these instructions if a register is available.
10721 [(match_scratch:DI 2 "r")
10722 (parallel [(set (zero_extract:DI
10723 (match_operand:DI 0 "register_operand")
10725 (match_operand:DI 1 "const_0_to_63_operand"))
10727 (clobber (reg:CC FLAGS_REG))])]
10728 "TARGET_64BIT && !TARGET_USE_BT"
10731 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10734 if (HOST_BITS_PER_WIDE_INT >= 64)
10735 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10736 else if (i < HOST_BITS_PER_WIDE_INT)
10737 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10739 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10741 op1 = immed_double_const (lo, hi, DImode);
10744 emit_move_insn (operands[2], op1);
10748 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10753 [(match_scratch:DI 2 "r")
10754 (parallel [(set (zero_extract:DI
10755 (match_operand:DI 0 "register_operand")
10757 (match_operand:DI 1 "const_0_to_63_operand"))
10759 (clobber (reg:CC FLAGS_REG))])]
10760 "TARGET_64BIT && !TARGET_USE_BT"
10763 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10766 if (HOST_BITS_PER_WIDE_INT >= 64)
10767 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10768 else if (i < HOST_BITS_PER_WIDE_INT)
10769 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10771 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10773 op1 = immed_double_const (~lo, ~hi, DImode);
10776 emit_move_insn (operands[2], op1);
10780 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10785 [(match_scratch:DI 2 "r")
10786 (parallel [(set (zero_extract:DI
10787 (match_operand:DI 0 "register_operand")
10789 (match_operand:DI 1 "const_0_to_63_operand"))
10790 (not:DI (zero_extract:DI
10791 (match_dup 0) (const_int 1) (match_dup 1))))
10792 (clobber (reg:CC FLAGS_REG))])]
10793 "TARGET_64BIT && !TARGET_USE_BT"
10796 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10799 if (HOST_BITS_PER_WIDE_INT >= 64)
10800 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10801 else if (i < HOST_BITS_PER_WIDE_INT)
10802 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10804 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10806 op1 = immed_double_const (lo, hi, DImode);
10809 emit_move_insn (operands[2], op1);
10813 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10817 (define_insn "*bt<mode>"
10818 [(set (reg:CCC FLAGS_REG)
10820 (zero_extract:SWI48
10821 (match_operand:SWI48 0 "register_operand" "r")
10823 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10825 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10826 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10827 [(set_attr "type" "alu1")
10828 (set_attr "prefix_0f" "1")
10829 (set_attr "mode" "<MODE>")])
10831 ;; Store-flag instructions.
10833 ;; For all sCOND expanders, also expand the compare or test insn that
10834 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10836 (define_insn_and_split "*setcc_di_1"
10837 [(set (match_operand:DI 0 "register_operand" "=q")
10838 (match_operator:DI 1 "ix86_comparison_operator"
10839 [(reg FLAGS_REG) (const_int 0)]))]
10840 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10842 "&& reload_completed"
10843 [(set (match_dup 2) (match_dup 1))
10844 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10846 PUT_MODE (operands[1], QImode);
10847 operands[2] = gen_lowpart (QImode, operands[0]);
10850 (define_insn_and_split "*setcc_si_1_and"
10851 [(set (match_operand:SI 0 "register_operand" "=q")
10852 (match_operator:SI 1 "ix86_comparison_operator"
10853 [(reg FLAGS_REG) (const_int 0)]))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "!TARGET_PARTIAL_REG_STALL
10856 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10858 "&& reload_completed"
10859 [(set (match_dup 2) (match_dup 1))
10860 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10861 (clobber (reg:CC FLAGS_REG))])]
10863 PUT_MODE (operands[1], QImode);
10864 operands[2] = gen_lowpart (QImode, operands[0]);
10867 (define_insn_and_split "*setcc_si_1_movzbl"
10868 [(set (match_operand:SI 0 "register_operand" "=q")
10869 (match_operator:SI 1 "ix86_comparison_operator"
10870 [(reg FLAGS_REG) (const_int 0)]))]
10871 "!TARGET_PARTIAL_REG_STALL
10872 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10874 "&& reload_completed"
10875 [(set (match_dup 2) (match_dup 1))
10876 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10878 PUT_MODE (operands[1], QImode);
10879 operands[2] = gen_lowpart (QImode, operands[0]);
10882 (define_insn "*setcc_qi"
10883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10884 (match_operator:QI 1 "ix86_comparison_operator"
10885 [(reg FLAGS_REG) (const_int 0)]))]
10888 [(set_attr "type" "setcc")
10889 (set_attr "mode" "QI")])
10891 (define_insn "*setcc_qi_slp"
10892 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10893 (match_operator:QI 1 "ix86_comparison_operator"
10894 [(reg FLAGS_REG) (const_int 0)]))]
10897 [(set_attr "type" "setcc")
10898 (set_attr "mode" "QI")])
10900 ;; In general it is not safe to assume too much about CCmode registers,
10901 ;; so simplify-rtx stops when it sees a second one. Under certain
10902 ;; conditions this is safe on x86, so help combine not create
10909 [(set (match_operand:QI 0 "nonimmediate_operand")
10910 (ne:QI (match_operator 1 "ix86_comparison_operator"
10911 [(reg FLAGS_REG) (const_int 0)])
10914 [(set (match_dup 0) (match_dup 1))]
10915 "PUT_MODE (operands[1], QImode);")
10918 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10919 (ne:QI (match_operator 1 "ix86_comparison_operator"
10920 [(reg FLAGS_REG) (const_int 0)])
10923 [(set (match_dup 0) (match_dup 1))]
10924 "PUT_MODE (operands[1], QImode);")
10927 [(set (match_operand:QI 0 "nonimmediate_operand")
10928 (eq:QI (match_operator 1 "ix86_comparison_operator"
10929 [(reg FLAGS_REG) (const_int 0)])
10932 [(set (match_dup 0) (match_dup 1))]
10934 rtx new_op1 = copy_rtx (operands[1]);
10935 operands[1] = new_op1;
10936 PUT_MODE (new_op1, QImode);
10937 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10938 GET_MODE (XEXP (new_op1, 0))));
10940 /* Make sure that (a) the CCmode we have for the flags is strong
10941 enough for the reversed compare or (b) we have a valid FP compare. */
10942 if (! ix86_comparison_operator (new_op1, VOIDmode))
10947 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10948 (eq:QI (match_operator 1 "ix86_comparison_operator"
10949 [(reg FLAGS_REG) (const_int 0)])
10952 [(set (match_dup 0) (match_dup 1))]
10954 rtx new_op1 = copy_rtx (operands[1]);
10955 operands[1] = new_op1;
10956 PUT_MODE (new_op1, QImode);
10957 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10958 GET_MODE (XEXP (new_op1, 0))));
10960 /* Make sure that (a) the CCmode we have for the flags is strong
10961 enough for the reversed compare or (b) we have a valid FP compare. */
10962 if (! ix86_comparison_operator (new_op1, VOIDmode))
10966 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10967 ;; subsequent logical operations are used to imitate conditional moves.
10968 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10971 (define_insn "setcc_<mode>_sse"
10972 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10973 (match_operator:MODEF 3 "sse_comparison_operator"
10974 [(match_operand:MODEF 1 "register_operand" "0,x")
10975 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10976 "SSE_FLOAT_MODE_P (<MODE>mode)"
10978 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10979 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10980 [(set_attr "isa" "noavx,avx")
10981 (set_attr "type" "ssecmp")
10982 (set_attr "length_immediate" "1")
10983 (set_attr "prefix" "orig,vex")
10984 (set_attr "mode" "<MODE>")])
10986 ;; Basic conditional jump instructions.
10987 ;; We ignore the overflow flag for signed branch instructions.
10989 (define_insn "*jcc_1_bnd"
10991 (if_then_else (match_operator 1 "ix86_comparison_operator"
10992 [(reg FLAGS_REG) (const_int 0)])
10993 (label_ref (match_operand 0))
10995 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10997 [(set_attr "type" "ibr")
10998 (set_attr "modrm" "0")
10999 (set (attr "length")
11000 (if_then_else (and (ge (minus (match_dup 0) (pc))
11002 (lt (minus (match_dup 0) (pc))
11007 (define_insn "*jcc_1"
11009 (if_then_else (match_operator 1 "ix86_comparison_operator"
11010 [(reg FLAGS_REG) (const_int 0)])
11011 (label_ref (match_operand 0))
11015 [(set_attr "type" "ibr")
11016 (set_attr "modrm" "0")
11017 (set (attr "length")
11018 (if_then_else (and (ge (minus (match_dup 0) (pc))
11020 (lt (minus (match_dup 0) (pc))
11025 (define_insn "*jcc_2_bnd"
11027 (if_then_else (match_operator 1 "ix86_comparison_operator"
11028 [(reg FLAGS_REG) (const_int 0)])
11030 (label_ref (match_operand 0))))]
11031 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11033 [(set_attr "type" "ibr")
11034 (set_attr "modrm" "0")
11035 (set (attr "length")
11036 (if_then_else (and (ge (minus (match_dup 0) (pc))
11038 (lt (minus (match_dup 0) (pc))
11043 (define_insn "*jcc_2"
11045 (if_then_else (match_operator 1 "ix86_comparison_operator"
11046 [(reg FLAGS_REG) (const_int 0)])
11048 (label_ref (match_operand 0))))]
11051 [(set_attr "type" "ibr")
11052 (set_attr "modrm" "0")
11053 (set (attr "length")
11054 (if_then_else (and (ge (minus (match_dup 0) (pc))
11056 (lt (minus (match_dup 0) (pc))
11061 ;; In general it is not safe to assume too much about CCmode registers,
11062 ;; so simplify-rtx stops when it sees a second one. Under certain
11063 ;; conditions this is safe on x86, so help combine not create
11071 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11072 [(reg FLAGS_REG) (const_int 0)])
11074 (label_ref (match_operand 1))
11078 (if_then_else (match_dup 0)
11079 (label_ref (match_dup 1))
11081 "PUT_MODE (operands[0], VOIDmode);")
11085 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11086 [(reg FLAGS_REG) (const_int 0)])
11088 (label_ref (match_operand 1))
11092 (if_then_else (match_dup 0)
11093 (label_ref (match_dup 1))
11096 rtx new_op0 = copy_rtx (operands[0]);
11097 operands[0] = new_op0;
11098 PUT_MODE (new_op0, VOIDmode);
11099 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11100 GET_MODE (XEXP (new_op0, 0))));
11102 /* Make sure that (a) the CCmode we have for the flags is strong
11103 enough for the reversed compare or (b) we have a valid FP compare. */
11104 if (! ix86_comparison_operator (new_op0, VOIDmode))
11108 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11109 ;; pass generates from shift insn with QImode operand. Actually, the mode
11110 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11111 ;; appropriate modulo of the bit offset value.
11113 (define_insn_and_split "*jcc_bt<mode>"
11115 (if_then_else (match_operator 0 "bt_comparison_operator"
11116 [(zero_extract:SWI48
11117 (match_operand:SWI48 1 "register_operand" "r")
11120 (match_operand:QI 2 "register_operand" "r")))
11122 (label_ref (match_operand 3))
11124 (clobber (reg:CC FLAGS_REG))]
11125 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11128 [(set (reg:CCC FLAGS_REG)
11130 (zero_extract:SWI48
11136 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11137 (label_ref (match_dup 3))
11140 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11142 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11145 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11146 ;; zero extended to SImode.
11147 (define_insn_and_split "*jcc_bt<mode>_1"
11149 (if_then_else (match_operator 0 "bt_comparison_operator"
11150 [(zero_extract:SWI48
11151 (match_operand:SWI48 1 "register_operand" "r")
11153 (match_operand:SI 2 "register_operand" "r"))
11155 (label_ref (match_operand 3))
11157 (clobber (reg:CC FLAGS_REG))]
11158 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11161 [(set (reg:CCC FLAGS_REG)
11163 (zero_extract:SWI48
11169 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11170 (label_ref (match_dup 3))
11173 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11175 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11178 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11179 ;; also for DImode, this is what combine produces.
11180 (define_insn_and_split "*jcc_bt<mode>_mask"
11182 (if_then_else (match_operator 0 "bt_comparison_operator"
11183 [(zero_extract:SWI48
11184 (match_operand:SWI48 1 "register_operand" "r")
11187 (match_operand:SI 2 "register_operand" "r")
11188 (match_operand:SI 3 "const_int_operand" "n")))])
11189 (label_ref (match_operand 4))
11191 (clobber (reg:CC FLAGS_REG))]
11192 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11193 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11194 == GET_MODE_BITSIZE (<MODE>mode)-1"
11197 [(set (reg:CCC FLAGS_REG)
11199 (zero_extract:SWI48
11205 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11206 (label_ref (match_dup 4))
11209 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11211 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11214 (define_insn_and_split "*jcc_btsi_1"
11216 (if_then_else (match_operator 0 "bt_comparison_operator"
11219 (match_operand:SI 1 "register_operand" "r")
11220 (match_operand:QI 2 "register_operand" "r"))
11223 (label_ref (match_operand 3))
11225 (clobber (reg:CC FLAGS_REG))]
11226 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11229 [(set (reg:CCC FLAGS_REG)
11237 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11238 (label_ref (match_dup 3))
11241 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11243 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11246 ;; avoid useless masking of bit offset operand
11247 (define_insn_and_split "*jcc_btsi_mask_1"
11250 (match_operator 0 "bt_comparison_operator"
11253 (match_operand:SI 1 "register_operand" "r")
11256 (match_operand:SI 2 "register_operand" "r")
11257 (match_operand:SI 3 "const_int_operand" "n")) 0))
11260 (label_ref (match_operand 4))
11262 (clobber (reg:CC FLAGS_REG))]
11263 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11264 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11267 [(set (reg:CCC FLAGS_REG)
11275 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11276 (label_ref (match_dup 4))
11278 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11280 ;; Define combination compare-and-branch fp compare instructions to help
11283 (define_insn "*jcc<mode>_0_i387"
11285 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11286 [(match_operand:X87MODEF 1 "register_operand" "f")
11287 (match_operand:X87MODEF 2 "const0_operand")])
11288 (label_ref (match_operand 3))
11290 (clobber (reg:CCFP FPSR_REG))
11291 (clobber (reg:CCFP FLAGS_REG))
11292 (clobber (match_scratch:HI 4 "=a"))]
11293 "TARGET_80387 && !TARGET_CMOVE"
11296 (define_insn "*jcc<mode>_0_r_i387"
11298 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11299 [(match_operand:X87MODEF 1 "register_operand" "f")
11300 (match_operand:X87MODEF 2 "const0_operand")])
11302 (label_ref (match_operand 3))))
11303 (clobber (reg:CCFP FPSR_REG))
11304 (clobber (reg:CCFP FLAGS_REG))
11305 (clobber (match_scratch:HI 4 "=a"))]
11306 "TARGET_80387 && !TARGET_CMOVE"
11309 (define_insn "*jccxf_i387"
11311 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11312 [(match_operand:XF 1 "register_operand" "f")
11313 (match_operand:XF 2 "register_operand" "f")])
11314 (label_ref (match_operand 3))
11316 (clobber (reg:CCFP FPSR_REG))
11317 (clobber (reg:CCFP FLAGS_REG))
11318 (clobber (match_scratch:HI 4 "=a"))]
11319 "TARGET_80387 && !TARGET_CMOVE"
11322 (define_insn "*jccxf_r_i387"
11324 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11325 [(match_operand:XF 1 "register_operand" "f")
11326 (match_operand:XF 2 "register_operand" "f")])
11328 (label_ref (match_operand 3))))
11329 (clobber (reg:CCFP FPSR_REG))
11330 (clobber (reg:CCFP FLAGS_REG))
11331 (clobber (match_scratch:HI 4 "=a"))]
11332 "TARGET_80387 && !TARGET_CMOVE"
11335 (define_insn "*jcc<mode>_i387"
11337 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11338 [(match_operand:MODEF 1 "register_operand" "f")
11339 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11340 (label_ref (match_operand 3))
11342 (clobber (reg:CCFP FPSR_REG))
11343 (clobber (reg:CCFP FLAGS_REG))
11344 (clobber (match_scratch:HI 4 "=a"))]
11345 "TARGET_80387 && !TARGET_CMOVE"
11348 (define_insn "*jcc<mode>_r_i387"
11350 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11351 [(match_operand:MODEF 1 "register_operand" "f")
11352 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11354 (label_ref (match_operand 3))))
11355 (clobber (reg:CCFP FPSR_REG))
11356 (clobber (reg:CCFP FLAGS_REG))
11357 (clobber (match_scratch:HI 4 "=a"))]
11358 "TARGET_80387 && !TARGET_CMOVE"
11361 (define_insn "*jccu<mode>_i387"
11363 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11364 [(match_operand:X87MODEF 1 "register_operand" "f")
11365 (match_operand:X87MODEF 2 "register_operand" "f")])
11366 (label_ref (match_operand 3))
11368 (clobber (reg:CCFP FPSR_REG))
11369 (clobber (reg:CCFP FLAGS_REG))
11370 (clobber (match_scratch:HI 4 "=a"))]
11371 "TARGET_80387 && !TARGET_CMOVE"
11374 (define_insn "*jccu<mode>_r_i387"
11376 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11377 [(match_operand:X87MODEF 1 "register_operand" "f")
11378 (match_operand:X87MODEF 2 "register_operand" "f")])
11380 (label_ref (match_operand 3))))
11381 (clobber (reg:CCFP FPSR_REG))
11382 (clobber (reg:CCFP FLAGS_REG))
11383 (clobber (match_scratch:HI 4 "=a"))]
11384 "TARGET_80387 && !TARGET_CMOVE"
11389 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11390 [(match_operand:X87MODEF 1 "register_operand")
11391 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11393 (match_operand 4)))
11394 (clobber (reg:CCFP FPSR_REG))
11395 (clobber (reg:CCFP FLAGS_REG))]
11396 "TARGET_80387 && !TARGET_CMOVE
11397 && reload_completed"
11400 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11401 operands[3], operands[4], NULL_RTX);
11407 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11408 [(match_operand:X87MODEF 1 "register_operand")
11409 (match_operand:X87MODEF 2 "general_operand")])
11411 (match_operand 4)))
11412 (clobber (reg:CCFP FPSR_REG))
11413 (clobber (reg:CCFP FLAGS_REG))
11414 (clobber (match_scratch:HI 5))]
11415 "TARGET_80387 && !TARGET_CMOVE
11416 && reload_completed"
11419 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11420 operands[3], operands[4], operands[5]);
11424 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11425 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11426 ;; with a precedence over other operators and is always put in the first
11427 ;; place. Swap condition and operands to match ficom instruction.
11429 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11432 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11433 [(match_operator:X87MODEF 1 "float_operator"
11434 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11435 (match_operand:X87MODEF 3 "register_operand" "f")])
11436 (label_ref (match_operand 4))
11438 (clobber (reg:CCFP FPSR_REG))
11439 (clobber (reg:CCFP FLAGS_REG))
11440 (clobber (match_scratch:HI 5 "=a"))]
11441 "TARGET_80387 && !TARGET_CMOVE
11442 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11443 || optimize_function_for_size_p (cfun))"
11446 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11449 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11450 [(match_operator:X87MODEF 1 "float_operator"
11451 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11452 (match_operand:X87MODEF 3 "register_operand" "f")])
11454 (label_ref (match_operand 4))))
11455 (clobber (reg:CCFP FPSR_REG))
11456 (clobber (reg:CCFP FLAGS_REG))
11457 (clobber (match_scratch:HI 5 "=a"))]
11458 "TARGET_80387 && !TARGET_CMOVE
11459 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11460 || optimize_function_for_size_p (cfun))"
11466 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11467 [(match_operator:X87MODEF 1 "float_operator"
11468 [(match_operand:SWI24 2 "memory_operand")])
11469 (match_operand:X87MODEF 3 "register_operand")])
11471 (match_operand 5)))
11472 (clobber (reg:CCFP FPSR_REG))
11473 (clobber (reg:CCFP FLAGS_REG))
11474 (clobber (match_scratch:HI 6))]
11475 "TARGET_80387 && !TARGET_CMOVE
11476 && reload_completed"
11479 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11480 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11481 operands[4], operands[5], operands[6]);
11485 ;; Unconditional and other jump instructions
11487 (define_insn "jump_bnd"
11489 (label_ref (match_operand 0)))]
11490 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11492 [(set_attr "type" "ibr")
11493 (set (attr "length")
11494 (if_then_else (and (ge (minus (match_dup 0) (pc))
11496 (lt (minus (match_dup 0) (pc))
11500 (set_attr "modrm" "0")])
11502 (define_insn "jump"
11504 (label_ref (match_operand 0)))]
11507 [(set_attr "type" "ibr")
11508 (set (attr "length")
11509 (if_then_else (and (ge (minus (match_dup 0) (pc))
11511 (lt (minus (match_dup 0) (pc))
11515 (set_attr "modrm" "0")])
11517 (define_expand "indirect_jump"
11518 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11522 operands[0] = convert_memory_address (word_mode, operands[0]);
11525 (define_insn "*indirect_jump"
11526 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11529 [(set_attr "type" "ibr")
11530 (set_attr "length_immediate" "0")])
11532 (define_expand "tablejump"
11533 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11534 (use (label_ref (match_operand 1)))])]
11537 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11538 relative. Convert the relative address to an absolute address. */
11542 enum rtx_code code;
11544 /* We can't use @GOTOFF for text labels on VxWorks;
11545 see gotoff_operand. */
11546 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11550 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11552 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11556 op1 = pic_offset_table_rtx;
11561 op0 = pic_offset_table_rtx;
11565 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11570 operands[0] = convert_memory_address (word_mode, operands[0]);
11573 (define_insn "*tablejump_1"
11574 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11575 (use (label_ref (match_operand 1)))]
11578 [(set_attr "type" "ibr")
11579 (set_attr "length_immediate" "0")])
11581 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11584 [(set (reg FLAGS_REG) (match_operand 0))
11585 (set (match_operand:QI 1 "register_operand")
11586 (match_operator:QI 2 "ix86_comparison_operator"
11587 [(reg FLAGS_REG) (const_int 0)]))
11588 (set (match_operand 3 "q_regs_operand")
11589 (zero_extend (match_dup 1)))]
11590 "(peep2_reg_dead_p (3, operands[1])
11591 || operands_match_p (operands[1], operands[3]))
11592 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11593 [(set (match_dup 4) (match_dup 0))
11594 (set (strict_low_part (match_dup 5))
11597 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11598 operands[5] = gen_lowpart (QImode, operands[3]);
11599 ix86_expand_clear (operands[3]);
11603 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11604 (match_operand 4)])
11605 (set (match_operand:QI 1 "register_operand")
11606 (match_operator:QI 2 "ix86_comparison_operator"
11607 [(reg FLAGS_REG) (const_int 0)]))
11608 (set (match_operand 3 "q_regs_operand")
11609 (zero_extend (match_dup 1)))]
11610 "(peep2_reg_dead_p (3, operands[1])
11611 || operands_match_p (operands[1], operands[3]))
11612 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11613 [(parallel [(set (match_dup 5) (match_dup 0))
11615 (set (strict_low_part (match_dup 6))
11618 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11619 operands[6] = gen_lowpart (QImode, operands[3]);
11620 ix86_expand_clear (operands[3]);
11623 ;; Similar, but match zero extend with andsi3.
11626 [(set (reg FLAGS_REG) (match_operand 0))
11627 (set (match_operand:QI 1 "register_operand")
11628 (match_operator:QI 2 "ix86_comparison_operator"
11629 [(reg FLAGS_REG) (const_int 0)]))
11630 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11631 (and:SI (match_dup 3) (const_int 255)))
11632 (clobber (reg:CC FLAGS_REG))])]
11633 "REGNO (operands[1]) == REGNO (operands[3])
11634 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11635 [(set (match_dup 4) (match_dup 0))
11636 (set (strict_low_part (match_dup 5))
11639 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11640 operands[5] = gen_lowpart (QImode, operands[3]);
11641 ix86_expand_clear (operands[3]);
11645 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11646 (match_operand 4)])
11647 (set (match_operand:QI 1 "register_operand")
11648 (match_operator:QI 2 "ix86_comparison_operator"
11649 [(reg FLAGS_REG) (const_int 0)]))
11650 (parallel [(set (match_operand 3 "q_regs_operand")
11651 (zero_extend (match_dup 1)))
11652 (clobber (reg:CC FLAGS_REG))])]
11653 "(peep2_reg_dead_p (3, operands[1])
11654 || operands_match_p (operands[1], operands[3]))
11655 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11656 [(parallel [(set (match_dup 5) (match_dup 0))
11658 (set (strict_low_part (match_dup 6))
11661 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11662 operands[6] = gen_lowpart (QImode, operands[3]);
11663 ix86_expand_clear (operands[3]);
11666 ;; Call instructions.
11668 ;; The predicates normally associated with named expanders are not properly
11669 ;; checked for calls. This is a bug in the generic code, but it isn't that
11670 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11672 ;; P6 processors will jump to the address after the decrement when %esp
11673 ;; is used as a call operand, so they will execute return address as a code.
11674 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11676 ;; Register constraint for call instruction.
11677 (define_mode_attr c [(SI "l") (DI "r")])
11679 ;; Call subroutine returning no value.
11681 (define_expand "call"
11682 [(call (match_operand:QI 0)
11684 (use (match_operand 2))]
11687 ix86_expand_call (NULL, operands[0], operands[1],
11688 operands[2], NULL, false);
11692 (define_expand "sibcall"
11693 [(call (match_operand:QI 0)
11695 (use (match_operand 2))]
11698 ix86_expand_call (NULL, operands[0], operands[1],
11699 operands[2], NULL, true);
11703 (define_insn "*call"
11704 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11705 (match_operand 1))]
11706 "!SIBLING_CALL_P (insn)"
11707 "* return ix86_output_call_insn (insn, operands[0]);"
11708 [(set_attr "type" "call")])
11710 (define_insn "*sibcall"
11711 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11712 (match_operand 1))]
11713 "SIBLING_CALL_P (insn)"
11714 "* return ix86_output_call_insn (insn, operands[0]);"
11715 [(set_attr "type" "call")])
11717 (define_insn "*sibcall_memory"
11718 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11720 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11722 "* return ix86_output_call_insn (insn, operands[0]);"
11723 [(set_attr "type" "call")])
11726 [(set (match_operand:W 0 "register_operand")
11727 (match_operand:W 1 "memory_operand"))
11728 (call (mem:QI (match_dup 0))
11729 (match_operand 3))]
11730 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11731 && peep2_reg_dead_p (2, operands[0])"
11732 [(parallel [(call (mem:QI (match_dup 1))
11734 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11737 [(set (match_operand:W 0 "register_operand")
11738 (match_operand:W 1 "memory_operand"))
11739 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11740 (call (mem:QI (match_dup 0))
11741 (match_operand 3))]
11742 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11743 && peep2_reg_dead_p (3, operands[0])"
11744 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11745 (parallel [(call (mem:QI (match_dup 1))
11747 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11749 (define_expand "call_pop"
11750 [(parallel [(call (match_operand:QI 0)
11751 (match_operand:SI 1))
11752 (set (reg:SI SP_REG)
11753 (plus:SI (reg:SI SP_REG)
11754 (match_operand:SI 3)))])]
11757 ix86_expand_call (NULL, operands[0], operands[1],
11758 operands[2], operands[3], false);
11762 (define_insn "*call_pop"
11763 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11765 (set (reg:SI SP_REG)
11766 (plus:SI (reg:SI SP_REG)
11767 (match_operand:SI 2 "immediate_operand" "i")))]
11768 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11769 "* return ix86_output_call_insn (insn, operands[0]);"
11770 [(set_attr "type" "call")])
11772 (define_insn "*sibcall_pop"
11773 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11775 (set (reg:SI SP_REG)
11776 (plus:SI (reg:SI SP_REG)
11777 (match_operand:SI 2 "immediate_operand" "i")))]
11778 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11779 "* return ix86_output_call_insn (insn, operands[0]);"
11780 [(set_attr "type" "call")])
11782 (define_insn "*sibcall_pop_memory"
11783 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11785 (set (reg:SI SP_REG)
11786 (plus:SI (reg:SI SP_REG)
11787 (match_operand:SI 2 "immediate_operand" "i")))
11788 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11790 "* return ix86_output_call_insn (insn, operands[0]);"
11791 [(set_attr "type" "call")])
11794 [(set (match_operand:SI 0 "register_operand")
11795 (match_operand:SI 1 "memory_operand"))
11796 (parallel [(call (mem:QI (match_dup 0))
11798 (set (reg:SI SP_REG)
11799 (plus:SI (reg:SI SP_REG)
11800 (match_operand:SI 4 "immediate_operand")))])]
11801 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11802 && peep2_reg_dead_p (2, operands[0])"
11803 [(parallel [(call (mem:QI (match_dup 1))
11805 (set (reg:SI SP_REG)
11806 (plus:SI (reg:SI SP_REG)
11808 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11811 [(set (match_operand:SI 0 "register_operand")
11812 (match_operand:SI 1 "memory_operand"))
11813 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11814 (parallel [(call (mem:QI (match_dup 0))
11816 (set (reg:SI SP_REG)
11817 (plus:SI (reg:SI SP_REG)
11818 (match_operand:SI 4 "immediate_operand")))])]
11819 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11820 && peep2_reg_dead_p (3, operands[0])"
11821 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11822 (parallel [(call (mem:QI (match_dup 1))
11824 (set (reg:SI SP_REG)
11825 (plus:SI (reg:SI SP_REG)
11827 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11829 ;; Combining simple memory jump instruction
11832 [(set (match_operand:W 0 "register_operand")
11833 (match_operand:W 1 "memory_operand"))
11834 (set (pc) (match_dup 0))]
11835 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11836 [(set (pc) (match_dup 1))])
11838 ;; Call subroutine, returning value in operand 0
11840 (define_expand "call_value"
11841 [(set (match_operand 0)
11842 (call (match_operand:QI 1)
11843 (match_operand 2)))
11844 (use (match_operand 3))]
11847 ix86_expand_call (operands[0], operands[1], operands[2],
11848 operands[3], NULL, false);
11852 (define_expand "sibcall_value"
11853 [(set (match_operand 0)
11854 (call (match_operand:QI 1)
11855 (match_operand 2)))
11856 (use (match_operand 3))]
11859 ix86_expand_call (operands[0], operands[1], operands[2],
11860 operands[3], NULL, true);
11864 (define_insn "*call_value"
11865 [(set (match_operand 0)
11866 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11867 (match_operand 2)))]
11868 "!SIBLING_CALL_P (insn)"
11869 "* return ix86_output_call_insn (insn, operands[1]);"
11870 [(set_attr "type" "callv")])
11872 (define_insn "*sibcall_value"
11873 [(set (match_operand 0)
11874 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11875 (match_operand 2)))]
11876 "SIBLING_CALL_P (insn)"
11877 "* return ix86_output_call_insn (insn, operands[1]);"
11878 [(set_attr "type" "callv")])
11880 (define_insn "*sibcall_value_memory"
11881 [(set (match_operand 0)
11882 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11883 (match_operand 2)))
11884 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11886 "* return ix86_output_call_insn (insn, operands[1]);"
11887 [(set_attr "type" "callv")])
11890 [(set (match_operand:W 0 "register_operand")
11891 (match_operand:W 1 "memory_operand"))
11892 (set (match_operand 2)
11893 (call (mem:QI (match_dup 0))
11894 (match_operand 3)))]
11895 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11896 && peep2_reg_dead_p (2, operands[0])"
11897 [(parallel [(set (match_dup 2)
11898 (call (mem:QI (match_dup 1))
11900 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11903 [(set (match_operand:W 0 "register_operand")
11904 (match_operand:W 1 "memory_operand"))
11905 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11906 (set (match_operand 2)
11907 (call (mem:QI (match_dup 0))
11908 (match_operand 3)))]
11909 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11910 && peep2_reg_dead_p (3, operands[0])"
11911 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11912 (parallel [(set (match_dup 2)
11913 (call (mem:QI (match_dup 1))
11915 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11917 (define_expand "call_value_pop"
11918 [(parallel [(set (match_operand 0)
11919 (call (match_operand:QI 1)
11920 (match_operand:SI 2)))
11921 (set (reg:SI SP_REG)
11922 (plus:SI (reg:SI SP_REG)
11923 (match_operand:SI 4)))])]
11926 ix86_expand_call (operands[0], operands[1], operands[2],
11927 operands[3], operands[4], false);
11931 (define_insn "*call_value_pop"
11932 [(set (match_operand 0)
11933 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11934 (match_operand 2)))
11935 (set (reg:SI SP_REG)
11936 (plus:SI (reg:SI SP_REG)
11937 (match_operand:SI 3 "immediate_operand" "i")))]
11938 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11939 "* return ix86_output_call_insn (insn, operands[1]);"
11940 [(set_attr "type" "callv")])
11942 (define_insn "*sibcall_value_pop"
11943 [(set (match_operand 0)
11944 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11945 (match_operand 2)))
11946 (set (reg:SI SP_REG)
11947 (plus:SI (reg:SI SP_REG)
11948 (match_operand:SI 3 "immediate_operand" "i")))]
11949 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11950 "* return ix86_output_call_insn (insn, operands[1]);"
11951 [(set_attr "type" "callv")])
11953 (define_insn "*sibcall_value_pop_memory"
11954 [(set (match_operand 0)
11955 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11956 (match_operand 2)))
11957 (set (reg:SI SP_REG)
11958 (plus:SI (reg:SI SP_REG)
11959 (match_operand:SI 3 "immediate_operand" "i")))
11960 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11962 "* return ix86_output_call_insn (insn, operands[1]);"
11963 [(set_attr "type" "callv")])
11966 [(set (match_operand:SI 0 "register_operand")
11967 (match_operand:SI 1 "memory_operand"))
11968 (parallel [(set (match_operand 2)
11969 (call (mem:QI (match_dup 0))
11970 (match_operand 3)))
11971 (set (reg:SI SP_REG)
11972 (plus:SI (reg:SI SP_REG)
11973 (match_operand:SI 4 "immediate_operand")))])]
11974 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11975 && peep2_reg_dead_p (2, operands[0])"
11976 [(parallel [(set (match_dup 2)
11977 (call (mem:QI (match_dup 1))
11979 (set (reg:SI SP_REG)
11980 (plus:SI (reg:SI SP_REG)
11982 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11985 [(set (match_operand:SI 0 "register_operand")
11986 (match_operand:SI 1 "memory_operand"))
11987 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11988 (parallel [(set (match_operand 2)
11989 (call (mem:QI (match_dup 0))
11990 (match_operand 3)))
11991 (set (reg:SI SP_REG)
11992 (plus:SI (reg:SI SP_REG)
11993 (match_operand:SI 4 "immediate_operand")))])]
11994 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11995 && peep2_reg_dead_p (3, operands[0])"
11996 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11997 (parallel [(set (match_dup 2)
11998 (call (mem:QI (match_dup 1))
12000 (set (reg:SI SP_REG)
12001 (plus:SI (reg:SI SP_REG)
12003 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12005 ;; Call subroutine returning any type.
12007 (define_expand "untyped_call"
12008 [(parallel [(call (match_operand 0)
12011 (match_operand 2)])]
12016 /* In order to give reg-stack an easier job in validating two
12017 coprocessor registers as containing a possible return value,
12018 simply pretend the untyped call returns a complex long double
12021 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12022 and should have the default ABI. */
12024 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12025 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12026 operands[0], const0_rtx,
12027 GEN_INT ((TARGET_64BIT
12028 ? (ix86_abi == SYSV_ABI
12029 ? X86_64_SSE_REGPARM_MAX
12030 : X86_64_MS_SSE_REGPARM_MAX)
12031 : X86_32_SSE_REGPARM_MAX)
12035 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12037 rtx set = XVECEXP (operands[2], 0, i);
12038 emit_move_insn (SET_DEST (set), SET_SRC (set));
12041 /* The optimizer does not know that the call sets the function value
12042 registers we stored in the result block. We avoid problems by
12043 claiming that all hard registers are used and clobbered at this
12045 emit_insn (gen_blockage ());
12050 ;; Prologue and epilogue instructions
12052 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12053 ;; all of memory. This blocks insns from being moved across this point.
12055 (define_insn "blockage"
12056 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12059 [(set_attr "length" "0")])
12061 ;; Do not schedule instructions accessing memory across this point.
12063 (define_expand "memory_blockage"
12064 [(set (match_dup 0)
12065 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12068 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12069 MEM_VOLATILE_P (operands[0]) = 1;
12072 (define_insn "*memory_blockage"
12073 [(set (match_operand:BLK 0)
12074 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12077 [(set_attr "length" "0")])
12079 ;; As USE insns aren't meaningful after reload, this is used instead
12080 ;; to prevent deleting instructions setting registers for PIC code
12081 (define_insn "prologue_use"
12082 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12085 [(set_attr "length" "0")])
12087 ;; Insn emitted into the body of a function to return from a function.
12088 ;; This is only done if the function's epilogue is known to be simple.
12089 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12091 (define_expand "return"
12093 "ix86_can_use_return_insn_p ()"
12095 if (crtl->args.pops_args)
12097 rtx popc = GEN_INT (crtl->args.pops_args);
12098 emit_jump_insn (gen_simple_return_pop_internal (popc));
12103 ;; We need to disable this for TARGET_SEH, as otherwise
12104 ;; shrink-wrapped prologue gets enabled too. This might exceed
12105 ;; the maximum size of prologue in unwind information.
12107 (define_expand "simple_return"
12111 if (crtl->args.pops_args)
12113 rtx popc = GEN_INT (crtl->args.pops_args);
12114 emit_jump_insn (gen_simple_return_pop_internal (popc));
12119 (define_insn "simple_return_internal"
12123 [(set_attr "length_nobnd" "1")
12124 (set_attr "atom_unit" "jeu")
12125 (set_attr "length_immediate" "0")
12126 (set_attr "modrm" "0")])
12128 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12129 ;; instruction Athlon and K8 have.
12131 (define_insn "simple_return_internal_long"
12133 (unspec [(const_int 0)] UNSPEC_REP)]
12136 if (ix86_bnd_prefixed_insn_p (insn))
12139 return "rep%; ret";
12141 [(set_attr "length" "2")
12142 (set_attr "atom_unit" "jeu")
12143 (set_attr "length_immediate" "0")
12144 (set_attr "prefix_rep" "1")
12145 (set_attr "modrm" "0")])
12147 (define_insn "simple_return_pop_internal"
12149 (use (match_operand:SI 0 "const_int_operand"))]
12152 [(set_attr "length_nobnd" "3")
12153 (set_attr "atom_unit" "jeu")
12154 (set_attr "length_immediate" "2")
12155 (set_attr "modrm" "0")])
12157 (define_insn "simple_return_indirect_internal"
12159 (use (match_operand:SI 0 "register_operand" "r"))]
12162 [(set_attr "type" "ibr")
12163 (set_attr "length_immediate" "0")])
12169 [(set_attr "length" "1")
12170 (set_attr "length_immediate" "0")
12171 (set_attr "modrm" "0")])
12173 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12174 (define_insn "nops"
12175 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12179 int num = INTVAL (operands[0]);
12181 gcc_assert (IN_RANGE (num, 1, 8));
12184 fputs ("\tnop\n", asm_out_file);
12188 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12189 (set_attr "length_immediate" "0")
12190 (set_attr "modrm" "0")])
12192 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12193 ;; branch prediction penalty for the third jump in a 16-byte
12197 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12200 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12201 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12203 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12204 The align insn is used to avoid 3 jump instructions in the row to improve
12205 branch prediction and the benefits hardly outweigh the cost of extra 8
12206 nops on the average inserted by full alignment pseudo operation. */
12210 [(set_attr "length" "16")])
12212 (define_expand "prologue"
12215 "ix86_expand_prologue (); DONE;")
12217 (define_insn "set_got"
12218 [(set (match_operand:SI 0 "register_operand" "=r")
12219 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12220 (clobber (reg:CC FLAGS_REG))]
12222 "* return output_set_got (operands[0], NULL_RTX);"
12223 [(set_attr "type" "multi")
12224 (set_attr "length" "12")])
12226 (define_insn "set_got_labelled"
12227 [(set (match_operand:SI 0 "register_operand" "=r")
12228 (unspec:SI [(label_ref (match_operand 1))]
12230 (clobber (reg:CC FLAGS_REG))]
12232 "* return output_set_got (operands[0], operands[1]);"
12233 [(set_attr "type" "multi")
12234 (set_attr "length" "12")])
12236 (define_insn "set_got_rex64"
12237 [(set (match_operand:DI 0 "register_operand" "=r")
12238 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12240 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12241 [(set_attr "type" "lea")
12242 (set_attr "length_address" "4")
12243 (set_attr "mode" "DI")])
12245 (define_insn "set_rip_rex64"
12246 [(set (match_operand:DI 0 "register_operand" "=r")
12247 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12249 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12250 [(set_attr "type" "lea")
12251 (set_attr "length_address" "4")
12252 (set_attr "mode" "DI")])
12254 (define_insn "set_got_offset_rex64"
12255 [(set (match_operand:DI 0 "register_operand" "=r")
12257 [(label_ref (match_operand 1))]
12258 UNSPEC_SET_GOT_OFFSET))]
12260 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12261 [(set_attr "type" "imov")
12262 (set_attr "length_immediate" "0")
12263 (set_attr "length_address" "8")
12264 (set_attr "mode" "DI")])
12266 (define_expand "epilogue"
12269 "ix86_expand_epilogue (1); DONE;")
12271 (define_expand "sibcall_epilogue"
12274 "ix86_expand_epilogue (0); DONE;")
12276 (define_expand "eh_return"
12277 [(use (match_operand 0 "register_operand"))]
12280 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12282 /* Tricky bit: we write the address of the handler to which we will
12283 be returning into someone else's stack frame, one word below the
12284 stack address we wish to restore. */
12285 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12286 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12287 tmp = gen_rtx_MEM (Pmode, tmp);
12288 emit_move_insn (tmp, ra);
12290 emit_jump_insn (gen_eh_return_internal ());
12295 (define_insn_and_split "eh_return_internal"
12299 "epilogue_completed"
12301 "ix86_expand_epilogue (2); DONE;")
12303 (define_insn "leave"
12304 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12305 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12306 (clobber (mem:BLK (scratch)))]
12309 [(set_attr "type" "leave")])
12311 (define_insn "leave_rex64"
12312 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12313 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12314 (clobber (mem:BLK (scratch)))]
12317 [(set_attr "type" "leave")])
12319 ;; Handle -fsplit-stack.
12321 (define_expand "split_stack_prologue"
12325 ix86_expand_split_stack_prologue ();
12329 ;; In order to support the call/return predictor, we use a return
12330 ;; instruction which the middle-end doesn't see.
12331 (define_insn "split_stack_return"
12332 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12333 UNSPECV_SPLIT_STACK_RETURN)]
12336 if (operands[0] == const0_rtx)
12341 [(set_attr "atom_unit" "jeu")
12342 (set_attr "modrm" "0")
12343 (set (attr "length")
12344 (if_then_else (match_operand:SI 0 "const0_operand")
12347 (set (attr "length_immediate")
12348 (if_then_else (match_operand:SI 0 "const0_operand")
12352 ;; If there are operand 0 bytes available on the stack, jump to
12355 (define_expand "split_stack_space_check"
12356 [(set (pc) (if_then_else
12357 (ltu (minus (reg SP_REG)
12358 (match_operand 0 "register_operand"))
12359 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12360 (label_ref (match_operand 1))
12364 rtx reg, size, limit;
12366 reg = gen_reg_rtx (Pmode);
12367 size = force_reg (Pmode, operands[0]);
12368 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12369 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12370 UNSPEC_STACK_CHECK);
12371 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12372 ix86_expand_branch (GEU, reg, limit, operands[1]);
12377 ;; Bit manipulation instructions.
12379 (define_expand "ffs<mode>2"
12380 [(set (match_dup 2) (const_int -1))
12381 (parallel [(set (match_dup 3) (match_dup 4))
12382 (set (match_operand:SWI48 0 "register_operand")
12384 (match_operand:SWI48 1 "nonimmediate_operand")))])
12385 (set (match_dup 0) (if_then_else:SWI48
12386 (eq (match_dup 3) (const_int 0))
12389 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12390 (clobber (reg:CC FLAGS_REG))])]
12393 machine_mode flags_mode;
12395 if (<MODE>mode == SImode && !TARGET_CMOVE)
12397 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12402 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12404 operands[2] = gen_reg_rtx (<MODE>mode);
12405 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12406 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12409 (define_insn_and_split "ffssi2_no_cmove"
12410 [(set (match_operand:SI 0 "register_operand" "=r")
12411 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12412 (clobber (match_scratch:SI 2 "=&q"))
12413 (clobber (reg:CC FLAGS_REG))]
12416 "&& reload_completed"
12417 [(parallel [(set (match_dup 4) (match_dup 5))
12418 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12419 (set (strict_low_part (match_dup 3))
12420 (eq:QI (match_dup 4) (const_int 0)))
12421 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12422 (clobber (reg:CC FLAGS_REG))])
12423 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12424 (clobber (reg:CC FLAGS_REG))])
12425 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12426 (clobber (reg:CC FLAGS_REG))])]
12428 machine_mode flags_mode
12429 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12431 operands[3] = gen_lowpart (QImode, operands[2]);
12432 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12433 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12435 ix86_expand_clear (operands[2]);
12438 (define_insn "*tzcnt<mode>_1"
12439 [(set (reg:CCC FLAGS_REG)
12440 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12442 (set (match_operand:SWI48 0 "register_operand" "=r")
12443 (ctz:SWI48 (match_dup 1)))]
12444 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12445 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12446 [(set_attr "type" "alu1")
12447 (set_attr "prefix_0f" "1")
12448 (set_attr "prefix_rep" "1")
12449 (set_attr "btver2_decode" "double")
12450 (set_attr "mode" "<MODE>")])
12452 (define_insn "*bsf<mode>_1"
12453 [(set (reg:CCZ FLAGS_REG)
12454 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12456 (set (match_operand:SWI48 0 "register_operand" "=r")
12457 (ctz:SWI48 (match_dup 1)))]
12459 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12460 [(set_attr "type" "alu1")
12461 (set_attr "prefix_0f" "1")
12462 (set_attr "btver2_decode" "double")
12463 (set_attr "mode" "<MODE>")])
12465 (define_expand "ctz<mode>2"
12467 [(set (match_operand:SWI248 0 "register_operand")
12469 (match_operand:SWI248 1 "nonimmediate_operand")))
12470 (clobber (reg:CC FLAGS_REG))])])
12472 ; False dependency happens when destination is only updated by tzcnt,
12473 ; lzcnt or popcnt. There is no false dependency when destination is
12474 ; also used in source.
12475 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12476 [(set (match_operand:SWI48 0 "register_operand" "=r")
12478 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12479 (clobber (reg:CC FLAGS_REG))]
12480 "(TARGET_BMI || TARGET_GENERIC)
12481 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12483 "&& reload_completed"
12485 [(set (match_dup 0)
12486 (ctz:SWI48 (match_dup 1)))
12487 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12488 (clobber (reg:CC FLAGS_REG))])]
12490 if (!reg_mentioned_p (operands[0], operands[1]))
12491 ix86_expand_clear (operands[0]);
12494 (define_insn "*ctz<mode>2_falsedep"
12495 [(set (match_operand:SWI48 0 "register_operand" "=r")
12497 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12498 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12499 UNSPEC_INSN_FALSE_DEP)
12500 (clobber (reg:CC FLAGS_REG))]
12504 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12505 else if (TARGET_GENERIC)
12506 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12507 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12509 gcc_unreachable ();
12511 [(set_attr "type" "alu1")
12512 (set_attr "prefix_0f" "1")
12513 (set_attr "prefix_rep" "1")
12514 (set_attr "mode" "<MODE>")])
12516 (define_insn "*ctz<mode>2"
12517 [(set (match_operand:SWI248 0 "register_operand" "=r")
12518 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12519 (clobber (reg:CC FLAGS_REG))]
12523 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12524 else if (optimize_function_for_size_p (cfun))
12526 else if (TARGET_GENERIC)
12527 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12528 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12530 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12532 [(set_attr "type" "alu1")
12533 (set_attr "prefix_0f" "1")
12534 (set (attr "prefix_rep")
12536 (ior (match_test "TARGET_BMI")
12537 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12538 (match_test "TARGET_GENERIC")))
12540 (const_string "0")))
12541 (set_attr "mode" "<MODE>")])
12543 (define_expand "clz<mode>2"
12545 [(set (match_operand:SWI248 0 "register_operand")
12548 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12549 (clobber (reg:CC FLAGS_REG))])
12551 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12552 (clobber (reg:CC FLAGS_REG))])]
12557 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12560 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12563 (define_expand "clz<mode>2_lzcnt"
12565 [(set (match_operand:SWI248 0 "register_operand")
12567 (match_operand:SWI248 1 "nonimmediate_operand")))
12568 (clobber (reg:CC FLAGS_REG))])]
12571 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12572 [(set (match_operand:SWI48 0 "register_operand" "=r")
12574 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12575 (clobber (reg:CC FLAGS_REG))]
12577 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12579 "&& reload_completed"
12581 [(set (match_dup 0)
12582 (clz:SWI48 (match_dup 1)))
12583 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12584 (clobber (reg:CC FLAGS_REG))])]
12586 if (!reg_mentioned_p (operands[0], operands[1]))
12587 ix86_expand_clear (operands[0]);
12590 (define_insn "*clz<mode>2_lzcnt_falsedep"
12591 [(set (match_operand:SWI48 0 "register_operand" "=r")
12593 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12594 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12595 UNSPEC_INSN_FALSE_DEP)
12596 (clobber (reg:CC FLAGS_REG))]
12598 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12599 [(set_attr "prefix_rep" "1")
12600 (set_attr "type" "bitmanip")
12601 (set_attr "mode" "<MODE>")])
12603 (define_insn "*clz<mode>2_lzcnt"
12604 [(set (match_operand:SWI248 0 "register_operand" "=r")
12605 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12606 (clobber (reg:CC FLAGS_REG))]
12608 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12609 [(set_attr "prefix_rep" "1")
12610 (set_attr "type" "bitmanip")
12611 (set_attr "mode" "<MODE>")])
12613 ;; BMI instructions.
12614 (define_insn "*bmi_andn_<mode>"
12615 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12618 (match_operand:SWI48 1 "register_operand" "r,r"))
12619 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12620 (clobber (reg:CC FLAGS_REG))]
12622 "andn\t{%2, %1, %0|%0, %1, %2}"
12623 [(set_attr "type" "bitmanip")
12624 (set_attr "btver2_decode" "direct, double")
12625 (set_attr "mode" "<MODE>")])
12627 (define_insn "bmi_bextr_<mode>"
12628 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12629 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12630 (match_operand:SWI48 2 "register_operand" "r,r")]
12632 (clobber (reg:CC FLAGS_REG))]
12634 "bextr\t{%2, %1, %0|%0, %1, %2}"
12635 [(set_attr "type" "bitmanip")
12636 (set_attr "btver2_decode" "direct, double")
12637 (set_attr "mode" "<MODE>")])
12639 (define_insn "*bmi_blsi_<mode>"
12640 [(set (match_operand:SWI48 0 "register_operand" "=r")
12643 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12645 (clobber (reg:CC FLAGS_REG))]
12647 "blsi\t{%1, %0|%0, %1}"
12648 [(set_attr "type" "bitmanip")
12649 (set_attr "btver2_decode" "double")
12650 (set_attr "mode" "<MODE>")])
12652 (define_insn "*bmi_blsmsk_<mode>"
12653 [(set (match_operand:SWI48 0 "register_operand" "=r")
12656 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12659 (clobber (reg:CC FLAGS_REG))]
12661 "blsmsk\t{%1, %0|%0, %1}"
12662 [(set_attr "type" "bitmanip")
12663 (set_attr "btver2_decode" "double")
12664 (set_attr "mode" "<MODE>")])
12666 (define_insn "*bmi_blsr_<mode>"
12667 [(set (match_operand:SWI48 0 "register_operand" "=r")
12670 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12673 (clobber (reg:CC FLAGS_REG))]
12675 "blsr\t{%1, %0|%0, %1}"
12676 [(set_attr "type" "bitmanip")
12677 (set_attr "btver2_decode" "double")
12678 (set_attr "mode" "<MODE>")])
12680 ;; BMI2 instructions.
12681 (define_expand "bmi2_bzhi_<mode>3"
12683 [(set (match_operand:SWI48 0 "register_operand")
12684 (zero_extract:SWI48
12685 (match_operand:SWI48 1 "nonimmediate_operand")
12687 (and:SWI48 (match_operand:SWI48 2 "register_operand")
12691 (clobber (reg:CC FLAGS_REG))])]
12693 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12695 (define_insn "*bmi2_bzhi_<mode>3"
12696 [(set (match_operand:SWI48 0 "register_operand" "=r")
12697 (zero_extract:SWI48
12698 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12700 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12702 (match_operand:SWI48 3 "const_int_operand" "n"))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12706 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12707 [(set_attr "type" "bitmanip")
12708 (set_attr "prefix" "vex")
12709 (set_attr "mode" "<MODE>")])
12711 (define_mode_attr k [(SI "k") (DI "q")])
12712 (define_insn "*bmi2_bzhi_<mode>3_1"
12713 [(set (match_operand:SWI48 0 "register_operand" "=r")
12714 (zero_extract:SWI48
12715 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12717 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12718 (match_operand:SWI48 3 "const_int_operand" "n"))
12720 (clobber (reg:CC FLAGS_REG))]
12721 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12722 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12723 [(set_attr "type" "bitmanip")
12724 (set_attr "prefix" "vex")
12725 (set_attr "mode" "<MODE>")])
12727 (define_insn "bmi2_pdep_<mode>3"
12728 [(set (match_operand:SWI48 0 "register_operand" "=r")
12729 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12730 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12733 "pdep\t{%2, %1, %0|%0, %1, %2}"
12734 [(set_attr "type" "bitmanip")
12735 (set_attr "prefix" "vex")
12736 (set_attr "mode" "<MODE>")])
12738 (define_insn "bmi2_pext_<mode>3"
12739 [(set (match_operand:SWI48 0 "register_operand" "=r")
12740 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12741 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12744 "pext\t{%2, %1, %0|%0, %1, %2}"
12745 [(set_attr "type" "bitmanip")
12746 (set_attr "prefix" "vex")
12747 (set_attr "mode" "<MODE>")])
12749 ;; TBM instructions.
12750 (define_insn "tbm_bextri_<mode>"
12751 [(set (match_operand:SWI48 0 "register_operand" "=r")
12752 (zero_extract:SWI48
12753 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12754 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12755 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12756 (clobber (reg:CC FLAGS_REG))]
12759 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12760 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12762 [(set_attr "type" "bitmanip")
12763 (set_attr "mode" "<MODE>")])
12765 (define_insn "*tbm_blcfill_<mode>"
12766 [(set (match_operand:SWI48 0 "register_operand" "=r")
12769 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12772 (clobber (reg:CC FLAGS_REG))]
12774 "blcfill\t{%1, %0|%0, %1}"
12775 [(set_attr "type" "bitmanip")
12776 (set_attr "mode" "<MODE>")])
12778 (define_insn "*tbm_blci_<mode>"
12779 [(set (match_operand:SWI48 0 "register_operand" "=r")
12783 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12786 (clobber (reg:CC FLAGS_REG))]
12788 "blci\t{%1, %0|%0, %1}"
12789 [(set_attr "type" "bitmanip")
12790 (set_attr "mode" "<MODE>")])
12792 (define_insn "*tbm_blcic_<mode>"
12793 [(set (match_operand:SWI48 0 "register_operand" "=r")
12796 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12800 (clobber (reg:CC FLAGS_REG))]
12802 "blcic\t{%1, %0|%0, %1}"
12803 [(set_attr "type" "bitmanip")
12804 (set_attr "mode" "<MODE>")])
12806 (define_insn "*tbm_blcmsk_<mode>"
12807 [(set (match_operand:SWI48 0 "register_operand" "=r")
12810 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12813 (clobber (reg:CC FLAGS_REG))]
12815 "blcmsk\t{%1, %0|%0, %1}"
12816 [(set_attr "type" "bitmanip")
12817 (set_attr "mode" "<MODE>")])
12819 (define_insn "*tbm_blcs_<mode>"
12820 [(set (match_operand:SWI48 0 "register_operand" "=r")
12823 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12826 (clobber (reg:CC FLAGS_REG))]
12828 "blcs\t{%1, %0|%0, %1}"
12829 [(set_attr "type" "bitmanip")
12830 (set_attr "mode" "<MODE>")])
12832 (define_insn "*tbm_blsfill_<mode>"
12833 [(set (match_operand:SWI48 0 "register_operand" "=r")
12836 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12839 (clobber (reg:CC FLAGS_REG))]
12841 "blsfill\t{%1, %0|%0, %1}"
12842 [(set_attr "type" "bitmanip")
12843 (set_attr "mode" "<MODE>")])
12845 (define_insn "*tbm_blsic_<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 "blsic\t{%1, %0|%0, %1}"
12856 [(set_attr "type" "bitmanip")
12857 (set_attr "mode" "<MODE>")])
12859 (define_insn "*tbm_t1mskc_<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 "t1mskc\t{%1, %0|%0, %1}"
12870 [(set_attr "type" "bitmanip")
12871 (set_attr "mode" "<MODE>")])
12873 (define_insn "*tbm_tzmsk_<mode>"
12874 [(set (match_operand:SWI48 0 "register_operand" "=r")
12877 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12881 (clobber (reg:CC FLAGS_REG))]
12883 "tzmsk\t{%1, %0|%0, %1}"
12884 [(set_attr "type" "bitmanip")
12885 (set_attr "mode" "<MODE>")])
12887 (define_insn "bsr_rex64"
12888 [(set (match_operand:DI 0 "register_operand" "=r")
12889 (minus:DI (const_int 63)
12890 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12891 (clobber (reg:CC FLAGS_REG))]
12893 "bsr{q}\t{%1, %0|%0, %1}"
12894 [(set_attr "type" "alu1")
12895 (set_attr "prefix_0f" "1")
12896 (set_attr "mode" "DI")])
12899 [(set (match_operand:SI 0 "register_operand" "=r")
12900 (minus:SI (const_int 31)
12901 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12902 (clobber (reg:CC FLAGS_REG))]
12904 "bsr{l}\t{%1, %0|%0, %1}"
12905 [(set_attr "type" "alu1")
12906 (set_attr "prefix_0f" "1")
12907 (set_attr "mode" "SI")])
12909 (define_insn "*bsrhi"
12910 [(set (match_operand:HI 0 "register_operand" "=r")
12911 (minus:HI (const_int 15)
12912 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12913 (clobber (reg:CC FLAGS_REG))]
12915 "bsr{w}\t{%1, %0|%0, %1}"
12916 [(set_attr "type" "alu1")
12917 (set_attr "prefix_0f" "1")
12918 (set_attr "mode" "HI")])
12920 (define_expand "popcount<mode>2"
12922 [(set (match_operand:SWI248 0 "register_operand")
12924 (match_operand:SWI248 1 "nonimmediate_operand")))
12925 (clobber (reg:CC FLAGS_REG))])]
12928 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12929 [(set (match_operand:SWI48 0 "register_operand" "=r")
12931 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12932 (clobber (reg:CC FLAGS_REG))]
12934 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12936 "&& reload_completed"
12938 [(set (match_dup 0)
12939 (popcount:SWI48 (match_dup 1)))
12940 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12941 (clobber (reg:CC FLAGS_REG))])]
12943 if (!reg_mentioned_p (operands[0], operands[1]))
12944 ix86_expand_clear (operands[0]);
12947 (define_insn "*popcount<mode>2_falsedep"
12948 [(set (match_operand:SWI48 0 "register_operand" "=r")
12950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12951 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12952 UNSPEC_INSN_FALSE_DEP)
12953 (clobber (reg:CC FLAGS_REG))]
12957 return "popcnt\t{%1, %0|%0, %1}";
12959 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12962 [(set_attr "prefix_rep" "1")
12963 (set_attr "type" "bitmanip")
12964 (set_attr "mode" "<MODE>")])
12966 (define_insn "*popcount<mode>2"
12967 [(set (match_operand:SWI248 0 "register_operand" "=r")
12969 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12970 (clobber (reg:CC FLAGS_REG))]
12974 return "popcnt\t{%1, %0|%0, %1}";
12976 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12979 [(set_attr "prefix_rep" "1")
12980 (set_attr "type" "bitmanip")
12981 (set_attr "mode" "<MODE>")])
12983 (define_expand "bswapdi2"
12984 [(set (match_operand:DI 0 "register_operand")
12985 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12989 operands[1] = force_reg (DImode, operands[1]);
12992 (define_expand "bswapsi2"
12993 [(set (match_operand:SI 0 "register_operand")
12994 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12999 else if (TARGET_BSWAP)
13000 operands[1] = force_reg (SImode, operands[1]);
13003 rtx x = operands[0];
13005 emit_move_insn (x, operands[1]);
13006 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13007 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13008 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13013 (define_insn "*bswap<mode>2_movbe"
13014 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13015 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13017 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13020 movbe\t{%1, %0|%0, %1}
13021 movbe\t{%1, %0|%0, %1}"
13022 [(set_attr "type" "bitmanip,imov,imov")
13023 (set_attr "modrm" "0,1,1")
13024 (set_attr "prefix_0f" "*,1,1")
13025 (set_attr "prefix_extra" "*,1,1")
13026 (set_attr "mode" "<MODE>")])
13028 (define_insn "*bswap<mode>2"
13029 [(set (match_operand:SWI48 0 "register_operand" "=r")
13030 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13033 [(set_attr "type" "bitmanip")
13034 (set_attr "modrm" "0")
13035 (set_attr "mode" "<MODE>")])
13037 (define_insn "*bswaphi_lowpart_1"
13038 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13039 (bswap:HI (match_dup 0)))
13040 (clobber (reg:CC FLAGS_REG))]
13041 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13043 xchg{b}\t{%h0, %b0|%b0, %h0}
13044 rol{w}\t{$8, %0|%0, 8}"
13045 [(set_attr "length" "2,4")
13046 (set_attr "mode" "QI,HI")])
13048 (define_insn "bswaphi_lowpart"
13049 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13050 (bswap:HI (match_dup 0)))
13051 (clobber (reg:CC FLAGS_REG))]
13053 "rol{w}\t{$8, %0|%0, 8}"
13054 [(set_attr "length" "4")
13055 (set_attr "mode" "HI")])
13057 (define_expand "paritydi2"
13058 [(set (match_operand:DI 0 "register_operand")
13059 (parity:DI (match_operand:DI 1 "register_operand")))]
13062 rtx scratch = gen_reg_rtx (QImode);
13065 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13066 NULL_RTX, operands[1]));
13068 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13069 gen_rtx_REG (CCmode, FLAGS_REG),
13071 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13074 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13077 rtx tmp = gen_reg_rtx (SImode);
13079 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13080 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13085 (define_expand "paritysi2"
13086 [(set (match_operand:SI 0 "register_operand")
13087 (parity:SI (match_operand:SI 1 "register_operand")))]
13090 rtx scratch = gen_reg_rtx (QImode);
13093 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13095 cond = gen_rtx_fmt_ee (ORDERED, QImode,
13096 gen_rtx_REG (CCmode, FLAGS_REG),
13098 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13100 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13104 (define_insn_and_split "paritydi2_cmp"
13105 [(set (reg:CC FLAGS_REG)
13106 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13108 (clobber (match_scratch:DI 0 "=r"))
13109 (clobber (match_scratch:SI 1 "=&r"))
13110 (clobber (match_scratch:HI 2 "=Q"))]
13113 "&& reload_completed"
13115 [(set (match_dup 1)
13116 (xor:SI (match_dup 1) (match_dup 4)))
13117 (clobber (reg:CC FLAGS_REG))])
13119 [(set (reg:CC FLAGS_REG)
13120 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13121 (clobber (match_dup 1))
13122 (clobber (match_dup 2))])]
13124 operands[4] = gen_lowpart (SImode, operands[3]);
13128 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13129 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13132 operands[1] = gen_highpart (SImode, operands[3]);
13135 (define_insn_and_split "paritysi2_cmp"
13136 [(set (reg:CC FLAGS_REG)
13137 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13139 (clobber (match_scratch:SI 0 "=r"))
13140 (clobber (match_scratch:HI 1 "=&Q"))]
13143 "&& reload_completed"
13145 [(set (match_dup 1)
13146 (xor:HI (match_dup 1) (match_dup 3)))
13147 (clobber (reg:CC FLAGS_REG))])
13149 [(set (reg:CC FLAGS_REG)
13150 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13151 (clobber (match_dup 1))])]
13153 operands[3] = gen_lowpart (HImode, operands[2]);
13155 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13156 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13159 (define_insn "*parityhi2_cmp"
13160 [(set (reg:CC FLAGS_REG)
13161 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13163 (clobber (match_scratch:HI 0 "=Q"))]
13165 "xor{b}\t{%h0, %b0|%b0, %h0}"
13166 [(set_attr "length" "2")
13167 (set_attr "mode" "HI")])
13170 ;; Thread-local storage patterns for ELF.
13172 ;; Note that these code sequences must appear exactly as shown
13173 ;; in order to allow linker relaxation.
13175 (define_insn "*tls_global_dynamic_32_gnu"
13176 [(set (match_operand:SI 0 "register_operand" "=a")
13178 [(match_operand:SI 1 "register_operand" "b")
13179 (match_operand 2 "tls_symbolic_operand")
13180 (match_operand 3 "constant_call_address_operand" "Bz")
13183 (clobber (match_scratch:SI 4 "=d"))
13184 (clobber (match_scratch:SI 5 "=c"))
13185 (clobber (reg:CC FLAGS_REG))]
13186 "!TARGET_64BIT && TARGET_GNU_TLS"
13189 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13190 if (TARGET_SUN_TLS)
13191 #ifdef HAVE_AS_IX86_TLSGDPLT
13192 return "call\t%a2@tlsgdplt";
13194 return "call\t%p3@plt";
13196 return "call\t%P3";
13198 [(set_attr "type" "multi")
13199 (set_attr "length" "12")])
13201 (define_expand "tls_global_dynamic_32"
13203 [(set (match_operand:SI 0 "register_operand")
13204 (unspec:SI [(match_operand:SI 2 "register_operand")
13205 (match_operand 1 "tls_symbolic_operand")
13206 (match_operand 3 "constant_call_address_operand")
13209 (clobber (match_scratch:SI 4))
13210 (clobber (match_scratch:SI 5))
13211 (clobber (reg:CC FLAGS_REG))])]
13213 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13215 (define_insn "*tls_global_dynamic_64_<mode>"
13216 [(set (match_operand:P 0 "register_operand" "=a")
13218 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13219 (match_operand 3)))
13220 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13225 fputs (ASM_BYTE "0x66\n", asm_out_file);
13227 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13228 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13229 fputs ("\trex64\n", asm_out_file);
13230 if (TARGET_SUN_TLS)
13231 return "call\t%p2@plt";
13232 return "call\t%P2";
13234 [(set_attr "type" "multi")
13235 (set (attr "length")
13236 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13238 (define_insn "*tls_global_dynamic_64_largepic"
13239 [(set (match_operand:DI 0 "register_operand" "=a")
13241 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13242 (match_operand:DI 3 "immediate_operand" "i")))
13243 (match_operand 4)))
13244 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13246 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13247 && GET_CODE (operands[3]) == CONST
13248 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13249 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13252 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13253 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13254 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13255 return "call\t{*%%rax|rax}";
13257 [(set_attr "type" "multi")
13258 (set_attr "length" "22")])
13260 (define_expand "tls_global_dynamic_64_<mode>"
13262 [(set (match_operand:P 0 "register_operand")
13264 (mem:QI (match_operand 2))
13266 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13269 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13271 (define_insn "*tls_local_dynamic_base_32_gnu"
13272 [(set (match_operand:SI 0 "register_operand" "=a")
13274 [(match_operand:SI 1 "register_operand" "b")
13275 (match_operand 2 "constant_call_address_operand" "Bz")
13277 UNSPEC_TLS_LD_BASE))
13278 (clobber (match_scratch:SI 3 "=d"))
13279 (clobber (match_scratch:SI 4 "=c"))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "!TARGET_64BIT && TARGET_GNU_TLS"
13284 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13285 if (TARGET_SUN_TLS)
13287 if (HAVE_AS_IX86_TLSLDMPLT)
13288 return "call\t%&@tlsldmplt";
13290 return "call\t%p2@plt";
13292 return "call\t%P2";
13294 [(set_attr "type" "multi")
13295 (set_attr "length" "11")])
13297 (define_expand "tls_local_dynamic_base_32"
13299 [(set (match_operand:SI 0 "register_operand")
13301 [(match_operand:SI 1 "register_operand")
13302 (match_operand 2 "constant_call_address_operand")
13304 UNSPEC_TLS_LD_BASE))
13305 (clobber (match_scratch:SI 3))
13306 (clobber (match_scratch:SI 4))
13307 (clobber (reg:CC FLAGS_REG))])]
13309 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13311 (define_insn "*tls_local_dynamic_base_64_<mode>"
13312 [(set (match_operand:P 0 "register_operand" "=a")
13314 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13315 (match_operand 2)))
13316 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13320 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13321 if (TARGET_SUN_TLS)
13322 return "call\t%p1@plt";
13323 return "call\t%P1";
13325 [(set_attr "type" "multi")
13326 (set_attr "length" "12")])
13328 (define_insn "*tls_local_dynamic_base_64_largepic"
13329 [(set (match_operand:DI 0 "register_operand" "=a")
13331 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13332 (match_operand:DI 2 "immediate_operand" "i")))
13333 (match_operand 3)))
13334 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13335 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13336 && GET_CODE (operands[2]) == CONST
13337 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13338 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13341 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13342 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13343 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13344 return "call\t{*%%rax|rax}";
13346 [(set_attr "type" "multi")
13347 (set_attr "length" "22")])
13349 (define_expand "tls_local_dynamic_base_64_<mode>"
13351 [(set (match_operand:P 0 "register_operand")
13353 (mem:QI (match_operand 1))
13355 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13357 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13359 ;; Local dynamic of a single variable is a lose. Show combine how
13360 ;; to convert that back to global dynamic.
13362 (define_insn_and_split "*tls_local_dynamic_32_once"
13363 [(set (match_operand:SI 0 "register_operand" "=a")
13365 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13366 (match_operand 2 "constant_call_address_operand" "Bz")
13368 UNSPEC_TLS_LD_BASE)
13369 (const:SI (unspec:SI
13370 [(match_operand 3 "tls_symbolic_operand")]
13372 (clobber (match_scratch:SI 4 "=d"))
13373 (clobber (match_scratch:SI 5 "=c"))
13374 (clobber (reg:CC FLAGS_REG))]
13379 [(set (match_dup 0)
13380 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13383 (clobber (match_dup 4))
13384 (clobber (match_dup 5))
13385 (clobber (reg:CC FLAGS_REG))])])
13387 ;; Segment register for the thread base ptr load
13388 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13390 ;; Load and add the thread base pointer from %<tp_seg>:0.
13391 (define_insn "*load_tp_x32"
13392 [(set (match_operand:SI 0 "register_operand" "=r")
13393 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13395 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13396 [(set_attr "type" "imov")
13397 (set_attr "modrm" "0")
13398 (set_attr "length" "7")
13399 (set_attr "memory" "load")
13400 (set_attr "imm_disp" "false")])
13402 (define_insn "*load_tp_x32_zext"
13403 [(set (match_operand:DI 0 "register_operand" "=r")
13404 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13406 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13407 [(set_attr "type" "imov")
13408 (set_attr "modrm" "0")
13409 (set_attr "length" "7")
13410 (set_attr "memory" "load")
13411 (set_attr "imm_disp" "false")])
13413 (define_insn "*load_tp_<mode>"
13414 [(set (match_operand:P 0 "register_operand" "=r")
13415 (unspec:P [(const_int 0)] UNSPEC_TP))]
13417 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13418 [(set_attr "type" "imov")
13419 (set_attr "modrm" "0")
13420 (set_attr "length" "7")
13421 (set_attr "memory" "load")
13422 (set_attr "imm_disp" "false")])
13424 (define_insn "*add_tp_x32"
13425 [(set (match_operand:SI 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, %0|%0, 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_x32_zext"
13438 [(set (match_operand:DI 0 "register_operand" "=r")
13440 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13441 (match_operand:SI 1 "register_operand" "0"))))
13442 (clobber (reg:CC FLAGS_REG))]
13444 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13445 [(set_attr "type" "alu")
13446 (set_attr "modrm" "0")
13447 (set_attr "length" "7")
13448 (set_attr "memory" "load")
13449 (set_attr "imm_disp" "false")])
13451 (define_insn "*add_tp_<mode>"
13452 [(set (match_operand:P 0 "register_operand" "=r")
13453 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13454 (match_operand:P 1 "register_operand" "0")))
13455 (clobber (reg:CC FLAGS_REG))]
13457 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13458 [(set_attr "type" "alu")
13459 (set_attr "modrm" "0")
13460 (set_attr "length" "7")
13461 (set_attr "memory" "load")
13462 (set_attr "imm_disp" "false")])
13464 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13465 ;; %rax as destination of the initial executable code sequence.
13466 (define_insn "tls_initial_exec_64_sun"
13467 [(set (match_operand:DI 0 "register_operand" "=a")
13469 [(match_operand 1 "tls_symbolic_operand")]
13470 UNSPEC_TLS_IE_SUN))
13471 (clobber (reg:CC FLAGS_REG))]
13472 "TARGET_64BIT && TARGET_SUN_TLS"
13475 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13476 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13478 [(set_attr "type" "multi")])
13480 ;; GNU2 TLS patterns can be split.
13482 (define_expand "tls_dynamic_gnu2_32"
13483 [(set (match_dup 3)
13484 (plus:SI (match_operand:SI 2 "register_operand")
13486 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13489 [(set (match_operand:SI 0 "register_operand")
13490 (unspec:SI [(match_dup 1) (match_dup 3)
13491 (match_dup 2) (reg:SI SP_REG)]
13493 (clobber (reg:CC FLAGS_REG))])]
13494 "!TARGET_64BIT && TARGET_GNU2_TLS"
13496 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13497 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13500 (define_insn "*tls_dynamic_gnu2_lea_32"
13501 [(set (match_operand:SI 0 "register_operand" "=r")
13502 (plus:SI (match_operand:SI 1 "register_operand" "b")
13504 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13505 UNSPEC_TLSDESC))))]
13506 "!TARGET_64BIT && TARGET_GNU2_TLS"
13507 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13508 [(set_attr "type" "lea")
13509 (set_attr "mode" "SI")
13510 (set_attr "length" "6")
13511 (set_attr "length_address" "4")])
13513 (define_insn "*tls_dynamic_gnu2_call_32"
13514 [(set (match_operand:SI 0 "register_operand" "=a")
13515 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13516 (match_operand:SI 2 "register_operand" "0")
13517 ;; we have to make sure %ebx still points to the GOT
13518 (match_operand:SI 3 "register_operand" "b")
13521 (clobber (reg:CC FLAGS_REG))]
13522 "!TARGET_64BIT && TARGET_GNU2_TLS"
13523 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13524 [(set_attr "type" "call")
13525 (set_attr "length" "2")
13526 (set_attr "length_address" "0")])
13528 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13529 [(set (match_operand:SI 0 "register_operand" "=&a")
13531 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13532 (match_operand:SI 4)
13533 (match_operand:SI 2 "register_operand" "b")
13536 (const:SI (unspec:SI
13537 [(match_operand 1 "tls_symbolic_operand")]
13539 (clobber (reg:CC FLAGS_REG))]
13540 "!TARGET_64BIT && TARGET_GNU2_TLS"
13543 [(set (match_dup 0) (match_dup 5))]
13545 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13546 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13549 (define_expand "tls_dynamic_gnu2_64"
13550 [(set (match_dup 2)
13551 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13554 [(set (match_operand:DI 0 "register_operand")
13555 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13557 (clobber (reg:CC FLAGS_REG))])]
13558 "TARGET_64BIT && TARGET_GNU2_TLS"
13560 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13561 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13564 (define_insn "*tls_dynamic_gnu2_lea_64"
13565 [(set (match_operand:DI 0 "register_operand" "=r")
13566 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13568 "TARGET_64BIT && TARGET_GNU2_TLS"
13569 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13570 [(set_attr "type" "lea")
13571 (set_attr "mode" "DI")
13572 (set_attr "length" "7")
13573 (set_attr "length_address" "4")])
13575 (define_insn "*tls_dynamic_gnu2_call_64"
13576 [(set (match_operand:DI 0 "register_operand" "=a")
13577 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13578 (match_operand:DI 2 "register_operand" "0")
13581 (clobber (reg:CC FLAGS_REG))]
13582 "TARGET_64BIT && TARGET_GNU2_TLS"
13583 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13584 [(set_attr "type" "call")
13585 (set_attr "length" "2")
13586 (set_attr "length_address" "0")])
13588 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13589 [(set (match_operand:DI 0 "register_operand" "=&a")
13591 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13592 (match_operand:DI 3)
13595 (const:DI (unspec:DI
13596 [(match_operand 1 "tls_symbolic_operand")]
13598 (clobber (reg:CC FLAGS_REG))]
13599 "TARGET_64BIT && TARGET_GNU2_TLS"
13602 [(set (match_dup 0) (match_dup 4))]
13604 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13605 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13608 ;; These patterns match the binary 387 instructions for addM3, subM3,
13609 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13610 ;; SFmode. The first is the normal insn, the second the same insn but
13611 ;; with one operand a conversion, and the third the same insn but with
13612 ;; the other operand a conversion. The conversion may be SFmode or
13613 ;; SImode if the target mode DFmode, but only SImode if the target mode
13616 ;; Gcc is slightly more smart about handling normal two address instructions
13617 ;; so use special patterns for add and mull.
13619 (define_insn "*fop_<mode>_comm_mixed"
13620 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13621 (match_operator:MODEF 3 "binary_fp_operator"
13622 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13623 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13624 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13625 && COMMUTATIVE_ARITH_P (operands[3])
13626 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13627 "* return output_387_binary_op (insn, operands);"
13628 [(set (attr "type")
13629 (if_then_else (eq_attr "alternative" "1,2")
13630 (if_then_else (match_operand:MODEF 3 "mult_operator")
13631 (const_string "ssemul")
13632 (const_string "sseadd"))
13633 (if_then_else (match_operand:MODEF 3 "mult_operator")
13634 (const_string "fmul")
13635 (const_string "fop"))))
13636 (set_attr "isa" "*,noavx,avx")
13637 (set_attr "prefix" "orig,orig,vex")
13638 (set_attr "mode" "<MODE>")])
13640 (define_insn "*fop_<mode>_comm_sse"
13641 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13642 (match_operator:MODEF 3 "binary_fp_operator"
13643 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13644 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13645 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13646 && COMMUTATIVE_ARITH_P (operands[3])
13647 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13648 "* return output_387_binary_op (insn, operands);"
13649 [(set (attr "type")
13650 (if_then_else (match_operand:MODEF 3 "mult_operator")
13651 (const_string "ssemul")
13652 (const_string "sseadd")))
13653 (set_attr "isa" "noavx,avx")
13654 (set_attr "prefix" "orig,vex")
13655 (set_attr "mode" "<MODE>")])
13657 (define_insn "*fop_<mode>_comm_i387"
13658 [(set (match_operand:MODEF 0 "register_operand" "=f")
13659 (match_operator:MODEF 3 "binary_fp_operator"
13660 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13661 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13662 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13663 && COMMUTATIVE_ARITH_P (operands[3])
13664 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13665 "* return output_387_binary_op (insn, operands);"
13666 [(set (attr "type")
13667 (if_then_else (match_operand:MODEF 3 "mult_operator")
13668 (const_string "fmul")
13669 (const_string "fop")))
13670 (set_attr "mode" "<MODE>")])
13672 (define_insn "*fop_<mode>_1_mixed"
13673 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13674 (match_operator:MODEF 3 "binary_fp_operator"
13675 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13676 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13677 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13678 && !COMMUTATIVE_ARITH_P (operands[3])
13679 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13680 "* return output_387_binary_op (insn, operands);"
13681 [(set (attr "type")
13682 (cond [(and (eq_attr "alternative" "2,3")
13683 (match_operand:MODEF 3 "mult_operator"))
13684 (const_string "ssemul")
13685 (and (eq_attr "alternative" "2,3")
13686 (match_operand:MODEF 3 "div_operator"))
13687 (const_string "ssediv")
13688 (eq_attr "alternative" "2,3")
13689 (const_string "sseadd")
13690 (match_operand:MODEF 3 "mult_operator")
13691 (const_string "fmul")
13692 (match_operand:MODEF 3 "div_operator")
13693 (const_string "fdiv")
13695 (const_string "fop")))
13696 (set_attr "isa" "*,*,noavx,avx")
13697 (set_attr "prefix" "orig,orig,orig,vex")
13698 (set_attr "mode" "<MODE>")])
13700 (define_insn "*rcpsf2_sse"
13701 [(set (match_operand:SF 0 "register_operand" "=x")
13702 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13705 "%vrcpss\t{%1, %d0|%d0, %1}"
13706 [(set_attr "type" "sse")
13707 (set_attr "atom_sse_attr" "rcp")
13708 (set_attr "btver2_sse_attr" "rcp")
13709 (set_attr "prefix" "maybe_vex")
13710 (set_attr "mode" "SF")])
13712 (define_insn "*fop_<mode>_1_sse"
13713 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13714 (match_operator:MODEF 3 "binary_fp_operator"
13715 [(match_operand:MODEF 1 "register_operand" "0,x")
13716 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13717 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13718 && !COMMUTATIVE_ARITH_P (operands[3])"
13719 "* return output_387_binary_op (insn, operands);"
13720 [(set (attr "type")
13721 (cond [(match_operand:MODEF 3 "mult_operator")
13722 (const_string "ssemul")
13723 (match_operand:MODEF 3 "div_operator")
13724 (const_string "ssediv")
13726 (const_string "sseadd")))
13727 (set_attr "isa" "noavx,avx")
13728 (set_attr "prefix" "orig,vex")
13729 (set_attr "mode" "<MODE>")])
13731 ;; This pattern is not fully shadowed by the pattern above.
13732 (define_insn "*fop_<mode>_1_i387"
13733 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13734 (match_operator:MODEF 3 "binary_fp_operator"
13735 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13736 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13737 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13738 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739 && !COMMUTATIVE_ARITH_P (operands[3])
13740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13741 "* return output_387_binary_op (insn, operands);"
13742 [(set (attr "type")
13743 (cond [(match_operand:MODEF 3 "mult_operator")
13744 (const_string "fmul")
13745 (match_operand:MODEF 3 "div_operator")
13746 (const_string "fdiv")
13748 (const_string "fop")))
13749 (set_attr "mode" "<MODE>")])
13751 ;; ??? Add SSE splitters for these!
13752 (define_insn "*fop_<MODEF:mode>_2_i387"
13753 [(set (match_operand:MODEF 0 "register_operand" "=f")
13754 (match_operator:MODEF 3 "binary_fp_operator"
13756 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13757 (match_operand:MODEF 2 "register_operand" "0")]))]
13758 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13759 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13760 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13761 || optimize_function_for_size_p (cfun))"
13762 { return output_387_binary_op (insn, operands); }
13763 [(set (attr "type")
13764 (cond [(match_operand:MODEF 3 "mult_operator")
13765 (const_string "fmul")
13766 (match_operand:MODEF 3 "div_operator")
13767 (const_string "fdiv")
13769 (const_string "fop")))
13770 (set_attr "fp_int_src" "true")
13771 (set_attr "mode" "<SWI24:MODE>")])
13773 (define_insn "*fop_<MODEF:mode>_3_i387"
13774 [(set (match_operand:MODEF 0 "register_operand" "=f")
13775 (match_operator:MODEF 3 "binary_fp_operator"
13776 [(match_operand:MODEF 1 "register_operand" "0")
13778 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13779 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13780 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13781 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13782 || optimize_function_for_size_p (cfun))"
13783 { return output_387_binary_op (insn, operands); }
13784 [(set (attr "type")
13785 (cond [(match_operand:MODEF 3 "mult_operator")
13786 (const_string "fmul")
13787 (match_operand:MODEF 3 "div_operator")
13788 (const_string "fdiv")
13790 (const_string "fop")))
13791 (set_attr "fp_int_src" "true")
13792 (set_attr "mode" "<MODE>")])
13794 (define_insn "*fop_df_4_i387"
13795 [(set (match_operand:DF 0 "register_operand" "=f,f")
13796 (match_operator:DF 3 "binary_fp_operator"
13798 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13799 (match_operand:DF 2 "register_operand" "0,f")]))]
13800 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13801 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13802 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13803 "* return output_387_binary_op (insn, operands);"
13804 [(set (attr "type")
13805 (cond [(match_operand:DF 3 "mult_operator")
13806 (const_string "fmul")
13807 (match_operand:DF 3 "div_operator")
13808 (const_string "fdiv")
13810 (const_string "fop")))
13811 (set_attr "mode" "SF")])
13813 (define_insn "*fop_df_5_i387"
13814 [(set (match_operand:DF 0 "register_operand" "=f,f")
13815 (match_operator:DF 3 "binary_fp_operator"
13816 [(match_operand:DF 1 "register_operand" "0,f")
13818 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13819 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13820 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13821 "* return output_387_binary_op (insn, operands);"
13822 [(set (attr "type")
13823 (cond [(match_operand:DF 3 "mult_operator")
13824 (const_string "fmul")
13825 (match_operand:DF 3 "div_operator")
13826 (const_string "fdiv")
13828 (const_string "fop")))
13829 (set_attr "mode" "SF")])
13831 (define_insn "*fop_df_6_i387"
13832 [(set (match_operand:DF 0 "register_operand" "=f,f")
13833 (match_operator:DF 3 "binary_fp_operator"
13835 (match_operand:SF 1 "register_operand" "0,f"))
13837 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13838 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13839 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13840 "* return output_387_binary_op (insn, operands);"
13841 [(set (attr "type")
13842 (cond [(match_operand:DF 3 "mult_operator")
13843 (const_string "fmul")
13844 (match_operand:DF 3 "div_operator")
13845 (const_string "fdiv")
13847 (const_string "fop")))
13848 (set_attr "mode" "SF")])
13850 (define_insn "*fop_xf_comm_i387"
13851 [(set (match_operand:XF 0 "register_operand" "=f")
13852 (match_operator:XF 3 "binary_fp_operator"
13853 [(match_operand:XF 1 "register_operand" "%0")
13854 (match_operand:XF 2 "register_operand" "f")]))]
13856 && COMMUTATIVE_ARITH_P (operands[3])"
13857 "* return output_387_binary_op (insn, operands);"
13858 [(set (attr "type")
13859 (if_then_else (match_operand:XF 3 "mult_operator")
13860 (const_string "fmul")
13861 (const_string "fop")))
13862 (set_attr "mode" "XF")])
13864 (define_insn "*fop_xf_1_i387"
13865 [(set (match_operand:XF 0 "register_operand" "=f,f")
13866 (match_operator:XF 3 "binary_fp_operator"
13867 [(match_operand:XF 1 "register_operand" "0,f")
13868 (match_operand:XF 2 "register_operand" "f,0")]))]
13870 && !COMMUTATIVE_ARITH_P (operands[3])"
13871 "* return output_387_binary_op (insn, operands);"
13872 [(set (attr "type")
13873 (cond [(match_operand:XF 3 "mult_operator")
13874 (const_string "fmul")
13875 (match_operand:XF 3 "div_operator")
13876 (const_string "fdiv")
13878 (const_string "fop")))
13879 (set_attr "mode" "XF")])
13881 (define_insn "*fop_xf_2_i387"
13882 [(set (match_operand:XF 0 "register_operand" "=f")
13883 (match_operator:XF 3 "binary_fp_operator"
13885 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13886 (match_operand:XF 2 "register_operand" "0")]))]
13888 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13889 { return output_387_binary_op (insn, operands); }
13890 [(set (attr "type")
13891 (cond [(match_operand:XF 3 "mult_operator")
13892 (const_string "fmul")
13893 (match_operand:XF 3 "div_operator")
13894 (const_string "fdiv")
13896 (const_string "fop")))
13897 (set_attr "fp_int_src" "true")
13898 (set_attr "mode" "<MODE>")])
13900 (define_insn "*fop_xf_3_i387"
13901 [(set (match_operand:XF 0 "register_operand" "=f")
13902 (match_operator:XF 3 "binary_fp_operator"
13903 [(match_operand:XF 1 "register_operand" "0")
13905 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13907 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13908 { return output_387_binary_op (insn, operands); }
13909 [(set (attr "type")
13910 (cond [(match_operand:XF 3 "mult_operator")
13911 (const_string "fmul")
13912 (match_operand:XF 3 "div_operator")
13913 (const_string "fdiv")
13915 (const_string "fop")))
13916 (set_attr "fp_int_src" "true")
13917 (set_attr "mode" "<MODE>")])
13919 (define_insn "*fop_xf_4_i387"
13920 [(set (match_operand:XF 0 "register_operand" "=f,f")
13921 (match_operator:XF 3 "binary_fp_operator"
13923 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13924 (match_operand:XF 2 "register_operand" "0,f")]))]
13926 "* return output_387_binary_op (insn, operands);"
13927 [(set (attr "type")
13928 (cond [(match_operand:XF 3 "mult_operator")
13929 (const_string "fmul")
13930 (match_operand:XF 3 "div_operator")
13931 (const_string "fdiv")
13933 (const_string "fop")))
13934 (set_attr "mode" "<MODE>")])
13936 (define_insn "*fop_xf_5_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f,f")
13938 (match_operator:XF 3 "binary_fp_operator"
13939 [(match_operand:XF 1 "register_operand" "0,f")
13941 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13943 "* return output_387_binary_op (insn, operands);"
13944 [(set (attr "type")
13945 (cond [(match_operand:XF 3 "mult_operator")
13946 (const_string "fmul")
13947 (match_operand:XF 3 "div_operator")
13948 (const_string "fdiv")
13950 (const_string "fop")))
13951 (set_attr "mode" "<MODE>")])
13953 (define_insn "*fop_xf_6_i387"
13954 [(set (match_operand:XF 0 "register_operand" "=f,f")
13955 (match_operator:XF 3 "binary_fp_operator"
13957 (match_operand:MODEF 1 "register_operand" "0,f"))
13959 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13961 "* return output_387_binary_op (insn, operands);"
13962 [(set (attr "type")
13963 (cond [(match_operand:XF 3 "mult_operator")
13964 (const_string "fmul")
13965 (match_operand:XF 3 "div_operator")
13966 (const_string "fdiv")
13968 (const_string "fop")))
13969 (set_attr "mode" "<MODE>")])
13971 ;; FPU special functions.
13973 ;; This pattern implements a no-op XFmode truncation for
13974 ;; all fancy i386 XFmode math functions.
13976 (define_insn "truncxf<mode>2_i387_noop_unspec"
13977 [(set (match_operand:MODEF 0 "register_operand" "=f")
13978 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13979 UNSPEC_TRUNC_NOOP))]
13980 "TARGET_USE_FANCY_MATH_387"
13981 "* return output_387_reg_move (insn, operands);"
13982 [(set_attr "type" "fmov")
13983 (set_attr "mode" "<MODE>")])
13985 (define_insn "sqrtxf2"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13988 "TARGET_USE_FANCY_MATH_387"
13990 [(set_attr "type" "fpspc")
13991 (set_attr "mode" "XF")
13992 (set_attr "athlon_decode" "direct")
13993 (set_attr "amdfam10_decode" "direct")
13994 (set_attr "bdver1_decode" "direct")])
13996 (define_insn "sqrt_extend<mode>xf2_i387"
13997 [(set (match_operand:XF 0 "register_operand" "=f")
14000 (match_operand:MODEF 1 "register_operand" "0"))))]
14001 "TARGET_USE_FANCY_MATH_387"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")
14005 (set_attr "athlon_decode" "direct")
14006 (set_attr "amdfam10_decode" "direct")
14007 (set_attr "bdver1_decode" "direct")])
14009 (define_insn "*rsqrtsf2_sse"
14010 [(set (match_operand:SF 0 "register_operand" "=x")
14011 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14014 "%vrsqrtss\t{%1, %d0|%d0, %1}"
14015 [(set_attr "type" "sse")
14016 (set_attr "atom_sse_attr" "rcp")
14017 (set_attr "btver2_sse_attr" "rcp")
14018 (set_attr "prefix" "maybe_vex")
14019 (set_attr "mode" "SF")])
14021 (define_expand "rsqrtsf2"
14022 [(set (match_operand:SF 0 "register_operand")
14023 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14027 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14031 (define_insn "*sqrt<mode>2_sse"
14032 [(set (match_operand:MODEF 0 "register_operand" "=x")
14034 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14035 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14036 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14037 [(set_attr "type" "sse")
14038 (set_attr "atom_sse_attr" "sqrt")
14039 (set_attr "btver2_sse_attr" "sqrt")
14040 (set_attr "prefix" "maybe_vex")
14041 (set_attr "mode" "<MODE>")
14042 (set_attr "athlon_decode" "*")
14043 (set_attr "amdfam10_decode" "*")
14044 (set_attr "bdver1_decode" "*")])
14046 (define_expand "sqrt<mode>2"
14047 [(set (match_operand:MODEF 0 "register_operand")
14049 (match_operand:MODEF 1 "nonimmediate_operand")))]
14050 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14051 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14053 if (<MODE>mode == SFmode
14055 && TARGET_RECIP_SQRT
14056 && !optimize_function_for_size_p (cfun)
14057 && flag_finite_math_only && !flag_trapping_math
14058 && flag_unsafe_math_optimizations)
14060 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14064 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14066 rtx op0 = gen_reg_rtx (XFmode);
14067 rtx op1 = force_reg (<MODE>mode, operands[1]);
14069 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14070 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14075 (define_insn "fpremxf4_i387"
14076 [(set (match_operand:XF 0 "register_operand" "=f")
14077 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14078 (match_operand:XF 3 "register_operand" "1")]
14080 (set (match_operand:XF 1 "register_operand" "=u")
14081 (unspec:XF [(match_dup 2) (match_dup 3)]
14083 (set (reg:CCFP FPSR_REG)
14084 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_finite_math_only"
14089 [(set_attr "type" "fpspc")
14090 (set_attr "mode" "XF")])
14092 (define_expand "fmodxf3"
14093 [(use (match_operand:XF 0 "register_operand"))
14094 (use (match_operand:XF 1 "general_operand"))
14095 (use (match_operand:XF 2 "general_operand"))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && flag_finite_math_only"
14099 rtx_code_label *label = gen_label_rtx ();
14101 rtx op1 = gen_reg_rtx (XFmode);
14102 rtx op2 = gen_reg_rtx (XFmode);
14104 emit_move_insn (op2, operands[2]);
14105 emit_move_insn (op1, operands[1]);
14107 emit_label (label);
14108 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14109 ix86_emit_fp_unordered_jump (label);
14110 LABEL_NUSES (label) = 1;
14112 emit_move_insn (operands[0], op1);
14116 (define_expand "fmod<mode>3"
14117 [(use (match_operand:MODEF 0 "register_operand"))
14118 (use (match_operand:MODEF 1 "general_operand"))
14119 (use (match_operand:MODEF 2 "general_operand"))]
14120 "TARGET_USE_FANCY_MATH_387
14121 && flag_finite_math_only"
14123 rtx (*gen_truncxf) (rtx, rtx);
14125 rtx_code_label *label = gen_label_rtx ();
14127 rtx op1 = gen_reg_rtx (XFmode);
14128 rtx op2 = gen_reg_rtx (XFmode);
14130 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14131 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14133 emit_label (label);
14134 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14135 ix86_emit_fp_unordered_jump (label);
14136 LABEL_NUSES (label) = 1;
14138 /* Truncate the result properly for strict SSE math. */
14139 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14140 && !TARGET_MIX_SSE_I387)
14141 gen_truncxf = gen_truncxf<mode>2;
14143 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14145 emit_insn (gen_truncxf (operands[0], op1));
14149 (define_insn "fprem1xf4_i387"
14150 [(set (match_operand:XF 0 "register_operand" "=f")
14151 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14152 (match_operand:XF 3 "register_operand" "1")]
14154 (set (match_operand:XF 1 "register_operand" "=u")
14155 (unspec:XF [(match_dup 2) (match_dup 3)]
14157 (set (reg:CCFP FPSR_REG)
14158 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14160 "TARGET_USE_FANCY_MATH_387
14161 && flag_finite_math_only"
14163 [(set_attr "type" "fpspc")
14164 (set_attr "mode" "XF")])
14166 (define_expand "remainderxf3"
14167 [(use (match_operand:XF 0 "register_operand"))
14168 (use (match_operand:XF 1 "general_operand"))
14169 (use (match_operand:XF 2 "general_operand"))]
14170 "TARGET_USE_FANCY_MATH_387
14171 && flag_finite_math_only"
14173 rtx_code_label *label = gen_label_rtx ();
14175 rtx op1 = gen_reg_rtx (XFmode);
14176 rtx op2 = gen_reg_rtx (XFmode);
14178 emit_move_insn (op2, operands[2]);
14179 emit_move_insn (op1, operands[1]);
14181 emit_label (label);
14182 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14183 ix86_emit_fp_unordered_jump (label);
14184 LABEL_NUSES (label) = 1;
14186 emit_move_insn (operands[0], op1);
14190 (define_expand "remainder<mode>3"
14191 [(use (match_operand:MODEF 0 "register_operand"))
14192 (use (match_operand:MODEF 1 "general_operand"))
14193 (use (match_operand:MODEF 2 "general_operand"))]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_finite_math_only"
14197 rtx (*gen_truncxf) (rtx, rtx);
14199 rtx_code_label *label = gen_label_rtx ();
14201 rtx op1 = gen_reg_rtx (XFmode);
14202 rtx op2 = gen_reg_rtx (XFmode);
14204 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14205 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14207 emit_label (label);
14209 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14210 ix86_emit_fp_unordered_jump (label);
14211 LABEL_NUSES (label) = 1;
14213 /* Truncate the result properly for strict SSE math. */
14214 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14215 && !TARGET_MIX_SSE_I387)
14216 gen_truncxf = gen_truncxf<mode>2;
14218 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14220 emit_insn (gen_truncxf (operands[0], op1));
14224 (define_int_iterator SINCOS
14228 (define_int_attr sincos
14229 [(UNSPEC_SIN "sin")
14230 (UNSPEC_COS "cos")])
14232 (define_insn "*<sincos>xf2_i387"
14233 [(set (match_operand:XF 0 "register_operand" "=f")
14234 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14236 "TARGET_USE_FANCY_MATH_387
14237 && flag_unsafe_math_optimizations"
14239 [(set_attr "type" "fpspc")
14240 (set_attr "mode" "XF")])
14242 (define_insn "*<sincos>_extend<mode>xf2_i387"
14243 [(set (match_operand:XF 0 "register_operand" "=f")
14244 (unspec:XF [(float_extend:XF
14245 (match_operand:MODEF 1 "register_operand" "0"))]
14247 "TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations"
14252 [(set_attr "type" "fpspc")
14253 (set_attr "mode" "XF")])
14255 ;; When sincos pattern is defined, sin and cos builtin functions will be
14256 ;; expanded to sincos pattern with one of its outputs left unused.
14257 ;; CSE pass will figure out if two sincos patterns can be combined,
14258 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14259 ;; depending on the unused output.
14261 (define_insn "sincosxf3"
14262 [(set (match_operand:XF 0 "register_operand" "=f")
14263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14264 UNSPEC_SINCOS_COS))
14265 (set (match_operand:XF 1 "register_operand" "=u")
14266 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14267 "TARGET_USE_FANCY_MATH_387
14268 && flag_unsafe_math_optimizations"
14270 [(set_attr "type" "fpspc")
14271 (set_attr "mode" "XF")])
14274 [(set (match_operand:XF 0 "register_operand")
14275 (unspec:XF [(match_operand:XF 2 "register_operand")]
14276 UNSPEC_SINCOS_COS))
14277 (set (match_operand:XF 1 "register_operand")
14278 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14279 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14280 && can_create_pseudo_p ()"
14281 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14284 [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 2 "register_operand")]
14286 UNSPEC_SINCOS_COS))
14287 (set (match_operand:XF 1 "register_operand")
14288 (unspec: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) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14293 (define_insn "sincos_extend<mode>xf3_i387"
14294 [(set (match_operand:XF 0 "register_operand" "=f")
14295 (unspec:XF [(float_extend:XF
14296 (match_operand:MODEF 2 "register_operand" "0"))]
14297 UNSPEC_SINCOS_COS))
14298 (set (match_operand:XF 1 "register_operand" "=u")
14299 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14302 || TARGET_MIX_SSE_I387)
14303 && flag_unsafe_math_optimizations"
14305 [(set_attr "type" "fpspc")
14306 (set_attr "mode" "XF")])
14309 [(set (match_operand:XF 0 "register_operand")
14310 (unspec:XF [(float_extend:XF
14311 (match_operand:MODEF 2 "register_operand"))]
14312 UNSPEC_SINCOS_COS))
14313 (set (match_operand:XF 1 "register_operand")
14314 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14315 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14316 && can_create_pseudo_p ()"
14317 [(set (match_dup 1)
14318 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14321 [(set (match_operand:XF 0 "register_operand")
14322 (unspec:XF [(float_extend:XF
14323 (match_operand:MODEF 2 "register_operand"))]
14324 UNSPEC_SINCOS_COS))
14325 (set (match_operand:XF 1 "register_operand")
14326 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14327 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14328 && can_create_pseudo_p ()"
14329 [(set (match_dup 0)
14330 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14332 (define_expand "sincos<mode>3"
14333 [(use (match_operand:MODEF 0 "register_operand"))
14334 (use (match_operand:MODEF 1 "register_operand"))
14335 (use (match_operand:MODEF 2 "register_operand"))]
14336 "TARGET_USE_FANCY_MATH_387
14337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14338 || TARGET_MIX_SSE_I387)
14339 && flag_unsafe_math_optimizations"
14341 rtx op0 = gen_reg_rtx (XFmode);
14342 rtx op1 = gen_reg_rtx (XFmode);
14344 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14350 (define_insn "fptanxf4_i387"
14351 [(set (match_operand:XF 0 "register_operand" "=f")
14352 (match_operand:XF 3 "const_double_operand" "F"))
14353 (set (match_operand:XF 1 "register_operand" "=u")
14354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14356 "TARGET_USE_FANCY_MATH_387
14357 && flag_unsafe_math_optimizations
14358 && standard_80387_constant_p (operands[3]) == 2"
14360 [(set_attr "type" "fpspc")
14361 (set_attr "mode" "XF")])
14363 (define_insn "fptan_extend<mode>xf4_i387"
14364 [(set (match_operand:MODEF 0 "register_operand" "=f")
14365 (match_operand:MODEF 3 "const_double_operand" "F"))
14366 (set (match_operand:XF 1 "register_operand" "=u")
14367 (unspec:XF [(float_extend:XF
14368 (match_operand:MODEF 2 "register_operand" "0"))]
14370 "TARGET_USE_FANCY_MATH_387
14371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14372 || TARGET_MIX_SSE_I387)
14373 && flag_unsafe_math_optimizations
14374 && standard_80387_constant_p (operands[3]) == 2"
14376 [(set_attr "type" "fpspc")
14377 (set_attr "mode" "XF")])
14379 (define_expand "tanxf2"
14380 [(use (match_operand:XF 0 "register_operand"))
14381 (use (match_operand:XF 1 "register_operand"))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && flag_unsafe_math_optimizations"
14385 rtx one = gen_reg_rtx (XFmode);
14386 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14388 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14392 (define_expand "tan<mode>2"
14393 [(use (match_operand:MODEF 0 "register_operand"))
14394 (use (match_operand:MODEF 1 "register_operand"))]
14395 "TARGET_USE_FANCY_MATH_387
14396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14397 || TARGET_MIX_SSE_I387)
14398 && flag_unsafe_math_optimizations"
14400 rtx op0 = gen_reg_rtx (XFmode);
14402 rtx one = gen_reg_rtx (<MODE>mode);
14403 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14405 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14406 operands[1], op2));
14407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14411 (define_insn "*fpatanxf3_i387"
14412 [(set (match_operand:XF 0 "register_operand" "=f")
14413 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14414 (match_operand:XF 2 "register_operand" "u")]
14416 (clobber (match_scratch:XF 3 "=2"))]
14417 "TARGET_USE_FANCY_MATH_387
14418 && flag_unsafe_math_optimizations"
14420 [(set_attr "type" "fpspc")
14421 (set_attr "mode" "XF")])
14423 (define_insn "fpatan_extend<mode>xf3_i387"
14424 [(set (match_operand:XF 0 "register_operand" "=f")
14425 (unspec:XF [(float_extend:XF
14426 (match_operand:MODEF 1 "register_operand" "0"))
14428 (match_operand:MODEF 2 "register_operand" "u"))]
14430 (clobber (match_scratch:XF 3 "=2"))]
14431 "TARGET_USE_FANCY_MATH_387
14432 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14433 || TARGET_MIX_SSE_I387)
14434 && flag_unsafe_math_optimizations"
14436 [(set_attr "type" "fpspc")
14437 (set_attr "mode" "XF")])
14439 (define_expand "atan2xf3"
14440 [(parallel [(set (match_operand:XF 0 "register_operand")
14441 (unspec:XF [(match_operand:XF 2 "register_operand")
14442 (match_operand:XF 1 "register_operand")]
14444 (clobber (match_scratch:XF 3))])]
14445 "TARGET_USE_FANCY_MATH_387
14446 && flag_unsafe_math_optimizations")
14448 (define_expand "atan2<mode>3"
14449 [(use (match_operand:MODEF 0 "register_operand"))
14450 (use (match_operand:MODEF 1 "register_operand"))
14451 (use (match_operand:MODEF 2 "register_operand"))]
14452 "TARGET_USE_FANCY_MATH_387
14453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14454 || TARGET_MIX_SSE_I387)
14455 && flag_unsafe_math_optimizations"
14457 rtx op0 = gen_reg_rtx (XFmode);
14459 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14464 (define_expand "atanxf2"
14465 [(parallel [(set (match_operand:XF 0 "register_operand")
14466 (unspec:XF [(match_dup 2)
14467 (match_operand:XF 1 "register_operand")]
14469 (clobber (match_scratch:XF 3))])]
14470 "TARGET_USE_FANCY_MATH_387
14471 && flag_unsafe_math_optimizations"
14473 operands[2] = gen_reg_rtx (XFmode);
14474 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14477 (define_expand "atan<mode>2"
14478 [(use (match_operand:MODEF 0 "register_operand"))
14479 (use (match_operand:MODEF 1 "register_operand"))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14485 rtx op0 = gen_reg_rtx (XFmode);
14487 rtx op2 = gen_reg_rtx (<MODE>mode);
14488 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14490 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14491 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14495 (define_expand "asinxf2"
14496 [(set (match_dup 2)
14497 (mult:XF (match_operand:XF 1 "register_operand")
14499 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14500 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14501 (parallel [(set (match_operand:XF 0 "register_operand")
14502 (unspec:XF [(match_dup 5) (match_dup 1)]
14504 (clobber (match_scratch:XF 6))])]
14505 "TARGET_USE_FANCY_MATH_387
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 for (i = 2; i < 6; i++)
14514 operands[i] = gen_reg_rtx (XFmode);
14516 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14519 (define_expand "asin<mode>2"
14520 [(use (match_operand:MODEF 0 "register_operand"))
14521 (use (match_operand:MODEF 1 "general_operand"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14524 || TARGET_MIX_SSE_I387)
14525 && flag_unsafe_math_optimizations"
14527 rtx op0 = gen_reg_rtx (XFmode);
14528 rtx op1 = gen_reg_rtx (XFmode);
14530 if (optimize_insn_for_size_p ())
14533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14534 emit_insn (gen_asinxf2 (op0, op1));
14535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14539 (define_expand "acosxf2"
14540 [(set (match_dup 2)
14541 (mult:XF (match_operand:XF 1 "register_operand")
14543 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14544 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14545 (parallel [(set (match_operand:XF 0 "register_operand")
14546 (unspec:XF [(match_dup 1) (match_dup 5)]
14548 (clobber (match_scratch:XF 6))])]
14549 "TARGET_USE_FANCY_MATH_387
14550 && flag_unsafe_math_optimizations"
14554 if (optimize_insn_for_size_p ())
14557 for (i = 2; i < 6; i++)
14558 operands[i] = gen_reg_rtx (XFmode);
14560 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14563 (define_expand "acos<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand"))
14565 (use (match_operand:MODEF 1 "general_operand"))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations"
14571 rtx op0 = gen_reg_rtx (XFmode);
14572 rtx op1 = gen_reg_rtx (XFmode);
14574 if (optimize_insn_for_size_p ())
14577 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14578 emit_insn (gen_acosxf2 (op0, op1));
14579 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14583 (define_insn "fyl2xxf3_i387"
14584 [(set (match_operand:XF 0 "register_operand" "=f")
14585 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14586 (match_operand:XF 2 "register_operand" "u")]
14588 (clobber (match_scratch:XF 3 "=2"))]
14589 "TARGET_USE_FANCY_MATH_387
14590 && flag_unsafe_math_optimizations"
14592 [(set_attr "type" "fpspc")
14593 (set_attr "mode" "XF")])
14595 (define_insn "fyl2x_extend<mode>xf3_i387"
14596 [(set (match_operand:XF 0 "register_operand" "=f")
14597 (unspec:XF [(float_extend:XF
14598 (match_operand:MODEF 1 "register_operand" "0"))
14599 (match_operand:XF 2 "register_operand" "u")]
14601 (clobber (match_scratch:XF 3 "=2"))]
14602 "TARGET_USE_FANCY_MATH_387
14603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14604 || TARGET_MIX_SSE_I387)
14605 && flag_unsafe_math_optimizations"
14607 [(set_attr "type" "fpspc")
14608 (set_attr "mode" "XF")])
14610 (define_expand "logxf2"
14611 [(parallel [(set (match_operand:XF 0 "register_operand")
14612 (unspec:XF [(match_operand:XF 1 "register_operand")
14613 (match_dup 2)] UNSPEC_FYL2X))
14614 (clobber (match_scratch:XF 3))])]
14615 "TARGET_USE_FANCY_MATH_387
14616 && flag_unsafe_math_optimizations"
14618 operands[2] = gen_reg_rtx (XFmode);
14619 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14622 (define_expand "log<mode>2"
14623 [(use (match_operand:MODEF 0 "register_operand"))
14624 (use (match_operand:MODEF 1 "register_operand"))]
14625 "TARGET_USE_FANCY_MATH_387
14626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14627 || TARGET_MIX_SSE_I387)
14628 && flag_unsafe_math_optimizations"
14630 rtx op0 = gen_reg_rtx (XFmode);
14632 rtx op2 = gen_reg_rtx (XFmode);
14633 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14635 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14636 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14640 (define_expand "log10xf2"
14641 [(parallel [(set (match_operand:XF 0 "register_operand")
14642 (unspec:XF [(match_operand:XF 1 "register_operand")
14643 (match_dup 2)] UNSPEC_FYL2X))
14644 (clobber (match_scratch:XF 3))])]
14645 "TARGET_USE_FANCY_MATH_387
14646 && flag_unsafe_math_optimizations"
14648 operands[2] = gen_reg_rtx (XFmode);
14649 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14652 (define_expand "log10<mode>2"
14653 [(use (match_operand:MODEF 0 "register_operand"))
14654 (use (match_operand:MODEF 1 "register_operand"))]
14655 "TARGET_USE_FANCY_MATH_387
14656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14657 || TARGET_MIX_SSE_I387)
14658 && flag_unsafe_math_optimizations"
14660 rtx op0 = gen_reg_rtx (XFmode);
14662 rtx op2 = gen_reg_rtx (XFmode);
14663 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14665 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14670 (define_expand "log2xf2"
14671 [(parallel [(set (match_operand:XF 0 "register_operand")
14672 (unspec:XF [(match_operand:XF 1 "register_operand")
14673 (match_dup 2)] UNSPEC_FYL2X))
14674 (clobber (match_scratch:XF 3))])]
14675 "TARGET_USE_FANCY_MATH_387
14676 && flag_unsafe_math_optimizations"
14678 operands[2] = gen_reg_rtx (XFmode);
14679 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14682 (define_expand "log2<mode>2"
14683 [(use (match_operand:MODEF 0 "register_operand"))
14684 (use (match_operand:MODEF 1 "register_operand"))]
14685 "TARGET_USE_FANCY_MATH_387
14686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14687 || TARGET_MIX_SSE_I387)
14688 && flag_unsafe_math_optimizations"
14690 rtx op0 = gen_reg_rtx (XFmode);
14692 rtx op2 = gen_reg_rtx (XFmode);
14693 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14695 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14696 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14700 (define_insn "fyl2xp1xf3_i387"
14701 [(set (match_operand:XF 0 "register_operand" "=f")
14702 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14703 (match_operand:XF 2 "register_operand" "u")]
14705 (clobber (match_scratch:XF 3 "=2"))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && flag_unsafe_math_optimizations"
14709 [(set_attr "type" "fpspc")
14710 (set_attr "mode" "XF")])
14712 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14713 [(set (match_operand:XF 0 "register_operand" "=f")
14714 (unspec:XF [(float_extend:XF
14715 (match_operand:MODEF 1 "register_operand" "0"))
14716 (match_operand:XF 2 "register_operand" "u")]
14718 (clobber (match_scratch:XF 3 "=2"))]
14719 "TARGET_USE_FANCY_MATH_387
14720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14721 || TARGET_MIX_SSE_I387)
14722 && flag_unsafe_math_optimizations"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "XF")])
14727 (define_expand "log1pxf2"
14728 [(use (match_operand:XF 0 "register_operand"))
14729 (use (match_operand:XF 1 "register_operand"))]
14730 "TARGET_USE_FANCY_MATH_387
14731 && flag_unsafe_math_optimizations"
14733 if (optimize_insn_for_size_p ())
14736 ix86_emit_i387_log1p (operands[0], operands[1]);
14740 (define_expand "log1p<mode>2"
14741 [(use (match_operand:MODEF 0 "register_operand"))
14742 (use (match_operand:MODEF 1 "register_operand"))]
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"
14750 if (optimize_insn_for_size_p ())
14753 op0 = gen_reg_rtx (XFmode);
14755 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14757 ix86_emit_i387_log1p (op0, operands[1]);
14758 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14762 (define_insn "fxtractxf3_i387"
14763 [(set (match_operand:XF 0 "register_operand" "=f")
14764 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14765 UNSPEC_XTRACT_FRACT))
14766 (set (match_operand:XF 1 "register_operand" "=u")
14767 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && flag_unsafe_math_optimizations"
14771 [(set_attr "type" "fpspc")
14772 (set_attr "mode" "XF")])
14774 (define_insn "fxtract_extend<mode>xf3_i387"
14775 [(set (match_operand:XF 0 "register_operand" "=f")
14776 (unspec:XF [(float_extend:XF
14777 (match_operand:MODEF 2 "register_operand" "0"))]
14778 UNSPEC_XTRACT_FRACT))
14779 (set (match_operand:XF 1 "register_operand" "=u")
14780 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14781 "TARGET_USE_FANCY_MATH_387
14782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14783 || TARGET_MIX_SSE_I387)
14784 && flag_unsafe_math_optimizations"
14786 [(set_attr "type" "fpspc")
14787 (set_attr "mode" "XF")])
14789 (define_expand "logbxf2"
14790 [(parallel [(set (match_dup 2)
14791 (unspec:XF [(match_operand:XF 1 "register_operand")]
14792 UNSPEC_XTRACT_FRACT))
14793 (set (match_operand:XF 0 "register_operand")
14794 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14797 "operands[2] = gen_reg_rtx (XFmode);")
14799 (define_expand "logb<mode>2"
14800 [(use (match_operand:MODEF 0 "register_operand"))
14801 (use (match_operand:MODEF 1 "register_operand"))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14804 || TARGET_MIX_SSE_I387)
14805 && flag_unsafe_math_optimizations"
14807 rtx op0 = gen_reg_rtx (XFmode);
14808 rtx op1 = gen_reg_rtx (XFmode);
14810 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14815 (define_expand "ilogbxf2"
14816 [(use (match_operand:SI 0 "register_operand"))
14817 (use (match_operand:XF 1 "register_operand"))]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14823 if (optimize_insn_for_size_p ())
14826 op0 = gen_reg_rtx (XFmode);
14827 op1 = gen_reg_rtx (XFmode);
14829 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14830 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14834 (define_expand "ilogb<mode>2"
14835 [(use (match_operand:SI 0 "register_operand"))
14836 (use (match_operand:MODEF 1 "register_operand"))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14839 || TARGET_MIX_SSE_I387)
14840 && flag_unsafe_math_optimizations"
14844 if (optimize_insn_for_size_p ())
14847 op0 = gen_reg_rtx (XFmode);
14848 op1 = gen_reg_rtx (XFmode);
14850 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14851 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14855 (define_insn "*f2xm1xf2_i387"
14856 [(set (match_operand:XF 0 "register_operand" "=f")
14857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")])
14865 (define_insn "fscalexf4_i387"
14866 [(set (match_operand:XF 0 "register_operand" "=f")
14867 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14868 (match_operand:XF 3 "register_operand" "1")]
14869 UNSPEC_FSCALE_FRACT))
14870 (set (match_operand:XF 1 "register_operand" "=u")
14871 (unspec:XF [(match_dup 2) (match_dup 3)]
14872 UNSPEC_FSCALE_EXP))]
14873 "TARGET_USE_FANCY_MATH_387
14874 && flag_unsafe_math_optimizations"
14876 [(set_attr "type" "fpspc")
14877 (set_attr "mode" "XF")])
14879 (define_expand "expNcorexf3"
14880 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14881 (match_operand:XF 2 "register_operand")))
14882 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14883 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14885 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14886 (parallel [(set (match_operand:XF 0 "register_operand")
14887 (unspec:XF [(match_dup 8) (match_dup 4)]
14888 UNSPEC_FSCALE_FRACT))
14890 (unspec:XF [(match_dup 8) (match_dup 4)]
14891 UNSPEC_FSCALE_EXP))])]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14897 if (optimize_insn_for_size_p ())
14900 for (i = 3; i < 10; i++)
14901 operands[i] = gen_reg_rtx (XFmode);
14903 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14906 (define_expand "expxf2"
14907 [(use (match_operand:XF 0 "register_operand"))
14908 (use (match_operand:XF 1 "register_operand"))]
14909 "TARGET_USE_FANCY_MATH_387
14910 && flag_unsafe_math_optimizations"
14914 if (optimize_insn_for_size_p ())
14917 op2 = gen_reg_rtx (XFmode);
14918 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14920 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14924 (define_expand "exp<mode>2"
14925 [(use (match_operand:MODEF 0 "register_operand"))
14926 (use (match_operand:MODEF 1 "general_operand"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14929 || TARGET_MIX_SSE_I387)
14930 && flag_unsafe_math_optimizations"
14934 if (optimize_insn_for_size_p ())
14937 op0 = gen_reg_rtx (XFmode);
14938 op1 = gen_reg_rtx (XFmode);
14940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14941 emit_insn (gen_expxf2 (op0, op1));
14942 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14946 (define_expand "exp10xf2"
14947 [(use (match_operand:XF 0 "register_operand"))
14948 (use (match_operand:XF 1 "register_operand"))]
14949 "TARGET_USE_FANCY_MATH_387
14950 && flag_unsafe_math_optimizations"
14954 if (optimize_insn_for_size_p ())
14957 op2 = gen_reg_rtx (XFmode);
14958 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14960 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14964 (define_expand "exp10<mode>2"
14965 [(use (match_operand:MODEF 0 "register_operand"))
14966 (use (match_operand:MODEF 1 "general_operand"))]
14967 "TARGET_USE_FANCY_MATH_387
14968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14969 || TARGET_MIX_SSE_I387)
14970 && flag_unsafe_math_optimizations"
14974 if (optimize_insn_for_size_p ())
14977 op0 = gen_reg_rtx (XFmode);
14978 op1 = gen_reg_rtx (XFmode);
14980 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14981 emit_insn (gen_exp10xf2 (op0, op1));
14982 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14986 (define_expand "exp2xf2"
14987 [(use (match_operand:XF 0 "register_operand"))
14988 (use (match_operand:XF 1 "register_operand"))]
14989 "TARGET_USE_FANCY_MATH_387
14990 && flag_unsafe_math_optimizations"
14994 if (optimize_insn_for_size_p ())
14997 op2 = gen_reg_rtx (XFmode);
14998 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15000 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15004 (define_expand "exp2<mode>2"
15005 [(use (match_operand:MODEF 0 "register_operand"))
15006 (use (match_operand:MODEF 1 "general_operand"))]
15007 "TARGET_USE_FANCY_MATH_387
15008 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15009 || TARGET_MIX_SSE_I387)
15010 && flag_unsafe_math_optimizations"
15014 if (optimize_insn_for_size_p ())
15017 op0 = gen_reg_rtx (XFmode);
15018 op1 = gen_reg_rtx (XFmode);
15020 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15021 emit_insn (gen_exp2xf2 (op0, op1));
15022 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15026 (define_expand "expm1xf2"
15027 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15029 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15030 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15031 (set (match_dup 9) (float_extend:XF (match_dup 13)))
15032 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15033 (parallel [(set (match_dup 7)
15034 (unspec:XF [(match_dup 6) (match_dup 4)]
15035 UNSPEC_FSCALE_FRACT))
15037 (unspec:XF [(match_dup 6) (match_dup 4)]
15038 UNSPEC_FSCALE_EXP))])
15039 (parallel [(set (match_dup 10)
15040 (unspec:XF [(match_dup 9) (match_dup 8)]
15041 UNSPEC_FSCALE_FRACT))
15042 (set (match_dup 11)
15043 (unspec:XF [(match_dup 9) (match_dup 8)]
15044 UNSPEC_FSCALE_EXP))])
15045 (set (match_dup 12) (minus:XF (match_dup 10)
15046 (float_extend:XF (match_dup 13))))
15047 (set (match_operand:XF 0 "register_operand")
15048 (plus:XF (match_dup 12) (match_dup 7)))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && flag_unsafe_math_optimizations"
15054 if (optimize_insn_for_size_p ())
15057 for (i = 2; i < 13; i++)
15058 operands[i] = gen_reg_rtx (XFmode);
15061 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15063 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15066 (define_expand "expm1<mode>2"
15067 [(use (match_operand:MODEF 0 "register_operand"))
15068 (use (match_operand:MODEF 1 "general_operand"))]
15069 "TARGET_USE_FANCY_MATH_387
15070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15071 || TARGET_MIX_SSE_I387)
15072 && flag_unsafe_math_optimizations"
15076 if (optimize_insn_for_size_p ())
15079 op0 = gen_reg_rtx (XFmode);
15080 op1 = gen_reg_rtx (XFmode);
15082 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15083 emit_insn (gen_expm1xf2 (op0, op1));
15084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15088 (define_expand "ldexpxf3"
15089 [(match_operand:XF 0 "register_operand")
15090 (match_operand:XF 1 "register_operand")
15091 (match_operand:SI 2 "register_operand")]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations"
15096 if (optimize_insn_for_size_p ())
15099 tmp1 = gen_reg_rtx (XFmode);
15100 tmp2 = gen_reg_rtx (XFmode);
15102 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15103 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15104 operands[1], tmp1));
15108 (define_expand "ldexp<mode>3"
15109 [(use (match_operand:MODEF 0 "register_operand"))
15110 (use (match_operand:MODEF 1 "general_operand"))
15111 (use (match_operand:SI 2 "register_operand"))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15114 || TARGET_MIX_SSE_I387)
15115 && flag_unsafe_math_optimizations"
15119 if (optimize_insn_for_size_p ())
15122 op0 = gen_reg_rtx (XFmode);
15123 op1 = gen_reg_rtx (XFmode);
15125 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15126 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15127 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15131 (define_expand "scalbxf3"
15132 [(parallel [(set (match_operand:XF 0 " register_operand")
15133 (unspec:XF [(match_operand:XF 1 "register_operand")
15134 (match_operand:XF 2 "register_operand")]
15135 UNSPEC_FSCALE_FRACT))
15137 (unspec:XF [(match_dup 1) (match_dup 2)]
15138 UNSPEC_FSCALE_EXP))])]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15142 if (optimize_insn_for_size_p ())
15145 operands[3] = gen_reg_rtx (XFmode);
15148 (define_expand "scalb<mode>3"
15149 [(use (match_operand:MODEF 0 "register_operand"))
15150 (use (match_operand:MODEF 1 "general_operand"))
15151 (use (match_operand:MODEF 2 "general_operand"))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15154 || TARGET_MIX_SSE_I387)
15155 && flag_unsafe_math_optimizations"
15159 if (optimize_insn_for_size_p ())
15162 op0 = gen_reg_rtx (XFmode);
15163 op1 = gen_reg_rtx (XFmode);
15164 op2 = gen_reg_rtx (XFmode);
15166 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15167 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15168 emit_insn (gen_scalbxf3 (op0, op1, op2));
15169 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15173 (define_expand "significandxf2"
15174 [(parallel [(set (match_operand:XF 0 "register_operand")
15175 (unspec:XF [(match_operand:XF 1 "register_operand")]
15176 UNSPEC_XTRACT_FRACT))
15178 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15179 "TARGET_USE_FANCY_MATH_387
15180 && flag_unsafe_math_optimizations"
15181 "operands[2] = gen_reg_rtx (XFmode);")
15183 (define_expand "significand<mode>2"
15184 [(use (match_operand:MODEF 0 "register_operand"))
15185 (use (match_operand:MODEF 1 "register_operand"))]
15186 "TARGET_USE_FANCY_MATH_387
15187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15188 || TARGET_MIX_SSE_I387)
15189 && flag_unsafe_math_optimizations"
15191 rtx op0 = gen_reg_rtx (XFmode);
15192 rtx op1 = gen_reg_rtx (XFmode);
15194 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15200 (define_insn "sse4_1_round<mode>2"
15201 [(set (match_operand:MODEF 0 "register_operand" "=x")
15202 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15203 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15206 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15207 [(set_attr "type" "ssecvt")
15208 (set_attr "prefix_extra" "1")
15209 (set_attr "prefix" "maybe_vex")
15210 (set_attr "mode" "<MODE>")])
15212 (define_insn "rintxf2"
15213 [(set (match_operand:XF 0 "register_operand" "=f")
15214 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15219 [(set_attr "type" "fpspc")
15220 (set_attr "mode" "XF")])
15222 (define_expand "rint<mode>2"
15223 [(use (match_operand:MODEF 0 "register_operand"))
15224 (use (match_operand:MODEF 1 "register_operand"))]
15225 "(TARGET_USE_FANCY_MATH_387
15226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15227 || TARGET_MIX_SSE_I387)
15228 && flag_unsafe_math_optimizations)
15229 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15230 && !flag_trapping_math)"
15232 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15233 && !flag_trapping_math)
15236 emit_insn (gen_sse4_1_round<mode>2
15237 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15238 else if (optimize_insn_for_size_p ())
15241 ix86_expand_rint (operands[0], operands[1]);
15245 rtx op0 = gen_reg_rtx (XFmode);
15246 rtx op1 = gen_reg_rtx (XFmode);
15248 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15249 emit_insn (gen_rintxf2 (op0, op1));
15251 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15256 (define_expand "round<mode>2"
15257 [(match_operand:X87MODEF 0 "register_operand")
15258 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15259 "(TARGET_USE_FANCY_MATH_387
15260 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15261 || TARGET_MIX_SSE_I387)
15262 && flag_unsafe_math_optimizations)
15263 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15264 && !flag_trapping_math && !flag_rounding_math)"
15266 if (optimize_insn_for_size_p ())
15269 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15270 && !flag_trapping_math && !flag_rounding_math)
15274 operands[1] = force_reg (<MODE>mode, operands[1]);
15275 ix86_expand_round_sse4 (operands[0], operands[1]);
15277 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15278 ix86_expand_round (operands[0], operands[1]);
15280 ix86_expand_rounddf_32 (operands[0], operands[1]);
15284 operands[1] = force_reg (<MODE>mode, operands[1]);
15285 ix86_emit_i387_round (operands[0], operands[1]);
15290 (define_insn_and_split "*fistdi2_1"
15291 [(set (match_operand:DI 0 "nonimmediate_operand")
15292 (unspec:DI [(match_operand:XF 1 "register_operand")]
15294 "TARGET_USE_FANCY_MATH_387
15295 && can_create_pseudo_p ()"
15300 if (memory_operand (operands[0], VOIDmode))
15301 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15304 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15305 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15310 [(set_attr "type" "fpspc")
15311 (set_attr "mode" "DI")])
15313 (define_insn "fistdi2"
15314 [(set (match_operand:DI 0 "memory_operand" "=m")
15315 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15317 (clobber (match_scratch:XF 2 "=&1f"))]
15318 "TARGET_USE_FANCY_MATH_387"
15319 "* return output_fix_trunc (insn, operands, false);"
15320 [(set_attr "type" "fpspc")
15321 (set_attr "mode" "DI")])
15323 (define_insn "fistdi2_with_temp"
15324 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15325 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15327 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15328 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15329 "TARGET_USE_FANCY_MATH_387"
15331 [(set_attr "type" "fpspc")
15332 (set_attr "mode" "DI")])
15335 [(set (match_operand:DI 0 "register_operand")
15336 (unspec:DI [(match_operand:XF 1 "register_operand")]
15338 (clobber (match_operand:DI 2 "memory_operand"))
15339 (clobber (match_scratch 3))]
15341 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15342 (clobber (match_dup 3))])
15343 (set (match_dup 0) (match_dup 2))])
15346 [(set (match_operand:DI 0 "memory_operand")
15347 (unspec:DI [(match_operand:XF 1 "register_operand")]
15349 (clobber (match_operand:DI 2 "memory_operand"))
15350 (clobber (match_scratch 3))]
15352 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15353 (clobber (match_dup 3))])])
15355 (define_insn_and_split "*fist<mode>2_1"
15356 [(set (match_operand:SWI24 0 "register_operand")
15357 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15359 "TARGET_USE_FANCY_MATH_387
15360 && can_create_pseudo_p ()"
15365 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15366 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15370 [(set_attr "type" "fpspc")
15371 (set_attr "mode" "<MODE>")])
15373 (define_insn "fist<mode>2"
15374 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15375 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15377 "TARGET_USE_FANCY_MATH_387"
15378 "* return output_fix_trunc (insn, operands, false);"
15379 [(set_attr "type" "fpspc")
15380 (set_attr "mode" "<MODE>")])
15382 (define_insn "fist<mode>2_with_temp"
15383 [(set (match_operand:SWI24 0 "register_operand" "=r")
15384 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15386 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15387 "TARGET_USE_FANCY_MATH_387"
15389 [(set_attr "type" "fpspc")
15390 (set_attr "mode" "<MODE>")])
15393 [(set (match_operand:SWI24 0 "register_operand")
15394 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15396 (clobber (match_operand:SWI24 2 "memory_operand"))]
15398 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15399 (set (match_dup 0) (match_dup 2))])
15402 [(set (match_operand:SWI24 0 "memory_operand")
15403 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15405 (clobber (match_operand:SWI24 2 "memory_operand"))]
15407 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15409 (define_expand "lrintxf<mode>2"
15410 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15411 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15413 "TARGET_USE_FANCY_MATH_387")
15415 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15416 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15417 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15418 UNSPEC_FIX_NOTRUNC))]
15419 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15421 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15422 [(match_operand:SWI248x 0 "nonimmediate_operand")
15423 (match_operand:X87MODEF 1 "register_operand")]
15424 "(TARGET_USE_FANCY_MATH_387
15425 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15426 || TARGET_MIX_SSE_I387)
15427 && flag_unsafe_math_optimizations)
15428 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15429 && <SWI248x:MODE>mode != HImode
15430 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15431 && !flag_trapping_math && !flag_rounding_math)"
15433 if (optimize_insn_for_size_p ())
15436 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15437 && <SWI248x:MODE>mode != HImode
15438 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15439 && !flag_trapping_math && !flag_rounding_math)
15440 ix86_expand_lround (operands[0], operands[1]);
15442 ix86_emit_i387_round (operands[0], operands[1]);
15446 (define_int_iterator FRNDINT_ROUNDING
15447 [UNSPEC_FRNDINT_FLOOR
15448 UNSPEC_FRNDINT_CEIL
15449 UNSPEC_FRNDINT_TRUNC])
15451 (define_int_iterator FIST_ROUNDING
15455 ;; Base name for define_insn
15456 (define_int_attr rounding_insn
15457 [(UNSPEC_FRNDINT_FLOOR "floor")
15458 (UNSPEC_FRNDINT_CEIL "ceil")
15459 (UNSPEC_FRNDINT_TRUNC "btrunc")
15460 (UNSPEC_FIST_FLOOR "floor")
15461 (UNSPEC_FIST_CEIL "ceil")])
15463 (define_int_attr rounding
15464 [(UNSPEC_FRNDINT_FLOOR "floor")
15465 (UNSPEC_FRNDINT_CEIL "ceil")
15466 (UNSPEC_FRNDINT_TRUNC "trunc")
15467 (UNSPEC_FIST_FLOOR "floor")
15468 (UNSPEC_FIST_CEIL "ceil")])
15470 (define_int_attr ROUNDING
15471 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15472 (UNSPEC_FRNDINT_CEIL "CEIL")
15473 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15474 (UNSPEC_FIST_FLOOR "FLOOR")
15475 (UNSPEC_FIST_CEIL "CEIL")])
15477 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15478 (define_insn_and_split "frndintxf2_<rounding>"
15479 [(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 && can_create_pseudo_p ()"
15490 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15492 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15493 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15495 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15496 operands[2], operands[3]));
15499 [(set_attr "type" "frndint")
15500 (set_attr "i387_cw" "<rounding>")
15501 (set_attr "mode" "XF")])
15503 (define_insn "frndintxf2_<rounding>_i387"
15504 [(set (match_operand:XF 0 "register_operand" "=f")
15505 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15507 (use (match_operand:HI 2 "memory_operand" "m"))
15508 (use (match_operand:HI 3 "memory_operand" "m"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && flag_unsafe_math_optimizations"
15511 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15512 [(set_attr "type" "frndint")
15513 (set_attr "i387_cw" "<rounding>")
15514 (set_attr "mode" "XF")])
15516 (define_expand "<rounding_insn>xf2"
15517 [(parallel [(set (match_operand:XF 0 "register_operand")
15518 (unspec:XF [(match_operand:XF 1 "register_operand")]
15520 (clobber (reg:CC FLAGS_REG))])]
15521 "TARGET_USE_FANCY_MATH_387
15522 && flag_unsafe_math_optimizations
15523 && !optimize_insn_for_size_p ()")
15525 (define_expand "<rounding_insn><mode>2"
15526 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15527 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15529 (clobber (reg:CC FLAGS_REG))])]
15530 "(TARGET_USE_FANCY_MATH_387
15531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15532 || TARGET_MIX_SSE_I387)
15533 && flag_unsafe_math_optimizations)
15534 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15535 && !flag_trapping_math)"
15537 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15538 && !flag_trapping_math)
15541 emit_insn (gen_sse4_1_round<mode>2
15542 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15543 else if (optimize_insn_for_size_p ())
15545 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15547 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15548 ix86_expand_floorceil (operands[0], operands[1], true);
15549 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15550 ix86_expand_floorceil (operands[0], operands[1], false);
15551 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15552 ix86_expand_trunc (operands[0], operands[1]);
15554 gcc_unreachable ();
15558 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15559 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15560 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15561 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15562 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15563 ix86_expand_truncdf_32 (operands[0], operands[1]);
15565 gcc_unreachable ();
15572 if (optimize_insn_for_size_p ())
15575 op0 = gen_reg_rtx (XFmode);
15576 op1 = gen_reg_rtx (XFmode);
15577 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15578 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15585 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15586 (define_insn_and_split "frndintxf2_mask_pm"
15587 [(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
15593 && can_create_pseudo_p ()"
15598 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15600 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15601 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15603 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15604 operands[2], operands[3]));
15607 [(set_attr "type" "frndint")
15608 (set_attr "i387_cw" "mask_pm")
15609 (set_attr "mode" "XF")])
15611 (define_insn "frndintxf2_mask_pm_i387"
15612 [(set (match_operand:XF 0 "register_operand" "=f")
15613 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15614 UNSPEC_FRNDINT_MASK_PM))
15615 (use (match_operand:HI 2 "memory_operand" "m"))
15616 (use (match_operand:HI 3 "memory_operand" "m"))]
15617 "TARGET_USE_FANCY_MATH_387
15618 && flag_unsafe_math_optimizations"
15619 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15620 [(set_attr "type" "frndint")
15621 (set_attr "i387_cw" "mask_pm")
15622 (set_attr "mode" "XF")])
15624 (define_expand "nearbyintxf2"
15625 [(parallel [(set (match_operand:XF 0 "register_operand")
15626 (unspec:XF [(match_operand:XF 1 "register_operand")]
15627 UNSPEC_FRNDINT_MASK_PM))
15628 (clobber (reg:CC FLAGS_REG))])]
15629 "TARGET_USE_FANCY_MATH_387
15630 && flag_unsafe_math_optimizations")
15632 (define_expand "nearbyint<mode>2"
15633 [(use (match_operand:MODEF 0 "register_operand"))
15634 (use (match_operand:MODEF 1 "register_operand"))]
15635 "TARGET_USE_FANCY_MATH_387
15636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15637 || TARGET_MIX_SSE_I387)
15638 && flag_unsafe_math_optimizations"
15640 rtx op0 = gen_reg_rtx (XFmode);
15641 rtx op1 = gen_reg_rtx (XFmode);
15643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15644 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15650 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15651 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15652 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15653 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15655 (clobber (reg:CC FLAGS_REG))]
15656 "TARGET_USE_FANCY_MATH_387
15657 && flag_unsafe_math_optimizations
15658 && can_create_pseudo_p ()"
15663 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15665 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15666 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15667 if (memory_operand (operands[0], VOIDmode))
15668 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15669 operands[2], operands[3]));
15672 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15673 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15674 (operands[0], operands[1], operands[2],
15675 operands[3], operands[4]));
15679 [(set_attr "type" "fistp")
15680 (set_attr "i387_cw" "<rounding>")
15681 (set_attr "mode" "<MODE>")])
15683 (define_insn "fistdi2_<rounding>"
15684 [(set (match_operand:DI 0 "memory_operand" "=m")
15685 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15687 (use (match_operand:HI 2 "memory_operand" "m"))
15688 (use (match_operand:HI 3 "memory_operand" "m"))
15689 (clobber (match_scratch:XF 4 "=&1f"))]
15690 "TARGET_USE_FANCY_MATH_387
15691 && flag_unsafe_math_optimizations"
15692 "* return output_fix_trunc (insn, operands, false);"
15693 [(set_attr "type" "fistp")
15694 (set_attr "i387_cw" "<rounding>")
15695 (set_attr "mode" "DI")])
15697 (define_insn "fistdi2_<rounding>_with_temp"
15698 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15699 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15701 (use (match_operand:HI 2 "memory_operand" "m,m"))
15702 (use (match_operand:HI 3 "memory_operand" "m,m"))
15703 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15704 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15705 "TARGET_USE_FANCY_MATH_387
15706 && flag_unsafe_math_optimizations"
15708 [(set_attr "type" "fistp")
15709 (set_attr "i387_cw" "<rounding>")
15710 (set_attr "mode" "DI")])
15713 [(set (match_operand:DI 0 "register_operand")
15714 (unspec:DI [(match_operand:XF 1 "register_operand")]
15716 (use (match_operand:HI 2 "memory_operand"))
15717 (use (match_operand:HI 3 "memory_operand"))
15718 (clobber (match_operand:DI 4 "memory_operand"))
15719 (clobber (match_scratch 5))]
15721 [(parallel [(set (match_dup 4)
15722 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15723 (use (match_dup 2))
15724 (use (match_dup 3))
15725 (clobber (match_dup 5))])
15726 (set (match_dup 0) (match_dup 4))])
15729 [(set (match_operand:DI 0 "memory_operand")
15730 (unspec:DI [(match_operand:XF 1 "register_operand")]
15732 (use (match_operand:HI 2 "memory_operand"))
15733 (use (match_operand:HI 3 "memory_operand"))
15734 (clobber (match_operand:DI 4 "memory_operand"))
15735 (clobber (match_scratch 5))]
15737 [(parallel [(set (match_dup 0)
15738 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15739 (use (match_dup 2))
15740 (use (match_dup 3))
15741 (clobber (match_dup 5))])])
15743 (define_insn "fist<mode>2_<rounding>"
15744 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15745 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15747 (use (match_operand:HI 2 "memory_operand" "m"))
15748 (use (match_operand:HI 3 "memory_operand" "m"))]
15749 "TARGET_USE_FANCY_MATH_387
15750 && flag_unsafe_math_optimizations"
15751 "* return output_fix_trunc (insn, operands, false);"
15752 [(set_attr "type" "fistp")
15753 (set_attr "i387_cw" "<rounding>")
15754 (set_attr "mode" "<MODE>")])
15756 (define_insn "fist<mode>2_<rounding>_with_temp"
15757 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15758 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15760 (use (match_operand:HI 2 "memory_operand" "m,m"))
15761 (use (match_operand:HI 3 "memory_operand" "m,m"))
15762 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && flag_unsafe_math_optimizations"
15766 [(set_attr "type" "fistp")
15767 (set_attr "i387_cw" "<rounding>")
15768 (set_attr "mode" "<MODE>")])
15771 [(set (match_operand:SWI24 0 "register_operand")
15772 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15774 (use (match_operand:HI 2 "memory_operand"))
15775 (use (match_operand:HI 3 "memory_operand"))
15776 (clobber (match_operand:SWI24 4 "memory_operand"))]
15778 [(parallel [(set (match_dup 4)
15779 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15780 (use (match_dup 2))
15781 (use (match_dup 3))])
15782 (set (match_dup 0) (match_dup 4))])
15785 [(set (match_operand:SWI24 0 "memory_operand")
15786 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15788 (use (match_operand:HI 2 "memory_operand"))
15789 (use (match_operand:HI 3 "memory_operand"))
15790 (clobber (match_operand:SWI24 4 "memory_operand"))]
15792 [(parallel [(set (match_dup 0)
15793 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15794 (use (match_dup 2))
15795 (use (match_dup 3))])])
15797 (define_expand "l<rounding_insn>xf<mode>2"
15798 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15799 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15801 (clobber (reg:CC FLAGS_REG))])]
15802 "TARGET_USE_FANCY_MATH_387
15803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15804 && flag_unsafe_math_optimizations")
15806 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15807 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15808 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15810 (clobber (reg:CC FLAGS_REG))])]
15811 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15812 && !flag_trapping_math"
15814 if (TARGET_64BIT && optimize_insn_for_size_p ())
15817 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15818 ix86_expand_lfloorceil (operands[0], operands[1], true);
15819 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15820 ix86_expand_lfloorceil (operands[0], operands[1], false);
15822 gcc_unreachable ();
15827 (define_insn "fxam<mode>2_i387"
15828 [(set (match_operand:HI 0 "register_operand" "=a")
15830 [(match_operand:X87MODEF 1 "register_operand" "f")]
15832 "TARGET_USE_FANCY_MATH_387"
15833 "fxam\n\tfnstsw\t%0"
15834 [(set_attr "type" "multi")
15835 (set_attr "length" "4")
15836 (set_attr "unit" "i387")
15837 (set_attr "mode" "<MODE>")])
15839 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15840 [(set (match_operand:HI 0 "register_operand")
15842 [(match_operand:MODEF 1 "memory_operand")]
15844 "TARGET_USE_FANCY_MATH_387
15845 && can_create_pseudo_p ()"
15848 [(set (match_dup 2)(match_dup 1))
15850 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15852 operands[2] = gen_reg_rtx (<MODE>mode);
15854 MEM_VOLATILE_P (operands[1]) = 1;
15856 [(set_attr "type" "multi")
15857 (set_attr "unit" "i387")
15858 (set_attr "mode" "<MODE>")])
15860 (define_expand "isinfxf2"
15861 [(use (match_operand:SI 0 "register_operand"))
15862 (use (match_operand:XF 1 "register_operand"))]
15863 "TARGET_USE_FANCY_MATH_387
15864 && ix86_libc_has_function (function_c99_misc)"
15866 rtx mask = GEN_INT (0x45);
15867 rtx val = GEN_INT (0x05);
15871 rtx scratch = gen_reg_rtx (HImode);
15872 rtx res = gen_reg_rtx (QImode);
15874 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15876 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15877 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15878 cond = gen_rtx_fmt_ee (EQ, QImode,
15879 gen_rtx_REG (CCmode, FLAGS_REG),
15881 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15882 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15886 (define_expand "isinf<mode>2"
15887 [(use (match_operand:SI 0 "register_operand"))
15888 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && ix86_libc_has_function (function_c99_misc)
15891 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15893 rtx mask = GEN_INT (0x45);
15894 rtx val = GEN_INT (0x05);
15898 rtx scratch = gen_reg_rtx (HImode);
15899 rtx res = gen_reg_rtx (QImode);
15901 /* Remove excess precision by forcing value through memory. */
15902 if (memory_operand (operands[1], VOIDmode))
15903 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15906 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15908 emit_move_insn (temp, operands[1]);
15909 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15912 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15913 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15914 cond = gen_rtx_fmt_ee (EQ, QImode,
15915 gen_rtx_REG (CCmode, FLAGS_REG),
15917 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15918 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15922 (define_expand "signbitxf2"
15923 [(use (match_operand:SI 0 "register_operand"))
15924 (use (match_operand:XF 1 "register_operand"))]
15925 "TARGET_USE_FANCY_MATH_387"
15927 rtx scratch = gen_reg_rtx (HImode);
15929 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15930 emit_insn (gen_andsi3 (operands[0],
15931 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15935 (define_insn "movmsk_df"
15936 [(set (match_operand:SI 0 "register_operand" "=r")
15938 [(match_operand:DF 1 "register_operand" "x")]
15940 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15941 "%vmovmskpd\t{%1, %0|%0, %1}"
15942 [(set_attr "type" "ssemov")
15943 (set_attr "prefix" "maybe_vex")
15944 (set_attr "mode" "DF")])
15946 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15947 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15948 (define_expand "signbitdf2"
15949 [(use (match_operand:SI 0 "register_operand"))
15950 (use (match_operand:DF 1 "register_operand"))]
15951 "TARGET_USE_FANCY_MATH_387
15952 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15954 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15956 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15957 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15961 rtx scratch = gen_reg_rtx (HImode);
15963 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15964 emit_insn (gen_andsi3 (operands[0],
15965 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15970 (define_expand "signbitsf2"
15971 [(use (match_operand:SI 0 "register_operand"))
15972 (use (match_operand:SF 1 "register_operand"))]
15973 "TARGET_USE_FANCY_MATH_387
15974 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15976 rtx scratch = gen_reg_rtx (HImode);
15978 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15979 emit_insn (gen_andsi3 (operands[0],
15980 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15984 ;; Block operation instructions
15987 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15990 [(set_attr "length" "1")
15991 (set_attr "length_immediate" "0")
15992 (set_attr "modrm" "0")])
15994 (define_expand "movmem<mode>"
15995 [(use (match_operand:BLK 0 "memory_operand"))
15996 (use (match_operand:BLK 1 "memory_operand"))
15997 (use (match_operand:SWI48 2 "nonmemory_operand"))
15998 (use (match_operand:SWI48 3 "const_int_operand"))
15999 (use (match_operand:SI 4 "const_int_operand"))
16000 (use (match_operand:SI 5 "const_int_operand"))
16001 (use (match_operand:SI 6 ""))
16002 (use (match_operand:SI 7 ""))
16003 (use (match_operand:SI 8 ""))]
16006 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16007 operands[2], NULL, operands[3],
16008 operands[4], operands[5],
16009 operands[6], operands[7],
16010 operands[8], false))
16016 ;; Most CPUs don't like single string operations
16017 ;; Handle this case here to simplify previous expander.
16019 (define_expand "strmov"
16020 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16021 (set (match_operand 1 "memory_operand") (match_dup 4))
16022 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16023 (clobber (reg:CC FLAGS_REG))])
16024 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16025 (clobber (reg:CC FLAGS_REG))])]
16028 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16030 /* If .md ever supports :P for Pmode, these can be directly
16031 in the pattern above. */
16032 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16033 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16035 /* Can't use this if the user has appropriated esi or edi. */
16036 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16037 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16039 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16040 operands[2], operands[3],
16041 operands[5], operands[6]));
16045 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16048 (define_expand "strmov_singleop"
16049 [(parallel [(set (match_operand 1 "memory_operand")
16050 (match_operand 3 "memory_operand"))
16051 (set (match_operand 0 "register_operand")
16053 (set (match_operand 2 "register_operand")
16054 (match_operand 5))])]
16056 "ix86_current_function_needs_cld = 1;")
16058 (define_insn "*strmovdi_rex_1"
16059 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16060 (mem:DI (match_operand:P 3 "register_operand" "1")))
16061 (set (match_operand:P 0 "register_operand" "=D")
16062 (plus:P (match_dup 2)
16064 (set (match_operand:P 1 "register_operand" "=S")
16065 (plus:P (match_dup 3)
16068 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16070 [(set_attr "type" "str")
16071 (set_attr "memory" "both")
16072 (set_attr "mode" "DI")])
16074 (define_insn "*strmovsi_1"
16075 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16076 (mem:SI (match_operand:P 3 "register_operand" "1")))
16077 (set (match_operand:P 0 "register_operand" "=D")
16078 (plus:P (match_dup 2)
16080 (set (match_operand:P 1 "register_operand" "=S")
16081 (plus:P (match_dup 3)
16083 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16085 [(set_attr "type" "str")
16086 (set_attr "memory" "both")
16087 (set_attr "mode" "SI")])
16089 (define_insn "*strmovhi_1"
16090 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16091 (mem:HI (match_operand:P 3 "register_operand" "1")))
16092 (set (match_operand:P 0 "register_operand" "=D")
16093 (plus:P (match_dup 2)
16095 (set (match_operand:P 1 "register_operand" "=S")
16096 (plus:P (match_dup 3)
16098 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16100 [(set_attr "type" "str")
16101 (set_attr "memory" "both")
16102 (set_attr "mode" "HI")])
16104 (define_insn "*strmovqi_1"
16105 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16106 (mem:QI (match_operand:P 3 "register_operand" "1")))
16107 (set (match_operand:P 0 "register_operand" "=D")
16108 (plus:P (match_dup 2)
16110 (set (match_operand:P 1 "register_operand" "=S")
16111 (plus:P (match_dup 3)
16113 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16115 [(set_attr "type" "str")
16116 (set_attr "memory" "both")
16117 (set (attr "prefix_rex")
16119 (match_test "<P:MODE>mode == DImode")
16121 (const_string "*")))
16122 (set_attr "mode" "QI")])
16124 (define_expand "rep_mov"
16125 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16126 (set (match_operand 0 "register_operand")
16128 (set (match_operand 2 "register_operand")
16130 (set (match_operand 1 "memory_operand")
16131 (match_operand 3 "memory_operand"))
16132 (use (match_dup 4))])]
16134 "ix86_current_function_needs_cld = 1;")
16136 (define_insn "*rep_movdi_rex64"
16137 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16138 (set (match_operand:P 0 "register_operand" "=D")
16139 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16141 (match_operand:P 3 "register_operand" "0")))
16142 (set (match_operand:P 1 "register_operand" "=S")
16143 (plus:P (ashift:P (match_dup 5) (const_int 3))
16144 (match_operand:P 4 "register_operand" "1")))
16145 (set (mem:BLK (match_dup 3))
16146 (mem:BLK (match_dup 4)))
16147 (use (match_dup 5))]
16149 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16151 [(set_attr "type" "str")
16152 (set_attr "prefix_rep" "1")
16153 (set_attr "memory" "both")
16154 (set_attr "mode" "DI")])
16156 (define_insn "*rep_movsi"
16157 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16158 (set (match_operand:P 0 "register_operand" "=D")
16159 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16161 (match_operand:P 3 "register_operand" "0")))
16162 (set (match_operand:P 1 "register_operand" "=S")
16163 (plus:P (ashift:P (match_dup 5) (const_int 2))
16164 (match_operand:P 4 "register_operand" "1")))
16165 (set (mem:BLK (match_dup 3))
16166 (mem:BLK (match_dup 4)))
16167 (use (match_dup 5))]
16168 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16169 "%^rep{%;} movs{l|d}"
16170 [(set_attr "type" "str")
16171 (set_attr "prefix_rep" "1")
16172 (set_attr "memory" "both")
16173 (set_attr "mode" "SI")])
16175 (define_insn "*rep_movqi"
16176 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16177 (set (match_operand:P 0 "register_operand" "=D")
16178 (plus:P (match_operand:P 3 "register_operand" "0")
16179 (match_operand:P 5 "register_operand" "2")))
16180 (set (match_operand:P 1 "register_operand" "=S")
16181 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16182 (set (mem:BLK (match_dup 3))
16183 (mem:BLK (match_dup 4)))
16184 (use (match_dup 5))]
16185 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16187 [(set_attr "type" "str")
16188 (set_attr "prefix_rep" "1")
16189 (set_attr "memory" "both")
16190 (set_attr "mode" "QI")])
16192 (define_expand "setmem<mode>"
16193 [(use (match_operand:BLK 0 "memory_operand"))
16194 (use (match_operand:SWI48 1 "nonmemory_operand"))
16195 (use (match_operand:QI 2 "nonmemory_operand"))
16196 (use (match_operand 3 "const_int_operand"))
16197 (use (match_operand:SI 4 "const_int_operand"))
16198 (use (match_operand:SI 5 "const_int_operand"))
16199 (use (match_operand:SI 6 ""))
16200 (use (match_operand:SI 7 ""))
16201 (use (match_operand:SI 8 ""))]
16204 if (ix86_expand_set_or_movmem (operands[0], NULL,
16205 operands[1], operands[2],
16206 operands[3], operands[4],
16207 operands[5], operands[6],
16208 operands[7], operands[8], true))
16214 ;; Most CPUs don't like single string operations
16215 ;; Handle this case here to simplify previous expander.
16217 (define_expand "strset"
16218 [(set (match_operand 1 "memory_operand")
16219 (match_operand 2 "register_operand"))
16220 (parallel [(set (match_operand 0 "register_operand")
16222 (clobber (reg:CC FLAGS_REG))])]
16225 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16226 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16228 /* If .md ever supports :P for Pmode, this can be directly
16229 in the pattern above. */
16230 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16231 GEN_INT (GET_MODE_SIZE (GET_MODE
16233 /* Can't use this if the user has appropriated eax or edi. */
16234 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16235 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16237 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16243 (define_expand "strset_singleop"
16244 [(parallel [(set (match_operand 1 "memory_operand")
16245 (match_operand 2 "register_operand"))
16246 (set (match_operand 0 "register_operand")
16248 (unspec [(const_int 0)] UNSPEC_STOS)])]
16250 "ix86_current_function_needs_cld = 1;")
16252 (define_insn "*strsetdi_rex_1"
16253 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16254 (match_operand:DI 2 "register_operand" "a"))
16255 (set (match_operand:P 0 "register_operand" "=D")
16256 (plus:P (match_dup 1)
16258 (unspec [(const_int 0)] UNSPEC_STOS)]
16260 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16262 [(set_attr "type" "str")
16263 (set_attr "memory" "store")
16264 (set_attr "mode" "DI")])
16266 (define_insn "*strsetsi_1"
16267 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16268 (match_operand:SI 2 "register_operand" "a"))
16269 (set (match_operand:P 0 "register_operand" "=D")
16270 (plus:P (match_dup 1)
16272 (unspec [(const_int 0)] UNSPEC_STOS)]
16273 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16275 [(set_attr "type" "str")
16276 (set_attr "memory" "store")
16277 (set_attr "mode" "SI")])
16279 (define_insn "*strsethi_1"
16280 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16281 (match_operand:HI 2 "register_operand" "a"))
16282 (set (match_operand:P 0 "register_operand" "=D")
16283 (plus:P (match_dup 1)
16285 (unspec [(const_int 0)] UNSPEC_STOS)]
16286 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16288 [(set_attr "type" "str")
16289 (set_attr "memory" "store")
16290 (set_attr "mode" "HI")])
16292 (define_insn "*strsetqi_1"
16293 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16294 (match_operand:QI 2 "register_operand" "a"))
16295 (set (match_operand:P 0 "register_operand" "=D")
16296 (plus:P (match_dup 1)
16298 (unspec [(const_int 0)] UNSPEC_STOS)]
16299 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16301 [(set_attr "type" "str")
16302 (set_attr "memory" "store")
16303 (set (attr "prefix_rex")
16305 (match_test "<P:MODE>mode == DImode")
16307 (const_string "*")))
16308 (set_attr "mode" "QI")])
16310 (define_expand "rep_stos"
16311 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16312 (set (match_operand 0 "register_operand")
16314 (set (match_operand 2 "memory_operand") (const_int 0))
16315 (use (match_operand 3 "register_operand"))
16316 (use (match_dup 1))])]
16318 "ix86_current_function_needs_cld = 1;")
16320 (define_insn "*rep_stosdi_rex64"
16321 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16322 (set (match_operand:P 0 "register_operand" "=D")
16323 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16325 (match_operand:P 3 "register_operand" "0")))
16326 (set (mem:BLK (match_dup 3))
16328 (use (match_operand:DI 2 "register_operand" "a"))
16329 (use (match_dup 4))]
16331 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16333 [(set_attr "type" "str")
16334 (set_attr "prefix_rep" "1")
16335 (set_attr "memory" "store")
16336 (set_attr "mode" "DI")])
16338 (define_insn "*rep_stossi"
16339 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16340 (set (match_operand:P 0 "register_operand" "=D")
16341 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16343 (match_operand:P 3 "register_operand" "0")))
16344 (set (mem:BLK (match_dup 3))
16346 (use (match_operand:SI 2 "register_operand" "a"))
16347 (use (match_dup 4))]
16348 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16349 "%^rep{%;} stos{l|d}"
16350 [(set_attr "type" "str")
16351 (set_attr "prefix_rep" "1")
16352 (set_attr "memory" "store")
16353 (set_attr "mode" "SI")])
16355 (define_insn "*rep_stosqi"
16356 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16357 (set (match_operand:P 0 "register_operand" "=D")
16358 (plus:P (match_operand:P 3 "register_operand" "0")
16359 (match_operand:P 4 "register_operand" "1")))
16360 (set (mem:BLK (match_dup 3))
16362 (use (match_operand:QI 2 "register_operand" "a"))
16363 (use (match_dup 4))]
16364 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16366 [(set_attr "type" "str")
16367 (set_attr "prefix_rep" "1")
16368 (set_attr "memory" "store")
16369 (set (attr "prefix_rex")
16371 (match_test "<P:MODE>mode == DImode")
16373 (const_string "*")))
16374 (set_attr "mode" "QI")])
16376 (define_expand "cmpstrnsi"
16377 [(set (match_operand:SI 0 "register_operand")
16378 (compare:SI (match_operand:BLK 1 "general_operand")
16379 (match_operand:BLK 2 "general_operand")))
16380 (use (match_operand 3 "general_operand"))
16381 (use (match_operand 4 "immediate_operand"))]
16384 rtx addr1, addr2, out, outlow, count, countreg, align;
16386 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16389 /* Can't use this if the user has appropriated ecx, esi or edi. */
16390 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16395 out = gen_reg_rtx (SImode);
16397 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16398 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16399 if (addr1 != XEXP (operands[1], 0))
16400 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16401 if (addr2 != XEXP (operands[2], 0))
16402 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16404 count = operands[3];
16405 countreg = ix86_zero_extend_to_Pmode (count);
16407 /* %%% Iff we are testing strict equality, we can use known alignment
16408 to good advantage. This may be possible with combine, particularly
16409 once cc0 is dead. */
16410 align = operands[4];
16412 if (CONST_INT_P (count))
16414 if (INTVAL (count) == 0)
16416 emit_move_insn (operands[0], const0_rtx);
16419 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16420 operands[1], operands[2]));
16424 rtx (*gen_cmp) (rtx, rtx);
16426 gen_cmp = (TARGET_64BIT
16427 ? gen_cmpdi_1 : gen_cmpsi_1);
16429 emit_insn (gen_cmp (countreg, countreg));
16430 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16431 operands[1], operands[2]));
16434 outlow = gen_lowpart (QImode, out);
16435 emit_insn (gen_cmpintqi (outlow));
16436 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16438 if (operands[0] != out)
16439 emit_move_insn (operands[0], out);
16444 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16446 (define_expand "cmpintqi"
16447 [(set (match_dup 1)
16448 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16450 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16451 (parallel [(set (match_operand:QI 0 "register_operand")
16452 (minus:QI (match_dup 1)
16454 (clobber (reg:CC FLAGS_REG))])]
16457 operands[1] = gen_reg_rtx (QImode);
16458 operands[2] = gen_reg_rtx (QImode);
16461 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16462 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16464 (define_expand "cmpstrnqi_nz_1"
16465 [(parallel [(set (reg:CC FLAGS_REG)
16466 (compare:CC (match_operand 4 "memory_operand")
16467 (match_operand 5 "memory_operand")))
16468 (use (match_operand 2 "register_operand"))
16469 (use (match_operand:SI 3 "immediate_operand"))
16470 (clobber (match_operand 0 "register_operand"))
16471 (clobber (match_operand 1 "register_operand"))
16472 (clobber (match_dup 2))])]
16474 "ix86_current_function_needs_cld = 1;")
16476 (define_insn "*cmpstrnqi_nz_1"
16477 [(set (reg:CC FLAGS_REG)
16478 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16479 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16480 (use (match_operand:P 6 "register_operand" "2"))
16481 (use (match_operand:SI 3 "immediate_operand" "i"))
16482 (clobber (match_operand:P 0 "register_operand" "=S"))
16483 (clobber (match_operand:P 1 "register_operand" "=D"))
16484 (clobber (match_operand:P 2 "register_operand" "=c"))]
16485 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16487 [(set_attr "type" "str")
16488 (set_attr "mode" "QI")
16489 (set (attr "prefix_rex")
16491 (match_test "<P:MODE>mode == DImode")
16493 (const_string "*")))
16494 (set_attr "prefix_rep" "1")])
16496 ;; The same, but the count is not known to not be zero.
16498 (define_expand "cmpstrnqi_1"
16499 [(parallel [(set (reg:CC FLAGS_REG)
16500 (if_then_else:CC (ne (match_operand 2 "register_operand")
16502 (compare:CC (match_operand 4 "memory_operand")
16503 (match_operand 5 "memory_operand"))
16505 (use (match_operand:SI 3 "immediate_operand"))
16506 (use (reg:CC FLAGS_REG))
16507 (clobber (match_operand 0 "register_operand"))
16508 (clobber (match_operand 1 "register_operand"))
16509 (clobber (match_dup 2))])]
16511 "ix86_current_function_needs_cld = 1;")
16513 (define_insn "*cmpstrnqi_1"
16514 [(set (reg:CC FLAGS_REG)
16515 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16517 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16518 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16520 (use (match_operand:SI 3 "immediate_operand" "i"))
16521 (use (reg:CC FLAGS_REG))
16522 (clobber (match_operand:P 0 "register_operand" "=S"))
16523 (clobber (match_operand:P 1 "register_operand" "=D"))
16524 (clobber (match_operand:P 2 "register_operand" "=c"))]
16525 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16527 [(set_attr "type" "str")
16528 (set_attr "mode" "QI")
16529 (set (attr "prefix_rex")
16531 (match_test "<P:MODE>mode == DImode")
16533 (const_string "*")))
16534 (set_attr "prefix_rep" "1")])
16536 (define_expand "strlen<mode>"
16537 [(set (match_operand:P 0 "register_operand")
16538 (unspec:P [(match_operand:BLK 1 "general_operand")
16539 (match_operand:QI 2 "immediate_operand")
16540 (match_operand 3 "immediate_operand")]
16544 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16550 (define_expand "strlenqi_1"
16551 [(parallel [(set (match_operand 0 "register_operand")
16553 (clobber (match_operand 1 "register_operand"))
16554 (clobber (reg:CC FLAGS_REG))])]
16556 "ix86_current_function_needs_cld = 1;")
16558 (define_insn "*strlenqi_1"
16559 [(set (match_operand:P 0 "register_operand" "=&c")
16560 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16561 (match_operand:QI 2 "register_operand" "a")
16562 (match_operand:P 3 "immediate_operand" "i")
16563 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16564 (clobber (match_operand:P 1 "register_operand" "=D"))
16565 (clobber (reg:CC FLAGS_REG))]
16566 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16567 "%^repnz{%;} scasb"
16568 [(set_attr "type" "str")
16569 (set_attr "mode" "QI")
16570 (set (attr "prefix_rex")
16572 (match_test "<P:MODE>mode == DImode")
16574 (const_string "*")))
16575 (set_attr "prefix_rep" "1")])
16577 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16578 ;; handled in combine, but it is not currently up to the task.
16579 ;; When used for their truth value, the cmpstrn* expanders generate
16588 ;; The intermediate three instructions are unnecessary.
16590 ;; This one handles cmpstrn*_nz_1...
16593 (set (reg:CC FLAGS_REG)
16594 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16595 (mem:BLK (match_operand 5 "register_operand"))))
16596 (use (match_operand 6 "register_operand"))
16597 (use (match_operand:SI 3 "immediate_operand"))
16598 (clobber (match_operand 0 "register_operand"))
16599 (clobber (match_operand 1 "register_operand"))
16600 (clobber (match_operand 2 "register_operand"))])
16601 (set (match_operand:QI 7 "register_operand")
16602 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16603 (set (match_operand:QI 8 "register_operand")
16604 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16605 (set (reg FLAGS_REG)
16606 (compare (match_dup 7) (match_dup 8)))
16608 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16610 (set (reg:CC FLAGS_REG)
16611 (compare:CC (mem:BLK (match_dup 4))
16612 (mem:BLK (match_dup 5))))
16613 (use (match_dup 6))
16614 (use (match_dup 3))
16615 (clobber (match_dup 0))
16616 (clobber (match_dup 1))
16617 (clobber (match_dup 2))])])
16619 ;; ...and this one handles cmpstrn*_1.
16622 (set (reg:CC FLAGS_REG)
16623 (if_then_else:CC (ne (match_operand 6 "register_operand")
16625 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16626 (mem:BLK (match_operand 5 "register_operand")))
16628 (use (match_operand:SI 3 "immediate_operand"))
16629 (use (reg:CC FLAGS_REG))
16630 (clobber (match_operand 0 "register_operand"))
16631 (clobber (match_operand 1 "register_operand"))
16632 (clobber (match_operand 2 "register_operand"))])
16633 (set (match_operand:QI 7 "register_operand")
16634 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16635 (set (match_operand:QI 8 "register_operand")
16636 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16637 (set (reg FLAGS_REG)
16638 (compare (match_dup 7) (match_dup 8)))
16640 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16642 (set (reg:CC FLAGS_REG)
16643 (if_then_else:CC (ne (match_dup 6)
16645 (compare:CC (mem:BLK (match_dup 4))
16646 (mem:BLK (match_dup 5)))
16648 (use (match_dup 3))
16649 (use (reg:CC FLAGS_REG))
16650 (clobber (match_dup 0))
16651 (clobber (match_dup 1))
16652 (clobber (match_dup 2))])])
16654 ;; Conditional move instructions.
16656 (define_expand "mov<mode>cc"
16657 [(set (match_operand:SWIM 0 "register_operand")
16658 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16659 (match_operand:SWIM 2 "<general_operand>")
16660 (match_operand:SWIM 3 "<general_operand>")))]
16662 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16664 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16665 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16666 ;; So just document what we're doing explicitly.
16668 (define_expand "x86_mov<mode>cc_0_m1"
16670 [(set (match_operand:SWI48 0 "register_operand")
16671 (if_then_else:SWI48
16672 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16673 [(match_operand 1 "flags_reg_operand")
16677 (clobber (reg:CC FLAGS_REG))])])
16679 (define_insn "*x86_mov<mode>cc_0_m1"
16680 [(set (match_operand:SWI48 0 "register_operand" "=r")
16681 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16682 [(reg FLAGS_REG) (const_int 0)])
16685 (clobber (reg:CC FLAGS_REG))]
16687 "sbb{<imodesuffix>}\t%0, %0"
16688 ; Since we don't have the proper number of operands for an alu insn,
16689 ; fill in all the blanks.
16690 [(set_attr "type" "alu")
16691 (set_attr "use_carry" "1")
16692 (set_attr "pent_pair" "pu")
16693 (set_attr "memory" "none")
16694 (set_attr "imm_disp" "false")
16695 (set_attr "mode" "<MODE>")
16696 (set_attr "length_immediate" "0")])
16698 (define_insn "*x86_mov<mode>cc_0_m1_se"
16699 [(set (match_operand:SWI48 0 "register_operand" "=r")
16700 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16701 [(reg FLAGS_REG) (const_int 0)])
16704 (clobber (reg:CC FLAGS_REG))]
16706 "sbb{<imodesuffix>}\t%0, %0"
16707 [(set_attr "type" "alu")
16708 (set_attr "use_carry" "1")
16709 (set_attr "pent_pair" "pu")
16710 (set_attr "memory" "none")
16711 (set_attr "imm_disp" "false")
16712 (set_attr "mode" "<MODE>")
16713 (set_attr "length_immediate" "0")])
16715 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16716 [(set (match_operand:SWI48 0 "register_operand" "=r")
16717 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16718 [(reg FLAGS_REG) (const_int 0)])))
16719 (clobber (reg:CC FLAGS_REG))]
16721 "sbb{<imodesuffix>}\t%0, %0"
16722 [(set_attr "type" "alu")
16723 (set_attr "use_carry" "1")
16724 (set_attr "pent_pair" "pu")
16725 (set_attr "memory" "none")
16726 (set_attr "imm_disp" "false")
16727 (set_attr "mode" "<MODE>")
16728 (set_attr "length_immediate" "0")])
16730 (define_insn "*mov<mode>cc_noc"
16731 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16732 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16733 [(reg FLAGS_REG) (const_int 0)])
16734 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16735 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16736 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16738 cmov%O2%C1\t{%2, %0|%0, %2}
16739 cmov%O2%c1\t{%3, %0|%0, %3}"
16740 [(set_attr "type" "icmov")
16741 (set_attr "mode" "<MODE>")])
16743 ;; Don't do conditional moves with memory inputs. This splitter helps
16744 ;; register starved x86_32 by forcing inputs into registers before reload.
16746 [(set (match_operand:SWI248 0 "register_operand")
16747 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16748 [(reg FLAGS_REG) (const_int 0)])
16749 (match_operand:SWI248 2 "nonimmediate_operand")
16750 (match_operand:SWI248 3 "nonimmediate_operand")))]
16751 "!TARGET_64BIT && TARGET_CMOVE
16752 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16753 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16754 && can_create_pseudo_p ()
16755 && optimize_insn_for_speed_p ()"
16756 [(set (match_dup 0)
16757 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16759 if (MEM_P (operands[2]))
16760 operands[2] = force_reg (<MODE>mode, operands[2]);
16761 if (MEM_P (operands[3]))
16762 operands[3] = force_reg (<MODE>mode, operands[3]);
16765 (define_insn "*movqicc_noc"
16766 [(set (match_operand:QI 0 "register_operand" "=r,r")
16767 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16768 [(reg FLAGS_REG) (const_int 0)])
16769 (match_operand:QI 2 "register_operand" "r,0")
16770 (match_operand:QI 3 "register_operand" "0,r")))]
16771 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16773 [(set_attr "type" "icmov")
16774 (set_attr "mode" "QI")])
16777 [(set (match_operand:SWI12 0 "register_operand")
16778 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16779 [(reg FLAGS_REG) (const_int 0)])
16780 (match_operand:SWI12 2 "register_operand")
16781 (match_operand:SWI12 3 "register_operand")))]
16782 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16783 && reload_completed"
16784 [(set (match_dup 0)
16785 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16787 operands[0] = gen_lowpart (SImode, operands[0]);
16788 operands[2] = gen_lowpart (SImode, operands[2]);
16789 operands[3] = gen_lowpart (SImode, operands[3]);
16792 ;; Don't do conditional moves with memory inputs
16794 [(match_scratch:SWI248 2 "r")
16795 (set (match_operand:SWI248 0 "register_operand")
16796 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16797 [(reg FLAGS_REG) (const_int 0)])
16799 (match_operand:SWI248 3 "memory_operand")))]
16800 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16801 && optimize_insn_for_speed_p ()"
16802 [(set (match_dup 2) (match_dup 3))
16804 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16807 [(match_scratch:SWI248 2 "r")
16808 (set (match_operand:SWI248 0 "register_operand")
16809 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16810 [(reg FLAGS_REG) (const_int 0)])
16811 (match_operand:SWI248 3 "memory_operand")
16813 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16814 && optimize_insn_for_speed_p ()"
16815 [(set (match_dup 2) (match_dup 3))
16817 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16819 (define_expand "mov<mode>cc"
16820 [(set (match_operand:X87MODEF 0 "register_operand")
16821 (if_then_else:X87MODEF
16822 (match_operand 1 "comparison_operator")
16823 (match_operand:X87MODEF 2 "register_operand")
16824 (match_operand:X87MODEF 3 "register_operand")))]
16825 "(TARGET_80387 && TARGET_CMOVE)
16826 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16827 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16829 (define_insn "*movxfcc_1"
16830 [(set (match_operand:XF 0 "register_operand" "=f,f")
16831 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16832 [(reg FLAGS_REG) (const_int 0)])
16833 (match_operand:XF 2 "register_operand" "f,0")
16834 (match_operand:XF 3 "register_operand" "0,f")))]
16835 "TARGET_80387 && TARGET_CMOVE"
16837 fcmov%F1\t{%2, %0|%0, %2}
16838 fcmov%f1\t{%3, %0|%0, %3}"
16839 [(set_attr "type" "fcmov")
16840 (set_attr "mode" "XF")])
16842 (define_insn "*movdfcc_1"
16843 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16844 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16845 [(reg FLAGS_REG) (const_int 0)])
16846 (match_operand:DF 2 "nonimmediate_operand"
16848 (match_operand:DF 3 "nonimmediate_operand"
16849 "0 ,f,0 ,rm,0, rm")))]
16850 "TARGET_80387 && TARGET_CMOVE
16851 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16853 fcmov%F1\t{%2, %0|%0, %2}
16854 fcmov%f1\t{%3, %0|%0, %3}
16857 cmov%O2%C1\t{%2, %0|%0, %2}
16858 cmov%O2%c1\t{%3, %0|%0, %3}"
16859 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16860 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16861 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16864 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16865 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16866 [(reg FLAGS_REG) (const_int 0)])
16867 (match_operand:DF 2 "nonimmediate_operand")
16868 (match_operand:DF 3 "nonimmediate_operand")))]
16869 "!TARGET_64BIT && reload_completed"
16870 [(set (match_dup 2)
16871 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16873 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16875 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16876 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16879 (define_insn "*movsfcc_1_387"
16880 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16881 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16882 [(reg FLAGS_REG) (const_int 0)])
16883 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16884 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16885 "TARGET_80387 && TARGET_CMOVE
16886 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16888 fcmov%F1\t{%2, %0|%0, %2}
16889 fcmov%f1\t{%3, %0|%0, %3}
16890 cmov%O2%C1\t{%2, %0|%0, %2}
16891 cmov%O2%c1\t{%3, %0|%0, %3}"
16892 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16893 (set_attr "mode" "SF,SF,SI,SI")])
16895 ;; Don't do conditional moves with memory inputs. This splitter helps
16896 ;; register starved x86_32 by forcing inputs into registers before reload.
16898 [(set (match_operand:MODEF 0 "register_operand")
16899 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16900 [(reg FLAGS_REG) (const_int 0)])
16901 (match_operand:MODEF 2 "nonimmediate_operand")
16902 (match_operand:MODEF 3 "nonimmediate_operand")))]
16903 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16905 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16906 && can_create_pseudo_p ()
16907 && optimize_insn_for_speed_p ()"
16908 [(set (match_dup 0)
16909 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16911 if (MEM_P (operands[2]))
16912 operands[2] = force_reg (<MODE>mode, operands[2]);
16913 if (MEM_P (operands[3]))
16914 operands[3] = force_reg (<MODE>mode, operands[3]);
16917 ;; Don't do conditional moves with memory inputs
16919 [(match_scratch:MODEF 2 "r")
16920 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16921 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16922 [(reg FLAGS_REG) (const_int 0)])
16924 (match_operand:MODEF 3 "memory_operand")))]
16925 "(<MODE>mode != DFmode || TARGET_64BIT)
16926 && TARGET_80387 && TARGET_CMOVE
16927 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16928 && optimize_insn_for_speed_p ()"
16929 [(set (match_dup 2) (match_dup 3))
16931 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16934 [(match_scratch:MODEF 2 "r")
16935 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16936 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16937 [(reg FLAGS_REG) (const_int 0)])
16938 (match_operand:MODEF 3 "memory_operand")
16940 "(<MODE>mode != DFmode || TARGET_64BIT)
16941 && TARGET_80387 && TARGET_CMOVE
16942 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16943 && optimize_insn_for_speed_p ()"
16944 [(set (match_dup 2) (match_dup 3))
16946 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16948 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16949 ;; the scalar versions to have only XMM registers as operands.
16951 ;; XOP conditional move
16952 (define_insn "*xop_pcmov_<mode>"
16953 [(set (match_operand:MODEF 0 "register_operand" "=x")
16954 (if_then_else:MODEF
16955 (match_operand:MODEF 1 "register_operand" "x")
16956 (match_operand:MODEF 2 "register_operand" "x")
16957 (match_operand:MODEF 3 "register_operand" "x")))]
16959 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16960 [(set_attr "type" "sse4arg")])
16962 ;; These versions of the min/max patterns are intentionally ignorant of
16963 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16964 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16965 ;; are undefined in this condition, we're certain this is correct.
16967 (define_insn "<code><mode>3"
16968 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16970 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16971 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16972 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16974 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16975 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16976 [(set_attr "isa" "noavx,avx")
16977 (set_attr "prefix" "orig,vex")
16978 (set_attr "type" "sseadd")
16979 (set_attr "mode" "<MODE>")])
16981 ;; These versions of the min/max patterns implement exactly the operations
16982 ;; min = (op1 < op2 ? op1 : op2)
16983 ;; max = (!(op1 < op2) ? op1 : op2)
16984 ;; Their operands are not commutative, and thus they may be used in the
16985 ;; presence of -0.0 and NaN.
16987 (define_int_iterator IEEE_MAXMIN
16991 (define_int_attr ieee_maxmin
16992 [(UNSPEC_IEEE_MAX "max")
16993 (UNSPEC_IEEE_MIN "min")])
16995 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16996 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16998 [(match_operand:MODEF 1 "register_operand" "0,x")
16999 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17001 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17003 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17004 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17005 [(set_attr "isa" "noavx,avx")
17006 (set_attr "prefix" "orig,vex")
17007 (set_attr "type" "sseadd")
17008 (set_attr "mode" "<MODE>")])
17010 ;; Make two stack loads independent:
17012 ;; fld %st(0) -> fld bb
17013 ;; fmul bb fmul %st(1), %st
17015 ;; Actually we only match the last two instructions for simplicity.
17017 [(set (match_operand 0 "fp_register_operand")
17018 (match_operand 1 "fp_register_operand"))
17020 (match_operator 2 "binary_fp_operator"
17022 (match_operand 3 "memory_operand")]))]
17023 "REGNO (operands[0]) != REGNO (operands[1])"
17024 [(set (match_dup 0) (match_dup 3))
17025 (set (match_dup 0) (match_dup 4))]
17027 ;; The % modifier is not operational anymore in peephole2's, so we have to
17028 ;; swap the operands manually in the case of addition and multiplication.
17032 if (COMMUTATIVE_ARITH_P (operands[2]))
17033 op0 = operands[0], op1 = operands[1];
17035 op0 = operands[1], op1 = operands[0];
17037 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17038 GET_MODE (operands[2]),
17042 ;; Conditional addition patterns
17043 (define_expand "add<mode>cc"
17044 [(match_operand:SWI 0 "register_operand")
17045 (match_operand 1 "ordered_comparison_operator")
17046 (match_operand:SWI 2 "register_operand")
17047 (match_operand:SWI 3 "const_int_operand")]
17049 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17051 ;; Misc patterns (?)
17053 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17054 ;; Otherwise there will be nothing to keep
17056 ;; [(set (reg ebp) (reg esp))]
17057 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17058 ;; (clobber (eflags)]
17059 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17061 ;; in proper program order.
17063 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17064 [(set (match_operand:P 0 "register_operand" "=r,r")
17065 (plus:P (match_operand:P 1 "register_operand" "0,r")
17066 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17067 (clobber (reg:CC FLAGS_REG))
17068 (clobber (mem:BLK (scratch)))]
17071 switch (get_attr_type (insn))
17074 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17077 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17078 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17079 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17081 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17085 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17088 [(set (attr "type")
17089 (cond [(and (eq_attr "alternative" "0")
17090 (not (match_test "TARGET_OPT_AGU")))
17091 (const_string "alu")
17092 (match_operand:<MODE> 2 "const0_operand")
17093 (const_string "imov")
17095 (const_string "lea")))
17096 (set (attr "length_immediate")
17097 (cond [(eq_attr "type" "imov")
17099 (and (eq_attr "type" "alu")
17100 (match_operand 2 "const128_operand"))
17103 (const_string "*")))
17104 (set_attr "mode" "<MODE>")])
17106 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17107 [(set (match_operand:P 0 "register_operand" "=r")
17108 (minus:P (match_operand:P 1 "register_operand" "0")
17109 (match_operand:P 2 "register_operand" "r")))
17110 (clobber (reg:CC FLAGS_REG))
17111 (clobber (mem:BLK (scratch)))]
17113 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17114 [(set_attr "type" "alu")
17115 (set_attr "mode" "<MODE>")])
17117 (define_insn "allocate_stack_worker_probe_<mode>"
17118 [(set (match_operand:P 0 "register_operand" "=a")
17119 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17120 UNSPECV_STACK_PROBE))
17121 (clobber (reg:CC FLAGS_REG))]
17122 "ix86_target_stack_probe ()"
17123 "call\t___chkstk_ms"
17124 [(set_attr "type" "multi")
17125 (set_attr "length" "5")])
17127 (define_expand "allocate_stack"
17128 [(match_operand 0 "register_operand")
17129 (match_operand 1 "general_operand")]
17130 "ix86_target_stack_probe ()"
17134 #ifndef CHECK_STACK_LIMIT
17135 #define CHECK_STACK_LIMIT 0
17138 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17139 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17143 rtx (*insn) (rtx, rtx);
17145 x = copy_to_mode_reg (Pmode, operands[1]);
17147 insn = (TARGET_64BIT
17148 ? gen_allocate_stack_worker_probe_di
17149 : gen_allocate_stack_worker_probe_si);
17151 emit_insn (insn (x, x));
17154 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17155 stack_pointer_rtx, 0, OPTAB_DIRECT);
17157 if (x != stack_pointer_rtx)
17158 emit_move_insn (stack_pointer_rtx, x);
17160 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17164 ;; Use IOR for stack probes, this is shorter.
17165 (define_expand "probe_stack"
17166 [(match_operand 0 "memory_operand")]
17169 rtx (*gen_ior3) (rtx, rtx, rtx);
17171 gen_ior3 = (GET_MODE (operands[0]) == DImode
17172 ? gen_iordi3 : gen_iorsi3);
17174 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17178 (define_insn "adjust_stack_and_probe<mode>"
17179 [(set (match_operand:P 0 "register_operand" "=r")
17180 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17181 UNSPECV_PROBE_STACK_RANGE))
17182 (set (reg:P SP_REG)
17183 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17184 (clobber (reg:CC FLAGS_REG))
17185 (clobber (mem:BLK (scratch)))]
17187 "* return output_adjust_stack_and_probe (operands[0]);"
17188 [(set_attr "type" "multi")])
17190 (define_insn "probe_stack_range<mode>"
17191 [(set (match_operand:P 0 "register_operand" "=r")
17192 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17193 (match_operand:P 2 "const_int_operand" "n")]
17194 UNSPECV_PROBE_STACK_RANGE))
17195 (clobber (reg:CC FLAGS_REG))]
17197 "* return output_probe_stack_range (operands[0], operands[2]);"
17198 [(set_attr "type" "multi")])
17200 (define_expand "builtin_setjmp_receiver"
17201 [(label_ref (match_operand 0))]
17202 "!TARGET_64BIT && flag_pic"
17208 rtx_code_label *label_rtx = gen_label_rtx ();
17209 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17210 xops[0] = xops[1] = pic_offset_table_rtx;
17211 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17212 ix86_expand_binary_operator (MINUS, SImode, xops);
17216 emit_insn (gen_set_got (pic_offset_table_rtx));
17220 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17221 ;; Do not split instructions with mask registers.
17223 [(set (match_operand 0 "general_reg_operand")
17224 (match_operator 3 "promotable_binary_operator"
17225 [(match_operand 1 "general_reg_operand")
17226 (match_operand 2 "aligned_operand")]))
17227 (clobber (reg:CC FLAGS_REG))]
17228 "! TARGET_PARTIAL_REG_STALL && reload_completed
17229 && ((GET_MODE (operands[0]) == HImode
17230 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17231 /* ??? next two lines just !satisfies_constraint_K (...) */
17232 || !CONST_INT_P (operands[2])
17233 || satisfies_constraint_K (operands[2])))
17234 || (GET_MODE (operands[0]) == QImode
17235 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17236 [(parallel [(set (match_dup 0)
17237 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17238 (clobber (reg:CC FLAGS_REG))])]
17240 operands[0] = gen_lowpart (SImode, operands[0]);
17241 operands[1] = gen_lowpart (SImode, operands[1]);
17242 if (GET_CODE (operands[3]) != ASHIFT)
17243 operands[2] = gen_lowpart (SImode, operands[2]);
17244 PUT_MODE (operands[3], SImode);
17247 ; Promote the QImode tests, as i386 has encoding of the AND
17248 ; instruction with 32-bit sign-extended immediate and thus the
17249 ; instruction size is unchanged, except in the %eax case for
17250 ; which it is increased by one byte, hence the ! optimize_size.
17252 [(set (match_operand 0 "flags_reg_operand")
17253 (match_operator 2 "compare_operator"
17254 [(and (match_operand 3 "aligned_operand")
17255 (match_operand 4 "const_int_operand"))
17257 (set (match_operand 1 "register_operand")
17258 (and (match_dup 3) (match_dup 4)))]
17259 "! TARGET_PARTIAL_REG_STALL && reload_completed
17260 && optimize_insn_for_speed_p ()
17261 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17262 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17263 /* Ensure that the operand will remain sign-extended immediate. */
17264 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17265 [(parallel [(set (match_dup 0)
17266 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17269 (and:SI (match_dup 3) (match_dup 4)))])]
17272 = gen_int_mode (INTVAL (operands[4])
17273 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17274 operands[1] = gen_lowpart (SImode, operands[1]);
17275 operands[3] = gen_lowpart (SImode, operands[3]);
17278 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17279 ; the TEST instruction with 32-bit sign-extended immediate and thus
17280 ; the instruction size would at least double, which is not what we
17281 ; want even with ! optimize_size.
17283 [(set (match_operand 0 "flags_reg_operand")
17284 (match_operator 1 "compare_operator"
17285 [(and (match_operand:HI 2 "aligned_operand")
17286 (match_operand:HI 3 "const_int_operand"))
17288 "! TARGET_PARTIAL_REG_STALL && reload_completed
17289 && ! TARGET_FAST_PREFIX
17290 && optimize_insn_for_speed_p ()
17291 /* Ensure that the operand will remain sign-extended immediate. */
17292 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17293 [(set (match_dup 0)
17294 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17298 = gen_int_mode (INTVAL (operands[3])
17299 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17300 operands[2] = gen_lowpart (SImode, operands[2]);
17304 [(set (match_operand 0 "register_operand")
17305 (neg (match_operand 1 "register_operand")))
17306 (clobber (reg:CC FLAGS_REG))]
17307 "! TARGET_PARTIAL_REG_STALL && reload_completed
17308 && (GET_MODE (operands[0]) == HImode
17309 || (GET_MODE (operands[0]) == QImode
17310 && (TARGET_PROMOTE_QImode
17311 || optimize_insn_for_size_p ())))"
17312 [(parallel [(set (match_dup 0)
17313 (neg:SI (match_dup 1)))
17314 (clobber (reg:CC FLAGS_REG))])]
17316 operands[0] = gen_lowpart (SImode, operands[0]);
17317 operands[1] = gen_lowpart (SImode, operands[1]);
17320 ;; Do not split instructions with mask regs.
17322 [(set (match_operand 0 "general_reg_operand")
17323 (not (match_operand 1 "general_reg_operand")))]
17324 "! TARGET_PARTIAL_REG_STALL && reload_completed
17325 && (GET_MODE (operands[0]) == HImode
17326 || (GET_MODE (operands[0]) == QImode
17327 && (TARGET_PROMOTE_QImode
17328 || optimize_insn_for_size_p ())))"
17329 [(set (match_dup 0)
17330 (not:SI (match_dup 1)))]
17332 operands[0] = gen_lowpart (SImode, operands[0]);
17333 operands[1] = gen_lowpart (SImode, operands[1]);
17336 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17337 ;; transform a complex memory operation into two memory to register operations.
17339 ;; Don't push memory operands
17341 [(set (match_operand:SWI 0 "push_operand")
17342 (match_operand:SWI 1 "memory_operand"))
17343 (match_scratch:SWI 2 "<r>")]
17344 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17345 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17346 [(set (match_dup 2) (match_dup 1))
17347 (set (match_dup 0) (match_dup 2))])
17349 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17352 [(set (match_operand:SF 0 "push_operand")
17353 (match_operand:SF 1 "memory_operand"))
17354 (match_scratch:SF 2 "r")]
17355 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17356 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17357 [(set (match_dup 2) (match_dup 1))
17358 (set (match_dup 0) (match_dup 2))])
17360 ;; Don't move an immediate directly to memory when the instruction
17361 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17363 [(match_scratch:SWI124 1 "<r>")
17364 (set (match_operand:SWI124 0 "memory_operand")
17366 "optimize_insn_for_speed_p ()
17367 && ((<MODE>mode == HImode
17368 && TARGET_LCP_STALL)
17369 || (!TARGET_USE_MOV0
17370 && TARGET_SPLIT_LONG_MOVES
17371 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17372 && peep2_regno_dead_p (0, FLAGS_REG)"
17373 [(parallel [(set (match_dup 2) (const_int 0))
17374 (clobber (reg:CC FLAGS_REG))])
17375 (set (match_dup 0) (match_dup 1))]
17376 "operands[2] = gen_lowpart (SImode, operands[1]);")
17379 [(match_scratch:SWI124 2 "<r>")
17380 (set (match_operand:SWI124 0 "memory_operand")
17381 (match_operand:SWI124 1 "immediate_operand"))]
17382 "optimize_insn_for_speed_p ()
17383 && ((<MODE>mode == HImode
17384 && TARGET_LCP_STALL)
17385 || (TARGET_SPLIT_LONG_MOVES
17386 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17387 [(set (match_dup 2) (match_dup 1))
17388 (set (match_dup 0) (match_dup 2))])
17390 ;; Don't compare memory with zero, load and use a test instead.
17392 [(set (match_operand 0 "flags_reg_operand")
17393 (match_operator 1 "compare_operator"
17394 [(match_operand:SI 2 "memory_operand")
17396 (match_scratch:SI 3 "r")]
17397 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17398 [(set (match_dup 3) (match_dup 2))
17399 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17401 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17402 ;; Don't split NOTs with a displacement operand, because resulting XOR
17403 ;; will not be pairable anyway.
17405 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17406 ;; represented using a modRM byte. The XOR replacement is long decoded,
17407 ;; so this split helps here as well.
17409 ;; Note: Can't do this as a regular split because we can't get proper
17410 ;; lifetime information then.
17413 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17414 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17415 "optimize_insn_for_speed_p ()
17416 && ((TARGET_NOT_UNPAIRABLE
17417 && (!MEM_P (operands[0])
17418 || !memory_displacement_operand (operands[0], <MODE>mode)))
17419 || (TARGET_NOT_VECTORMODE
17420 && long_memory_operand (operands[0], <MODE>mode)))
17421 && peep2_regno_dead_p (0, FLAGS_REG)"
17422 [(parallel [(set (match_dup 0)
17423 (xor:SWI124 (match_dup 1) (const_int -1)))
17424 (clobber (reg:CC FLAGS_REG))])])
17426 ;; Non pairable "test imm, reg" instructions can be translated to
17427 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17428 ;; byte opcode instead of two, have a short form for byte operands),
17429 ;; so do it for other CPUs as well. Given that the value was dead,
17430 ;; this should not create any new dependencies. Pass on the sub-word
17431 ;; versions if we're concerned about partial register stalls.
17434 [(set (match_operand 0 "flags_reg_operand")
17435 (match_operator 1 "compare_operator"
17436 [(and:SI (match_operand:SI 2 "register_operand")
17437 (match_operand:SI 3 "immediate_operand"))
17439 "ix86_match_ccmode (insn, CCNOmode)
17440 && (true_regnum (operands[2]) != AX_REG
17441 || satisfies_constraint_K (operands[3]))
17442 && peep2_reg_dead_p (1, operands[2])"
17444 [(set (match_dup 0)
17445 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17448 (and:SI (match_dup 2) (match_dup 3)))])])
17450 ;; We don't need to handle HImode case, because it will be promoted to SImode
17451 ;; on ! TARGET_PARTIAL_REG_STALL
17454 [(set (match_operand 0 "flags_reg_operand")
17455 (match_operator 1 "compare_operator"
17456 [(and:QI (match_operand:QI 2 "register_operand")
17457 (match_operand:QI 3 "immediate_operand"))
17459 "! TARGET_PARTIAL_REG_STALL
17460 && ix86_match_ccmode (insn, CCNOmode)
17461 && true_regnum (operands[2]) != AX_REG
17462 && peep2_reg_dead_p (1, operands[2])"
17464 [(set (match_dup 0)
17465 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17468 (and:QI (match_dup 2) (match_dup 3)))])])
17471 [(set (match_operand 0 "flags_reg_operand")
17472 (match_operator 1 "compare_operator"
17475 (match_operand 2 "ext_register_operand")
17478 (match_operand 3 "const_int_operand"))
17480 "! TARGET_PARTIAL_REG_STALL
17481 && ix86_match_ccmode (insn, CCNOmode)
17482 && true_regnum (operands[2]) != AX_REG
17483 && peep2_reg_dead_p (1, operands[2])"
17484 [(parallel [(set (match_dup 0)
17493 (set (zero_extract:SI (match_dup 2)
17501 (match_dup 3)))])])
17503 ;; Don't do logical operations with memory inputs.
17505 [(match_scratch:SI 2 "r")
17506 (parallel [(set (match_operand:SI 0 "register_operand")
17507 (match_operator:SI 3 "arith_or_logical_operator"
17509 (match_operand:SI 1 "memory_operand")]))
17510 (clobber (reg:CC FLAGS_REG))])]
17511 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17512 [(set (match_dup 2) (match_dup 1))
17513 (parallel [(set (match_dup 0)
17514 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17515 (clobber (reg:CC FLAGS_REG))])])
17518 [(match_scratch:SI 2 "r")
17519 (parallel [(set (match_operand:SI 0 "register_operand")
17520 (match_operator:SI 3 "arith_or_logical_operator"
17521 [(match_operand:SI 1 "memory_operand")
17523 (clobber (reg:CC FLAGS_REG))])]
17524 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17525 [(set (match_dup 2) (match_dup 1))
17526 (parallel [(set (match_dup 0)
17527 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17528 (clobber (reg:CC FLAGS_REG))])])
17530 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17531 ;; refers to the destination of the load!
17534 [(set (match_operand:SI 0 "register_operand")
17535 (match_operand:SI 1 "register_operand"))
17536 (parallel [(set (match_dup 0)
17537 (match_operator:SI 3 "commutative_operator"
17539 (match_operand:SI 2 "memory_operand")]))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "REGNO (operands[0]) != REGNO (operands[1])
17542 && GENERAL_REGNO_P (REGNO (operands[0]))
17543 && GENERAL_REGNO_P (REGNO (operands[1]))"
17544 [(set (match_dup 0) (match_dup 4))
17545 (parallel [(set (match_dup 0)
17546 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17547 (clobber (reg:CC FLAGS_REG))])]
17548 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17551 [(set (match_operand 0 "register_operand")
17552 (match_operand 1 "register_operand"))
17554 (match_operator 3 "commutative_operator"
17556 (match_operand 2 "memory_operand")]))]
17557 "REGNO (operands[0]) != REGNO (operands[1])
17558 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17559 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17560 [(set (match_dup 0) (match_dup 2))
17562 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17564 ; Don't do logical operations with memory outputs
17566 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17567 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17568 ; the same decoder scheduling characteristics as the original.
17571 [(match_scratch:SI 2 "r")
17572 (parallel [(set (match_operand:SI 0 "memory_operand")
17573 (match_operator:SI 3 "arith_or_logical_operator"
17575 (match_operand:SI 1 "nonmemory_operand")]))
17576 (clobber (reg:CC FLAGS_REG))])]
17577 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17578 /* Do not split stack checking probes. */
17579 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17580 [(set (match_dup 2) (match_dup 0))
17581 (parallel [(set (match_dup 2)
17582 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17583 (clobber (reg:CC FLAGS_REG))])
17584 (set (match_dup 0) (match_dup 2))])
17587 [(match_scratch:SI 2 "r")
17588 (parallel [(set (match_operand:SI 0 "memory_operand")
17589 (match_operator:SI 3 "arith_or_logical_operator"
17590 [(match_operand:SI 1 "nonmemory_operand")
17592 (clobber (reg:CC FLAGS_REG))])]
17593 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17594 /* Do not split stack checking probes. */
17595 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17596 [(set (match_dup 2) (match_dup 0))
17597 (parallel [(set (match_dup 2)
17598 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17599 (clobber (reg:CC FLAGS_REG))])
17600 (set (match_dup 0) (match_dup 2))])
17602 ;; Attempt to use arith or logical operations with memory outputs with
17603 ;; setting of flags.
17605 [(set (match_operand:SWI 0 "register_operand")
17606 (match_operand:SWI 1 "memory_operand"))
17607 (parallel [(set (match_dup 0)
17608 (match_operator:SWI 3 "plusminuslogic_operator"
17610 (match_operand:SWI 2 "<nonmemory_operand>")]))
17611 (clobber (reg:CC FLAGS_REG))])
17612 (set (match_dup 1) (match_dup 0))
17613 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17614 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17615 && peep2_reg_dead_p (4, operands[0])
17616 && !reg_overlap_mentioned_p (operands[0], operands[1])
17617 && !reg_overlap_mentioned_p (operands[0], operands[2])
17618 && (<MODE>mode != QImode
17619 || immediate_operand (operands[2], QImode)
17620 || q_regs_operand (operands[2], QImode))
17621 && ix86_match_ccmode (peep2_next_insn (3),
17622 (GET_CODE (operands[3]) == PLUS
17623 || GET_CODE (operands[3]) == MINUS)
17624 ? CCGOCmode : CCNOmode)"
17625 [(parallel [(set (match_dup 4) (match_dup 5))
17626 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17627 (match_dup 2)]))])]
17629 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17630 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17631 copy_rtx (operands[1]),
17632 copy_rtx (operands[2]));
17633 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17634 operands[5], const0_rtx);
17638 [(parallel [(set (match_operand:SWI 0 "register_operand")
17639 (match_operator:SWI 2 "plusminuslogic_operator"
17641 (match_operand:SWI 1 "memory_operand")]))
17642 (clobber (reg:CC FLAGS_REG))])
17643 (set (match_dup 1) (match_dup 0))
17644 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17645 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17646 && GET_CODE (operands[2]) != MINUS
17647 && peep2_reg_dead_p (3, operands[0])
17648 && !reg_overlap_mentioned_p (operands[0], operands[1])
17649 && ix86_match_ccmode (peep2_next_insn (2),
17650 GET_CODE (operands[2]) == PLUS
17651 ? CCGOCmode : CCNOmode)"
17652 [(parallel [(set (match_dup 3) (match_dup 4))
17653 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17654 (match_dup 0)]))])]
17656 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17657 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17658 copy_rtx (operands[1]),
17659 copy_rtx (operands[0]));
17660 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17661 operands[4], const0_rtx);
17665 [(set (match_operand:SWI12 0 "register_operand")
17666 (match_operand:SWI12 1 "memory_operand"))
17667 (parallel [(set (match_operand:SI 4 "register_operand")
17668 (match_operator:SI 3 "plusminuslogic_operator"
17670 (match_operand:SI 2 "nonmemory_operand")]))
17671 (clobber (reg:CC FLAGS_REG))])
17672 (set (match_dup 1) (match_dup 0))
17673 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17674 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17675 && REG_P (operands[0]) && REG_P (operands[4])
17676 && REGNO (operands[0]) == REGNO (operands[4])
17677 && peep2_reg_dead_p (4, operands[0])
17678 && (<MODE>mode != QImode
17679 || immediate_operand (operands[2], SImode)
17680 || q_regs_operand (operands[2], SImode))
17681 && !reg_overlap_mentioned_p (operands[0], operands[1])
17682 && !reg_overlap_mentioned_p (operands[0], operands[2])
17683 && ix86_match_ccmode (peep2_next_insn (3),
17684 (GET_CODE (operands[3]) == PLUS
17685 || GET_CODE (operands[3]) == MINUS)
17686 ? CCGOCmode : CCNOmode)"
17687 [(parallel [(set (match_dup 4) (match_dup 5))
17688 (set (match_dup 1) (match_dup 6))])]
17690 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17691 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17692 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17693 copy_rtx (operands[1]), operands[2]);
17694 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17695 operands[5], const0_rtx);
17696 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17697 copy_rtx (operands[1]),
17698 copy_rtx (operands[2]));
17701 ;; Attempt to always use XOR for zeroing registers.
17703 [(set (match_operand 0 "register_operand")
17704 (match_operand 1 "const0_operand"))]
17705 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17706 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17707 && GENERAL_REG_P (operands[0])
17708 && peep2_regno_dead_p (0, FLAGS_REG)"
17709 [(parallel [(set (match_dup 0) (const_int 0))
17710 (clobber (reg:CC FLAGS_REG))])]
17711 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17714 [(set (strict_low_part (match_operand 0 "register_operand"))
17716 "(GET_MODE (operands[0]) == QImode
17717 || GET_MODE (operands[0]) == HImode)
17718 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17719 && peep2_regno_dead_p (0, FLAGS_REG)"
17720 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17721 (clobber (reg:CC FLAGS_REG))])])
17723 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17725 [(set (match_operand:SWI248 0 "register_operand")
17727 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17728 && peep2_regno_dead_p (0, FLAGS_REG)"
17729 [(parallel [(set (match_dup 0) (const_int -1))
17730 (clobber (reg:CC FLAGS_REG))])]
17732 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17733 operands[0] = gen_lowpart (SImode, operands[0]);
17736 ;; Attempt to convert simple lea to add/shift.
17737 ;; These can be created by move expanders.
17738 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17739 ;; relevant lea instructions were already split.
17742 [(set (match_operand:SWI48 0 "register_operand")
17743 (plus:SWI48 (match_dup 0)
17744 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17746 && peep2_regno_dead_p (0, FLAGS_REG)"
17747 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17748 (clobber (reg:CC FLAGS_REG))])])
17751 [(set (match_operand:SWI48 0 "register_operand")
17752 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17755 && peep2_regno_dead_p (0, FLAGS_REG)"
17756 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17757 (clobber (reg:CC FLAGS_REG))])])
17760 [(set (match_operand:DI 0 "register_operand")
17762 (plus:SI (match_operand:SI 1 "register_operand")
17763 (match_operand:SI 2 "nonmemory_operand"))))]
17764 "TARGET_64BIT && !TARGET_OPT_AGU
17765 && REGNO (operands[0]) == REGNO (operands[1])
17766 && peep2_regno_dead_p (0, FLAGS_REG)"
17767 [(parallel [(set (match_dup 0)
17768 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17769 (clobber (reg:CC FLAGS_REG))])])
17772 [(set (match_operand:DI 0 "register_operand")
17774 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17775 (match_operand:SI 2 "register_operand"))))]
17776 "TARGET_64BIT && !TARGET_OPT_AGU
17777 && REGNO (operands[0]) == REGNO (operands[2])
17778 && peep2_regno_dead_p (0, FLAGS_REG)"
17779 [(parallel [(set (match_dup 0)
17780 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17781 (clobber (reg:CC FLAGS_REG))])])
17784 [(set (match_operand:SWI48 0 "register_operand")
17785 (mult:SWI48 (match_dup 0)
17786 (match_operand:SWI48 1 "const_int_operand")))]
17787 "exact_log2 (INTVAL (operands[1])) >= 0
17788 && peep2_regno_dead_p (0, FLAGS_REG)"
17789 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17790 (clobber (reg:CC FLAGS_REG))])]
17791 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17794 [(set (match_operand:DI 0 "register_operand")
17796 (mult:SI (match_operand:SI 1 "register_operand")
17797 (match_operand:SI 2 "const_int_operand"))))]
17799 && exact_log2 (INTVAL (operands[2])) >= 0
17800 && REGNO (operands[0]) == REGNO (operands[1])
17801 && peep2_regno_dead_p (0, FLAGS_REG)"
17802 [(parallel [(set (match_dup 0)
17803 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17804 (clobber (reg:CC FLAGS_REG))])]
17805 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17807 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17808 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17809 ;; On many CPUs it is also faster, since special hardware to avoid esp
17810 ;; dependencies is present.
17812 ;; While some of these conversions may be done using splitters, we use
17813 ;; peepholes in order to allow combine_stack_adjustments pass to see
17814 ;; nonobfuscated RTL.
17816 ;; Convert prologue esp subtractions to push.
17817 ;; We need register to push. In order to keep verify_flow_info happy we have
17819 ;; - use scratch and clobber it in order to avoid dependencies
17820 ;; - use already live register
17821 ;; We can't use the second way right now, since there is no reliable way how to
17822 ;; verify that given register is live. First choice will also most likely in
17823 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17824 ;; call clobbered registers are dead. We may want to use base pointer as an
17825 ;; alternative when no register is available later.
17828 [(match_scratch:W 1 "r")
17829 (parallel [(set (reg:P SP_REG)
17830 (plus:P (reg:P SP_REG)
17831 (match_operand:P 0 "const_int_operand")))
17832 (clobber (reg:CC FLAGS_REG))
17833 (clobber (mem:BLK (scratch)))])]
17834 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17835 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17836 [(clobber (match_dup 1))
17837 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17838 (clobber (mem:BLK (scratch)))])])
17841 [(match_scratch:W 1 "r")
17842 (parallel [(set (reg:P SP_REG)
17843 (plus:P (reg:P SP_REG)
17844 (match_operand:P 0 "const_int_operand")))
17845 (clobber (reg:CC FLAGS_REG))
17846 (clobber (mem:BLK (scratch)))])]
17847 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17848 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17849 [(clobber (match_dup 1))
17850 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17851 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17852 (clobber (mem:BLK (scratch)))])])
17854 ;; Convert esp subtractions to push.
17856 [(match_scratch:W 1 "r")
17857 (parallel [(set (reg:P SP_REG)
17858 (plus:P (reg:P SP_REG)
17859 (match_operand:P 0 "const_int_operand")))
17860 (clobber (reg:CC FLAGS_REG))])]
17861 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17862 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17863 [(clobber (match_dup 1))
17864 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17867 [(match_scratch:W 1 "r")
17868 (parallel [(set (reg:P SP_REG)
17869 (plus:P (reg:P SP_REG)
17870 (match_operand:P 0 "const_int_operand")))
17871 (clobber (reg:CC FLAGS_REG))])]
17872 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17873 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17874 [(clobber (match_dup 1))
17875 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17876 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17878 ;; Convert epilogue deallocator to pop.
17880 [(match_scratch:W 1 "r")
17881 (parallel [(set (reg:P SP_REG)
17882 (plus:P (reg:P SP_REG)
17883 (match_operand:P 0 "const_int_operand")))
17884 (clobber (reg:CC FLAGS_REG))
17885 (clobber (mem:BLK (scratch)))])]
17886 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17887 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17888 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17889 (clobber (mem:BLK (scratch)))])])
17891 ;; Two pops case is tricky, since pop causes dependency
17892 ;; on destination register. We use two registers if available.
17894 [(match_scratch:W 1 "r")
17895 (match_scratch:W 2 "r")
17896 (parallel [(set (reg:P SP_REG)
17897 (plus:P (reg:P SP_REG)
17898 (match_operand:P 0 "const_int_operand")))
17899 (clobber (reg:CC FLAGS_REG))
17900 (clobber (mem:BLK (scratch)))])]
17901 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17902 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17903 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17904 (clobber (mem:BLK (scratch)))])
17905 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17908 [(match_scratch:W 1 "r")
17909 (parallel [(set (reg:P SP_REG)
17910 (plus:P (reg:P SP_REG)
17911 (match_operand:P 0 "const_int_operand")))
17912 (clobber (reg:CC FLAGS_REG))
17913 (clobber (mem:BLK (scratch)))])]
17914 "optimize_insn_for_size_p ()
17915 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17916 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17917 (clobber (mem:BLK (scratch)))])
17918 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17920 ;; Convert esp additions to pop.
17922 [(match_scratch:W 1 "r")
17923 (parallel [(set (reg:P SP_REG)
17924 (plus:P (reg:P SP_REG)
17925 (match_operand:P 0 "const_int_operand")))
17926 (clobber (reg:CC FLAGS_REG))])]
17927 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17928 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17930 ;; Two pops case is tricky, since pop causes dependency
17931 ;; on destination register. We use two registers if available.
17933 [(match_scratch:W 1 "r")
17934 (match_scratch:W 2 "r")
17935 (parallel [(set (reg:P SP_REG)
17936 (plus:P (reg:P SP_REG)
17937 (match_operand:P 0 "const_int_operand")))
17938 (clobber (reg:CC FLAGS_REG))])]
17939 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17940 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17941 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17944 [(match_scratch:W 1 "r")
17945 (parallel [(set (reg:P SP_REG)
17946 (plus:P (reg:P SP_REG)
17947 (match_operand:P 0 "const_int_operand")))
17948 (clobber (reg:CC FLAGS_REG))])]
17949 "optimize_insn_for_size_p ()
17950 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17951 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17952 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17954 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17955 ;; required and register dies. Similarly for 128 to -128.
17957 [(set (match_operand 0 "flags_reg_operand")
17958 (match_operator 1 "compare_operator"
17959 [(match_operand 2 "register_operand")
17960 (match_operand 3 "const_int_operand")]))]
17961 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17962 && incdec_operand (operands[3], GET_MODE (operands[3])))
17963 || (!TARGET_FUSE_CMP_AND_BRANCH
17964 && INTVAL (operands[3]) == 128))
17965 && ix86_match_ccmode (insn, CCGCmode)
17966 && peep2_reg_dead_p (1, operands[2])"
17967 [(parallel [(set (match_dup 0)
17968 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17969 (clobber (match_dup 2))])])
17971 ;; Convert imul by three, five and nine into lea
17974 [(set (match_operand:SWI48 0 "register_operand")
17975 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17976 (match_operand:SWI48 2 "const359_operand")))
17977 (clobber (reg:CC FLAGS_REG))])]
17978 "!TARGET_PARTIAL_REG_STALL
17979 || <MODE>mode == SImode
17980 || optimize_function_for_size_p (cfun)"
17981 [(set (match_dup 0)
17982 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17984 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17988 [(set (match_operand:SWI48 0 "register_operand")
17989 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17990 (match_operand:SWI48 2 "const359_operand")))
17991 (clobber (reg:CC FLAGS_REG))])]
17992 "optimize_insn_for_speed_p ()
17993 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17994 [(set (match_dup 0) (match_dup 1))
17996 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17998 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18000 ;; imul $32bit_imm, mem, reg is vector decoded, while
18001 ;; imul $32bit_imm, reg, reg is direct decoded.
18003 [(match_scratch:SWI48 3 "r")
18004 (parallel [(set (match_operand:SWI48 0 "register_operand")
18005 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18006 (match_operand:SWI48 2 "immediate_operand")))
18007 (clobber (reg:CC FLAGS_REG))])]
18008 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18009 && !satisfies_constraint_K (operands[2])"
18010 [(set (match_dup 3) (match_dup 1))
18011 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18012 (clobber (reg:CC FLAGS_REG))])])
18015 [(match_scratch:SI 3 "r")
18016 (parallel [(set (match_operand:DI 0 "register_operand")
18018 (mult:SI (match_operand:SI 1 "memory_operand")
18019 (match_operand:SI 2 "immediate_operand"))))
18020 (clobber (reg:CC FLAGS_REG))])]
18022 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18023 && !satisfies_constraint_K (operands[2])"
18024 [(set (match_dup 3) (match_dup 1))
18025 (parallel [(set (match_dup 0)
18026 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18027 (clobber (reg:CC FLAGS_REG))])])
18029 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18030 ;; Convert it into imul reg, reg
18031 ;; It would be better to force assembler to encode instruction using long
18032 ;; immediate, but there is apparently no way to do so.
18034 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18036 (match_operand:SWI248 1 "nonimmediate_operand")
18037 (match_operand:SWI248 2 "const_int_operand")))
18038 (clobber (reg:CC FLAGS_REG))])
18039 (match_scratch:SWI248 3 "r")]
18040 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18041 && satisfies_constraint_K (operands[2])"
18042 [(set (match_dup 3) (match_dup 2))
18043 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18044 (clobber (reg:CC FLAGS_REG))])]
18046 if (!rtx_equal_p (operands[0], operands[1]))
18047 emit_move_insn (operands[0], operands[1]);
18050 ;; After splitting up read-modify operations, array accesses with memory
18051 ;; operands might end up in form:
18053 ;; movl 4(%esp), %edx
18055 ;; instead of pre-splitting:
18057 ;; addl 4(%esp), %eax
18059 ;; movl 4(%esp), %edx
18060 ;; leal (%edx,%eax,4), %eax
18063 [(match_scratch:W 5 "r")
18064 (parallel [(set (match_operand 0 "register_operand")
18065 (ashift (match_operand 1 "register_operand")
18066 (match_operand 2 "const_int_operand")))
18067 (clobber (reg:CC FLAGS_REG))])
18068 (parallel [(set (match_operand 3 "register_operand")
18069 (plus (match_dup 0)
18070 (match_operand 4 "x86_64_general_operand")))
18071 (clobber (reg:CC FLAGS_REG))])]
18072 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18073 /* Validate MODE for lea. */
18074 && ((!TARGET_PARTIAL_REG_STALL
18075 && (GET_MODE (operands[0]) == QImode
18076 || GET_MODE (operands[0]) == HImode))
18077 || GET_MODE (operands[0]) == SImode
18078 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18079 && (rtx_equal_p (operands[0], operands[3])
18080 || peep2_reg_dead_p (2, operands[0]))
18081 /* We reorder load and the shift. */
18082 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18083 [(set (match_dup 5) (match_dup 4))
18084 (set (match_dup 0) (match_dup 1))]
18086 machine_mode op1mode = GET_MODE (operands[1]);
18087 machine_mode mode = op1mode == DImode ? DImode : SImode;
18088 int scale = 1 << INTVAL (operands[2]);
18089 rtx index = gen_lowpart (word_mode, operands[1]);
18090 rtx base = gen_lowpart (word_mode, operands[5]);
18091 rtx dest = gen_lowpart (mode, operands[3]);
18093 operands[1] = gen_rtx_PLUS (word_mode, base,
18094 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18095 operands[5] = base;
18096 if (mode != word_mode)
18097 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18098 if (op1mode != word_mode)
18099 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18100 operands[0] = dest;
18103 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18104 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18105 ;; caught for use by garbage collectors and the like. Using an insn that
18106 ;; maps to SIGILL makes it more likely the program will rightfully die.
18107 ;; Keeping with tradition, "6" is in honor of #UD.
18108 (define_insn "trap"
18109 [(trap_if (const_int 1) (const_int 6))]
18112 #ifdef HAVE_AS_IX86_UD2
18115 return ASM_SHORT "0x0b0f";
18118 [(set_attr "length" "2")])
18120 (define_expand "prefetch"
18121 [(prefetch (match_operand 0 "address_operand")
18122 (match_operand:SI 1 "const_int_operand")
18123 (match_operand:SI 2 "const_int_operand"))]
18124 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18126 bool write = INTVAL (operands[1]) != 0;
18127 int locality = INTVAL (operands[2]);
18129 gcc_assert (IN_RANGE (locality, 0, 3));
18131 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18132 supported by SSE counterpart or the SSE prefetch is not available
18133 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18135 if (TARGET_PREFETCHWT1 && write && locality <= 2)
18136 operands[2] = const2_rtx;
18137 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18138 operands[2] = GEN_INT (3);
18140 operands[1] = const0_rtx;
18143 (define_insn "*prefetch_sse"
18144 [(prefetch (match_operand 0 "address_operand" "p")
18146 (match_operand:SI 1 "const_int_operand"))]
18147 "TARGET_PREFETCH_SSE"
18149 static const char * const patterns[4] = {
18150 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18153 int locality = INTVAL (operands[1]);
18154 gcc_assert (IN_RANGE (locality, 0, 3));
18156 return patterns[locality];
18158 [(set_attr "type" "sse")
18159 (set_attr "atom_sse_attr" "prefetch")
18160 (set (attr "length_address")
18161 (symbol_ref "memory_address_length (operands[0], false)"))
18162 (set_attr "memory" "none")])
18164 (define_insn "*prefetch_3dnow"
18165 [(prefetch (match_operand 0 "address_operand" "p")
18166 (match_operand:SI 1 "const_int_operand" "n")
18170 if (INTVAL (operands[1]) == 0)
18171 return "prefetch\t%a0";
18173 return "prefetchw\t%a0";
18175 [(set_attr "type" "mmx")
18176 (set (attr "length_address")
18177 (symbol_ref "memory_address_length (operands[0], false)"))
18178 (set_attr "memory" "none")])
18180 (define_insn "*prefetch_prefetchwt1"
18181 [(prefetch (match_operand 0 "address_operand" "p")
18184 "TARGET_PREFETCHWT1"
18185 "prefetchwt1\t%a0";
18186 [(set_attr "type" "sse")
18187 (set (attr "length_address")
18188 (symbol_ref "memory_address_length (operands[0], false)"))
18189 (set_attr "memory" "none")])
18191 (define_expand "stack_protect_set"
18192 [(match_operand 0 "memory_operand")
18193 (match_operand 1 "memory_operand")]
18194 "TARGET_SSP_TLS_GUARD"
18196 rtx (*insn)(rtx, rtx);
18198 #ifdef TARGET_THREAD_SSP_OFFSET
18199 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18200 insn = (TARGET_LP64
18201 ? gen_stack_tls_protect_set_di
18202 : gen_stack_tls_protect_set_si);
18204 insn = (TARGET_LP64
18205 ? gen_stack_protect_set_di
18206 : gen_stack_protect_set_si);
18209 emit_insn (insn (operands[0], operands[1]));
18213 (define_insn "stack_protect_set_<mode>"
18214 [(set (match_operand:PTR 0 "memory_operand" "=m")
18215 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18217 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18218 (clobber (reg:CC FLAGS_REG))]
18219 "TARGET_SSP_TLS_GUARD"
18220 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18221 [(set_attr "type" "multi")])
18223 (define_insn "stack_tls_protect_set_<mode>"
18224 [(set (match_operand:PTR 0 "memory_operand" "=m")
18225 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18226 UNSPEC_SP_TLS_SET))
18227 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18228 (clobber (reg:CC FLAGS_REG))]
18230 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18231 [(set_attr "type" "multi")])
18233 (define_expand "stack_protect_test"
18234 [(match_operand 0 "memory_operand")
18235 (match_operand 1 "memory_operand")
18237 "TARGET_SSP_TLS_GUARD"
18239 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18241 rtx (*insn)(rtx, rtx, rtx);
18243 #ifdef TARGET_THREAD_SSP_OFFSET
18244 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18245 insn = (TARGET_LP64
18246 ? gen_stack_tls_protect_test_di
18247 : gen_stack_tls_protect_test_si);
18249 insn = (TARGET_LP64
18250 ? gen_stack_protect_test_di
18251 : gen_stack_protect_test_si);
18254 emit_insn (insn (flags, operands[0], operands[1]));
18256 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18257 flags, const0_rtx, operands[2]));
18261 (define_insn "stack_protect_test_<mode>"
18262 [(set (match_operand:CCZ 0 "flags_reg_operand")
18263 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18264 (match_operand:PTR 2 "memory_operand" "m")]
18266 (clobber (match_scratch:PTR 3 "=&r"))]
18267 "TARGET_SSP_TLS_GUARD"
18268 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18269 [(set_attr "type" "multi")])
18271 (define_insn "stack_tls_protect_test_<mode>"
18272 [(set (match_operand:CCZ 0 "flags_reg_operand")
18273 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18274 (match_operand:PTR 2 "const_int_operand" "i")]
18275 UNSPEC_SP_TLS_TEST))
18276 (clobber (match_scratch:PTR 3 "=r"))]
18278 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18279 [(set_attr "type" "multi")])
18281 (define_insn "sse4_2_crc32<mode>"
18282 [(set (match_operand:SI 0 "register_operand" "=r")
18284 [(match_operand:SI 1 "register_operand" "0")
18285 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18287 "TARGET_SSE4_2 || TARGET_CRC32"
18288 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18289 [(set_attr "type" "sselog1")
18290 (set_attr "prefix_rep" "1")
18291 (set_attr "prefix_extra" "1")
18292 (set (attr "prefix_data16")
18293 (if_then_else (match_operand:HI 2)
18295 (const_string "*")))
18296 (set (attr "prefix_rex")
18297 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18299 (const_string "*")))
18300 (set_attr "mode" "SI")])
18302 (define_insn "sse4_2_crc32di"
18303 [(set (match_operand:DI 0 "register_operand" "=r")
18305 [(match_operand:DI 1 "register_operand" "0")
18306 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18308 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18309 "crc32{q}\t{%2, %0|%0, %2}"
18310 [(set_attr "type" "sselog1")
18311 (set_attr "prefix_rep" "1")
18312 (set_attr "prefix_extra" "1")
18313 (set_attr "mode" "DI")])
18315 (define_insn "rdpmc"
18316 [(set (match_operand:DI 0 "register_operand" "=A")
18317 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18321 [(set_attr "type" "other")
18322 (set_attr "length" "2")])
18324 (define_insn "rdpmc_rex64"
18325 [(set (match_operand:DI 0 "register_operand" "=a")
18326 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18328 (set (match_operand:DI 1 "register_operand" "=d")
18329 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18332 [(set_attr "type" "other")
18333 (set_attr "length" "2")])
18335 (define_insn "rdtsc"
18336 [(set (match_operand:DI 0 "register_operand" "=A")
18337 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18340 [(set_attr "type" "other")
18341 (set_attr "length" "2")])
18343 (define_insn "rdtsc_rex64"
18344 [(set (match_operand:DI 0 "register_operand" "=a")
18345 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18346 (set (match_operand:DI 1 "register_operand" "=d")
18347 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18350 [(set_attr "type" "other")
18351 (set_attr "length" "2")])
18353 (define_insn "rdtscp"
18354 [(set (match_operand:DI 0 "register_operand" "=A")
18355 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18356 (set (match_operand:SI 1 "register_operand" "=c")
18357 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18360 [(set_attr "type" "other")
18361 (set_attr "length" "3")])
18363 (define_insn "rdtscp_rex64"
18364 [(set (match_operand:DI 0 "register_operand" "=a")
18365 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18366 (set (match_operand:DI 1 "register_operand" "=d")
18367 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18368 (set (match_operand:SI 2 "register_operand" "=c")
18369 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18372 [(set_attr "type" "other")
18373 (set_attr "length" "3")])
18375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18377 ;; FXSR, XSAVE and XSAVEOPT instructions
18379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18381 (define_insn "fxsave"
18382 [(set (match_operand:BLK 0 "memory_operand" "=m")
18383 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18386 [(set_attr "type" "other")
18387 (set_attr "memory" "store")
18388 (set (attr "length")
18389 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18391 (define_insn "fxsave64"
18392 [(set (match_operand:BLK 0 "memory_operand" "=m")
18393 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18394 "TARGET_64BIT && TARGET_FXSR"
18396 [(set_attr "type" "other")
18397 (set_attr "memory" "store")
18398 (set (attr "length")
18399 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18401 (define_insn "fxrstor"
18402 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18406 [(set_attr "type" "other")
18407 (set_attr "memory" "load")
18408 (set (attr "length")
18409 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18411 (define_insn "fxrstor64"
18412 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18413 UNSPECV_FXRSTOR64)]
18414 "TARGET_64BIT && TARGET_FXSR"
18416 [(set_attr "type" "other")
18417 (set_attr "memory" "load")
18418 (set (attr "length")
18419 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18421 (define_int_iterator ANY_XSAVE
18423 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18424 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18425 (UNSPECV_XSAVES "TARGET_XSAVES")])
18427 (define_int_iterator ANY_XSAVE64
18429 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18430 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18431 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18433 (define_int_attr xsave
18434 [(UNSPECV_XSAVE "xsave")
18435 (UNSPECV_XSAVE64 "xsave64")
18436 (UNSPECV_XSAVEOPT "xsaveopt")
18437 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18438 (UNSPECV_XSAVEC "xsavec")
18439 (UNSPECV_XSAVEC64 "xsavec64")
18440 (UNSPECV_XSAVES "xsaves")
18441 (UNSPECV_XSAVES64 "xsaves64")])
18443 (define_int_iterator ANY_XRSTOR
18445 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18447 (define_int_iterator ANY_XRSTOR64
18449 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18451 (define_int_attr xrstor
18452 [(UNSPECV_XRSTOR "xrstor")
18453 (UNSPECV_XRSTOR64 "xrstor")
18454 (UNSPECV_XRSTORS "xrstors")
18455 (UNSPECV_XRSTORS64 "xrstors")])
18457 (define_insn "<xsave>"
18458 [(set (match_operand:BLK 0 "memory_operand" "=m")
18459 (unspec_volatile:BLK
18460 [(match_operand:DI 1 "register_operand" "A")]
18462 "!TARGET_64BIT && TARGET_XSAVE"
18464 [(set_attr "type" "other")
18465 (set_attr "memory" "store")
18466 (set (attr "length")
18467 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18469 (define_insn "<xsave>_rex64"
18470 [(set (match_operand:BLK 0 "memory_operand" "=m")
18471 (unspec_volatile:BLK
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" "store")
18479 (set (attr "length")
18480 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18482 (define_insn "<xsave>"
18483 [(set (match_operand:BLK 0 "memory_operand" "=m")
18484 (unspec_volatile:BLK
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" "store")
18492 (set (attr "length")
18493 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18495 (define_insn "<xrstor>"
18496 [(unspec_volatile:BLK
18497 [(match_operand:BLK 0 "memory_operand" "m")
18498 (match_operand:DI 1 "register_operand" "A")]
18500 "!TARGET_64BIT && TARGET_XSAVE"
18502 [(set_attr "type" "other")
18503 (set_attr "memory" "load")
18504 (set (attr "length")
18505 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18507 (define_insn "<xrstor>_rex64"
18508 [(unspec_volatile:BLK
18509 [(match_operand:BLK 0 "memory_operand" "m")
18510 (match_operand:SI 1 "register_operand" "a")
18511 (match_operand:SI 2 "register_operand" "d")]
18513 "TARGET_64BIT && TARGET_XSAVE"
18515 [(set_attr "type" "other")
18516 (set_attr "memory" "load")
18517 (set (attr "length")
18518 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18520 (define_insn "<xrstor>64"
18521 [(unspec_volatile:BLK
18522 [(match_operand:BLK 0 "memory_operand" "m")
18523 (match_operand:SI 1 "register_operand" "a")
18524 (match_operand:SI 2 "register_operand" "d")]
18526 "TARGET_64BIT && TARGET_XSAVE"
18528 [(set_attr "type" "other")
18529 (set_attr "memory" "load")
18530 (set (attr "length")
18531 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18533 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18535 ;; Floating-point instructions for atomic compound assignments
18537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18539 ; Clobber all floating-point registers on environment save and restore
18540 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18541 (define_insn "fnstenv"
18542 [(set (match_operand:BLK 0 "memory_operand" "=m")
18543 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18544 (clobber (reg:HI FPCR_REG))
18545 (clobber (reg:XF ST0_REG))
18546 (clobber (reg:XF ST1_REG))
18547 (clobber (reg:XF ST2_REG))
18548 (clobber (reg:XF ST3_REG))
18549 (clobber (reg:XF ST4_REG))
18550 (clobber (reg:XF ST5_REG))
18551 (clobber (reg:XF ST6_REG))
18552 (clobber (reg:XF ST7_REG))]
18555 [(set_attr "type" "other")
18556 (set_attr "memory" "store")
18557 (set (attr "length")
18558 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18560 (define_insn "fldenv"
18561 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18563 (clobber (reg:CCFP FPSR_REG))
18564 (clobber (reg:HI FPCR_REG))
18565 (clobber (reg:XF ST0_REG))
18566 (clobber (reg:XF ST1_REG))
18567 (clobber (reg:XF ST2_REG))
18568 (clobber (reg:XF ST3_REG))
18569 (clobber (reg:XF ST4_REG))
18570 (clobber (reg:XF ST5_REG))
18571 (clobber (reg:XF ST6_REG))
18572 (clobber (reg:XF ST7_REG))]
18575 [(set_attr "type" "other")
18576 (set_attr "memory" "load")
18577 (set (attr "length")
18578 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18580 (define_insn "fnstsw"
18581 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18582 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18585 [(set_attr "type" "other,other")
18586 (set_attr "memory" "none,store")
18587 (set (attr "length")
18588 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18590 (define_insn "fnclex"
18591 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18594 [(set_attr "type" "other")
18595 (set_attr "memory" "none")
18596 (set_attr "length" "2")])
18598 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18600 ;; LWP instructions
18602 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18604 (define_expand "lwp_llwpcb"
18605 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18606 UNSPECV_LLWP_INTRINSIC)]
18609 (define_insn "*lwp_llwpcb<mode>1"
18610 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18611 UNSPECV_LLWP_INTRINSIC)]
18614 [(set_attr "type" "lwp")
18615 (set_attr "mode" "<MODE>")
18616 (set_attr "length" "5")])
18618 (define_expand "lwp_slwpcb"
18619 [(set (match_operand 0 "register_operand" "=r")
18620 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18625 insn = (Pmode == DImode
18627 : gen_lwp_slwpcbsi);
18629 emit_insn (insn (operands[0]));
18633 (define_insn "lwp_slwpcb<mode>"
18634 [(set (match_operand:P 0 "register_operand" "=r")
18635 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18638 [(set_attr "type" "lwp")
18639 (set_attr "mode" "<MODE>")
18640 (set_attr "length" "5")])
18642 (define_expand "lwp_lwpval<mode>3"
18643 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18644 (match_operand:SI 2 "nonimmediate_operand" "rm")
18645 (match_operand:SI 3 "const_int_operand" "i")]
18646 UNSPECV_LWPVAL_INTRINSIC)]
18648 ;; Avoid unused variable warning.
18649 "(void) operands[0];")
18651 (define_insn "*lwp_lwpval<mode>3_1"
18652 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18653 (match_operand:SI 1 "nonimmediate_operand" "rm")
18654 (match_operand:SI 2 "const_int_operand" "i")]
18655 UNSPECV_LWPVAL_INTRINSIC)]
18657 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18658 [(set_attr "type" "lwp")
18659 (set_attr "mode" "<MODE>")
18660 (set (attr "length")
18661 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18663 (define_expand "lwp_lwpins<mode>3"
18664 [(set (reg:CCC FLAGS_REG)
18665 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18666 (match_operand:SI 2 "nonimmediate_operand" "rm")
18667 (match_operand:SI 3 "const_int_operand" "i")]
18668 UNSPECV_LWPINS_INTRINSIC))
18669 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18670 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18673 (define_insn "*lwp_lwpins<mode>3_1"
18674 [(set (reg:CCC FLAGS_REG)
18675 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18676 (match_operand:SI 1 "nonimmediate_operand" "rm")
18677 (match_operand:SI 2 "const_int_operand" "i")]
18678 UNSPECV_LWPINS_INTRINSIC))]
18680 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18681 [(set_attr "type" "lwp")
18682 (set_attr "mode" "<MODE>")
18683 (set (attr "length")
18684 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18686 (define_int_iterator RDFSGSBASE
18690 (define_int_iterator WRFSGSBASE
18694 (define_int_attr fsgs
18695 [(UNSPECV_RDFSBASE "fs")
18696 (UNSPECV_RDGSBASE "gs")
18697 (UNSPECV_WRFSBASE "fs")
18698 (UNSPECV_WRGSBASE "gs")])
18700 (define_insn "rd<fsgs>base<mode>"
18701 [(set (match_operand:SWI48 0 "register_operand" "=r")
18702 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18703 "TARGET_64BIT && TARGET_FSGSBASE"
18705 [(set_attr "type" "other")
18706 (set_attr "prefix_extra" "2")])
18708 (define_insn "wr<fsgs>base<mode>"
18709 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18711 "TARGET_64BIT && TARGET_FSGSBASE"
18713 [(set_attr "type" "other")
18714 (set_attr "prefix_extra" "2")])
18716 (define_insn "rdrand<mode>_1"
18717 [(set (match_operand:SWI248 0 "register_operand" "=r")
18718 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18719 (set (reg:CCC FLAGS_REG)
18720 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18723 [(set_attr "type" "other")
18724 (set_attr "prefix_extra" "1")])
18726 (define_insn "rdseed<mode>_1"
18727 [(set (match_operand:SWI248 0 "register_operand" "=r")
18728 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18729 (set (reg:CCC FLAGS_REG)
18730 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18733 [(set_attr "type" "other")
18734 (set_attr "prefix_extra" "1")])
18736 (define_expand "pause"
18737 [(set (match_dup 0)
18738 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18741 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18742 MEM_VOLATILE_P (operands[0]) = 1;
18745 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18746 ;; They have the same encoding.
18747 (define_insn "*pause"
18748 [(set (match_operand:BLK 0)
18749 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18752 [(set_attr "length" "2")
18753 (set_attr "memory" "unknown")])
18755 (define_expand "xbegin"
18756 [(set (match_operand:SI 0 "register_operand")
18757 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18760 rtx_code_label *label = gen_label_rtx ();
18762 /* xbegin is emitted as jump_insn, so reload won't be able
18763 to reload its operand. Force the value into AX hard register. */
18764 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18765 emit_move_insn (ax_reg, constm1_rtx);
18767 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18769 emit_label (label);
18770 LABEL_NUSES (label) = 1;
18772 emit_move_insn (operands[0], ax_reg);
18777 (define_insn "xbegin_1"
18779 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18781 (label_ref (match_operand 1))
18783 (set (match_operand:SI 0 "register_operand" "+a")
18784 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18787 [(set_attr "type" "other")
18788 (set_attr "length" "6")])
18790 (define_insn "xend"
18791 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18794 [(set_attr "type" "other")
18795 (set_attr "length" "3")])
18797 (define_insn "xabort"
18798 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18802 [(set_attr "type" "other")
18803 (set_attr "length" "3")])
18805 (define_expand "xtest"
18806 [(set (match_operand:QI 0 "register_operand")
18807 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18810 emit_insn (gen_xtest_1 ());
18812 ix86_expand_setcc (operands[0], NE,
18813 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18817 (define_insn "xtest_1"
18818 [(set (reg:CCZ FLAGS_REG)
18819 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18822 [(set_attr "type" "other")
18823 (set_attr "length" "3")])
18825 (define_insn "pcommit"
18826 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18829 [(set_attr "type" "other")
18830 (set_attr "length" "4")])
18832 (define_insn "clwb"
18833 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18837 [(set_attr "type" "sse")
18838 (set_attr "atom_sse_attr" "fence")
18839 (set_attr "memory" "unknown")])
18841 (define_insn "clflushopt"
18842 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18843 UNSPECV_CLFLUSHOPT)]
18844 "TARGET_CLFLUSHOPT"
18846 [(set_attr "type" "sse")
18847 (set_attr "atom_sse_attr" "fence")
18848 (set_attr "memory" "unknown")])
18850 ;; MPX instructions
18852 (define_expand "<mode>_mk"
18853 [(set (match_operand:BND 0 "register_operand")
18857 [(match_operand:<bnd_ptr> 1 "register_operand")
18858 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18862 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18864 UNSPEC_BNDMK_ADDR);
18867 (define_insn "*<mode>_mk"
18868 [(set (match_operand:BND 0 "register_operand" "=w")
18870 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18872 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18873 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18874 UNSPEC_BNDMK_ADDR)])]
18877 "bndmk\t{%3, %0|%0, %3}"
18878 [(set_attr "type" "mpxmk")])
18880 (define_expand "mov<mode>"
18881 [(set (match_operand:BND 0 "general_operand")
18882 (match_operand:BND 1 "general_operand"))]
18885 ix86_expand_move (<MODE>mode, operands);DONE;
18888 (define_insn "*mov<mode>_internal_mpx"
18889 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18890 (match_operand:BND 1 "general_operand" "wm,w"))]
18892 "bndmov\t{%1, %0|%0, %1}"
18893 [(set_attr "type" "mpxmov")])
18895 (define_expand "<mode>_<bndcheck>"
18896 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18897 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18899 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18902 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18903 MEM_VOLATILE_P (operands[2]) = 1;
18906 (define_insn "*<mode>_<bndcheck>"
18907 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18908 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18909 (set (match_operand:BLK 2 "bnd_mem_operator")
18910 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18912 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18913 [(set_attr "type" "mpxchk")])
18915 (define_expand "<mode>_ldx"
18916 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18920 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18921 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18923 (use (mem:BLK (match_dup 1)))])]
18926 /* Avoid registers which connot be used as index. */
18927 if (!index_register_operand (operands[2], Pmode))
18929 rtx temp = gen_reg_rtx (Pmode);
18930 emit_move_insn (temp, operands[2]);
18931 operands[2] = temp;
18934 /* If it was a register originally then it may have
18935 mode other than Pmode. We need to extend in such
18936 case because bndldx may work only with Pmode regs. */
18937 if (GET_MODE (operands[2]) != Pmode)
18938 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18940 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18942 UNSPEC_BNDLDX_ADDR);
18945 (define_insn "*<mode>_ldx"
18946 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18948 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18950 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18951 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18952 UNSPEC_BNDLDX_ADDR)])]
18954 (use (mem:BLK (match_dup 1)))])]
18956 "bndldx\t{%3, %0|%0, %3}"
18957 [(set_attr "type" "mpxld")])
18959 (define_expand "<mode>_stx"
18960 [(parallel [(unspec [(mem:<bnd_ptr>
18962 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18963 (match_operand:<bnd_ptr> 1 "register_operand")]))
18964 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18966 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18969 /* Avoid registers which connot be used as index. */
18970 if (!index_register_operand (operands[1], Pmode))
18972 rtx temp = gen_reg_rtx (Pmode);
18973 emit_move_insn (temp, operands[1]);
18974 operands[1] = temp;
18977 /* If it was a register originally then it may have
18978 mode other than Pmode. We need to extend in such
18979 case because bndstx may work only with Pmode regs. */
18980 if (GET_MODE (operands[1]) != Pmode)
18981 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18983 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18985 UNSPEC_BNDLDX_ADDR);
18986 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18987 MEM_VOLATILE_P (operands[4]) = 1;
18990 (define_insn "*<mode>_stx"
18991 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18993 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18994 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18995 UNSPEC_BNDLDX_ADDR)])
18996 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18997 (set (match_operand:BLK 4 "bnd_mem_operator")
18998 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19000 "bndstx\t{%2, %3|%3, %2}"
19001 [(set_attr "type" "mpxst")])
19003 (define_insn "move_size_reloc_<mode>"
19004 [(set (match_operand:SWI48 0 "register_operand" "=r")
19006 [(match_operand:SWI48 1 "symbol_operand")]
19010 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19011 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19013 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19015 [(set_attr "type" "imov")
19016 (set_attr "mode" "<MODE>")])
19020 (include "sync.md")