1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 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_speed" "" (const_int 1))
821 ;; Describe a user's asm statement.
822 (define_asm_attributes
823 [(set_attr "length" "128")
824 (set_attr "type" "multi")])
826 (define_code_iterator plusminus [plus minus])
828 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
830 (define_code_iterator multdiv [mult div])
832 ;; Base name for define_insn
833 (define_code_attr plusminus_insn
834 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
835 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
837 ;; Base name for insn mnemonic.
838 (define_code_attr plusminus_mnemonic
839 [(plus "add") (ss_plus "adds") (us_plus "addus")
840 (minus "sub") (ss_minus "subs") (us_minus "subus")])
841 (define_code_attr plusminus_carry_mnemonic
842 [(plus "adc") (minus "sbb")])
843 (define_code_attr multdiv_mnemonic
844 [(mult "mul") (div "div")])
846 ;; Mark commutative operators as such in constraints.
847 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
848 (minus "") (ss_minus "") (us_minus "")])
850 ;; Mapping of max and min
851 (define_code_iterator maxmin [smax smin umax umin])
853 ;; Mapping of signed max and min
854 (define_code_iterator smaxmin [smax smin])
856 ;; Mapping of unsigned max and min
857 (define_code_iterator umaxmin [umax umin])
859 ;; Base name for integer and FP insn mnemonic
860 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
861 (umax "maxu") (umin "minu")])
862 (define_code_attr maxmin_float [(smax "max") (smin "min")])
864 ;; Mapping of logic operators
865 (define_code_iterator any_logic [and ior xor])
866 (define_code_iterator any_or [ior xor])
867 (define_code_iterator fpint_logic [and xor])
869 ;; Base name for insn mnemonic.
870 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
872 ;; Mapping of logic-shift operators
873 (define_code_iterator any_lshift [ashift lshiftrt])
875 ;; Mapping of shift-right operators
876 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
878 ;; Mapping of all shift operators
879 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
881 ;; Base name for define_insn
882 (define_code_attr shift_insn
883 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
885 ;; Base name for insn mnemonic.
886 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
887 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
889 ;; Mapping of rotate operators
890 (define_code_iterator any_rotate [rotate rotatert])
892 ;; Base name for define_insn
893 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
895 ;; Base name for insn mnemonic.
896 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
898 ;; Mapping of abs neg operators
899 (define_code_iterator absneg [abs neg])
901 ;; Base name for x87 insn mnemonic.
902 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
904 ;; Used in signed and unsigned widening multiplications.
905 (define_code_iterator any_extend [sign_extend zero_extend])
907 ;; Prefix for insn menmonic.
908 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
910 ;; Prefix for define_insn
911 (define_code_attr u [(sign_extend "") (zero_extend "u")])
912 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
913 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
915 ;; Used in signed and unsigned truncations.
916 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
917 ;; Instruction suffix for truncations.
918 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
920 ;; Used in signed and unsigned fix.
921 (define_code_iterator any_fix [fix unsigned_fix])
922 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
924 ;; Used in signed and unsigned float.
925 (define_code_iterator any_float [float unsigned_float])
926 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
928 ;; All integer modes.
929 (define_mode_iterator SWI1248x [QI HI SI DI])
931 ;; All integer modes with AVX512BW.
932 (define_mode_iterator SWI1248_AVX512BW
933 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
935 ;; All integer modes without QImode.
936 (define_mode_iterator SWI248x [HI SI DI])
938 ;; All integer modes without QImode and HImode.
939 (define_mode_iterator SWI48x [SI DI])
941 ;; All integer modes without SImode and DImode.
942 (define_mode_iterator SWI12 [QI HI])
944 ;; All integer modes without DImode.
945 (define_mode_iterator SWI124 [QI HI SI])
947 ;; All integer modes without QImode and DImode.
948 (define_mode_iterator SWI24 [HI SI])
950 ;; Single word integer modes.
951 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
953 ;; Single word integer modes without QImode.
954 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
956 ;; Single word integer modes without QImode and HImode.
957 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
959 ;; All math-dependant single and double word integer modes.
960 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
961 (HI "TARGET_HIMODE_MATH")
962 SI DI (TI "TARGET_64BIT")])
964 ;; Math-dependant single word integer modes.
965 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
966 (HI "TARGET_HIMODE_MATH")
967 SI (DI "TARGET_64BIT")])
969 ;; Math-dependant integer modes without DImode.
970 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
971 (HI "TARGET_HIMODE_MATH")
974 ;; Math-dependant single word integer modes without QImode.
975 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
976 SI (DI "TARGET_64BIT")])
978 ;; Double word integer modes.
979 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
980 (TI "TARGET_64BIT")])
982 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
983 ;; compile time constant, it is faster to use <MODE_SIZE> than
984 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
985 ;; command line options just use GET_MODE_SIZE macro.
986 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
987 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
988 (V16QI "16") (V32QI "32") (V64QI "64")
989 (V8HI "16") (V16HI "32") (V32HI "64")
990 (V4SI "16") (V8SI "32") (V16SI "64")
991 (V2DI "16") (V4DI "32") (V8DI "64")
992 (V1TI "16") (V2TI "32") (V4TI "64")
993 (V2DF "16") (V4DF "32") (V8DF "64")
994 (V4SF "16") (V8SF "32") (V16SF "64")])
996 ;; Double word integer modes as mode attribute.
997 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
998 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1000 ;; Half mode for double word integer modes.
1001 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1002 (DI "TARGET_64BIT")])
1005 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1006 (BND64 "TARGET_LP64")])
1008 ;; Pointer mode corresponding to bound mode.
1009 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1012 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1015 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1017 (UNSPEC_BNDCN "cn")])
1019 ;; Instruction suffix for integer modes.
1020 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1022 ;; Instruction suffix for masks.
1023 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1025 ;; Pointer size prefix for integer modes (Intel asm dialect)
1026 (define_mode_attr iptrsize [(QI "BYTE")
1031 ;; Register class for integer modes.
1032 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1034 ;; Immediate operand constraint for integer modes.
1035 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1037 ;; General operand constraint for word modes.
1038 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1040 ;; Immediate operand constraint for double integer modes.
1041 (define_mode_attr di [(SI "nF") (DI "e")])
1043 ;; Immediate operand constraint for shifts.
1044 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1046 ;; General operand predicate for integer modes.
1047 (define_mode_attr general_operand
1048 [(QI "general_operand")
1049 (HI "general_operand")
1050 (SI "x86_64_general_operand")
1051 (DI "x86_64_general_operand")
1052 (TI "x86_64_general_operand")])
1054 ;; General sign extend operand predicate for integer modes,
1055 ;; which disallows VOIDmode operands and thus it is suitable
1056 ;; for use inside sign_extend.
1057 (define_mode_attr general_sext_operand
1058 [(QI "sext_operand")
1060 (SI "x86_64_sext_operand")
1061 (DI "x86_64_sext_operand")])
1063 ;; General sign/zero extend operand predicate for integer modes.
1064 (define_mode_attr general_szext_operand
1065 [(QI "general_operand")
1066 (HI "general_operand")
1067 (SI "x86_64_szext_general_operand")
1068 (DI "x86_64_szext_general_operand")])
1070 ;; Immediate operand predicate for integer modes.
1071 (define_mode_attr immediate_operand
1072 [(QI "immediate_operand")
1073 (HI "immediate_operand")
1074 (SI "x86_64_immediate_operand")
1075 (DI "x86_64_immediate_operand")])
1077 ;; Nonmemory operand predicate for integer modes.
1078 (define_mode_attr nonmemory_operand
1079 [(QI "nonmemory_operand")
1080 (HI "nonmemory_operand")
1081 (SI "x86_64_nonmemory_operand")
1082 (DI "x86_64_nonmemory_operand")])
1084 ;; Operand predicate for shifts.
1085 (define_mode_attr shift_operand
1086 [(QI "nonimmediate_operand")
1087 (HI "nonimmediate_operand")
1088 (SI "nonimmediate_operand")
1089 (DI "shiftdi_operand")
1090 (TI "register_operand")])
1092 ;; Operand predicate for shift argument.
1093 (define_mode_attr shift_immediate_operand
1094 [(QI "const_1_to_31_operand")
1095 (HI "const_1_to_31_operand")
1096 (SI "const_1_to_31_operand")
1097 (DI "const_1_to_63_operand")])
1099 ;; Input operand predicate for arithmetic left shifts.
1100 (define_mode_attr ashl_input_operand
1101 [(QI "nonimmediate_operand")
1102 (HI "nonimmediate_operand")
1103 (SI "nonimmediate_operand")
1104 (DI "ashldi_input_operand")
1105 (TI "reg_or_pm1_operand")])
1107 ;; SSE and x87 SFmode and DFmode floating point modes
1108 (define_mode_iterator MODEF [SF DF])
1110 ;; All x87 floating point modes
1111 (define_mode_iterator X87MODEF [SF DF XF])
1113 ;; SSE instruction suffix for various modes
1114 (define_mode_attr ssemodesuffix
1115 [(SF "ss") (DF "sd")
1116 (V16SF "ps") (V8DF "pd")
1117 (V8SF "ps") (V4DF "pd")
1118 (V4SF "ps") (V2DF "pd")
1119 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1120 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1121 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1123 ;; SSE vector suffix for floating point modes
1124 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1126 ;; SSE vector mode corresponding to a scalar mode
1127 (define_mode_attr ssevecmode
1128 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1129 (define_mode_attr ssevecmodelower
1130 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1132 ;; Instruction suffix for REX 64bit operators.
1133 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1135 ;; This mode iterator allows :P to be used for patterns that operate on
1136 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1137 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1139 ;; This mode iterator allows :W to be used for patterns that operate on
1140 ;; word_mode sized quantities.
1141 (define_mode_iterator W
1142 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1144 ;; This mode iterator allows :PTR to be used for patterns that operate on
1145 ;; ptr_mode sized quantities.
1146 (define_mode_iterator PTR
1147 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1149 ;; Scheduling descriptions
1151 (include "pentium.md")
1154 (include "athlon.md")
1155 (include "bdver1.md")
1156 (include "bdver3.md")
1157 (include "btver2.md")
1158 (include "geode.md")
1161 (include "core2.md")
1164 ;; Operand and operator predicates and constraints
1166 (include "predicates.md")
1167 (include "constraints.md")
1170 ;; Compare and branch/compare and store instructions.
1172 (define_expand "cbranch<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1175 (match_operand:SDWIM 2 "<general_operand>")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ordered_comparison_operator"
1178 [(reg:CC FLAGS_REG) (const_int 0)])
1179 (label_ref (match_operand 3))
1183 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1184 operands[1] = force_reg (<MODE>mode, operands[1]);
1185 ix86_expand_branch (GET_CODE (operands[0]),
1186 operands[1], operands[2], operands[3]);
1190 (define_expand "cstore<mode>4"
1191 [(set (reg:CC FLAGS_REG)
1192 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1193 (match_operand:SWIM 3 "<general_operand>")))
1194 (set (match_operand:QI 0 "register_operand")
1195 (match_operator 1 "ordered_comparison_operator"
1196 [(reg:CC FLAGS_REG) (const_int 0)]))]
1199 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1200 operands[2] = force_reg (<MODE>mode, operands[2]);
1201 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1202 operands[2], operands[3]);
1206 (define_expand "cmp<mode>_1"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1209 (match_operand:SWI48 1 "<general_operand>")))])
1211 (define_insn "*cmp<mode>_ccno_1"
1212 [(set (reg FLAGS_REG)
1213 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1214 (match_operand:SWI 1 "const0_operand")))]
1215 "ix86_match_ccmode (insn, CCNOmode)"
1217 test{<imodesuffix>}\t%0, %0
1218 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1219 [(set_attr "type" "test,icmp")
1220 (set_attr "length_immediate" "0,1")
1221 (set_attr "mode" "<MODE>")])
1223 (define_insn "*cmp<mode>_1"
1224 [(set (reg FLAGS_REG)
1225 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1226 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1227 "ix86_match_ccmode (insn, CCmode)"
1228 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1229 [(set_attr "type" "icmp")
1230 (set_attr "mode" "<MODE>")])
1232 (define_insn "*cmp<mode>_minus_1"
1233 [(set (reg FLAGS_REG)
1235 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1236 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1238 "ix86_match_ccmode (insn, CCGOCmode)"
1239 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1240 [(set_attr "type" "icmp")
1241 (set_attr "mode" "<MODE>")])
1243 (define_insn "*cmpqi_ext_1"
1244 [(set (reg FLAGS_REG)
1246 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1249 (match_operand 1 "ext_register_operand" "Q,Q")
1251 (const_int 8)) 0)))]
1252 "ix86_match_ccmode (insn, CCmode)"
1253 "cmp{b}\t{%h1, %0|%0, %h1}"
1254 [(set_attr "isa" "*,nox64")
1255 (set_attr "type" "icmp")
1256 (set_attr "mode" "QI")])
1258 (define_insn "*cmpqi_ext_2"
1259 [(set (reg FLAGS_REG)
1263 (match_operand 0 "ext_register_operand" "Q")
1266 (match_operand:QI 1 "const0_operand")))]
1267 "ix86_match_ccmode (insn, CCNOmode)"
1269 [(set_attr "type" "test")
1270 (set_attr "length_immediate" "0")
1271 (set_attr "mode" "QI")])
1273 (define_expand "cmpqi_ext_3"
1274 [(set (reg:CC FLAGS_REG)
1278 (match_operand 0 "ext_register_operand")
1281 (match_operand:QI 1 "const_int_operand")))])
1283 (define_insn "*cmpqi_ext_3"
1284 [(set (reg FLAGS_REG)
1288 (match_operand 0 "ext_register_operand" "Q,Q")
1291 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1292 "ix86_match_ccmode (insn, CCmode)"
1293 "cmp{b}\t{%1, %h0|%h0, %1}"
1294 [(set_attr "isa" "*,nox64")
1295 (set_attr "type" "icmp")
1296 (set_attr "modrm" "1")
1297 (set_attr "mode" "QI")])
1299 (define_insn "*cmpqi_ext_4"
1300 [(set (reg FLAGS_REG)
1304 (match_operand 0 "ext_register_operand" "Q")
1309 (match_operand 1 "ext_register_operand" "Q")
1311 (const_int 8)) 0)))]
1312 "ix86_match_ccmode (insn, CCmode)"
1313 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1314 [(set_attr "type" "icmp")
1315 (set_attr "mode" "QI")])
1317 ;; These implement float point compares.
1318 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1319 ;; which would allow mix and match FP modes on the compares. Which is what
1320 ;; the old patterns did, but with many more of them.
1322 (define_expand "cbranchxf4"
1323 [(set (reg:CC FLAGS_REG)
1324 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1325 (match_operand:XF 2 "nonmemory_operand")))
1326 (set (pc) (if_then_else
1327 (match_operator 0 "ix86_fp_comparison_operator"
1330 (label_ref (match_operand 3))
1334 ix86_expand_branch (GET_CODE (operands[0]),
1335 operands[1], operands[2], operands[3]);
1339 (define_expand "cstorexf4"
1340 [(set (reg:CC FLAGS_REG)
1341 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1342 (match_operand:XF 3 "nonmemory_operand")))
1343 (set (match_operand:QI 0 "register_operand")
1344 (match_operator 1 "ix86_fp_comparison_operator"
1349 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1350 operands[2], operands[3]);
1354 (define_expand "cbranch<mode>4"
1355 [(set (reg:CC FLAGS_REG)
1356 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1357 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1358 (set (pc) (if_then_else
1359 (match_operator 0 "ix86_fp_comparison_operator"
1362 (label_ref (match_operand 3))
1364 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1366 ix86_expand_branch (GET_CODE (operands[0]),
1367 operands[1], operands[2], operands[3]);
1371 (define_expand "cstore<mode>4"
1372 [(set (reg:CC FLAGS_REG)
1373 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1374 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1375 (set (match_operand:QI 0 "register_operand")
1376 (match_operator 1 "ix86_fp_comparison_operator"
1379 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1381 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1382 operands[2], operands[3]);
1386 (define_expand "cbranchcc4"
1387 [(set (pc) (if_then_else
1388 (match_operator 0 "comparison_operator"
1389 [(match_operand 1 "flags_reg_operand")
1390 (match_operand 2 "const0_operand")])
1391 (label_ref (match_operand 3))
1395 ix86_expand_branch (GET_CODE (operands[0]),
1396 operands[1], operands[2], operands[3]);
1400 (define_expand "cstorecc4"
1401 [(set (match_operand:QI 0 "register_operand")
1402 (match_operator 1 "comparison_operator"
1403 [(match_operand 2 "flags_reg_operand")
1404 (match_operand 3 "const0_operand")]))]
1407 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1408 operands[2], operands[3]);
1413 ;; FP compares, step 1:
1414 ;; Set the FP condition codes.
1416 ;; CCFPmode compare with exceptions
1417 ;; CCFPUmode compare with no exceptions
1419 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1420 ;; used to manage the reg stack popping would not be preserved.
1422 (define_insn "*cmp<mode>_0_i387"
1423 [(set (match_operand:HI 0 "register_operand" "=a")
1426 (match_operand:X87MODEF 1 "register_operand" "f")
1427 (match_operand:X87MODEF 2 "const0_operand"))]
1430 "* return output_fp_compare (insn, operands, false, false);"
1431 [(set_attr "type" "multi")
1432 (set_attr "unit" "i387")
1433 (set_attr "mode" "<MODE>")])
1435 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1436 [(set (reg:CCFP FLAGS_REG)
1438 (match_operand:X87MODEF 1 "register_operand" "f")
1439 (match_operand:X87MODEF 2 "const0_operand")))
1440 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1441 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1443 "&& reload_completed"
1446 [(compare:CCFP (match_dup 1)(match_dup 2))]
1448 (set (reg:CC FLAGS_REG)
1449 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1451 [(set_attr "type" "multi")
1452 (set_attr "unit" "i387")
1453 (set_attr "mode" "<MODE>")])
1455 (define_insn "*cmpxf_i387"
1456 [(set (match_operand:HI 0 "register_operand" "=a")
1459 (match_operand:XF 1 "register_operand" "f")
1460 (match_operand:XF 2 "register_operand" "f"))]
1463 "* return output_fp_compare (insn, operands, false, false);"
1464 [(set_attr "type" "multi")
1465 (set_attr "unit" "i387")
1466 (set_attr "mode" "XF")])
1468 (define_insn_and_split "*cmpxf_cc_i387"
1469 [(set (reg:CCFP FLAGS_REG)
1471 (match_operand:XF 1 "register_operand" "f")
1472 (match_operand:XF 2 "register_operand" "f")))
1473 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1474 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1476 "&& reload_completed"
1479 [(compare:CCFP (match_dup 1)(match_dup 2))]
1481 (set (reg:CC FLAGS_REG)
1482 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1484 [(set_attr "type" "multi")
1485 (set_attr "unit" "i387")
1486 (set_attr "mode" "XF")])
1488 (define_insn "*cmp<mode>_i387"
1489 [(set (match_operand:HI 0 "register_operand" "=a")
1492 (match_operand:MODEF 1 "register_operand" "f")
1493 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1496 "* return output_fp_compare (insn, operands, false, false);"
1497 [(set_attr "type" "multi")
1498 (set_attr "unit" "i387")
1499 (set_attr "mode" "<MODE>")])
1501 (define_insn_and_split "*cmp<mode>_cc_i387"
1502 [(set (reg:CCFP FLAGS_REG)
1504 (match_operand:MODEF 1 "register_operand" "f")
1505 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1506 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1507 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1509 "&& reload_completed"
1512 [(compare:CCFP (match_dup 1)(match_dup 2))]
1514 (set (reg:CC FLAGS_REG)
1515 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1517 [(set_attr "type" "multi")
1518 (set_attr "unit" "i387")
1519 (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmpu<mode>_i387"
1522 [(set (match_operand:HI 0 "register_operand" "=a")
1525 (match_operand:X87MODEF 1 "register_operand" "f")
1526 (match_operand:X87MODEF 2 "register_operand" "f"))]
1529 "* return output_fp_compare (insn, operands, false, true);"
1530 [(set_attr "type" "multi")
1531 (set_attr "unit" "i387")
1532 (set_attr "mode" "<MODE>")])
1534 (define_insn_and_split "*cmpu<mode>_cc_i387"
1535 [(set (reg:CCFPU FLAGS_REG)
1537 (match_operand:X87MODEF 1 "register_operand" "f")
1538 (match_operand:X87MODEF 2 "register_operand" "f")))
1539 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1540 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1542 "&& reload_completed"
1545 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1547 (set (reg:CC FLAGS_REG)
1548 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "mode" "<MODE>")])
1554 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1558 (match_operand:X87MODEF 1 "register_operand" "f")
1559 (match_operator:X87MODEF 3 "float_operator"
1560 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1563 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1564 || optimize_function_for_size_p (cfun))"
1565 "* return output_fp_compare (insn, operands, false, false);"
1566 [(set_attr "type" "multi")
1567 (set_attr "unit" "i387")
1568 (set_attr "fp_int_src" "true")
1569 (set_attr "mode" "<SWI24:MODE>")])
1571 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1572 [(set (reg:CCFP FLAGS_REG)
1574 (match_operand:X87MODEF 1 "register_operand" "f")
1575 (match_operator:X87MODEF 3 "float_operator"
1576 [(match_operand:SWI24 2 "memory_operand" "m")])))
1577 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1578 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1579 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1580 || optimize_function_for_size_p (cfun))"
1582 "&& reload_completed"
1587 (match_op_dup 3 [(match_dup 2)]))]
1589 (set (reg:CC FLAGS_REG)
1590 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1592 [(set_attr "type" "multi")
1593 (set_attr "unit" "i387")
1594 (set_attr "fp_int_src" "true")
1595 (set_attr "mode" "<SWI24:MODE>")])
1597 ;; FP compares, step 2
1598 ;; Move the fpsw to ax.
1600 (define_insn "x86_fnstsw_1"
1601 [(set (match_operand:HI 0 "register_operand" "=a")
1602 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1605 [(set_attr "length" "2")
1606 (set_attr "mode" "SI")
1607 (set_attr "unit" "i387")])
1609 ;; FP compares, step 3
1610 ;; Get ax into flags, general case.
1612 (define_insn "x86_sahf_1"
1613 [(set (reg:CC FLAGS_REG)
1614 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1618 #ifndef HAVE_AS_IX86_SAHF
1620 return ASM_BYTE "0x9e";
1625 [(set_attr "length" "1")
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "direct")
1628 (set_attr "bdver1_decode" "direct")
1629 (set_attr "mode" "SI")])
1631 ;; Pentium Pro can do steps 1 through 3 in one go.
1632 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1633 ;; (these i387 instructions set flags directly)
1635 (define_mode_iterator FPCMP [CCFP CCFPU])
1636 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1638 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1639 [(set (reg:FPCMP FLAGS_REG)
1641 (match_operand:MODEF 0 "register_operand" "f,x")
1642 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1643 "TARGET_MIX_SSE_I387
1644 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1645 "* return output_fp_compare (insn, operands, true,
1646 <FPCMP:MODE>mode == CCFPUmode);"
1647 [(set_attr "type" "fcmp,ssecomi")
1648 (set_attr "prefix" "orig,maybe_vex")
1649 (set_attr "mode" "<MODEF:MODE>")
1650 (set (attr "prefix_rep")
1651 (if_then_else (eq_attr "type" "ssecomi")
1653 (const_string "*")))
1654 (set (attr "prefix_data16")
1655 (cond [(eq_attr "type" "fcmp")
1657 (eq_attr "mode" "DF")
1660 (const_string "0")))
1661 (set_attr "athlon_decode" "vector")
1662 (set_attr "amdfam10_decode" "direct")
1663 (set_attr "bdver1_decode" "double")])
1665 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1666 [(set (reg:FPCMP FLAGS_REG)
1668 (match_operand:MODEF 0 "register_operand" "x")
1669 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1671 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1672 "* return output_fp_compare (insn, operands, true,
1673 <FPCMP:MODE>mode == CCFPUmode);"
1674 [(set_attr "type" "ssecomi")
1675 (set_attr "prefix" "maybe_vex")
1676 (set_attr "mode" "<MODEF:MODE>")
1677 (set_attr "prefix_rep" "0")
1678 (set (attr "prefix_data16")
1679 (if_then_else (eq_attr "mode" "DF")
1681 (const_string "0")))
1682 (set_attr "athlon_decode" "vector")
1683 (set_attr "amdfam10_decode" "direct")
1684 (set_attr "bdver1_decode" "double")])
1686 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1687 [(set (reg:FPCMP FLAGS_REG)
1689 (match_operand:X87MODEF 0 "register_operand" "f")
1690 (match_operand:X87MODEF 1 "register_operand" "f")))]
1691 "TARGET_80387 && TARGET_CMOVE
1692 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1693 "* return output_fp_compare (insn, operands, true,
1694 <FPCMP:MODE>mode == CCFPUmode);"
1695 [(set_attr "type" "fcmp")
1696 (set_attr "mode" "<X87MODEF:MODE>")
1697 (set_attr "athlon_decode" "vector")
1698 (set_attr "amdfam10_decode" "direct")
1699 (set_attr "bdver1_decode" "double")])
1701 ;; Push/pop instructions.
1703 (define_insn "*push<mode>2"
1704 [(set (match_operand:DWI 0 "push_operand" "=<")
1705 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1708 [(set_attr "type" "multi")
1709 (set_attr "mode" "<MODE>")])
1712 [(set (match_operand:TI 0 "push_operand")
1713 (match_operand:TI 1 "general_operand"))]
1714 "TARGET_64BIT && reload_completed
1715 && !SSE_REG_P (operands[1])"
1717 "ix86_split_long_move (operands); DONE;")
1719 (define_insn "*pushdi2_rex64"
1720 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1721 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1726 [(set_attr "type" "push,multi")
1727 (set_attr "mode" "DI")])
1729 ;; Convert impossible pushes of immediate to existing instructions.
1730 ;; First try to get scratch register and go through it. In case this
1731 ;; fails, push sign extended lower part first and then overwrite
1732 ;; upper part by 32bit move.
1734 [(match_scratch:DI 2 "r")
1735 (set (match_operand:DI 0 "push_operand")
1736 (match_operand:DI 1 "immediate_operand"))]
1737 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1738 && !x86_64_immediate_operand (operands[1], DImode)"
1739 [(set (match_dup 2) (match_dup 1))
1740 (set (match_dup 0) (match_dup 2))])
1742 ;; We need to define this as both peepholer and splitter for case
1743 ;; peephole2 pass is not run.
1744 ;; "&& 1" is needed to keep it from matching the previous pattern.
1746 [(set (match_operand:DI 0 "push_operand")
1747 (match_operand:DI 1 "immediate_operand"))]
1748 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1749 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1750 [(set (match_dup 0) (match_dup 1))
1751 (set (match_dup 2) (match_dup 3))]
1753 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1755 operands[1] = gen_lowpart (DImode, operands[2]);
1756 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1761 [(set (match_operand:DI 0 "push_operand")
1762 (match_operand:DI 1 "immediate_operand"))]
1763 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1764 ? epilogue_completed : reload_completed)
1765 && !symbolic_operand (operands[1], DImode)
1766 && !x86_64_immediate_operand (operands[1], DImode)"
1767 [(set (match_dup 0) (match_dup 1))
1768 (set (match_dup 2) (match_dup 3))]
1770 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1772 operands[1] = gen_lowpart (DImode, operands[2]);
1773 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1778 [(set (match_operand:DI 0 "push_operand")
1779 (match_operand:DI 1 "general_operand"))]
1780 "!TARGET_64BIT && reload_completed
1781 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1783 "ix86_split_long_move (operands); DONE;")
1785 (define_insn "*pushsi2"
1786 [(set (match_operand:SI 0 "push_operand" "=<")
1787 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1790 [(set_attr "type" "push")
1791 (set_attr "mode" "SI")])
1793 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1794 ;; "push a byte/word". But actually we use pushl, which has the effect
1795 ;; of rounding the amount pushed up to a word.
1797 ;; For TARGET_64BIT we always round up to 8 bytes.
1798 (define_insn "*push<mode>2_rex64"
1799 [(set (match_operand:SWI124 0 "push_operand" "=X")
1800 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1803 [(set_attr "type" "push")
1804 (set_attr "mode" "DI")])
1806 (define_insn "*push<mode>2"
1807 [(set (match_operand:SWI12 0 "push_operand" "=X")
1808 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1811 [(set_attr "type" "push")
1812 (set_attr "mode" "SI")])
1814 (define_insn "*push<mode>2_prologue"
1815 [(set (match_operand:W 0 "push_operand" "=<")
1816 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1817 (clobber (mem:BLK (scratch)))]
1819 "push{<imodesuffix>}\t%1"
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "<MODE>")])
1823 (define_insn "*pop<mode>1"
1824 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1825 (match_operand:W 1 "pop_operand" ">"))]
1827 "pop{<imodesuffix>}\t%0"
1828 [(set_attr "type" "pop")
1829 (set_attr "mode" "<MODE>")])
1831 (define_insn "*pop<mode>1_epilogue"
1832 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1833 (match_operand:W 1 "pop_operand" ">"))
1834 (clobber (mem:BLK (scratch)))]
1836 "pop{<imodesuffix>}\t%0"
1837 [(set_attr "type" "pop")
1838 (set_attr "mode" "<MODE>")])
1840 (define_insn "*pushfl<mode>2"
1841 [(set (match_operand:W 0 "push_operand" "=<")
1842 (match_operand:W 1 "flags_reg_operand"))]
1844 "pushf{<imodesuffix>}"
1845 [(set_attr "type" "push")
1846 (set_attr "mode" "<MODE>")])
1848 (define_insn "*popfl<mode>1"
1849 [(set (match_operand:W 0 "flags_reg_operand")
1850 (match_operand:W 1 "pop_operand" ">"))]
1852 "popf{<imodesuffix>}"
1853 [(set_attr "type" "pop")
1854 (set_attr "mode" "<MODE>")])
1857 ;; Move instructions.
1859 (define_expand "movxi"
1860 [(set (match_operand:XI 0 "nonimmediate_operand")
1861 (match_operand:XI 1 "general_operand"))]
1863 "ix86_expand_move (XImode, operands); DONE;")
1865 ;; Reload patterns to support multi-word load/store
1866 ;; with non-offsetable address.
1867 (define_expand "reload_noff_store"
1868 [(parallel [(match_operand 0 "memory_operand" "=m")
1869 (match_operand 1 "register_operand" "r")
1870 (match_operand:DI 2 "register_operand" "=&r")])]
1873 rtx mem = operands[0];
1874 rtx addr = XEXP (mem, 0);
1876 emit_move_insn (operands[2], addr);
1877 mem = replace_equiv_address_nv (mem, operands[2]);
1879 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1883 (define_expand "reload_noff_load"
1884 [(parallel [(match_operand 0 "register_operand" "=r")
1885 (match_operand 1 "memory_operand" "m")
1886 (match_operand:DI 2 "register_operand" "=r")])]
1889 rtx mem = operands[1];
1890 rtx addr = XEXP (mem, 0);
1892 emit_move_insn (operands[2], addr);
1893 mem = replace_equiv_address_nv (mem, operands[2]);
1895 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1899 (define_expand "movoi"
1900 [(set (match_operand:OI 0 "nonimmediate_operand")
1901 (match_operand:OI 1 "general_operand"))]
1903 "ix86_expand_move (OImode, operands); DONE;")
1905 (define_expand "movti"
1906 [(set (match_operand:TI 0 "nonimmediate_operand")
1907 (match_operand:TI 1 "nonimmediate_operand"))]
1908 "TARGET_64BIT || TARGET_SSE"
1911 ix86_expand_move (TImode, operands);
1913 ix86_expand_vector_move (TImode, operands);
1917 ;; This expands to what emit_move_complex would generate if we didn't
1918 ;; have a movti pattern. Having this avoids problems with reload on
1919 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1920 ;; to have around all the time.
1921 (define_expand "movcdi"
1922 [(set (match_operand:CDI 0 "nonimmediate_operand")
1923 (match_operand:CDI 1 "general_operand"))]
1926 if (push_operand (operands[0], CDImode))
1927 emit_move_complex_push (CDImode, operands[0], operands[1]);
1929 emit_move_complex_parts (operands[0], operands[1]);
1933 (define_expand "mov<mode>"
1934 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1935 (match_operand:SWI1248x 1 "general_operand"))]
1937 "ix86_expand_move (<MODE>mode, operands); DONE;")
1939 (define_insn "*mov<mode>_xor"
1940 [(set (match_operand:SWI48 0 "register_operand" "=r")
1941 (match_operand:SWI48 1 "const0_operand"))
1942 (clobber (reg:CC FLAGS_REG))]
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "SI")
1947 (set_attr "length_immediate" "0")])
1949 (define_insn "*mov<mode>_or"
1950 [(set (match_operand:SWI48 0 "register_operand" "=r")
1951 (match_operand:SWI48 1 "const_int_operand"))
1952 (clobber (reg:CC FLAGS_REG))]
1954 && operands[1] == constm1_rtx"
1955 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "alu1")
1957 (set_attr "mode" "<MODE>")
1958 (set_attr "length_immediate" "1")])
1960 (define_insn "*movxi_internal_avx512f"
1961 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1962 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1963 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1965 switch (which_alternative)
1968 return standard_sse_constant_opcode (insn, operands[1]);
1971 if (misaligned_operand (operands[0], XImode)
1972 || misaligned_operand (operands[1], XImode))
1973 return "vmovdqu32\t{%1, %0|%0, %1}";
1975 return "vmovdqa32\t{%1, %0|%0, %1}";
1980 [(set_attr "type" "sselog1,ssemov,ssemov")
1981 (set_attr "prefix" "evex")
1982 (set_attr "mode" "XI")])
1984 (define_insn "*movoi_internal_avx"
1985 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1986 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1987 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989 switch (get_attr_type (insn))
1992 return standard_sse_constant_opcode (insn, operands[1]);
1995 if (misaligned_operand (operands[0], OImode)
1996 || misaligned_operand (operands[1], OImode))
1998 if (get_attr_mode (insn) == MODE_V8SF)
1999 return "vmovups\t{%1, %0|%0, %1}";
2000 else if (get_attr_mode (insn) == MODE_XI)
2001 return "vmovdqu32\t{%1, %0|%0, %1}";
2003 return "vmovdqu\t{%1, %0|%0, %1}";
2007 if (get_attr_mode (insn) == MODE_V8SF)
2008 return "vmovaps\t{%1, %0|%0, %1}";
2009 else if (get_attr_mode (insn) == MODE_XI)
2010 return "vmovdqa32\t{%1, %0|%0, %1}";
2012 return "vmovdqa\t{%1, %0|%0, %1}";
2019 [(set_attr "type" "sselog1,ssemov,ssemov")
2020 (set_attr "prefix" "vex")
2022 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2023 (match_operand 1 "ext_sse_reg_operand"))
2025 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2026 (const_string "V8SF")
2027 (and (eq_attr "alternative" "2")
2028 (match_test "TARGET_SSE_TYPELESS_STORES"))
2029 (const_string "V8SF")
2031 (const_string "OI")))])
2033 (define_insn "*movti_internal"
2034 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2035 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2036 "(TARGET_64BIT || TARGET_SSE)
2037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2039 switch (get_attr_type (insn))
2045 return standard_sse_constant_opcode (insn, operands[1]);
2048 /* TDmode values are passed as TImode on the stack. Moving them
2049 to stack may result in unaligned memory access. */
2050 if (misaligned_operand (operands[0], TImode)
2051 || misaligned_operand (operands[1], TImode))
2053 if (get_attr_mode (insn) == MODE_V4SF)
2054 return "%vmovups\t{%1, %0|%0, %1}";
2055 else if (get_attr_mode (insn) == MODE_XI)
2056 return "vmovdqu32\t{%1, %0|%0, %1}";
2058 return "%vmovdqu\t{%1, %0|%0, %1}";
2062 if (get_attr_mode (insn) == MODE_V4SF)
2063 return "%vmovaps\t{%1, %0|%0, %1}";
2064 else if (get_attr_mode (insn) == MODE_XI)
2065 return "vmovdqa32\t{%1, %0|%0, %1}";
2067 return "%vmovdqa\t{%1, %0|%0, %1}";
2074 [(set_attr "isa" "x64,x64,*,*,*")
2075 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2076 (set (attr "prefix")
2077 (if_then_else (eq_attr "type" "sselog1,ssemov")
2078 (const_string "maybe_vex")
2079 (const_string "orig")))
2081 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2082 (match_operand 1 "ext_sse_reg_operand"))
2084 (eq_attr "alternative" "0,1")
2086 (ior (not (match_test "TARGET_SSE2"))
2087 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2088 (const_string "V4SF")
2089 (and (eq_attr "alternative" "4")
2090 (match_test "TARGET_SSE_TYPELESS_STORES"))
2091 (const_string "V4SF")
2092 (match_test "TARGET_AVX")
2094 (match_test "optimize_function_for_size_p (cfun)")
2095 (const_string "V4SF")
2097 (const_string "TI")))])
2100 [(set (match_operand:TI 0 "nonimmediate_operand")
2101 (match_operand:TI 1 "general_operand"))]
2103 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2105 "ix86_split_long_move (operands); DONE;")
2107 (define_insn "*movdi_internal"
2108 [(set (match_operand:DI 0 "nonimmediate_operand"
2109 "=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")
2110 (match_operand:DI 1 "general_operand"
2111 "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"))]
2112 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2114 switch (get_attr_type (insn))
2117 return "kmovq\t{%1, %0|%0, %1}";
2123 return "pxor\t%0, %0";
2126 /* Handle broken assemblers that require movd instead of movq. */
2127 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2128 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2129 return "movd\t{%1, %0|%0, %1}";
2130 return "movq\t{%1, %0|%0, %1}";
2133 if (GENERAL_REG_P (operands[0]))
2134 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2136 return standard_sse_constant_opcode (insn, operands[1]);
2139 switch (get_attr_mode (insn))
2142 /* Handle broken assemblers that require movd instead of movq. */
2143 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2144 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2145 return "%vmovd\t{%1, %0|%0, %1}";
2146 return "%vmovq\t{%1, %0|%0, %1}";
2148 return "%vmovdqa\t{%1, %0|%0, %1}";
2150 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2153 gcc_assert (!TARGET_AVX);
2154 return "movlps\t{%1, %0|%0, %1}";
2156 return "%vmovaps\t{%1, %0|%0, %1}";
2163 if (SSE_REG_P (operands[0]))
2164 return "movq2dq\t{%1, %0|%0, %1}";
2166 return "movdq2q\t{%1, %0|%0, %1}";
2169 return "lea{q}\t{%E1, %0|%0, %E1}";
2172 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2173 if (get_attr_mode (insn) == MODE_SI)
2174 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2175 else if (which_alternative == 4)
2176 return "movabs{q}\t{%1, %0|%0, %1}";
2177 else if (ix86_use_lea_for_mov (insn, operands))
2178 return "lea{q}\t{%E1, %0|%0, %E1}";
2180 return "mov{q}\t{%1, %0|%0, %1}";
2187 (cond [(eq_attr "alternative" "0,1")
2188 (const_string "nox64")
2189 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2190 (const_string "x64")
2191 (eq_attr "alternative" "17")
2192 (const_string "x64_sse4")
2194 (const_string "*")))
2196 (cond [(eq_attr "alternative" "0,1")
2197 (const_string "multi")
2198 (eq_attr "alternative" "6")
2199 (const_string "mmx")
2200 (eq_attr "alternative" "7,8,9,10,11")
2201 (const_string "mmxmov")
2202 (eq_attr "alternative" "12,17")
2203 (const_string "sselog1")
2204 (eq_attr "alternative" "13,14,15,16,18")
2205 (const_string "ssemov")
2206 (eq_attr "alternative" "19,20")
2207 (const_string "ssecvt")
2208 (eq_attr "alternative" "21,22,23,24")
2209 (const_string "mskmov")
2210 (match_operand 1 "pic_32bit_operand")
2211 (const_string "lea")
2213 (const_string "imov")))
2216 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2218 (const_string "*")))
2219 (set (attr "length_immediate")
2220 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2222 (eq_attr "alternative" "17")
2225 (const_string "*")))
2226 (set (attr "prefix_rex")
2227 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2229 (const_string "*")))
2230 (set (attr "prefix_extra")
2231 (if_then_else (eq_attr "alternative" "17")
2233 (const_string "*")))
2234 (set (attr "prefix")
2235 (if_then_else (eq_attr "type" "sselog1,ssemov")
2236 (const_string "maybe_vex")
2237 (const_string "orig")))
2238 (set (attr "prefix_data16")
2239 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2241 (const_string "*")))
2243 (cond [(eq_attr "alternative" "2")
2245 (eq_attr "alternative" "12,13")
2246 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2247 (match_operand 1 "ext_sse_reg_operand"))
2249 (ior (not (match_test "TARGET_SSE2"))
2250 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2251 (const_string "V4SF")
2252 (match_test "TARGET_AVX")
2254 (match_test "optimize_function_for_size_p (cfun)")
2255 (const_string "V4SF")
2257 (const_string "TI"))
2259 (and (eq_attr "alternative" "14,15")
2260 (not (match_test "TARGET_SSE2")))
2261 (const_string "V2SF")
2262 (eq_attr "alternative" "17")
2265 (const_string "DI")))])
2268 [(set (match_operand:DI 0 "nonimmediate_operand")
2269 (match_operand:DI 1 "general_operand"))]
2270 "!TARGET_64BIT && reload_completed
2271 && !(MMX_REG_P (operands[0])
2272 || SSE_REG_P (operands[0])
2273 || MASK_REG_P (operands[0]))
2274 && !(MMX_REG_P (operands[1])
2275 || SSE_REG_P (operands[1])
2276 || MASK_REG_P (operands[1]))"
2278 "ix86_split_long_move (operands); DONE;")
2280 (define_insn "*movsi_internal"
2281 [(set (match_operand:SI 0 "nonimmediate_operand"
2282 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2283 (match_operand:SI 1 "general_operand"
2284 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2287 switch (get_attr_type (insn))
2290 if (GENERAL_REG_P (operands[0]))
2291 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2293 return standard_sse_constant_opcode (insn, operands[1]);
2296 return "kmovd\t{%1, %0|%0, %1}";
2299 switch (get_attr_mode (insn))
2302 return "%vmovd\t{%1, %0|%0, %1}";
2304 return "%vmovdqa\t{%1, %0|%0, %1}";
2306 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2309 return "%vmovaps\t{%1, %0|%0, %1}";
2312 gcc_assert (!TARGET_AVX);
2313 return "movss\t{%1, %0|%0, %1}";
2320 return "pxor\t%0, %0";
2323 switch (get_attr_mode (insn))
2326 return "movq\t{%1, %0|%0, %1}";
2328 return "movd\t{%1, %0|%0, %1}";
2335 return "lea{l}\t{%E1, %0|%0, %E1}";
2338 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2339 if (ix86_use_lea_for_mov (insn, operands))
2340 return "lea{l}\t{%E1, %0|%0, %E1}";
2342 return "mov{l}\t{%1, %0|%0, %1}";
2349 (if_then_else (eq_attr "alternative" "11")
2350 (const_string "sse4")
2351 (const_string "*")))
2353 (cond [(eq_attr "alternative" "2")
2354 (const_string "mmx")
2355 (eq_attr "alternative" "3,4,5")
2356 (const_string "mmxmov")
2357 (eq_attr "alternative" "6,11")
2358 (const_string "sselog1")
2359 (eq_attr "alternative" "7,8,9,10,12")
2360 (const_string "ssemov")
2361 (eq_attr "alternative" "13,14")
2362 (const_string "mskmov")
2363 (match_operand 1 "pic_32bit_operand")
2364 (const_string "lea")
2366 (const_string "imov")))
2367 (set (attr "length_immediate")
2368 (if_then_else (eq_attr "alternative" "11")
2370 (const_string "*")))
2371 (set (attr "prefix_extra")
2372 (if_then_else (eq_attr "alternative" "11")
2374 (const_string "*")))
2375 (set (attr "prefix")
2376 (if_then_else (eq_attr "type" "sselog1,ssemov")
2377 (const_string "maybe_vex")
2378 (const_string "orig")))
2379 (set (attr "prefix_data16")
2380 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2382 (const_string "*")))
2384 (cond [(eq_attr "alternative" "2,3")
2386 (eq_attr "alternative" "6,7")
2387 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2388 (match_operand 1 "ext_sse_reg_operand"))
2390 (ior (not (match_test "TARGET_SSE2"))
2391 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2392 (const_string "V4SF")
2393 (match_test "TARGET_AVX")
2395 (match_test "optimize_function_for_size_p (cfun)")
2396 (const_string "V4SF")
2398 (const_string "TI"))
2400 (and (eq_attr "alternative" "8,9")
2401 (not (match_test "TARGET_SSE2")))
2403 (eq_attr "alternative" "11")
2406 (const_string "SI")))])
2408 (define_insn "kmovw"
2409 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2411 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2413 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2415 kmovw\t{%k1, %0|%0, %k1}
2416 kmovw\t{%1, %0|%0, %1}";
2417 [(set_attr "mode" "HI")
2418 (set_attr "type" "mskmov")
2419 (set_attr "prefix" "vex")])
2422 (define_insn "*movhi_internal"
2423 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2424 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2425 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2427 switch (get_attr_type (insn))
2430 /* movzwl is faster than movw on p2 due to partial word stalls,
2431 though not as fast as an aligned movl. */
2432 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2435 switch (which_alternative)
2437 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2438 case 5: return "kmovw\t{%1, %0|%0, %1}";
2439 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2440 default: gcc_unreachable ();
2444 if (get_attr_mode (insn) == MODE_SI)
2445 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2447 return "mov{w}\t{%1, %0|%0, %1}";
2451 (cond [(eq_attr "alternative" "4,5,6")
2452 (const_string "mskmov")
2453 (match_test "optimize_function_for_size_p (cfun)")
2454 (const_string "imov")
2455 (and (eq_attr "alternative" "0")
2456 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2457 (not (match_test "TARGET_HIMODE_MATH"))))
2458 (const_string "imov")
2459 (and (eq_attr "alternative" "1,2")
2460 (match_operand:HI 1 "aligned_operand"))
2461 (const_string "imov")
2462 (and (match_test "TARGET_MOVX")
2463 (eq_attr "alternative" "0,2"))
2464 (const_string "imovx")
2466 (const_string "imov")))
2467 (set (attr "prefix")
2468 (if_then_else (eq_attr "alternative" "4,5,6")
2469 (const_string "vex")
2470 (const_string "orig")))
2472 (cond [(eq_attr "type" "imovx")
2474 (and (eq_attr "alternative" "1,2")
2475 (match_operand:HI 1 "aligned_operand"))
2477 (and (eq_attr "alternative" "0")
2478 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2479 (not (match_test "TARGET_HIMODE_MATH"))))
2482 (const_string "HI")))])
2484 ;; Situation is quite tricky about when to choose full sized (SImode) move
2485 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2486 ;; partial register dependency machines (such as AMD Athlon), where QImode
2487 ;; moves issue extra dependency and for partial register stalls machines
2488 ;; that don't use QImode patterns (and QImode move cause stall on the next
2491 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2492 ;; register stall machines with, where we use QImode instructions, since
2493 ;; partial register stall can be caused there. Then we use movzx.
2495 (define_insn "*movqi_internal"
2496 [(set (match_operand:QI 0 "nonimmediate_operand"
2497 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2498 (match_operand:QI 1 "general_operand"
2499 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2502 switch (get_attr_type (insn))
2505 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2506 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2509 switch (which_alternative)
2511 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2512 : "kmovw\t{%k1, %0|%0, %k1}";
2513 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2514 : "kmovw\t{%1, %0|%0, %1}";
2515 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2516 : "kmovw\t{%1, %k0|%k0, %1}";
2519 gcc_assert (TARGET_AVX512DQ);
2520 return "kmovb\t{%1, %0|%0, %1}";
2521 default: gcc_unreachable ();
2525 if (get_attr_mode (insn) == MODE_SI)
2526 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2528 return "mov{b}\t{%1, %0|%0, %1}";
2531 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2533 (cond [(eq_attr "alternative" "3,5")
2534 (const_string "imovx")
2535 (eq_attr "alternative" "7,8,9,10,11")
2536 (const_string "mskmov")
2537 (and (eq_attr "alternative" "5")
2538 (not (match_operand:QI 1 "aligned_operand")))
2539 (const_string "imovx")
2540 (match_test "optimize_function_for_size_p (cfun)")
2541 (const_string "imov")
2542 (and (eq_attr "alternative" "3")
2543 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2544 (not (match_test "TARGET_QIMODE_MATH"))))
2545 (const_string "imov")
2546 (and (match_test "TARGET_MOVX")
2547 (eq_attr "alternative" "2"))
2548 (const_string "imovx")
2550 (const_string "imov")))
2551 (set (attr "prefix")
2552 (if_then_else (eq_attr "alternative" "7,8,9")
2553 (const_string "vex")
2554 (const_string "orig")))
2556 (cond [(eq_attr "alternative" "3,4,5")
2558 (eq_attr "alternative" "6")
2560 (eq_attr "type" "imovx")
2562 (and (eq_attr "type" "imov")
2563 (and (eq_attr "alternative" "0,1")
2564 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2565 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2566 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2568 ;; Avoid partial register stalls when not using QImode arithmetic
2569 (and (eq_attr "type" "imov")
2570 (and (eq_attr "alternative" "0,1")
2571 (and (match_test "TARGET_PARTIAL_REG_STALL")
2572 (not (match_test "TARGET_QIMODE_MATH")))))
2575 (const_string "QI")))])
2577 ;; Stores and loads of ax to arbitrary constant address.
2578 ;; We fake an second form of instruction to force reload to load address
2579 ;; into register when rax is not available
2580 (define_insn "*movabs<mode>_1"
2581 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2582 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2583 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2585 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2586 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2587 [(set_attr "type" "imov")
2588 (set_attr "modrm" "0,*")
2589 (set_attr "length_address" "8,0")
2590 (set_attr "length_immediate" "0,*")
2591 (set_attr "memory" "store")
2592 (set_attr "mode" "<MODE>")])
2594 (define_insn "*movabs<mode>_2"
2595 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2596 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2597 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2599 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2600 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2601 [(set_attr "type" "imov")
2602 (set_attr "modrm" "0,*")
2603 (set_attr "length_address" "8,0")
2604 (set_attr "length_immediate" "0")
2605 (set_attr "memory" "load")
2606 (set_attr "mode" "<MODE>")])
2608 (define_insn "*swap<mode>"
2609 [(set (match_operand:SWI48 0 "register_operand" "+r")
2610 (match_operand:SWI48 1 "register_operand" "+r"))
2614 "xchg{<imodesuffix>}\t%1, %0"
2615 [(set_attr "type" "imov")
2616 (set_attr "mode" "<MODE>")
2617 (set_attr "pent_pair" "np")
2618 (set_attr "athlon_decode" "vector")
2619 (set_attr "amdfam10_decode" "double")
2620 (set_attr "bdver1_decode" "double")])
2622 (define_insn "*swap<mode>_1"
2623 [(set (match_operand:SWI12 0 "register_operand" "+r")
2624 (match_operand:SWI12 1 "register_operand" "+r"))
2627 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2629 [(set_attr "type" "imov")
2630 (set_attr "mode" "SI")
2631 (set_attr "pent_pair" "np")
2632 (set_attr "athlon_decode" "vector")
2633 (set_attr "amdfam10_decode" "double")
2634 (set_attr "bdver1_decode" "double")])
2636 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2637 ;; is disabled for AMDFAM10
2638 (define_insn "*swap<mode>_2"
2639 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2640 (match_operand:SWI12 1 "register_operand" "+<r>"))
2643 "TARGET_PARTIAL_REG_STALL"
2644 "xchg{<imodesuffix>}\t%1, %0"
2645 [(set_attr "type" "imov")
2646 (set_attr "mode" "<MODE>")
2647 (set_attr "pent_pair" "np")
2648 (set_attr "athlon_decode" "vector")])
2650 (define_expand "movstrict<mode>"
2651 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2652 (match_operand:SWI12 1 "general_operand"))]
2655 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2657 if (GET_CODE (operands[0]) == SUBREG
2658 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2660 /* Don't generate memory->memory moves, go through a register */
2661 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2662 operands[1] = force_reg (<MODE>mode, operands[1]);
2665 (define_insn "*movstrict<mode>_1"
2666 [(set (strict_low_part
2667 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2668 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2669 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2670 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2671 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2672 [(set_attr "type" "imov")
2673 (set_attr "mode" "<MODE>")])
2675 (define_insn "*movstrict<mode>_xor"
2676 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2677 (match_operand:SWI12 1 "const0_operand"))
2678 (clobber (reg:CC FLAGS_REG))]
2680 "xor{<imodesuffix>}\t%0, %0"
2681 [(set_attr "type" "alu1")
2682 (set_attr "mode" "<MODE>")
2683 (set_attr "length_immediate" "0")])
2685 (define_insn "*mov<mode>_extv_1"
2686 [(set (match_operand:SWI24 0 "register_operand" "=R")
2687 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2691 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2692 [(set_attr "type" "imovx")
2693 (set_attr "mode" "SI")])
2695 (define_insn "*movqi_extv_1"
2696 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2697 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2702 switch (get_attr_type (insn))
2705 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2707 return "mov{b}\t{%h1, %0|%0, %h1}";
2710 [(set_attr "isa" "*,*,nox64")
2712 (if_then_else (and (match_operand:QI 0 "register_operand")
2713 (ior (not (match_operand:QI 0 "QIreg_operand"))
2714 (match_test "TARGET_MOVX")))
2715 (const_string "imovx")
2716 (const_string "imov")))
2718 (if_then_else (eq_attr "type" "imovx")
2720 (const_string "QI")))])
2722 (define_insn "*mov<mode>_extzv_1"
2723 [(set (match_operand:SWI48 0 "register_operand" "=R")
2724 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2728 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2729 [(set_attr "type" "imovx")
2730 (set_attr "mode" "SI")])
2732 (define_insn "*movqi_extzv_2"
2733 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2735 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2740 switch (get_attr_type (insn))
2743 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2745 return "mov{b}\t{%h1, %0|%0, %h1}";
2748 [(set_attr "isa" "*,*,nox64")
2750 (if_then_else (and (match_operand:QI 0 "register_operand")
2751 (ior (not (match_operand:QI 0 "QIreg_operand"))
2752 (match_test "TARGET_MOVX")))
2753 (const_string "imovx")
2754 (const_string "imov")))
2756 (if_then_else (eq_attr "type" "imovx")
2758 (const_string "QI")))])
2760 (define_insn "mov<mode>_insv_1"
2761 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2764 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2767 if (CONST_INT_P (operands[1]))
2768 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2769 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2771 [(set_attr "isa" "*,nox64")
2772 (set_attr "type" "imov")
2773 (set_attr "mode" "QI")])
2775 (define_insn "*movqi_insv_2"
2776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2779 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2782 "mov{b}\t{%h1, %h0|%h0, %h1}"
2783 [(set_attr "type" "imov")
2784 (set_attr "mode" "QI")])
2786 ;; Floating point push instructions.
2788 (define_insn "*pushtf"
2789 [(set (match_operand:TF 0 "push_operand" "=<,<")
2790 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2791 "TARGET_64BIT || TARGET_SSE"
2793 /* This insn should be already split before reg-stack. */
2796 [(set_attr "isa" "*,x64")
2797 (set_attr "type" "multi")
2798 (set_attr "unit" "sse,*")
2799 (set_attr "mode" "TF,DI")])
2801 ;; %%% Kill this when call knows how to work this out.
2803 [(set (match_operand:TF 0 "push_operand")
2804 (match_operand:TF 1 "sse_reg_operand"))]
2805 "TARGET_SSE && reload_completed"
2806 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2807 (set (match_dup 0) (match_dup 1))]
2809 /* Preserve memory attributes. */
2810 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2813 (define_insn "*pushxf"
2814 [(set (match_operand:XF 0 "push_operand" "=<,<")
2815 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2818 /* This insn should be already split before reg-stack. */
2821 [(set_attr "type" "multi")
2822 (set_attr "unit" "i387,*")
2824 (cond [(eq_attr "alternative" "1")
2825 (if_then_else (match_test "TARGET_64BIT")
2827 (const_string "SI"))
2829 (const_string "XF")))])
2831 ;; %%% Kill this when call knows how to work this out.
2833 [(set (match_operand:XF 0 "push_operand")
2834 (match_operand:XF 1 "fp_register_operand"))]
2836 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2837 (set (match_dup 0) (match_dup 1))]
2839 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2840 /* Preserve memory attributes. */
2841 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2844 (define_insn "*pushdf"
2845 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2846 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2849 /* This insn should be already split before reg-stack. */
2852 [(set_attr "isa" "*,nox64,x64,sse2")
2853 (set_attr "type" "multi")
2854 (set_attr "unit" "i387,*,*,sse")
2855 (set_attr "mode" "DF,SI,DI,DF")])
2857 ;; %%% Kill this when call knows how to work this out.
2859 [(set (match_operand:DF 0 "push_operand")
2860 (match_operand:DF 1 "any_fp_register_operand"))]
2862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2863 (set (match_dup 0) (match_dup 1))]
2865 /* Preserve memory attributes. */
2866 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2869 (define_insn "*pushsf_rex64"
2870 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2871 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2874 /* Anything else should be already split before reg-stack. */
2875 gcc_assert (which_alternative == 1);
2876 return "push{q}\t%q1";
2878 [(set_attr "type" "multi,push,multi")
2879 (set_attr "unit" "i387,*,*")
2880 (set_attr "mode" "SF,DI,SF")])
2882 (define_insn "*pushsf"
2883 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2884 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2887 /* Anything else should be already split before reg-stack. */
2888 gcc_assert (which_alternative == 1);
2889 return "push{l}\t%1";
2891 [(set_attr "type" "multi,push,multi")
2892 (set_attr "unit" "i387,*,*")
2893 (set_attr "mode" "SF,SI,SF")])
2895 ;; %%% Kill this when call knows how to work this out.
2897 [(set (match_operand:SF 0 "push_operand")
2898 (match_operand:SF 1 "any_fp_register_operand"))]
2900 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2901 (set (match_dup 0) (match_dup 1))]
2903 rtx op = XEXP (operands[0], 0);
2904 if (GET_CODE (op) == PRE_DEC)
2906 gcc_assert (!TARGET_64BIT);
2911 op = XEXP (XEXP (op, 1), 1);
2912 gcc_assert (CONST_INT_P (op));
2915 /* Preserve memory attributes. */
2916 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2920 [(set (match_operand:SF 0 "push_operand")
2921 (match_operand:SF 1 "memory_operand"))]
2923 && (operands[2] = find_constant_src (insn))"
2924 [(set (match_dup 0) (match_dup 2))])
2927 [(set (match_operand 0 "push_operand")
2928 (match_operand 1 "general_operand"))]
2930 && (GET_MODE (operands[0]) == TFmode
2931 || GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == DFmode)
2933 && !ANY_FP_REG_P (operands[1])"
2935 "ix86_split_long_move (operands); DONE;")
2937 ;; Floating point move instructions.
2939 (define_expand "movtf"
2940 [(set (match_operand:TF 0 "nonimmediate_operand")
2941 (match_operand:TF 1 "nonimmediate_operand"))]
2942 "TARGET_64BIT || TARGET_SSE"
2943 "ix86_expand_move (TFmode, operands); DONE;")
2945 (define_expand "mov<mode>"
2946 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2947 (match_operand:X87MODEF 1 "general_operand"))]
2949 "ix86_expand_move (<MODE>mode, operands); DONE;")
2951 (define_insn "*movtf_internal"
2952 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2953 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2954 "(TARGET_64BIT || TARGET_SSE)
2955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2956 && (!can_create_pseudo_p ()
2957 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2958 || GET_CODE (operands[1]) != CONST_DOUBLE
2959 || (optimize_function_for_size_p (cfun)
2960 && standard_sse_constant_p (operands[1])
2961 && !memory_operand (operands[0], TFmode))
2962 || (!TARGET_MEMORY_MISMATCH_STALL
2963 && memory_operand (operands[0], TFmode)))"
2965 switch (get_attr_type (insn))
2968 return standard_sse_constant_opcode (insn, operands[1]);
2971 /* Handle misaligned load/store since we
2972 don't have movmisaligntf pattern. */
2973 if (misaligned_operand (operands[0], TFmode)
2974 || misaligned_operand (operands[1], TFmode))
2976 if (get_attr_mode (insn) == MODE_V4SF)
2977 return "%vmovups\t{%1, %0|%0, %1}";
2979 return "%vmovdqu\t{%1, %0|%0, %1}";
2983 if (get_attr_mode (insn) == MODE_V4SF)
2984 return "%vmovaps\t{%1, %0|%0, %1}";
2986 return "%vmovdqa\t{%1, %0|%0, %1}";
2996 [(set_attr "isa" "*,*,*,x64,x64")
2997 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2998 (set (attr "prefix")
2999 (if_then_else (eq_attr "type" "sselog1,ssemov")
3000 (const_string "maybe_vex")
3001 (const_string "orig")))
3003 (cond [(eq_attr "alternative" "3,4")
3005 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3006 (const_string "V4SF")
3007 (and (eq_attr "alternative" "2")
3008 (match_test "TARGET_SSE_TYPELESS_STORES"))
3009 (const_string "V4SF")
3010 (match_test "TARGET_AVX")
3012 (ior (not (match_test "TARGET_SSE2"))
3013 (match_test "optimize_function_for_size_p (cfun)"))
3014 (const_string "V4SF")
3016 (const_string "TI")))])
3018 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
3019 (define_insn "*movxf_internal"
3020 [(set (match_operand:XF 0 "nonimmediate_operand"
3021 "=f,m,f,?Yx*r ,!o ,!o")
3022 (match_operand:XF 1 "general_operand"
3023 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
3024 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3025 && (!can_create_pseudo_p ()
3026 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3027 || GET_CODE (operands[1]) != CONST_DOUBLE
3028 || (optimize_function_for_size_p (cfun)
3029 && standard_80387_constant_p (operands[1]) > 0
3030 && !memory_operand (operands[0], XFmode))
3031 || (!TARGET_MEMORY_MISMATCH_STALL
3032 && memory_operand (operands[0], XFmode)))"
3034 switch (get_attr_type (insn))
3037 if (which_alternative == 2)
3038 return standard_80387_constant_opcode (operands[1]);
3039 return output_387_reg_move (insn, operands);
3048 [(set_attr "isa" "*,*,*,*,nox64,x64")
3049 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3051 (cond [(eq_attr "alternative" "3,4,5")
3052 (if_then_else (match_test "TARGET_64BIT")
3054 (const_string "SI"))
3056 (const_string "XF")))])
3058 ;; Possible store forwarding (partial memory) stall in alternative 4.
3059 (define_insn "*movdf_internal"
3060 [(set (match_operand:DF 0 "nonimmediate_operand"
3061 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3062 (match_operand:DF 1 "general_operand"
3063 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3064 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3065 && (!can_create_pseudo_p ()
3066 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3067 || GET_CODE (operands[1]) != CONST_DOUBLE
3068 || (optimize_function_for_size_p (cfun)
3069 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3070 && standard_80387_constant_p (operands[1]) > 0)
3071 || (TARGET_SSE2 && TARGET_SSE_MATH
3072 && standard_sse_constant_p (operands[1])))
3073 && !memory_operand (operands[0], DFmode))
3074 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3075 && memory_operand (operands[0], DFmode)))"
3077 switch (get_attr_type (insn))
3080 if (which_alternative == 2)
3081 return standard_80387_constant_opcode (operands[1]);
3082 return output_387_reg_move (insn, operands);
3088 if (get_attr_mode (insn) == MODE_SI)
3089 return "mov{l}\t{%1, %k0|%k0, %1}";
3090 else if (which_alternative == 8)
3091 return "movabs{q}\t{%1, %0|%0, %1}";
3093 return "mov{q}\t{%1, %0|%0, %1}";
3096 return standard_sse_constant_opcode (insn, operands[1]);
3099 switch (get_attr_mode (insn))
3102 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3103 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 return "%vmovsd\t{%1, %0|%0, %1}";
3107 return "%vmovaps\t{%1, %0|%0, %1}";
3109 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3111 return "%vmovapd\t{%1, %0|%0, %1}";
3114 gcc_assert (!TARGET_AVX);
3115 return "movlps\t{%1, %0|%0, %1}";
3117 gcc_assert (!TARGET_AVX);
3118 return "movlpd\t{%1, %0|%0, %1}";
3121 /* Handle broken assemblers that require movd instead of movq. */
3122 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3123 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3124 return "%vmovd\t{%1, %0|%0, %1}";
3125 return "%vmovq\t{%1, %0|%0, %1}";
3136 (cond [(eq_attr "alternative" "3,4")
3137 (const_string "nox64")
3138 (eq_attr "alternative" "5,6,7,8,17,18")
3139 (const_string "x64")
3140 (eq_attr "alternative" "9,10,11,12")
3141 (const_string "sse2")
3143 (const_string "*")))
3145 (cond [(eq_attr "alternative" "0,1,2")
3146 (const_string "fmov")
3147 (eq_attr "alternative" "3,4")
3148 (const_string "multi")
3149 (eq_attr "alternative" "5,6,7,8")
3150 (const_string "imov")
3151 (eq_attr "alternative" "9,13")
3152 (const_string "sselog1")
3154 (const_string "ssemov")))
3156 (if_then_else (eq_attr "alternative" "8")
3158 (const_string "*")))
3159 (set (attr "length_immediate")
3160 (if_then_else (eq_attr "alternative" "8")
3162 (const_string "*")))
3163 (set (attr "prefix")
3164 (if_then_else (eq_attr "type" "sselog1,ssemov")
3165 (const_string "maybe_vex")
3166 (const_string "orig")))
3167 (set (attr "prefix_data16")
3169 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3170 (eq_attr "mode" "V1DF"))
3172 (const_string "*")))
3174 (cond [(eq_attr "alternative" "3,4,7")
3176 (eq_attr "alternative" "5,6,8,17,18")
3179 /* xorps is one byte shorter for non-AVX targets. */
3180 (eq_attr "alternative" "9,13")
3181 (cond [(not (match_test "TARGET_SSE2"))
3182 (const_string "V4SF")
3183 (match_test "TARGET_AVX512F")
3185 (match_test "TARGET_AVX")
3186 (const_string "V2DF")
3187 (match_test "optimize_function_for_size_p (cfun)")
3188 (const_string "V4SF")
3189 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3192 (const_string "V2DF"))
3194 /* For architectures resolving dependencies on
3195 whole SSE registers use movapd to break dependency
3196 chains, otherwise use short move to avoid extra work. */
3198 /* movaps is one byte shorter for non-AVX targets. */
3199 (eq_attr "alternative" "10,14")
3200 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3201 (match_operand 1 "ext_sse_reg_operand"))
3202 (const_string "V8DF")
3203 (ior (not (match_test "TARGET_SSE2"))
3204 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3205 (const_string "V4SF")
3206 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3207 (const_string "V2DF")
3208 (match_test "TARGET_AVX")
3210 (match_test "optimize_function_for_size_p (cfun)")
3211 (const_string "V4SF")
3213 (const_string "DF"))
3215 /* For architectures resolving dependencies on register
3216 parts we may avoid extra work to zero out upper part
3218 (eq_attr "alternative" "11,15")
3219 (cond [(not (match_test "TARGET_SSE2"))
3220 (const_string "V2SF")
3221 (match_test "TARGET_AVX")
3223 (match_test "TARGET_SSE_SPLIT_REGS")
3224 (const_string "V1DF")
3226 (const_string "DF"))
3228 (and (eq_attr "alternative" "12,16")
3229 (not (match_test "TARGET_SSE2")))
3230 (const_string "V2SF")
3232 (const_string "DF")))])
3234 (define_insn "*movsf_internal"
3235 [(set (match_operand:SF 0 "nonimmediate_operand"
3236 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3237 (match_operand:SF 1 "general_operand"
3238 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3239 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3240 && (!can_create_pseudo_p ()
3241 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3242 || GET_CODE (operands[1]) != CONST_DOUBLE
3243 || (optimize_function_for_size_p (cfun)
3244 && ((!TARGET_SSE_MATH
3245 && standard_80387_constant_p (operands[1]) > 0)
3247 && standard_sse_constant_p (operands[1]))))
3248 || memory_operand (operands[0], SFmode))"
3250 switch (get_attr_type (insn))
3253 if (which_alternative == 2)
3254 return standard_80387_constant_opcode (operands[1]);
3255 return output_387_reg_move (insn, operands);
3258 return "mov{l}\t{%1, %0|%0, %1}";
3261 return standard_sse_constant_opcode (insn, operands[1]);
3264 switch (get_attr_mode (insn))
3267 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3268 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3269 return "%vmovss\t{%1, %0|%0, %1}";
3272 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3274 return "%vmovaps\t{%1, %0|%0, %1}";
3277 return "%vmovd\t{%1, %0|%0, %1}";
3284 switch (get_attr_mode (insn))
3287 return "movq\t{%1, %0|%0, %1}";
3289 return "movd\t{%1, %0|%0, %1}";
3300 (cond [(eq_attr "alternative" "0,1,2")
3301 (const_string "fmov")
3302 (eq_attr "alternative" "3,4")
3303 (const_string "imov")
3304 (eq_attr "alternative" "5")
3305 (const_string "sselog1")
3306 (eq_attr "alternative" "11,12,13,14,15")
3307 (const_string "mmxmov")
3309 (const_string "ssemov")))
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "type" "sselog1,ssemov")
3312 (const_string "maybe_vex")
3313 (const_string "orig")))
3314 (set (attr "prefix_data16")
3315 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3317 (const_string "*")))
3319 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3321 (eq_attr "alternative" "11")
3323 (eq_attr "alternative" "5")
3324 (cond [(not (match_test "TARGET_SSE2"))
3325 (const_string "V4SF")
3326 (match_test "TARGET_AVX512F")
3327 (const_string "V16SF")
3328 (match_test "TARGET_AVX")
3329 (const_string "V4SF")
3330 (match_test "optimize_function_for_size_p (cfun)")
3331 (const_string "V4SF")
3332 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3335 (const_string "V4SF"))
3337 /* For architectures resolving dependencies on
3338 whole SSE registers use APS move to break dependency
3339 chains, otherwise use short move to avoid extra work.
3341 Do the same for architectures resolving dependencies on
3342 the parts. While in DF mode it is better to always handle
3343 just register parts, the SF mode is different due to lack
3344 of instructions to load just part of the register. It is
3345 better to maintain the whole registers in single format
3346 to avoid problems on using packed logical operations. */
3347 (eq_attr "alternative" "6")
3348 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3349 (match_operand 1 "ext_sse_reg_operand"))
3350 (const_string "V16SF")
3351 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3352 (match_test "TARGET_SSE_SPLIT_REGS"))
3353 (const_string "V4SF")
3355 (const_string "SF"))
3357 (const_string "SF")))])
3360 [(set (match_operand 0 "any_fp_register_operand")
3361 (match_operand 1 "memory_operand"))]
3363 && (GET_MODE (operands[0]) == TFmode
3364 || GET_MODE (operands[0]) == XFmode
3365 || GET_MODE (operands[0]) == DFmode
3366 || GET_MODE (operands[0]) == SFmode)
3367 && (operands[2] = find_constant_src (insn))"
3368 [(set (match_dup 0) (match_dup 2))]
3370 rtx c = operands[2];
3371 int r = REGNO (operands[0]);
3373 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3374 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3379 [(set (match_operand 0 "any_fp_register_operand")
3380 (float_extend (match_operand 1 "memory_operand")))]
3382 && (GET_MODE (operands[0]) == TFmode
3383 || GET_MODE (operands[0]) == XFmode
3384 || GET_MODE (operands[0]) == DFmode)
3385 && (operands[2] = find_constant_src (insn))"
3386 [(set (match_dup 0) (match_dup 2))]
3388 rtx c = operands[2];
3389 int r = REGNO (operands[0]);
3391 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3392 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3396 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3398 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3399 (match_operand:X87MODEF 1 "immediate_operand"))]
3401 && (standard_80387_constant_p (operands[1]) == 8
3402 || standard_80387_constant_p (operands[1]) == 9)"
3403 [(set (match_dup 0)(match_dup 1))
3405 (neg:X87MODEF (match_dup 0)))]
3409 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3410 if (real_isnegzero (&r))
3411 operands[1] = CONST0_RTX (<MODE>mode);
3413 operands[1] = CONST1_RTX (<MODE>mode);
3417 [(set (match_operand 0 "nonimmediate_operand")
3418 (match_operand 1 "general_operand"))]
3420 && (GET_MODE (operands[0]) == TFmode
3421 || GET_MODE (operands[0]) == XFmode
3422 || GET_MODE (operands[0]) == DFmode)
3423 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3425 "ix86_split_long_move (operands); DONE;")
3427 (define_insn "swapxf"
3428 [(set (match_operand:XF 0 "register_operand" "+f")
3429 (match_operand:XF 1 "register_operand" "+f"))
3434 if (STACK_TOP_P (operands[0]))
3439 [(set_attr "type" "fxch")
3440 (set_attr "mode" "XF")])
3442 (define_insn "*swap<mode>"
3443 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3444 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3447 "TARGET_80387 || reload_completed"
3449 if (STACK_TOP_P (operands[0]))
3454 [(set_attr "type" "fxch")
3455 (set_attr "mode" "<MODE>")])
3457 ;; Zero extension instructions
3459 (define_expand "zero_extendsidi2"
3460 [(set (match_operand:DI 0 "nonimmediate_operand")
3461 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3463 (define_insn "*zero_extendsidi2"
3464 [(set (match_operand:DI 0 "nonimmediate_operand"
3465 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3467 (match_operand:SI 1 "x86_64_zext_operand"
3468 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3471 switch (get_attr_type (insn))
3474 if (ix86_use_lea_for_mov (insn, operands))
3475 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3477 return "mov{l}\t{%1, %k0|%k0, %1}";
3483 return "movd\t{%1, %0|%0, %1}";
3486 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3489 if (GENERAL_REG_P (operands[0]))
3490 return "%vmovd\t{%1, %k0|%k0, %1}";
3492 return "%vmovd\t{%1, %0|%0, %1}";
3499 (cond [(eq_attr "alternative" "0,1,2")
3500 (const_string "nox64")
3501 (eq_attr "alternative" "3,7")
3502 (const_string "x64")
3503 (eq_attr "alternative" "8")
3504 (const_string "x64_sse4")
3505 (eq_attr "alternative" "10")
3506 (const_string "sse2")
3508 (const_string "*")))
3510 (cond [(eq_attr "alternative" "0,1,2,4")
3511 (const_string "multi")
3512 (eq_attr "alternative" "5,6")
3513 (const_string "mmxmov")
3514 (eq_attr "alternative" "7,9,10")
3515 (const_string "ssemov")
3516 (eq_attr "alternative" "8")
3517 (const_string "sselog1")
3519 (const_string "imovx")))
3520 (set (attr "prefix_extra")
3521 (if_then_else (eq_attr "alternative" "8")
3523 (const_string "*")))
3524 (set (attr "length_immediate")
3525 (if_then_else (eq_attr "alternative" "8")
3527 (const_string "*")))
3528 (set (attr "prefix")
3529 (if_then_else (eq_attr "type" "ssemov,sselog1")
3530 (const_string "maybe_vex")
3531 (const_string "orig")))
3532 (set (attr "prefix_0f")
3533 (if_then_else (eq_attr "type" "imovx")
3535 (const_string "*")))
3537 (cond [(eq_attr "alternative" "5,6")
3539 (eq_attr "alternative" "7,8,9")
3542 (const_string "SI")))])
3545 [(set (match_operand:DI 0 "memory_operand")
3546 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3548 [(set (match_dup 4) (const_int 0))]
3549 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3552 [(set (match_operand:DI 0 "register_operand")
3553 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3554 "!TARGET_64BIT && reload_completed
3555 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3556 && true_regnum (operands[0]) == true_regnum (operands[1])"
3557 [(set (match_dup 4) (const_int 0))]
3558 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3561 [(set (match_operand:DI 0 "nonimmediate_operand")
3562 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3563 "!TARGET_64BIT && reload_completed
3564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3565 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3566 [(set (match_dup 3) (match_dup 1))
3567 (set (match_dup 4) (const_int 0))]
3568 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3570 (define_insn "zero_extend<mode>di2"
3571 [(set (match_operand:DI 0 "register_operand" "=r")
3573 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3575 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3576 [(set_attr "type" "imovx")
3577 (set_attr "mode" "SI")])
3579 (define_expand "zero_extend<mode>si2"
3580 [(set (match_operand:SI 0 "register_operand")
3581 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3584 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3586 operands[1] = force_reg (<MODE>mode, operands[1]);
3587 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3592 (define_insn_and_split "zero_extend<mode>si2_and"
3593 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3595 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3596 (clobber (reg:CC FLAGS_REG))]
3597 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3599 "&& reload_completed"
3600 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3601 (clobber (reg:CC FLAGS_REG))])]
3603 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3605 ix86_expand_clear (operands[0]);
3607 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3608 emit_insn (gen_movstrict<mode>
3609 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3613 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3615 [(set_attr "type" "alu1")
3616 (set_attr "mode" "SI")])
3618 (define_insn "*zero_extend<mode>si2"
3619 [(set (match_operand:SI 0 "register_operand" "=r")
3621 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3622 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3623 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3624 [(set_attr "type" "imovx")
3625 (set_attr "mode" "SI")])
3627 (define_expand "zero_extendqihi2"
3628 [(set (match_operand:HI 0 "register_operand")
3629 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3632 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3634 operands[1] = force_reg (QImode, operands[1]);
3635 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3640 (define_insn_and_split "zero_extendqihi2_and"
3641 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3642 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3643 (clobber (reg:CC FLAGS_REG))]
3644 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3646 "&& reload_completed"
3647 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3648 (clobber (reg:CC FLAGS_REG))])]
3650 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3652 ix86_expand_clear (operands[0]);
3654 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3655 emit_insn (gen_movstrictqi
3656 (gen_lowpart (QImode, operands[0]), operands[1]));
3660 operands[0] = gen_lowpart (SImode, operands[0]);
3662 [(set_attr "type" "alu1")
3663 (set_attr "mode" "SI")])
3665 ; zero extend to SImode to avoid partial register stalls
3666 (define_insn "*zero_extendqihi2"
3667 [(set (match_operand:HI 0 "register_operand" "=r")
3668 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3669 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3670 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "SI")])
3674 ;; Sign extension instructions
3676 (define_expand "extendsidi2"
3677 [(set (match_operand:DI 0 "register_operand")
3678 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3683 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3688 (define_insn "*extendsidi2_rex64"
3689 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3690 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3694 movs{lq|x}\t{%1, %0|%0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")
3697 (set_attr "prefix_0f" "0")
3698 (set_attr "modrm" "0,1")])
3700 (define_insn "extendsidi2_1"
3701 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3702 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3703 (clobber (reg:CC FLAGS_REG))
3704 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3708 ;; Split the memory case. If the source register doesn't die, it will stay
3709 ;; this way, if it does die, following peephole2s take care of it.
3711 [(set (match_operand:DI 0 "memory_operand")
3712 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3713 (clobber (reg:CC FLAGS_REG))
3714 (clobber (match_operand:SI 2 "register_operand"))]
3718 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3720 emit_move_insn (operands[3], operands[1]);
3722 /* Generate a cltd if possible and doing so it profitable. */
3723 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3724 && true_regnum (operands[1]) == AX_REG
3725 && true_regnum (operands[2]) == DX_REG)
3727 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3731 emit_move_insn (operands[2], operands[1]);
3732 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3734 emit_move_insn (operands[4], operands[2]);
3738 ;; Peepholes for the case where the source register does die, after
3739 ;; being split with the above splitter.
3741 [(set (match_operand:SI 0 "memory_operand")
3742 (match_operand:SI 1 "register_operand"))
3743 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3744 (parallel [(set (match_dup 2)
3745 (ashiftrt:SI (match_dup 2) (const_int 31)))
3746 (clobber (reg:CC FLAGS_REG))])
3747 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3748 "REGNO (operands[1]) != REGNO (operands[2])
3749 && peep2_reg_dead_p (2, operands[1])
3750 && peep2_reg_dead_p (4, operands[2])
3751 && !reg_mentioned_p (operands[2], operands[3])"
3752 [(set (match_dup 0) (match_dup 1))
3753 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3754 (clobber (reg:CC FLAGS_REG))])
3755 (set (match_dup 3) (match_dup 1))])
3758 [(set (match_operand:SI 0 "memory_operand")
3759 (match_operand:SI 1 "register_operand"))
3760 (parallel [(set (match_operand:SI 2 "register_operand")
3761 (ashiftrt:SI (match_dup 1) (const_int 31)))
3762 (clobber (reg:CC FLAGS_REG))])
3763 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3764 "/* cltd is shorter than sarl $31, %eax */
3765 !optimize_function_for_size_p (cfun)
3766 && true_regnum (operands[1]) == AX_REG
3767 && true_regnum (operands[2]) == DX_REG
3768 && peep2_reg_dead_p (2, operands[1])
3769 && peep2_reg_dead_p (3, operands[2])
3770 && !reg_mentioned_p (operands[2], operands[3])"
3771 [(set (match_dup 0) (match_dup 1))
3772 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3773 (clobber (reg:CC FLAGS_REG))])
3774 (set (match_dup 3) (match_dup 1))])
3776 ;; Extend to register case. Optimize case where source and destination
3777 ;; registers match and cases where we can use cltd.
3779 [(set (match_operand:DI 0 "register_operand")
3780 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3781 (clobber (reg:CC FLAGS_REG))
3782 (clobber (match_scratch:SI 2))]
3786 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3788 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3789 emit_move_insn (operands[3], operands[1]);
3791 /* Generate a cltd if possible and doing so it profitable. */
3792 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3793 && true_regnum (operands[3]) == AX_REG
3794 && true_regnum (operands[4]) == DX_REG)
3796 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3800 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3801 emit_move_insn (operands[4], operands[1]);
3803 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3807 (define_insn "extend<mode>di2"
3808 [(set (match_operand:DI 0 "register_operand" "=r")
3810 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3812 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "DI")])
3816 (define_insn "extendhisi2"
3817 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3818 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3821 switch (get_attr_prefix_0f (insn))
3824 return "{cwtl|cwde}";
3826 return "movs{wl|x}\t{%1, %0|%0, %1}";
3829 [(set_attr "type" "imovx")
3830 (set_attr "mode" "SI")
3831 (set (attr "prefix_0f")
3832 ;; movsx is short decodable while cwtl is vector decoded.
3833 (if_then_else (and (eq_attr "cpu" "!k6")
3834 (eq_attr "alternative" "0"))
3836 (const_string "1")))
3838 (if_then_else (eq_attr "prefix_0f" "0")
3840 (const_string "1")))])
3842 (define_insn "*extendhisi2_zext"
3843 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3846 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3849 switch (get_attr_prefix_0f (insn))
3852 return "{cwtl|cwde}";
3854 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3857 [(set_attr "type" "imovx")
3858 (set_attr "mode" "SI")
3859 (set (attr "prefix_0f")
3860 ;; movsx is short decodable while cwtl is vector decoded.
3861 (if_then_else (and (eq_attr "cpu" "!k6")
3862 (eq_attr "alternative" "0"))
3864 (const_string "1")))
3866 (if_then_else (eq_attr "prefix_0f" "0")
3868 (const_string "1")))])
3870 (define_insn "extendqisi2"
3871 [(set (match_operand:SI 0 "register_operand" "=r")
3872 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3874 "movs{bl|x}\t{%1, %0|%0, %1}"
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")])
3878 (define_insn "*extendqisi2_zext"
3879 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3883 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3884 [(set_attr "type" "imovx")
3885 (set_attr "mode" "SI")])
3887 (define_insn "extendqihi2"
3888 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3889 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3892 switch (get_attr_prefix_0f (insn))
3895 return "{cbtw|cbw}";
3897 return "movs{bw|x}\t{%1, %0|%0, %1}";
3900 [(set_attr "type" "imovx")
3901 (set_attr "mode" "HI")
3902 (set (attr "prefix_0f")
3903 ;; movsx is short decodable while cwtl is vector decoded.
3904 (if_then_else (and (eq_attr "cpu" "!k6")
3905 (eq_attr "alternative" "0"))
3907 (const_string "1")))
3909 (if_then_else (eq_attr "prefix_0f" "0")
3911 (const_string "1")))])
3913 ;; Conversions between float and double.
3915 ;; These are all no-ops in the model used for the 80387.
3916 ;; So just emit moves.
3918 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3920 [(set (match_operand:DF 0 "push_operand")
3921 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3923 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3924 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3927 [(set (match_operand:XF 0 "push_operand")
3928 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3930 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3931 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3932 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3934 (define_expand "extendsfdf2"
3935 [(set (match_operand:DF 0 "nonimmediate_operand")
3936 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3937 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3939 /* ??? Needed for compress_float_constant since all fp constants
3940 are TARGET_LEGITIMATE_CONSTANT_P. */
3941 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3943 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3944 && standard_80387_constant_p (operands[1]) > 0)
3946 operands[1] = simplify_const_unary_operation
3947 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3948 emit_move_insn_1 (operands[0], operands[1]);
3951 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3955 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3957 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3959 We do the conversion post reload to avoid producing of 128bit spills
3960 that might lead to ICE on 32bit target. The sequence unlikely combine
3963 [(set (match_operand:DF 0 "register_operand")
3965 (match_operand:SF 1 "nonimmediate_operand")))]
3966 "TARGET_USE_VECTOR_FP_CONVERTS
3967 && optimize_insn_for_speed_p ()
3968 && reload_completed && SSE_REG_P (operands[0])"
3973 (parallel [(const_int 0) (const_int 1)]))))]
3975 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3976 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3977 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3978 Try to avoid move when unpacking can be done in source. */
3979 if (REG_P (operands[1]))
3981 /* If it is unsafe to overwrite upper half of source, we need
3982 to move to destination and unpack there. */
3983 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3984 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3985 && true_regnum (operands[0]) != true_regnum (operands[1]))
3987 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3988 emit_move_insn (tmp, operands[1]);
3991 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3992 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3996 emit_insn (gen_vec_setv4sf_0 (operands[3],
3997 CONST0_RTX (V4SFmode), operands[1]));
4000 ;; It's more profitable to split and then extend in the same register.
4002 [(set (match_operand:DF 0 "register_operand")
4004 (match_operand:SF 1 "memory_operand")))]
4005 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4006 && optimize_insn_for_speed_p ()
4007 && SSE_REG_P (operands[0])"
4008 [(set (match_dup 2) (match_dup 1))
4009 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4010 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4012 (define_insn "*extendsfdf2_mixed"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4015 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4016 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4018 switch (which_alternative)
4022 return output_387_reg_move (insn, operands);
4025 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4031 [(set_attr "type" "fmov,fmov,ssecvt")
4032 (set_attr "prefix" "orig,orig,maybe_vex")
4033 (set_attr "mode" "SF,XF,DF")])
4035 (define_insn "*extendsfdf2_sse"
4036 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4037 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4038 "TARGET_SSE2 && TARGET_SSE_MATH"
4039 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4040 [(set_attr "type" "ssecvt")
4041 (set_attr "prefix" "maybe_vex")
4042 (set_attr "mode" "DF")])
4044 (define_insn "*extendsfdf2_i387"
4045 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4046 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4048 "* return output_387_reg_move (insn, operands);"
4049 [(set_attr "type" "fmov")
4050 (set_attr "mode" "SF,XF")])
4052 (define_expand "extend<mode>xf2"
4053 [(set (match_operand:XF 0 "nonimmediate_operand")
4054 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4057 /* ??? Needed for compress_float_constant since all fp constants
4058 are TARGET_LEGITIMATE_CONSTANT_P. */
4059 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4061 if (standard_80387_constant_p (operands[1]) > 0)
4063 operands[1] = simplify_const_unary_operation
4064 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4065 emit_move_insn_1 (operands[0], operands[1]);
4068 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4072 (define_insn "*extend<mode>xf2_i387"
4073 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4075 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4077 "* return output_387_reg_move (insn, operands);"
4078 [(set_attr "type" "fmov")
4079 (set_attr "mode" "<MODE>,XF")])
4081 ;; %%% This seems bad bad news.
4082 ;; This cannot output into an f-reg because there is no way to be sure
4083 ;; of truncating in that case. Otherwise this is just like a simple move
4084 ;; insn. So we pretend we can output to a reg in order to get better
4085 ;; register preferencing, but we really use a stack slot.
4087 ;; Conversion from DFmode to SFmode.
4089 (define_expand "truncdfsf2"
4090 [(set (match_operand:SF 0 "nonimmediate_operand")
4092 (match_operand:DF 1 "nonimmediate_operand")))]
4093 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4095 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4097 else if (flag_unsafe_math_optimizations)
4101 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4102 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4107 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4109 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4111 We do the conversion post reload to avoid producing of 128bit spills
4112 that might lead to ICE on 32bit target. The sequence unlikely combine
4115 [(set (match_operand:SF 0 "register_operand")
4117 (match_operand:DF 1 "nonimmediate_operand")))]
4118 "TARGET_USE_VECTOR_FP_CONVERTS
4119 && optimize_insn_for_speed_p ()
4120 && reload_completed && SSE_REG_P (operands[0])"
4123 (float_truncate:V2SF
4127 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4128 operands[3] = CONST0_RTX (V2SFmode);
4129 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4130 /* Use movsd for loading from memory, unpcklpd for registers.
4131 Try to avoid move when unpacking can be done in source, or SSE3
4132 movddup is available. */
4133 if (REG_P (operands[1]))
4136 && true_regnum (operands[0]) != true_regnum (operands[1])
4137 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4138 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4140 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4141 emit_move_insn (tmp, operands[1]);
4144 else if (!TARGET_SSE3)
4145 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4146 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4149 emit_insn (gen_sse2_loadlpd (operands[4],
4150 CONST0_RTX (V2DFmode), operands[1]));
4153 ;; It's more profitable to split and then extend in the same register.
4155 [(set (match_operand:SF 0 "register_operand")
4157 (match_operand:DF 1 "memory_operand")))]
4158 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4159 && optimize_insn_for_speed_p ()
4160 && SSE_REG_P (operands[0])"
4161 [(set (match_dup 2) (match_dup 1))
4162 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4163 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4165 (define_expand "truncdfsf2_with_temp"
4166 [(parallel [(set (match_operand:SF 0)
4167 (float_truncate:SF (match_operand:DF 1)))
4168 (clobber (match_operand:SF 2))])])
4170 (define_insn "*truncdfsf_fast_mixed"
4171 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4173 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4174 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4176 switch (which_alternative)
4179 return output_387_reg_move (insn, operands);
4181 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4186 [(set_attr "type" "fmov,ssecvt")
4187 (set_attr "prefix" "orig,maybe_vex")
4188 (set_attr "mode" "SF")])
4190 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4191 ;; because nothing we do here is unsafe.
4192 (define_insn "*truncdfsf_fast_sse"
4193 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4195 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4196 "TARGET_SSE2 && TARGET_SSE_MATH"
4197 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4198 [(set_attr "type" "ssecvt")
4199 (set_attr "prefix" "maybe_vex")
4200 (set_attr "mode" "SF")])
4202 (define_insn "*truncdfsf_fast_i387"
4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4205 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "SF")])
4211 (define_insn "*truncdfsf_mixed"
4212 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4214 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4215 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4216 "TARGET_MIX_SSE_I387"
4218 switch (which_alternative)
4221 return output_387_reg_move (insn, operands);
4223 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4229 [(set_attr "isa" "*,sse2,*,*,*")
4230 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4231 (set_attr "unit" "*,*,i387,i387,i387")
4232 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4233 (set_attr "mode" "SF")])
4235 (define_insn "*truncdfsf_i387"
4236 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4239 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4242 switch (which_alternative)
4245 return output_387_reg_move (insn, operands);
4251 [(set_attr "type" "fmov,multi,multi,multi")
4252 (set_attr "unit" "*,i387,i387,i387")
4253 (set_attr "mode" "SF")])
4255 (define_insn "*truncdfsf2_i387_1"
4256 [(set (match_operand:SF 0 "memory_operand" "=m")
4258 (match_operand:DF 1 "register_operand" "f")))]
4260 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4261 && !TARGET_MIX_SSE_I387"
4262 "* return output_387_reg_move (insn, operands);"
4263 [(set_attr "type" "fmov")
4264 (set_attr "mode" "SF")])
4267 [(set (match_operand:SF 0 "register_operand")
4269 (match_operand:DF 1 "fp_register_operand")))
4270 (clobber (match_operand 2))]
4272 [(set (match_dup 2) (match_dup 1))
4273 (set (match_dup 0) (match_dup 2))]
4274 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4276 ;; Conversion from XFmode to {SF,DF}mode
4278 (define_expand "truncxf<mode>2"
4279 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand")))
4282 (clobber (match_dup 2))])]
4285 if (flag_unsafe_math_optimizations)
4287 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4288 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4289 if (reg != operands[0])
4290 emit_move_insn (operands[0], reg);
4294 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4297 (define_insn "*truncxfsf2_mixed"
4298 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4300 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4301 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4304 gcc_assert (!which_alternative);
4305 return output_387_reg_move (insn, operands);
4307 [(set_attr "type" "fmov,multi,multi,multi")
4308 (set_attr "unit" "*,i387,i387,i387")
4309 (set_attr "mode" "SF")])
4311 (define_insn "*truncxfdf2_mixed"
4312 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4314 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4315 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4318 gcc_assert (!which_alternative);
4319 return output_387_reg_move (insn, operands);
4321 [(set_attr "isa" "*,*,sse2,*")
4322 (set_attr "type" "fmov,multi,multi,multi")
4323 (set_attr "unit" "*,i387,i387,i387")
4324 (set_attr "mode" "DF")])
4326 (define_insn "truncxf<mode>2_i387_noop"
4327 [(set (match_operand:MODEF 0 "register_operand" "=f")
4328 (float_truncate:MODEF
4329 (match_operand:XF 1 "register_operand" "f")))]
4330 "TARGET_80387 && flag_unsafe_math_optimizations"
4331 "* return output_387_reg_move (insn, operands);"
4332 [(set_attr "type" "fmov")
4333 (set_attr "mode" "<MODE>")])
4335 (define_insn "*truncxf<mode>2_i387"
4336 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4337 (float_truncate:MODEF
4338 (match_operand:XF 1 "register_operand" "f")))]
4340 "* return output_387_reg_move (insn, operands);"
4341 [(set_attr "type" "fmov")
4342 (set_attr "mode" "<MODE>")])
4345 [(set (match_operand:MODEF 0 "register_operand")
4346 (float_truncate:MODEF
4347 (match_operand:XF 1 "register_operand")))
4348 (clobber (match_operand:MODEF 2 "memory_operand"))]
4349 "TARGET_80387 && reload_completed"
4350 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4351 (set (match_dup 0) (match_dup 2))])
4354 [(set (match_operand:MODEF 0 "memory_operand")
4355 (float_truncate:MODEF
4356 (match_operand:XF 1 "register_operand")))
4357 (clobber (match_operand:MODEF 2 "memory_operand"))]
4359 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4361 ;; Signed conversion to DImode.
4363 (define_expand "fix_truncxfdi2"
4364 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4365 (fix:DI (match_operand:XF 1 "register_operand")))
4366 (clobber (reg:CC FLAGS_REG))])]
4371 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4376 (define_expand "fix_trunc<mode>di2"
4377 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4378 (fix:DI (match_operand:MODEF 1 "register_operand")))
4379 (clobber (reg:CC FLAGS_REG))])]
4380 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4383 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4385 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4388 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4390 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4391 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4392 if (out != operands[0])
4393 emit_move_insn (operands[0], out);
4398 ;; Signed conversion to SImode.
4400 (define_expand "fix_truncxfsi2"
4401 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4402 (fix:SI (match_operand:XF 1 "register_operand")))
4403 (clobber (reg:CC FLAGS_REG))])]
4408 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4413 (define_expand "fix_trunc<mode>si2"
4414 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4415 (fix:SI (match_operand:MODEF 1 "register_operand")))
4416 (clobber (reg:CC FLAGS_REG))])]
4417 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4420 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4422 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4425 if (SSE_FLOAT_MODE_P (<MODE>mode))
4427 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4428 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4429 if (out != operands[0])
4430 emit_move_insn (operands[0], out);
4435 ;; Signed conversion to HImode.
4437 (define_expand "fix_trunc<mode>hi2"
4438 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4439 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4440 (clobber (reg:CC FLAGS_REG))])]
4442 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4446 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4451 ;; Unsigned conversion to SImode.
4453 (define_expand "fixuns_trunc<mode>si2"
4455 [(set (match_operand:SI 0 "register_operand")
4457 (match_operand:MODEF 1 "nonimmediate_operand")))
4459 (clobber (match_scratch:<ssevecmode> 3))
4460 (clobber (match_scratch:<ssevecmode> 4))])]
4461 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4463 machine_mode mode = <MODE>mode;
4464 machine_mode vecmode = <ssevecmode>mode;
4465 REAL_VALUE_TYPE TWO31r;
4468 if (optimize_insn_for_size_p ())
4471 real_ldexp (&TWO31r, &dconst1, 31);
4472 two31 = const_double_from_real_value (TWO31r, mode);
4473 two31 = ix86_build_const_vector (vecmode, true, two31);
4474 operands[2] = force_reg (vecmode, two31);
4477 (define_insn_and_split "*fixuns_trunc<mode>_1"
4478 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4480 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4481 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4482 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4483 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4484 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4485 && optimize_function_for_speed_p (cfun)"
4487 "&& reload_completed"
4490 ix86_split_convert_uns_si_sse (operands);
4494 ;; Unsigned conversion to HImode.
4495 ;; Without these patterns, we'll try the unsigned SI conversion which
4496 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4498 (define_expand "fixuns_trunc<mode>hi2"
4500 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4501 (set (match_operand:HI 0 "nonimmediate_operand")
4502 (subreg:HI (match_dup 2) 0))]
4503 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4504 "operands[2] = gen_reg_rtx (SImode);")
4506 ;; When SSE is available, it is always faster to use it!
4507 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4508 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4509 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4510 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4511 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4512 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4513 [(set_attr "type" "sseicvt")
4514 (set_attr "prefix" "maybe_vex")
4515 (set (attr "prefix_rex")
4517 (match_test "<SWI48:MODE>mode == DImode")
4519 (const_string "*")))
4520 (set_attr "mode" "<MODEF:MODE>")
4521 (set_attr "athlon_decode" "double,vector")
4522 (set_attr "amdfam10_decode" "double,double")
4523 (set_attr "bdver1_decode" "double,double")])
4525 ;; Avoid vector decoded forms of the instruction.
4527 [(match_scratch:MODEF 2 "x")
4528 (set (match_operand:SWI48 0 "register_operand")
4529 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4530 "TARGET_AVOID_VECTOR_DECODE
4531 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4532 && optimize_insn_for_speed_p ()"
4533 [(set (match_dup 2) (match_dup 1))
4534 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4536 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4537 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4538 (fix:SWI248x (match_operand 1 "register_operand")))]
4539 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4541 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4542 && (TARGET_64BIT || <MODE>mode != DImode))
4544 && can_create_pseudo_p ()"
4549 if (memory_operand (operands[0], VOIDmode))
4550 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4553 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4554 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4560 [(set_attr "type" "fisttp")
4561 (set_attr "mode" "<MODE>")])
4563 (define_insn "fix_trunc<mode>_i387_fisttp"
4564 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4565 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4566 (clobber (match_scratch:XF 2 "=&1f"))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && (TARGET_64BIT || <MODE>mode != DImode))
4571 && TARGET_SSE_MATH)"
4572 "* return output_fix_trunc (insn, operands, true);"
4573 [(set_attr "type" "fisttp")
4574 (set_attr "mode" "<MODE>")])
4576 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4577 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4578 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4579 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4580 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && (TARGET_64BIT || <MODE>mode != DImode))
4585 && TARGET_SSE_MATH)"
4587 [(set_attr "type" "fisttp")
4588 (set_attr "mode" "<MODE>")])
4591 [(set (match_operand:SWI248x 0 "register_operand")
4592 (fix:SWI248x (match_operand 1 "register_operand")))
4593 (clobber (match_operand:SWI248x 2 "memory_operand"))
4594 (clobber (match_scratch 3))]
4596 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4597 (clobber (match_dup 3))])
4598 (set (match_dup 0) (match_dup 2))])
4601 [(set (match_operand:SWI248x 0 "memory_operand")
4602 (fix:SWI248x (match_operand 1 "register_operand")))
4603 (clobber (match_operand:SWI248x 2 "memory_operand"))
4604 (clobber (match_scratch 3))]
4606 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4607 (clobber (match_dup 3))])])
4609 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4610 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4611 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4612 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4613 ;; function in i386.c.
4614 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4615 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4616 (fix:SWI248x (match_operand 1 "register_operand")))
4617 (clobber (reg:CC FLAGS_REG))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4621 && (TARGET_64BIT || <MODE>mode != DImode))
4622 && can_create_pseudo_p ()"
4627 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4629 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4630 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4631 if (memory_operand (operands[0], VOIDmode))
4632 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4633 operands[2], operands[3]));
4636 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4637 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4638 operands[2], operands[3],
4643 [(set_attr "type" "fistp")
4644 (set_attr "i387_cw" "trunc")
4645 (set_attr "mode" "<MODE>")])
4647 (define_insn "fix_truncdi_i387"
4648 [(set (match_operand:DI 0 "memory_operand" "=m")
4649 (fix:DI (match_operand 1 "register_operand" "f")))
4650 (use (match_operand:HI 2 "memory_operand" "m"))
4651 (use (match_operand:HI 3 "memory_operand" "m"))
4652 (clobber (match_scratch:XF 4 "=&1f"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4656 "* return output_fix_trunc (insn, operands, false);"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "DI")])
4661 (define_insn "fix_truncdi_i387_with_temp"
4662 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4663 (fix:DI (match_operand 1 "register_operand" "f,f")))
4664 (use (match_operand:HI 2 "memory_operand" "m,m"))
4665 (use (match_operand:HI 3 "memory_operand" "m,m"))
4666 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4667 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4672 [(set_attr "type" "fistp")
4673 (set_attr "i387_cw" "trunc")
4674 (set_attr "mode" "DI")])
4677 [(set (match_operand:DI 0 "register_operand")
4678 (fix:DI (match_operand 1 "register_operand")))
4679 (use (match_operand:HI 2 "memory_operand"))
4680 (use (match_operand:HI 3 "memory_operand"))
4681 (clobber (match_operand:DI 4 "memory_operand"))
4682 (clobber (match_scratch 5))]
4684 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4687 (clobber (match_dup 5))])
4688 (set (match_dup 0) (match_dup 4))])
4691 [(set (match_operand:DI 0 "memory_operand")
4692 (fix:DI (match_operand 1 "register_operand")))
4693 (use (match_operand:HI 2 "memory_operand"))
4694 (use (match_operand:HI 3 "memory_operand"))
4695 (clobber (match_operand:DI 4 "memory_operand"))
4696 (clobber (match_scratch 5))]
4698 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4701 (clobber (match_dup 5))])])
4703 (define_insn "fix_trunc<mode>_i387"
4704 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4705 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4706 (use (match_operand:HI 2 "memory_operand" "m"))
4707 (use (match_operand:HI 3 "memory_operand" "m"))]
4708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4710 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4711 "* return output_fix_trunc (insn, operands, false);"
4712 [(set_attr "type" "fistp")
4713 (set_attr "i387_cw" "trunc")
4714 (set_attr "mode" "<MODE>")])
4716 (define_insn "fix_trunc<mode>_i387_with_temp"
4717 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4718 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4719 (use (match_operand:HI 2 "memory_operand" "m,m"))
4720 (use (match_operand:HI 3 "memory_operand" "m,m"))
4721 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4722 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4724 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4726 [(set_attr "type" "fistp")
4727 (set_attr "i387_cw" "trunc")
4728 (set_attr "mode" "<MODE>")])
4731 [(set (match_operand:SWI24 0 "register_operand")
4732 (fix:SWI24 (match_operand 1 "register_operand")))
4733 (use (match_operand:HI 2 "memory_operand"))
4734 (use (match_operand:HI 3 "memory_operand"))
4735 (clobber (match_operand:SWI24 4 "memory_operand"))]
4737 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4739 (use (match_dup 3))])
4740 (set (match_dup 0) (match_dup 4))])
4743 [(set (match_operand:SWI24 0 "memory_operand")
4744 (fix:SWI24 (match_operand 1 "register_operand")))
4745 (use (match_operand:HI 2 "memory_operand"))
4746 (use (match_operand:HI 3 "memory_operand"))
4747 (clobber (match_operand:SWI24 4 "memory_operand"))]
4749 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4751 (use (match_dup 3))])])
4753 (define_insn "x86_fnstcw_1"
4754 [(set (match_operand:HI 0 "memory_operand" "=m")
4755 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4758 [(set (attr "length")
4759 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4760 (set_attr "mode" "HI")
4761 (set_attr "unit" "i387")
4762 (set_attr "bdver1_decode" "vector")])
4764 (define_insn "x86_fldcw_1"
4765 [(set (reg:HI FPCR_REG)
4766 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4769 [(set (attr "length")
4770 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4771 (set_attr "mode" "HI")
4772 (set_attr "unit" "i387")
4773 (set_attr "athlon_decode" "vector")
4774 (set_attr "amdfam10_decode" "vector")
4775 (set_attr "bdver1_decode" "vector")])
4777 ;; Conversion between fixed point and floating point.
4779 ;; Even though we only accept memory inputs, the backend _really_
4780 ;; wants to be able to do this between registers. Thankfully, LRA
4781 ;; will fix this up for us during register allocation.
4783 (define_insn "floathi<mode>2"
4784 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4785 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4788 || TARGET_MIX_SSE_I387)"
4790 [(set_attr "type" "fmov")
4791 (set_attr "mode" "<MODE>")
4792 (set_attr "fp_int_src" "true")])
4794 (define_insn "float<SWI48x:mode>xf2"
4795 [(set (match_operand:XF 0 "register_operand" "=f")
4796 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4799 [(set_attr "type" "fmov")
4800 (set_attr "mode" "XF")
4801 (set_attr "fp_int_src" "true")])
4803 (define_expand "float<SWI48:mode><MODEF:mode>2"
4804 [(set (match_operand:MODEF 0 "register_operand")
4805 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4806 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4808 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4809 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4811 rtx reg = gen_reg_rtx (XFmode);
4812 rtx (*insn)(rtx, rtx);
4814 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4816 if (<MODEF:MODE>mode == SFmode)
4817 insn = gen_truncxfsf2;
4818 else if (<MODEF:MODE>mode == DFmode)
4819 insn = gen_truncxfdf2;
4823 emit_insn (insn (operands[0], reg));
4828 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4829 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4831 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4832 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4835 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4836 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4837 [(set_attr "type" "fmov,sseicvt,sseicvt")
4838 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4839 (set_attr "mode" "<MODEF:MODE>")
4840 (set (attr "prefix_rex")
4842 (and (eq_attr "prefix" "maybe_vex")
4843 (match_test "<SWI48:MODE>mode == DImode"))
4845 (const_string "*")))
4846 (set_attr "unit" "i387,*,*")
4847 (set_attr "athlon_decode" "*,double,direct")
4848 (set_attr "amdfam10_decode" "*,vector,double")
4849 (set_attr "bdver1_decode" "*,double,direct")
4850 (set_attr "fp_int_src" "true")
4851 (set (attr "enabled")
4852 (cond [(eq_attr "alternative" "0")
4853 (symbol_ref "TARGET_MIX_SSE_I387
4854 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4857 (symbol_ref "true")))
4858 (set (attr "preferred_for_speed")
4859 (cond [(eq_attr "alternative" "1")
4860 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4861 (symbol_ref "true")))
4864 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4865 [(set (match_operand:MODEF 0 "register_operand" "=f")
4866 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4867 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4869 [(set_attr "type" "fmov")
4870 (set_attr "mode" "<MODEF:MODE>")
4871 (set_attr "fp_int_src" "true")])
4873 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4874 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4875 ;; alternative in sse2_loadld.
4877 [(set (match_operand:MODEF 0 "register_operand")
4878 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4879 "TARGET_SSE2 && TARGET_SSE_MATH
4880 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4881 && reload_completed && SSE_REG_P (operands[0])
4882 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4885 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4887 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4889 emit_insn (gen_sse2_loadld (operands[4],
4890 CONST0_RTX (V4SImode), operands[1]));
4892 if (<ssevecmode>mode == V4SFmode)
4893 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4895 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4899 ;; Avoid partial SSE register dependency stalls
4901 [(set (match_operand:MODEF 0 "register_operand")
4902 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4903 "TARGET_SSE2 && TARGET_SSE_MATH
4904 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4905 && optimize_function_for_speed_p (cfun)
4906 && reload_completed && SSE_REG_P (operands[0])"
4909 const machine_mode vmode = <MODEF:ssevecmode>mode;
4910 const machine_mode mode = <MODEF:MODE>mode;
4911 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4913 emit_move_insn (op0, CONST0_RTX (vmode));
4915 t = gen_rtx_FLOAT (mode, operands[1]);
4916 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4917 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4918 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4922 ;; Break partial reg stall for cvtsd2ss.
4925 [(set (match_operand:SF 0 "register_operand")
4927 (match_operand:DF 1 "nonimmediate_operand")))]
4928 "TARGET_SSE2 && TARGET_SSE_MATH
4929 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4930 && optimize_function_for_speed_p (cfun)
4931 && SSE_REG_P (operands[0])
4932 && (!SSE_REG_P (operands[1])
4933 || REGNO (operands[0]) != REGNO (operands[1]))"
4937 (float_truncate:V2SF
4942 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4944 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4946 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4949 ;; Break partial reg stall for cvtss2sd.
4952 [(set (match_operand:DF 0 "register_operand")
4954 (match_operand:SF 1 "nonimmediate_operand")))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4957 && optimize_function_for_speed_p (cfun)
4958 && SSE_REG_P (operands[0])
4959 && (!SSE_REG_P (operands[1])
4960 || REGNO (operands[0]) != REGNO (operands[1]))"
4966 (parallel [(const_int 0) (const_int 1)])))
4970 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4972 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4974 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4977 ;; Avoid store forwarding (partial memory) stall penalty
4978 ;; by passing DImode value through XMM registers. */
4980 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4981 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4983 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4984 (clobber (match_scratch:V4SI 3 "=X,x"))
4985 (clobber (match_scratch:V4SI 4 "=X,x"))
4986 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4987 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4988 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4989 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4991 [(set_attr "type" "multi")
4992 (set_attr "mode" "<X87MODEF:MODE>")
4993 (set_attr "unit" "i387")
4994 (set_attr "fp_int_src" "true")])
4997 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4998 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4999 (clobber (match_scratch:V4SI 3))
5000 (clobber (match_scratch:V4SI 4))
5001 (clobber (match_operand:DI 2 "memory_operand"))]
5002 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5003 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5004 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5005 && reload_completed"
5006 [(set (match_dup 2) (match_dup 3))
5007 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5009 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5010 Assemble the 64-bit DImode value in an xmm register. */
5011 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5012 gen_rtx_SUBREG (SImode, operands[1], 0)));
5013 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5014 gen_rtx_SUBREG (SImode, operands[1], 4)));
5015 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5018 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5022 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5023 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5024 (clobber (match_scratch:V4SI 3))
5025 (clobber (match_scratch:V4SI 4))
5026 (clobber (match_operand:DI 2 "memory_operand"))]
5027 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5028 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5029 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5030 && reload_completed"
5031 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5033 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5034 [(set (match_operand:MODEF 0 "register_operand")
5035 (unsigned_float:MODEF
5036 (match_operand:SWI12 1 "nonimmediate_operand")))]
5038 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5040 operands[1] = convert_to_mode (SImode, operands[1], 1);
5041 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5045 ;; Avoid store forwarding (partial memory) stall penalty by extending
5046 ;; SImode value to DImode through XMM register instead of pushing two
5047 ;; SImode values to stack. Also note that fild loads from memory only.
5049 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5050 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5051 (unsigned_float:X87MODEF
5052 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5053 (clobber (match_scratch:DI 3 "=x"))
5054 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5056 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5057 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5059 "&& reload_completed"
5060 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5061 (set (match_dup 2) (match_dup 3))
5063 (float:X87MODEF (match_dup 2)))]
5065 [(set_attr "type" "multi")
5066 (set_attr "mode" "<MODE>")])
5068 (define_expand "floatunssi<mode>2"
5070 [(set (match_operand:X87MODEF 0 "register_operand")
5071 (unsigned_float:X87MODEF
5072 (match_operand:SI 1 "nonimmediate_operand")))
5073 (clobber (match_scratch:DI 3))
5074 (clobber (match_dup 2))])]
5076 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5077 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5078 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5080 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5082 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5086 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5089 (define_expand "floatunsdisf2"
5090 [(use (match_operand:SF 0 "register_operand"))
5091 (use (match_operand:DI 1 "nonimmediate_operand"))]
5092 "TARGET_64BIT && TARGET_SSE_MATH"
5093 "x86_emit_floatuns (operands); DONE;")
5095 (define_expand "floatunsdidf2"
5096 [(use (match_operand:DF 0 "register_operand"))
5097 (use (match_operand:DI 1 "nonimmediate_operand"))]
5098 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5099 && TARGET_SSE2 && TARGET_SSE_MATH"
5102 x86_emit_floatuns (operands);
5104 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5108 ;; Load effective address instructions
5110 (define_insn_and_split "*lea<mode>"
5111 [(set (match_operand:SWI48 0 "register_operand" "=r")
5112 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5115 if (SImode_address_operand (operands[1], VOIDmode))
5117 gcc_assert (TARGET_64BIT);
5118 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5121 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5123 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5126 machine_mode mode = <MODE>mode;
5129 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5130 change operands[] array behind our back. */
5131 pat = PATTERN (curr_insn);
5133 operands[0] = SET_DEST (pat);
5134 operands[1] = SET_SRC (pat);
5136 /* Emit all operations in SImode for zero-extended addresses. */
5137 if (SImode_address_operand (operands[1], VOIDmode))
5140 ix86_split_lea_for_addr (curr_insn, operands, mode);
5142 /* Zero-extend return register to DImode for zero-extended addresses. */
5143 if (mode != <MODE>mode)
5144 emit_insn (gen_zero_extendsidi2
5145 (operands[0], gen_lowpart (mode, operands[0])));
5149 [(set_attr "type" "lea")
5152 (match_operand 1 "SImode_address_operand")
5154 (const_string "<MODE>")))])
5158 (define_expand "add<mode>3"
5159 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5160 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5161 (match_operand:SDWIM 2 "<general_operand>")))]
5163 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5165 (define_insn_and_split "*add<dwi>3_doubleword"
5166 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5168 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5169 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5170 (clobber (reg:CC FLAGS_REG))]
5171 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5174 [(parallel [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_dup 1) (match_dup 2)]
5178 (plus:DWIH (match_dup 1) (match_dup 2)))])
5179 (parallel [(set (match_dup 3)
5183 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5185 (clobber (reg:CC FLAGS_REG))])]
5186 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5188 (define_insn "*add<mode>3_cc"
5189 [(set (reg:CC FLAGS_REG)
5191 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5192 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5194 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5195 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5196 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5197 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5198 [(set_attr "type" "alu")
5199 (set_attr "mode" "<MODE>")])
5201 (define_insn "addqi3_cc"
5202 [(set (reg:CC FLAGS_REG)
5204 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5205 (match_operand:QI 2 "general_operand" "qn,qm")]
5207 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5208 (plus:QI (match_dup 1) (match_dup 2)))]
5209 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5210 "add{b}\t{%2, %0|%0, %2}"
5211 [(set_attr "type" "alu")
5212 (set_attr "mode" "QI")])
5214 (define_insn "*add<mode>_1"
5215 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5217 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5218 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5219 (clobber (reg:CC FLAGS_REG))]
5220 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5222 switch (get_attr_type (insn))
5228 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5229 if (operands[2] == const1_rtx)
5230 return "inc{<imodesuffix>}\t%0";
5233 gcc_assert (operands[2] == constm1_rtx);
5234 return "dec{<imodesuffix>}\t%0";
5238 /* For most processors, ADD is faster than LEA. This alternative
5239 was added to use ADD as much as possible. */
5240 if (which_alternative == 2)
5241 std::swap (operands[1], operands[2]);
5243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5244 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5245 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5247 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5251 (cond [(eq_attr "alternative" "3")
5252 (const_string "lea")
5253 (match_operand:SWI48 2 "incdec_operand")
5254 (const_string "incdec")
5256 (const_string "alu")))
5257 (set (attr "length_immediate")
5259 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5261 (const_string "*")))
5262 (set_attr "mode" "<MODE>")])
5264 ;; It may seem that nonimmediate operand is proper one for operand 1.
5265 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5266 ;; we take care in ix86_binary_operator_ok to not allow two memory
5267 ;; operands so proper swapping will be done in reload. This allow
5268 ;; patterns constructed from addsi_1 to match.
5270 (define_insn "addsi_1_zext"
5271 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5273 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5274 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5275 (clobber (reg:CC FLAGS_REG))]
5276 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5278 switch (get_attr_type (insn))
5284 if (operands[2] == const1_rtx)
5285 return "inc{l}\t%k0";
5288 gcc_assert (operands[2] == constm1_rtx);
5289 return "dec{l}\t%k0";
5293 /* For most processors, ADD is faster than LEA. This alternative
5294 was added to use ADD as much as possible. */
5295 if (which_alternative == 1)
5296 std::swap (operands[1], operands[2]);
5298 if (x86_maybe_negate_const_int (&operands[2], SImode))
5299 return "sub{l}\t{%2, %k0|%k0, %2}";
5301 return "add{l}\t{%2, %k0|%k0, %2}";
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 (match_operand:SI 2 "incdec_operand")
5308 (const_string "incdec")
5310 (const_string "alu")))
5311 (set (attr "length_immediate")
5313 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5315 (const_string "*")))
5316 (set_attr "mode" "SI")])
5318 (define_insn "*addhi_1"
5319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5320 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5321 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5322 (clobber (reg:CC FLAGS_REG))]
5323 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5325 switch (get_attr_type (insn))
5331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332 if (operands[2] == const1_rtx)
5333 return "inc{w}\t%0";
5336 gcc_assert (operands[2] == constm1_rtx);
5337 return "dec{w}\t%0";
5341 /* For most processors, ADD is faster than LEA. This alternative
5342 was added to use ADD as much as possible. */
5343 if (which_alternative == 2)
5344 std::swap (operands[1], operands[2]);
5346 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5347 if (x86_maybe_negate_const_int (&operands[2], HImode))
5348 return "sub{w}\t{%2, %0|%0, %2}";
5350 return "add{w}\t{%2, %0|%0, %2}";
5354 (cond [(eq_attr "alternative" "3")
5355 (const_string "lea")
5356 (match_operand:HI 2 "incdec_operand")
5357 (const_string "incdec")
5359 (const_string "alu")))
5360 (set (attr "length_immediate")
5362 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5364 (const_string "*")))
5365 (set_attr "mode" "HI,HI,HI,SI")])
5367 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5368 (define_insn "*addqi_1"
5369 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5370 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5371 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5372 (clobber (reg:CC FLAGS_REG))]
5373 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5375 bool widen = (which_alternative == 3 || which_alternative == 4);
5377 switch (get_attr_type (insn))
5383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5384 if (operands[2] == const1_rtx)
5385 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5388 gcc_assert (operands[2] == constm1_rtx);
5389 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5393 /* For most processors, ADD is faster than LEA. These alternatives
5394 were added to use ADD as much as possible. */
5395 if (which_alternative == 2 || which_alternative == 4)
5396 std::swap (operands[1], operands[2]);
5398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399 if (x86_maybe_negate_const_int (&operands[2], QImode))
5402 return "sub{l}\t{%2, %k0|%k0, %2}";
5404 return "sub{b}\t{%2, %0|%0, %2}";
5407 return "add{l}\t{%k2, %k0|%k0, %k2}";
5409 return "add{b}\t{%2, %0|%0, %2}";
5413 (cond [(eq_attr "alternative" "5")
5414 (const_string "lea")
5415 (match_operand:QI 2 "incdec_operand")
5416 (const_string "incdec")
5418 (const_string "alu")))
5419 (set (attr "length_immediate")
5421 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5423 (const_string "*")))
5424 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5426 (define_insn "*addqi_1_slp"
5427 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5428 (plus:QI (match_dup 0)
5429 (match_operand:QI 1 "general_operand" "qn,qm")))
5430 (clobber (reg:CC FLAGS_REG))]
5431 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5432 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5434 switch (get_attr_type (insn))
5437 if (operands[1] == const1_rtx)
5438 return "inc{b}\t%0";
5441 gcc_assert (operands[1] == constm1_rtx);
5442 return "dec{b}\t%0";
5446 if (x86_maybe_negate_const_int (&operands[1], QImode))
5447 return "sub{b}\t{%1, %0|%0, %1}";
5449 return "add{b}\t{%1, %0|%0, %1}";
5453 (if_then_else (match_operand:QI 1 "incdec_operand")
5454 (const_string "incdec")
5455 (const_string "alu1")))
5456 (set (attr "memory")
5457 (if_then_else (match_operand 1 "memory_operand")
5458 (const_string "load")
5459 (const_string "none")))
5460 (set_attr "mode" "QI")])
5462 ;; Split non destructive adds if we cannot use lea.
5464 [(set (match_operand:SWI48 0 "register_operand")
5465 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5466 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5469 [(set (match_dup 0) (match_dup 1))
5470 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5471 (clobber (reg:CC FLAGS_REG))])])
5473 ;; Convert add to the lea pattern to avoid flags dependency.
5475 [(set (match_operand:SWI 0 "register_operand")
5476 (plus:SWI (match_operand:SWI 1 "register_operand")
5477 (match_operand:SWI 2 "<nonmemory_operand>")))
5478 (clobber (reg:CC FLAGS_REG))]
5479 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5482 machine_mode mode = <MODE>mode;
5485 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5488 operands[0] = gen_lowpart (mode, operands[0]);
5489 operands[1] = gen_lowpart (mode, operands[1]);
5490 operands[2] = gen_lowpart (mode, operands[2]);
5493 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5495 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5499 ;; Split non destructive adds if we cannot use lea.
5501 [(set (match_operand:DI 0 "register_operand")
5503 (plus:SI (match_operand:SI 1 "register_operand")
5504 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5505 (clobber (reg:CC FLAGS_REG))]
5507 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5508 [(set (match_dup 3) (match_dup 1))
5509 (parallel [(set (match_dup 0)
5510 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5511 (clobber (reg:CC FLAGS_REG))])]
5512 "operands[3] = gen_lowpart (SImode, operands[0]);")
5514 ;; Convert add to the lea pattern to avoid flags dependency.
5516 [(set (match_operand:DI 0 "register_operand")
5518 (plus:SI (match_operand:SI 1 "register_operand")
5519 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5523 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5525 (define_insn "*add<mode>_2"
5526 [(set (reg FLAGS_REG)
5529 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5530 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5532 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5533 (plus:SWI (match_dup 1) (match_dup 2)))]
5534 "ix86_match_ccmode (insn, CCGOCmode)
5535 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5537 switch (get_attr_type (insn))
5540 if (operands[2] == const1_rtx)
5541 return "inc{<imodesuffix>}\t%0";
5544 gcc_assert (operands[2] == constm1_rtx);
5545 return "dec{<imodesuffix>}\t%0";
5549 if (which_alternative == 2)
5550 std::swap (operands[1], operands[2]);
5552 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5553 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5554 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5556 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5560 (if_then_else (match_operand:SWI 2 "incdec_operand")
5561 (const_string "incdec")
5562 (const_string "alu")))
5563 (set (attr "length_immediate")
5565 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5567 (const_string "*")))
5568 (set_attr "mode" "<MODE>")])
5570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5571 (define_insn "*addsi_2_zext"
5572 [(set (reg FLAGS_REG)
5574 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5575 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5577 (set (match_operand:DI 0 "register_operand" "=r,r")
5578 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5579 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5580 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5582 switch (get_attr_type (insn))
5585 if (operands[2] == const1_rtx)
5586 return "inc{l}\t%k0";
5589 gcc_assert (operands[2] == constm1_rtx);
5590 return "dec{l}\t%k0";
5594 if (which_alternative == 1)
5595 std::swap (operands[1], operands[2]);
5597 if (x86_maybe_negate_const_int (&operands[2], SImode))
5598 return "sub{l}\t{%2, %k0|%k0, %2}";
5600 return "add{l}\t{%2, %k0|%k0, %2}";
5604 (if_then_else (match_operand:SI 2 "incdec_operand")
5605 (const_string "incdec")
5606 (const_string "alu")))
5607 (set (attr "length_immediate")
5609 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5611 (const_string "*")))
5612 (set_attr "mode" "SI")])
5614 (define_insn "*add<mode>_3"
5615 [(set (reg FLAGS_REG)
5617 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5618 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5619 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5620 "ix86_match_ccmode (insn, CCZmode)
5621 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5623 switch (get_attr_type (insn))
5626 if (operands[2] == const1_rtx)
5627 return "inc{<imodesuffix>}\t%0";
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{<imodesuffix>}\t%0";
5635 if (which_alternative == 1)
5636 std::swap (operands[1], operands[2]);
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5640 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5642 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5646 (if_then_else (match_operand:SWI 2 "incdec_operand")
5647 (const_string "incdec")
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5653 (const_string "*")))
5654 (set_attr "mode" "<MODE>")])
5656 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5657 (define_insn "*addsi_3_zext"
5658 [(set (reg FLAGS_REG)
5660 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5661 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5662 (set (match_operand:DI 0 "register_operand" "=r,r")
5663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5664 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5665 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5667 switch (get_attr_type (insn))
5670 if (operands[2] == const1_rtx)
5671 return "inc{l}\t%k0";
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return "dec{l}\t%k0";
5679 if (which_alternative == 1)
5680 std::swap (operands[1], operands[2]);
5682 if (x86_maybe_negate_const_int (&operands[2], SImode))
5683 return "sub{l}\t{%2, %k0|%k0, %2}";
5685 return "add{l}\t{%2, %k0|%k0, %2}";
5689 (if_then_else (match_operand:SI 2 "incdec_operand")
5690 (const_string "incdec")
5691 (const_string "alu")))
5692 (set (attr "length_immediate")
5694 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5696 (const_string "*")))
5697 (set_attr "mode" "SI")])
5699 ; For comparisons against 1, -1 and 128, we may generate better code
5700 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5701 ; is matched then. We can't accept general immediate, because for
5702 ; case of overflows, the result is messed up.
5703 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5704 ; only for comparisons not depending on it.
5706 (define_insn "*adddi_4"
5707 [(set (reg FLAGS_REG)
5709 (match_operand:DI 1 "nonimmediate_operand" "0")
5710 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5711 (clobber (match_scratch:DI 0 "=rm"))]
5713 && ix86_match_ccmode (insn, CCGCmode)"
5715 switch (get_attr_type (insn))
5718 if (operands[2] == constm1_rtx)
5719 return "inc{q}\t%0";
5722 gcc_assert (operands[2] == const1_rtx);
5723 return "dec{q}\t%0";
5727 if (x86_maybe_negate_const_int (&operands[2], DImode))
5728 return "add{q}\t{%2, %0|%0, %2}";
5730 return "sub{q}\t{%2, %0|%0, %2}";
5734 (if_then_else (match_operand:DI 2 "incdec_operand")
5735 (const_string "incdec")
5736 (const_string "alu")))
5737 (set (attr "length_immediate")
5739 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5741 (const_string "*")))
5742 (set_attr "mode" "DI")])
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5749 ; only for comparisons not depending on it.
5751 (define_insn "*add<mode>_4"
5752 [(set (reg FLAGS_REG)
5754 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5755 (match_operand:SWI124 2 "const_int_operand" "n")))
5756 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5757 "ix86_match_ccmode (insn, CCGCmode)"
5759 switch (get_attr_type (insn))
5762 if (operands[2] == constm1_rtx)
5763 return "inc{<imodesuffix>}\t%0";
5766 gcc_assert (operands[2] == const1_rtx);
5767 return "dec{<imodesuffix>}\t%0";
5771 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5772 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5774 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5778 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5779 (const_string "incdec")
5780 (const_string "alu")))
5781 (set (attr "length_immediate")
5783 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5785 (const_string "*")))
5786 (set_attr "mode" "<MODE>")])
5788 (define_insn "*add<mode>_5"
5789 [(set (reg FLAGS_REG)
5792 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5793 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5795 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5796 "ix86_match_ccmode (insn, CCGOCmode)
5797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5799 switch (get_attr_type (insn))
5802 if (operands[2] == const1_rtx)
5803 return "inc{<imodesuffix>}\t%0";
5806 gcc_assert (operands[2] == constm1_rtx);
5807 return "dec{<imodesuffix>}\t%0";
5811 if (which_alternative == 1)
5812 std::swap (operands[1], operands[2]);
5814 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5815 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5816 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5818 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5822 (if_then_else (match_operand:SWI 2 "incdec_operand")
5823 (const_string "incdec")
5824 (const_string "alu")))
5825 (set (attr "length_immediate")
5827 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5829 (const_string "*")))
5830 (set_attr "mode" "<MODE>")])
5832 (define_insn "addqi_ext_1"
5833 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5838 (match_operand 1 "ext_register_operand" "0,0")
5841 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5842 (clobber (reg:CC FLAGS_REG))]
5845 switch (get_attr_type (insn))
5848 if (operands[2] == const1_rtx)
5849 return "inc{b}\t%h0";
5852 gcc_assert (operands[2] == constm1_rtx);
5853 return "dec{b}\t%h0";
5857 return "add{b}\t{%2, %h0|%h0, %2}";
5860 [(set_attr "isa" "*,nox64")
5862 (if_then_else (match_operand:QI 2 "incdec_operand")
5863 (const_string "incdec")
5864 (const_string "alu")))
5865 (set_attr "modrm" "1")
5866 (set_attr "mode" "QI")])
5868 (define_insn "*addqi_ext_2"
5869 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5874 (match_operand 1 "ext_register_operand" "%0")
5878 (match_operand 2 "ext_register_operand" "Q")
5881 (clobber (reg:CC FLAGS_REG))]
5883 "add{b}\t{%h2, %h0|%h0, %h2}"
5884 [(set_attr "type" "alu")
5885 (set_attr "mode" "QI")])
5887 ;; Add with jump on overflow.
5888 (define_expand "addv<mode>4"
5889 [(parallel [(set (reg:CCO FLAGS_REG)
5892 (match_operand:SWI 1 "nonimmediate_operand"))
5895 (plus:SWI (match_dup 1)
5896 (match_operand:SWI 2
5897 "<general_operand>")))))
5898 (set (match_operand:SWI 0 "register_operand")
5899 (plus:SWI (match_dup 1) (match_dup 2)))])
5900 (set (pc) (if_then_else
5901 (eq (reg:CCO FLAGS_REG) (const_int 0))
5902 (label_ref (match_operand 3))
5906 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5907 if (CONST_INT_P (operands[2]))
5908 operands[4] = operands[2];
5910 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5913 (define_insn "*addv<mode>4"
5914 [(set (reg:CCO FLAGS_REG)
5917 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5919 (match_operand:SWI 2 "<general_sext_operand>"
5922 (plus:SWI (match_dup 1) (match_dup 2)))))
5923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5924 (plus:SWI (match_dup 1) (match_dup 2)))]
5925 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5926 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5927 [(set_attr "type" "alu")
5928 (set_attr "mode" "<MODE>")])
5930 (define_insn "*addv<mode>4_1"
5931 [(set (reg:CCO FLAGS_REG)
5934 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5935 (match_operand:<DWI> 3 "const_int_operand" "i"))
5937 (plus:SWI (match_dup 1)
5938 (match_operand:SWI 2 "x86_64_immediate_operand"
5940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5941 (plus:SWI (match_dup 1) (match_dup 2)))]
5942 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5943 && CONST_INT_P (operands[2])
5944 && INTVAL (operands[2]) == INTVAL (operands[3])"
5945 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5946 [(set_attr "type" "alu")
5947 (set_attr "mode" "<MODE>")
5948 (set (attr "length_immediate")
5949 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5951 (match_test "<MODE_SIZE> == 8")
5953 (const_string "<MODE_SIZE>")))])
5955 ;; The lea patterns for modes less than 32 bits need to be matched by
5956 ;; several insns converted to real lea by splitters.
5958 (define_insn_and_split "*lea_general_1"
5959 [(set (match_operand 0 "register_operand" "=r")
5960 (plus (plus (match_operand 1 "index_register_operand" "l")
5961 (match_operand 2 "register_operand" "r"))
5962 (match_operand 3 "immediate_operand" "i")))]
5963 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5964 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5965 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5966 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5967 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5968 || GET_MODE (operands[3]) == VOIDmode)"
5970 "&& reload_completed"
5973 machine_mode mode = SImode;
5976 operands[0] = gen_lowpart (mode, operands[0]);
5977 operands[1] = gen_lowpart (mode, operands[1]);
5978 operands[2] = gen_lowpart (mode, operands[2]);
5979 operands[3] = gen_lowpart (mode, operands[3]);
5981 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5987 [(set_attr "type" "lea")
5988 (set_attr "mode" "SI")])
5990 (define_insn_and_split "*lea_general_2"
5991 [(set (match_operand 0 "register_operand" "=r")
5992 (plus (mult (match_operand 1 "index_register_operand" "l")
5993 (match_operand 2 "const248_operand" "n"))
5994 (match_operand 3 "nonmemory_operand" "ri")))]
5995 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5996 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5997 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5998 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5999 || GET_MODE (operands[3]) == VOIDmode)"
6001 "&& reload_completed"
6004 machine_mode mode = SImode;
6007 operands[0] = gen_lowpart (mode, operands[0]);
6008 operands[1] = gen_lowpart (mode, operands[1]);
6009 operands[3] = gen_lowpart (mode, operands[3]);
6011 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6014 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6017 [(set_attr "type" "lea")
6018 (set_attr "mode" "SI")])
6020 (define_insn_and_split "*lea_general_3"
6021 [(set (match_operand 0 "register_operand" "=r")
6022 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6023 (match_operand 2 "const248_operand" "n"))
6024 (match_operand 3 "register_operand" "r"))
6025 (match_operand 4 "immediate_operand" "i")))]
6026 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6027 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6028 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6029 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6031 "&& reload_completed"
6034 machine_mode mode = SImode;
6037 operands[0] = gen_lowpart (mode, operands[0]);
6038 operands[1] = gen_lowpart (mode, operands[1]);
6039 operands[3] = gen_lowpart (mode, operands[3]);
6040 operands[4] = gen_lowpart (mode, operands[4]);
6042 pat = gen_rtx_PLUS (mode,
6044 gen_rtx_MULT (mode, operands[1],
6049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6052 [(set_attr "type" "lea")
6053 (set_attr "mode" "SI")])
6055 (define_insn_and_split "*lea_general_4"
6056 [(set (match_operand 0 "register_operand" "=r")
6058 (match_operand 1 "index_register_operand" "l")
6059 (match_operand 2 "const_int_operand" "n"))
6060 (match_operand 3 "const_int_operand" "n")))]
6061 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6062 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6063 || GET_MODE (operands[0]) == SImode
6064 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6066 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6067 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6068 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6070 "&& reload_completed"
6073 machine_mode mode = GET_MODE (operands[0]);
6076 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6079 operands[0] = gen_lowpart (mode, operands[0]);
6080 operands[1] = gen_lowpart (mode, operands[1]);
6083 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6085 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6086 INTVAL (operands[3]));
6088 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6091 [(set_attr "type" "lea")
6093 (if_then_else (match_operand:DI 0)
6095 (const_string "SI")))])
6097 ;; Subtract instructions
6099 (define_expand "sub<mode>3"
6100 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6101 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6102 (match_operand:SDWIM 2 "<general_operand>")))]
6104 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6106 (define_insn_and_split "*sub<dwi>3_doubleword"
6107 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6109 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6110 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6111 (clobber (reg:CC FLAGS_REG))]
6112 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6115 [(parallel [(set (reg:CC FLAGS_REG)
6116 (compare:CC (match_dup 1) (match_dup 2)))
6118 (minus:DWIH (match_dup 1) (match_dup 2)))])
6119 (parallel [(set (match_dup 3)
6123 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6125 (clobber (reg:CC FLAGS_REG))])]
6126 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6128 (define_insn "*sub<mode>_1"
6129 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6131 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6132 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6135 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6136 [(set_attr "type" "alu")
6137 (set_attr "mode" "<MODE>")])
6139 (define_insn "*subsi_1_zext"
6140 [(set (match_operand:DI 0 "register_operand" "=r")
6142 (minus:SI (match_operand:SI 1 "register_operand" "0")
6143 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6144 (clobber (reg:CC FLAGS_REG))]
6145 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6146 "sub{l}\t{%2, %k0|%k0, %2}"
6147 [(set_attr "type" "alu")
6148 (set_attr "mode" "SI")])
6150 (define_insn "*subqi_1_slp"
6151 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6152 (minus:QI (match_dup 0)
6153 (match_operand:QI 1 "general_operand" "qn,qm")))
6154 (clobber (reg:CC FLAGS_REG))]
6155 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6156 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6157 "sub{b}\t{%1, %0|%0, %1}"
6158 [(set_attr "type" "alu1")
6159 (set_attr "mode" "QI")])
6161 (define_insn "*sub<mode>_2"
6162 [(set (reg FLAGS_REG)
6165 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6166 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6168 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6169 (minus:SWI (match_dup 1) (match_dup 2)))]
6170 "ix86_match_ccmode (insn, CCGOCmode)
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_2_zext"
6177 [(set (reg FLAGS_REG)
6179 (minus:SI (match_operand:SI 1 "register_operand" "0")
6180 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6182 (set (match_operand:DI 0 "register_operand" "=r")
6184 (minus:SI (match_dup 1)
6186 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6188 "sub{l}\t{%2, %k0|%k0, %2}"
6189 [(set_attr "type" "alu")
6190 (set_attr "mode" "SI")])
6192 ;; Subtract with jump on overflow.
6193 (define_expand "subv<mode>4"
6194 [(parallel [(set (reg:CCO FLAGS_REG)
6195 (eq:CCO (minus:<DWI>
6197 (match_operand:SWI 1 "nonimmediate_operand"))
6200 (minus:SWI (match_dup 1)
6201 (match_operand:SWI 2
6202 "<general_operand>")))))
6203 (set (match_operand:SWI 0 "register_operand")
6204 (minus:SWI (match_dup 1) (match_dup 2)))])
6205 (set (pc) (if_then_else
6206 (eq (reg:CCO FLAGS_REG) (const_int 0))
6207 (label_ref (match_operand 3))
6211 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6212 if (CONST_INT_P (operands[2]))
6213 operands[4] = operands[2];
6215 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6218 (define_insn "*subv<mode>4"
6219 [(set (reg:CCO FLAGS_REG)
6220 (eq:CCO (minus:<DWI>
6222 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6224 (match_operand:SWI 2 "<general_sext_operand>"
6227 (minus:SWI (match_dup 1) (match_dup 2)))))
6228 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6229 (minus:SWI (match_dup 1) (match_dup 2)))]
6230 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6231 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6232 [(set_attr "type" "alu")
6233 (set_attr "mode" "<MODE>")])
6235 (define_insn "*subv<mode>4_1"
6236 [(set (reg:CCO FLAGS_REG)
6237 (eq:CCO (minus:<DWI>
6239 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6240 (match_operand:<DWI> 3 "const_int_operand" "i"))
6242 (minus:SWI (match_dup 1)
6243 (match_operand:SWI 2 "x86_64_immediate_operand"
6245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6246 (minus:SWI (match_dup 1) (match_dup 2)))]
6247 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6248 && CONST_INT_P (operands[2])
6249 && INTVAL (operands[2]) == INTVAL (operands[3])"
6250 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6251 [(set_attr "type" "alu")
6252 (set_attr "mode" "<MODE>")
6253 (set (attr "length_immediate")
6254 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6256 (match_test "<MODE_SIZE> == 8")
6258 (const_string "<MODE_SIZE>")))])
6260 (define_insn "*sub<mode>_3"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6263 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6264 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6265 (minus:SWI (match_dup 1) (match_dup 2)))]
6266 "ix86_match_ccmode (insn, CCmode)
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 "*subsi_3_zext"
6273 [(set (reg FLAGS_REG)
6274 (compare (match_operand:SI 1 "register_operand" "0")
6275 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6276 (set (match_operand:DI 0 "register_operand" "=r")
6278 (minus:SI (match_dup 1)
6280 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6281 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6282 "sub{l}\t{%2, %1|%1, %2}"
6283 [(set_attr "type" "alu")
6284 (set_attr "mode" "SI")])
6286 ;; Add with carry and subtract with borrow
6288 (define_expand "<plusminus_insn><mode>3_carry"
6290 [(set (match_operand:SWI 0 "nonimmediate_operand")
6292 (match_operand:SWI 1 "nonimmediate_operand")
6293 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6294 [(match_operand 3 "flags_reg_operand")
6296 (match_operand:SWI 2 "<general_operand>"))))
6297 (clobber (reg:CC FLAGS_REG))])]
6298 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6300 (define_insn "*<plusminus_insn><mode>3_carry"
6301 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6303 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6305 (match_operator 3 "ix86_carry_flag_operator"
6306 [(reg FLAGS_REG) (const_int 0)])
6307 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6308 (clobber (reg:CC FLAGS_REG))]
6309 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6310 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6311 [(set_attr "type" "alu")
6312 (set_attr "use_carry" "1")
6313 (set_attr "pent_pair" "pu")
6314 (set_attr "mode" "<MODE>")])
6316 (define_insn "*addsi3_carry_zext"
6317 [(set (match_operand:DI 0 "register_operand" "=r")
6319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6320 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6321 [(reg FLAGS_REG) (const_int 0)])
6322 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6323 (clobber (reg:CC FLAGS_REG))]
6324 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6325 "adc{l}\t{%2, %k0|%k0, %2}"
6326 [(set_attr "type" "alu")
6327 (set_attr "use_carry" "1")
6328 (set_attr "pent_pair" "pu")
6329 (set_attr "mode" "SI")])
6331 (define_insn "*subsi3_carry_zext"
6332 [(set (match_operand:DI 0 "register_operand" "=r")
6334 (minus:SI (match_operand:SI 1 "register_operand" "0")
6335 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6336 [(reg FLAGS_REG) (const_int 0)])
6337 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6338 (clobber (reg:CC FLAGS_REG))]
6339 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6340 "sbb{l}\t{%2, %k0|%k0, %2}"
6341 [(set_attr "type" "alu")
6342 (set_attr "pent_pair" "pu")
6343 (set_attr "mode" "SI")])
6347 (define_insn "adcx<mode>3"
6348 [(set (reg:CCC FLAGS_REG)
6351 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6353 (match_operator 4 "ix86_carry_flag_operator"
6354 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6355 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6357 (set (match_operand:SWI48 0 "register_operand" "=r")
6358 (plus:SWI48 (match_dup 1)
6359 (plus:SWI48 (match_op_dup 4
6360 [(match_dup 3) (const_int 0)])
6362 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6363 "adcx\t{%2, %0|%0, %2}"
6364 [(set_attr "type" "alu")
6365 (set_attr "use_carry" "1")
6366 (set_attr "mode" "<MODE>")])
6368 ;; Overflow setting add instructions
6370 (define_insn "*add<mode>3_cconly_overflow"
6371 [(set (reg:CCC FLAGS_REG)
6374 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6375 (match_operand:SWI 2 "<general_operand>" "<g>"))
6377 (clobber (match_scratch:SWI 0 "=<r>"))]
6378 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6379 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "<MODE>")])
6383 (define_insn "*add<mode>3_cc_overflow"
6384 [(set (reg:CCC FLAGS_REG)
6387 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6390 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6391 (plus:SWI (match_dup 1) (match_dup 2)))]
6392 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6393 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6394 [(set_attr "type" "alu")
6395 (set_attr "mode" "<MODE>")])
6397 (define_insn "*addsi3_zext_cc_overflow"
6398 [(set (reg:CCC FLAGS_REG)
6401 (match_operand:SI 1 "nonimmediate_operand" "%0")
6402 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6404 (set (match_operand:DI 0 "register_operand" "=r")
6405 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6406 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6407 "add{l}\t{%2, %k0|%k0, %2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "SI")])
6411 ;; The patterns that match these are at the end of this file.
6413 (define_expand "<plusminus_insn>xf3"
6414 [(set (match_operand:XF 0 "register_operand")
6416 (match_operand:XF 1 "register_operand")
6417 (match_operand:XF 2 "register_operand")))]
6420 (define_expand "<plusminus_insn><mode>3"
6421 [(set (match_operand:MODEF 0 "register_operand")
6423 (match_operand:MODEF 1 "register_operand")
6424 (match_operand:MODEF 2 "nonimmediate_operand")))]
6425 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6426 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6428 ;; Multiply instructions
6430 (define_expand "mul<mode>3"
6431 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6433 (match_operand:SWIM248 1 "register_operand")
6434 (match_operand:SWIM248 2 "<general_operand>")))
6435 (clobber (reg:CC FLAGS_REG))])])
6437 (define_expand "mulqi3"
6438 [(parallel [(set (match_operand:QI 0 "register_operand")
6440 (match_operand:QI 1 "register_operand")
6441 (match_operand:QI 2 "nonimmediate_operand")))
6442 (clobber (reg:CC FLAGS_REG))])]
6443 "TARGET_QIMODE_MATH")
6446 ;; IMUL reg32/64, reg32/64, imm8 Direct
6447 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6448 ;; IMUL reg32/64, reg32/64, imm32 Direct
6449 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6450 ;; IMUL reg32/64, reg32/64 Direct
6451 ;; IMUL reg32/64, mem32/64 Direct
6453 ;; On BDVER1, all above IMULs use DirectPath
6455 (define_insn "*mul<mode>3_1"
6456 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6458 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6459 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6463 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6464 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6465 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6466 [(set_attr "type" "imul")
6467 (set_attr "prefix_0f" "0,0,1")
6468 (set (attr "athlon_decode")
6469 (cond [(eq_attr "cpu" "athlon")
6470 (const_string "vector")
6471 (eq_attr "alternative" "1")
6472 (const_string "vector")
6473 (and (eq_attr "alternative" "2")
6474 (match_operand 1 "memory_operand"))
6475 (const_string "vector")]
6476 (const_string "direct")))
6477 (set (attr "amdfam10_decode")
6478 (cond [(and (eq_attr "alternative" "0,1")
6479 (match_operand 1 "memory_operand"))
6480 (const_string "vector")]
6481 (const_string "direct")))
6482 (set_attr "bdver1_decode" "direct")
6483 (set_attr "mode" "<MODE>")])
6485 (define_insn "*mulsi3_1_zext"
6486 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6488 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6489 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6490 (clobber (reg:CC FLAGS_REG))]
6492 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6494 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6495 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6496 imul{l}\t{%2, %k0|%k0, %2}"
6497 [(set_attr "type" "imul")
6498 (set_attr "prefix_0f" "0,0,1")
6499 (set (attr "athlon_decode")
6500 (cond [(eq_attr "cpu" "athlon")
6501 (const_string "vector")
6502 (eq_attr "alternative" "1")
6503 (const_string "vector")
6504 (and (eq_attr "alternative" "2")
6505 (match_operand 1 "memory_operand"))
6506 (const_string "vector")]
6507 (const_string "direct")))
6508 (set (attr "amdfam10_decode")
6509 (cond [(and (eq_attr "alternative" "0,1")
6510 (match_operand 1 "memory_operand"))
6511 (const_string "vector")]
6512 (const_string "direct")))
6513 (set_attr "bdver1_decode" "direct")
6514 (set_attr "mode" "SI")])
6517 ;; IMUL reg16, reg16, imm8 VectorPath
6518 ;; IMUL reg16, mem16, imm8 VectorPath
6519 ;; IMUL reg16, reg16, imm16 VectorPath
6520 ;; IMUL reg16, mem16, imm16 VectorPath
6521 ;; IMUL reg16, reg16 Direct
6522 ;; IMUL reg16, mem16 Direct
6524 ;; On BDVER1, all HI MULs use DoublePath
6526 (define_insn "*mulhi3_1"
6527 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6528 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6529 (match_operand:HI 2 "general_operand" "K,n,mr")))
6530 (clobber (reg:CC FLAGS_REG))]
6532 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6534 imul{w}\t{%2, %1, %0|%0, %1, %2}
6535 imul{w}\t{%2, %1, %0|%0, %1, %2}
6536 imul{w}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "imul")
6538 (set_attr "prefix_0f" "0,0,1")
6539 (set (attr "athlon_decode")
6540 (cond [(eq_attr "cpu" "athlon")
6541 (const_string "vector")
6542 (eq_attr "alternative" "1,2")
6543 (const_string "vector")]
6544 (const_string "direct")))
6545 (set (attr "amdfam10_decode")
6546 (cond [(eq_attr "alternative" "0,1")
6547 (const_string "vector")]
6548 (const_string "direct")))
6549 (set_attr "bdver1_decode" "double")
6550 (set_attr "mode" "HI")])
6552 ;;On AMDFAM10 and BDVER1
6556 (define_insn "*mulqi3_1"
6557 [(set (match_operand:QI 0 "register_operand" "=a")
6558 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6559 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6560 (clobber (reg:CC FLAGS_REG))]
6562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6564 [(set_attr "type" "imul")
6565 (set_attr "length_immediate" "0")
6566 (set (attr "athlon_decode")
6567 (if_then_else (eq_attr "cpu" "athlon")
6568 (const_string "vector")
6569 (const_string "direct")))
6570 (set_attr "amdfam10_decode" "direct")
6571 (set_attr "bdver1_decode" "direct")
6572 (set_attr "mode" "QI")])
6574 ;; Multiply with jump on overflow.
6575 (define_expand "mulv<mode>4"
6576 [(parallel [(set (reg:CCO FLAGS_REG)
6579 (match_operand:SWI48 1 "register_operand"))
6582 (mult:SWI48 (match_dup 1)
6583 (match_operand:SWI48 2
6584 "<general_operand>")))))
6585 (set (match_operand:SWI48 0 "register_operand")
6586 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6587 (set (pc) (if_then_else
6588 (eq (reg:CCO FLAGS_REG) (const_int 0))
6589 (label_ref (match_operand 3))
6593 if (CONST_INT_P (operands[2]))
6594 operands[4] = operands[2];
6596 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6599 (define_insn "*mulv<mode>4"
6600 [(set (reg:CCO FLAGS_REG)
6603 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6605 (match_operand:SWI48 2 "<general_sext_operand>"
6608 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6609 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6610 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6611 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6613 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6614 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "imul")
6616 (set_attr "prefix_0f" "0,1")
6617 (set (attr "athlon_decode")
6618 (cond [(eq_attr "cpu" "athlon")
6619 (const_string "vector")
6620 (eq_attr "alternative" "0")
6621 (const_string "vector")
6622 (and (eq_attr "alternative" "1")
6623 (match_operand 1 "memory_operand"))
6624 (const_string "vector")]
6625 (const_string "direct")))
6626 (set (attr "amdfam10_decode")
6627 (cond [(and (eq_attr "alternative" "1")
6628 (match_operand 1 "memory_operand"))
6629 (const_string "vector")]
6630 (const_string "direct")))
6631 (set_attr "bdver1_decode" "direct")
6632 (set_attr "mode" "<MODE>")])
6634 (define_insn "*mulv<mode>4_1"
6635 [(set (reg:CCO FLAGS_REG)
6638 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6639 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6641 (mult:SWI48 (match_dup 1)
6642 (match_operand:SWI 2 "x86_64_immediate_operand"
6644 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6645 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6646 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6647 && CONST_INT_P (operands[2])
6648 && INTVAL (operands[2]) == INTVAL (operands[3])"
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6652 [(set_attr "type" "imul")
6653 (set (attr "athlon_decode")
6654 (cond [(eq_attr "cpu" "athlon")
6655 (const_string "vector")
6656 (eq_attr "alternative" "1")
6657 (const_string "vector")]
6658 (const_string "direct")))
6659 (set (attr "amdfam10_decode")
6660 (cond [(match_operand 1 "memory_operand")
6661 (const_string "vector")]
6662 (const_string "direct")))
6663 (set_attr "bdver1_decode" "direct")
6664 (set_attr "mode" "<MODE>")
6665 (set (attr "length_immediate")
6666 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6668 (match_test "<MODE_SIZE> == 8")
6670 (const_string "<MODE_SIZE>")))])
6672 (define_expand "umulv<mode>4"
6673 [(parallel [(set (reg:CCO FLAGS_REG)
6676 (match_operand:SWI48 1
6677 "nonimmediate_operand"))
6679 (match_operand:SWI48 2
6680 "nonimmediate_operand")))
6682 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6683 (set (match_operand:SWI48 0 "register_operand")
6684 (mult:SWI48 (match_dup 1) (match_dup 2)))
6685 (clobber (match_scratch:SWI48 4))])
6686 (set (pc) (if_then_else
6687 (eq (reg:CCO FLAGS_REG) (const_int 0))
6688 (label_ref (match_operand 3))
6692 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6693 operands[1] = force_reg (<MODE>mode, operands[1]);
6696 (define_insn "*umulv<mode>4"
6697 [(set (reg:CCO FLAGS_REG)
6700 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6702 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6704 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6705 (set (match_operand:SWI48 0 "register_operand" "=a")
6706 (mult:SWI48 (match_dup 1) (match_dup 2)))
6707 (clobber (match_scratch:SWI48 3 "=d"))]
6708 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 "mul{<imodesuffix>}\t%2"
6710 [(set_attr "type" "imul")
6711 (set_attr "length_immediate" "0")
6712 (set (attr "athlon_decode")
6713 (if_then_else (eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (const_string "double")))
6716 (set_attr "amdfam10_decode" "double")
6717 (set_attr "bdver1_decode" "direct")
6718 (set_attr "mode" "<MODE>")])
6720 (define_expand "<u>mulvqi4"
6721 [(parallel [(set (reg:CCO FLAGS_REG)
6724 (match_operand:QI 1 "nonimmediate_operand"))
6726 (match_operand:QI 2 "nonimmediate_operand")))
6728 (mult:QI (match_dup 1) (match_dup 2)))))
6729 (set (match_operand:QI 0 "register_operand")
6730 (mult:QI (match_dup 1) (match_dup 2)))])
6731 (set (pc) (if_then_else
6732 (eq (reg:CCO FLAGS_REG) (const_int 0))
6733 (label_ref (match_operand 3))
6735 "TARGET_QIMODE_MATH"
6737 if (MEM_P (operands[1]) && MEM_P (operands[2]))
6738 operands[1] = force_reg (QImode, operands[1]);
6741 (define_insn "*<u>mulvqi4"
6742 [(set (reg:CCO FLAGS_REG)
6745 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6747 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6749 (mult:QI (match_dup 1) (match_dup 2)))))
6750 (set (match_operand:QI 0 "register_operand" "=a")
6751 (mult:QI (match_dup 1) (match_dup 2)))]
6753 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6754 "<sgnprefix>mul{b}\t%2"
6755 [(set_attr "type" "imul")
6756 (set_attr "length_immediate" "0")
6757 (set (attr "athlon_decode")
6758 (if_then_else (eq_attr "cpu" "athlon")
6759 (const_string "vector")
6760 (const_string "direct")))
6761 (set_attr "amdfam10_decode" "direct")
6762 (set_attr "bdver1_decode" "direct")
6763 (set_attr "mode" "QI")])
6765 (define_expand "<u>mul<mode><dwi>3"
6766 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6769 (match_operand:DWIH 1 "nonimmediate_operand"))
6771 (match_operand:DWIH 2 "register_operand"))))
6772 (clobber (reg:CC FLAGS_REG))])])
6774 (define_expand "<u>mulqihi3"
6775 [(parallel [(set (match_operand:HI 0 "register_operand")
6778 (match_operand:QI 1 "nonimmediate_operand"))
6780 (match_operand:QI 2 "register_operand"))))
6781 (clobber (reg:CC FLAGS_REG))])]
6782 "TARGET_QIMODE_MATH")
6784 (define_insn "*bmi2_umulditi3_1"
6785 [(set (match_operand:DI 0 "register_operand" "=r")
6787 (match_operand:DI 2 "nonimmediate_operand" "%d")
6788 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6789 (set (match_operand:DI 1 "register_operand" "=r")
6792 (mult:TI (zero_extend:TI (match_dup 2))
6793 (zero_extend:TI (match_dup 3)))
6795 "TARGET_64BIT && TARGET_BMI2
6796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797 "mulx\t{%3, %0, %1|%1, %0, %3}"
6798 [(set_attr "type" "imulx")
6799 (set_attr "prefix" "vex")
6800 (set_attr "mode" "DI")])
6802 (define_insn "*bmi2_umulsidi3_1"
6803 [(set (match_operand:SI 0 "register_operand" "=r")
6805 (match_operand:SI 2 "nonimmediate_operand" "%d")
6806 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6807 (set (match_operand:SI 1 "register_operand" "=r")
6810 (mult:DI (zero_extend:DI (match_dup 2))
6811 (zero_extend:DI (match_dup 3)))
6813 "!TARGET_64BIT && TARGET_BMI2
6814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 "mulx\t{%3, %0, %1|%1, %0, %3}"
6816 [(set_attr "type" "imulx")
6817 (set_attr "prefix" "vex")
6818 (set_attr "mode" "SI")])
6820 (define_insn "*umul<mode><dwi>3_1"
6821 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6824 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6826 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6827 (clobber (reg:CC FLAGS_REG))]
6828 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6831 mul{<imodesuffix>}\t%2"
6832 [(set_attr "isa" "bmi2,*")
6833 (set_attr "type" "imulx,imul")
6834 (set_attr "length_immediate" "*,0")
6835 (set (attr "athlon_decode")
6836 (cond [(eq_attr "alternative" "1")
6837 (if_then_else (eq_attr "cpu" "athlon")
6838 (const_string "vector")
6839 (const_string "double"))]
6840 (const_string "*")))
6841 (set_attr "amdfam10_decode" "*,double")
6842 (set_attr "bdver1_decode" "*,direct")
6843 (set_attr "prefix" "vex,orig")
6844 (set_attr "mode" "<MODE>")])
6846 ;; Convert mul to the mulx pattern to avoid flags dependency.
6848 [(set (match_operand:<DWI> 0 "register_operand")
6851 (match_operand:DWIH 1 "register_operand"))
6853 (match_operand:DWIH 2 "nonimmediate_operand"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "TARGET_BMI2 && reload_completed
6856 && true_regnum (operands[1]) == DX_REG"
6857 [(parallel [(set (match_dup 3)
6858 (mult:DWIH (match_dup 1) (match_dup 2)))
6862 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6863 (zero_extend:<DWI> (match_dup 2)))
6866 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6868 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6871 (define_insn "*mul<mode><dwi>3_1"
6872 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6875 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6877 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6878 (clobber (reg:CC FLAGS_REG))]
6879 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6880 "imul{<imodesuffix>}\t%2"
6881 [(set_attr "type" "imul")
6882 (set_attr "length_immediate" "0")
6883 (set (attr "athlon_decode")
6884 (if_then_else (eq_attr "cpu" "athlon")
6885 (const_string "vector")
6886 (const_string "double")))
6887 (set_attr "amdfam10_decode" "double")
6888 (set_attr "bdver1_decode" "direct")
6889 (set_attr "mode" "<MODE>")])
6891 (define_insn "*<u>mulqihi3_1"
6892 [(set (match_operand:HI 0 "register_operand" "=a")
6895 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6897 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6900 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "<sgnprefix>mul{b}\t%2"
6902 [(set_attr "type" "imul")
6903 (set_attr "length_immediate" "0")
6904 (set (attr "athlon_decode")
6905 (if_then_else (eq_attr "cpu" "athlon")
6906 (const_string "vector")
6907 (const_string "direct")))
6908 (set_attr "amdfam10_decode" "direct")
6909 (set_attr "bdver1_decode" "direct")
6910 (set_attr "mode" "QI")])
6912 (define_expand "<s>mul<mode>3_highpart"
6913 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6918 (match_operand:SWI48 1 "nonimmediate_operand"))
6920 (match_operand:SWI48 2 "register_operand")))
6922 (clobber (match_scratch:SWI48 3))
6923 (clobber (reg:CC FLAGS_REG))])]
6925 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6927 (define_insn "*<s>muldi3_highpart_1"
6928 [(set (match_operand:DI 0 "register_operand" "=d")
6933 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6935 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6937 (clobber (match_scratch:DI 3 "=1"))
6938 (clobber (reg:CC FLAGS_REG))]
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{q}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "DI")])
6952 (define_insn "*<s>mulsi3_highpart_1"
6953 [(set (match_operand:SI 0 "register_operand" "=d")
6958 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6960 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6962 (clobber (match_scratch:SI 3 "=1"))
6963 (clobber (reg:CC FLAGS_REG))]
6964 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965 "<sgnprefix>mul{l}\t%2"
6966 [(set_attr "type" "imul")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "amdfam10_decode" "double")
6973 (set_attr "bdver1_decode" "direct")
6974 (set_attr "mode" "SI")])
6976 (define_insn "*<s>mulsi3_highpart_zext"
6977 [(set (match_operand:DI 0 "register_operand" "=d")
6978 (zero_extend:DI (truncate:SI
6980 (mult:DI (any_extend:DI
6981 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6983 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6985 (clobber (match_scratch:SI 3 "=1"))
6986 (clobber (reg:CC FLAGS_REG))]
6988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6989 "<sgnprefix>mul{l}\t%2"
6990 [(set_attr "type" "imul")
6991 (set_attr "length_immediate" "0")
6992 (set (attr "athlon_decode")
6993 (if_then_else (eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (const_string "double")))
6996 (set_attr "amdfam10_decode" "double")
6997 (set_attr "bdver1_decode" "direct")
6998 (set_attr "mode" "SI")])
7000 ;; The patterns that match these are at the end of this file.
7002 (define_expand "mulxf3"
7003 [(set (match_operand:XF 0 "register_operand")
7004 (mult:XF (match_operand:XF 1 "register_operand")
7005 (match_operand:XF 2 "register_operand")))]
7008 (define_expand "mul<mode>3"
7009 [(set (match_operand:MODEF 0 "register_operand")
7010 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7011 (match_operand:MODEF 2 "nonimmediate_operand")))]
7012 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7013 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7015 ;; Divide instructions
7017 ;; The patterns that match these are at the end of this file.
7019 (define_expand "divxf3"
7020 [(set (match_operand:XF 0 "register_operand")
7021 (div:XF (match_operand:XF 1 "register_operand")
7022 (match_operand:XF 2 "register_operand")))]
7025 (define_expand "divdf3"
7026 [(set (match_operand:DF 0 "register_operand")
7027 (div:DF (match_operand:DF 1 "register_operand")
7028 (match_operand:DF 2 "nonimmediate_operand")))]
7029 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7030 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7032 (define_expand "divsf3"
7033 [(set (match_operand:SF 0 "register_operand")
7034 (div:SF (match_operand:SF 1 "register_operand")
7035 (match_operand:SF 2 "nonimmediate_operand")))]
7036 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7041 && optimize_insn_for_speed_p ()
7042 && flag_finite_math_only && !flag_trapping_math
7043 && flag_unsafe_math_optimizations)
7045 ix86_emit_swdivsf (operands[0], operands[1],
7046 operands[2], SFmode);
7051 ;; Divmod instructions.
7053 (define_expand "divmod<mode>4"
7054 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7056 (match_operand:SWIM248 1 "register_operand")
7057 (match_operand:SWIM248 2 "nonimmediate_operand")))
7058 (set (match_operand:SWIM248 3 "register_operand")
7059 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7060 (clobber (reg:CC FLAGS_REG))])])
7062 ;; Split with 8bit unsigned divide:
7063 ;; if (dividend an divisor are in [0-255])
7064 ;; use 8bit unsigned integer divide
7066 ;; use original integer divide
7068 [(set (match_operand:SWI48 0 "register_operand")
7069 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7070 (match_operand:SWI48 3 "nonimmediate_operand")))
7071 (set (match_operand:SWI48 1 "register_operand")
7072 (mod:SWI48 (match_dup 2) (match_dup 3)))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "TARGET_USE_8BIT_IDIV
7075 && TARGET_QIMODE_MATH
7076 && can_create_pseudo_p ()
7077 && !optimize_insn_for_size_p ()"
7079 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7081 (define_insn_and_split "divmod<mode>4_1"
7082 [(set (match_operand:SWI48 0 "register_operand" "=a")
7083 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7084 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7085 (set (match_operand:SWI48 1 "register_operand" "=&d")
7086 (mod:SWI48 (match_dup 2) (match_dup 3)))
7087 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7088 (clobber (reg:CC FLAGS_REG))]
7092 [(parallel [(set (match_dup 1)
7093 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7094 (clobber (reg:CC FLAGS_REG))])
7095 (parallel [(set (match_dup 0)
7096 (div:SWI48 (match_dup 2) (match_dup 3)))
7098 (mod:SWI48 (match_dup 2) (match_dup 3)))
7100 (clobber (reg:CC FLAGS_REG))])]
7102 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7104 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7105 operands[4] = operands[2];
7108 /* Avoid use of cltd in favor of a mov+shift. */
7109 emit_move_insn (operands[1], operands[2]);
7110 operands[4] = operands[1];
7113 [(set_attr "type" "multi")
7114 (set_attr "mode" "<MODE>")])
7116 (define_insn_and_split "*divmod<mode>4"
7117 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7118 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7119 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7120 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7121 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7122 (clobber (reg:CC FLAGS_REG))]
7126 [(parallel [(set (match_dup 1)
7127 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7128 (clobber (reg:CC FLAGS_REG))])
7129 (parallel [(set (match_dup 0)
7130 (div:SWIM248 (match_dup 2) (match_dup 3)))
7132 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7134 (clobber (reg:CC FLAGS_REG))])]
7136 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7138 if (<MODE>mode != HImode
7139 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7140 operands[4] = operands[2];
7143 /* Avoid use of cltd in favor of a mov+shift. */
7144 emit_move_insn (operands[1], operands[2]);
7145 operands[4] = operands[1];
7148 [(set_attr "type" "multi")
7149 (set_attr "mode" "<MODE>")])
7151 (define_insn "*divmod<mode>4_noext"
7152 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7153 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7154 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7155 (set (match_operand:SWIM248 1 "register_operand" "=d")
7156 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7157 (use (match_operand:SWIM248 4 "register_operand" "1"))
7158 (clobber (reg:CC FLAGS_REG))]
7160 "idiv{<imodesuffix>}\t%3"
7161 [(set_attr "type" "idiv")
7162 (set_attr "mode" "<MODE>")])
7164 (define_expand "divmodqi4"
7165 [(parallel [(set (match_operand:QI 0 "register_operand")
7167 (match_operand:QI 1 "register_operand")
7168 (match_operand:QI 2 "nonimmediate_operand")))
7169 (set (match_operand:QI 3 "register_operand")
7170 (mod:QI (match_dup 1) (match_dup 2)))
7171 (clobber (reg:CC FLAGS_REG))])]
7172 "TARGET_QIMODE_MATH"
7177 tmp0 = gen_reg_rtx (HImode);
7178 tmp1 = gen_reg_rtx (HImode);
7180 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7182 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7183 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7185 /* Extract remainder from AH. */
7186 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7187 insn = emit_move_insn (operands[3], tmp1);
7189 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7190 set_unique_reg_note (insn, REG_EQUAL, mod);
7192 /* Extract quotient from AL. */
7193 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7195 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7196 set_unique_reg_note (insn, REG_EQUAL, div);
7201 ;; Divide AX by r/m8, with result stored in
7204 ;; Change div/mod to HImode and extend the second argument to HImode
7205 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7206 ;; combine may fail.
7207 (define_insn "divmodhiqi3"
7208 [(set (match_operand:HI 0 "register_operand" "=a")
7213 (mod:HI (match_operand:HI 1 "register_operand" "0")
7215 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7219 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_QIMODE_MATH"
7223 [(set_attr "type" "idiv")
7224 (set_attr "mode" "QI")])
7226 (define_expand "udivmod<mode>4"
7227 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7229 (match_operand:SWIM248 1 "register_operand")
7230 (match_operand:SWIM248 2 "nonimmediate_operand")))
7231 (set (match_operand:SWIM248 3 "register_operand")
7232 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7233 (clobber (reg:CC FLAGS_REG))])])
7235 ;; Split with 8bit unsigned divide:
7236 ;; if (dividend an divisor are in [0-255])
7237 ;; use 8bit unsigned integer divide
7239 ;; use original integer divide
7241 [(set (match_operand:SWI48 0 "register_operand")
7242 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7243 (match_operand:SWI48 3 "nonimmediate_operand")))
7244 (set (match_operand:SWI48 1 "register_operand")
7245 (umod:SWI48 (match_dup 2) (match_dup 3)))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "TARGET_USE_8BIT_IDIV
7248 && TARGET_QIMODE_MATH
7249 && can_create_pseudo_p ()
7250 && !optimize_insn_for_size_p ()"
7252 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7254 (define_insn_and_split "udivmod<mode>4_1"
7255 [(set (match_operand:SWI48 0 "register_operand" "=a")
7256 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7257 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SWI48 1 "register_operand" "=&d")
7259 (umod:SWI48 (match_dup 2) (match_dup 3)))
7260 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7261 (clobber (reg:CC FLAGS_REG))]
7265 [(set (match_dup 1) (const_int 0))
7266 (parallel [(set (match_dup 0)
7267 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7269 (umod:SWI48 (match_dup 2) (match_dup 3)))
7271 (clobber (reg:CC FLAGS_REG))])]
7273 [(set_attr "type" "multi")
7274 (set_attr "mode" "<MODE>")])
7276 (define_insn_and_split "*udivmod<mode>4"
7277 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7278 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7279 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7280 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7281 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7282 (clobber (reg:CC FLAGS_REG))]
7286 [(set (match_dup 1) (const_int 0))
7287 (parallel [(set (match_dup 0)
7288 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7290 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7292 (clobber (reg:CC FLAGS_REG))])]
7294 [(set_attr "type" "multi")
7295 (set_attr "mode" "<MODE>")])
7297 (define_insn "*udivmod<mode>4_noext"
7298 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301 (set (match_operand:SWIM248 1 "register_operand" "=d")
7302 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (use (match_operand:SWIM248 4 "register_operand" "1"))
7304 (clobber (reg:CC FLAGS_REG))]
7306 "div{<imodesuffix>}\t%3"
7307 [(set_attr "type" "idiv")
7308 (set_attr "mode" "<MODE>")])
7310 (define_expand "udivmodqi4"
7311 [(parallel [(set (match_operand:QI 0 "register_operand")
7313 (match_operand:QI 1 "register_operand")
7314 (match_operand:QI 2 "nonimmediate_operand")))
7315 (set (match_operand:QI 3 "register_operand")
7316 (umod:QI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 "TARGET_QIMODE_MATH"
7323 tmp0 = gen_reg_rtx (HImode);
7324 tmp1 = gen_reg_rtx (HImode);
7326 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7328 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7329 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7331 /* Extract remainder from AH. */
7332 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7333 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7334 insn = emit_move_insn (operands[3], tmp1);
7336 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7337 set_unique_reg_note (insn, REG_EQUAL, mod);
7339 /* Extract quotient from AL. */
7340 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7342 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7343 set_unique_reg_note (insn, REG_EQUAL, div);
7348 (define_insn "udivmodhiqi3"
7349 [(set (match_operand:HI 0 "register_operand" "=a")
7354 (mod:HI (match_operand:HI 1 "register_operand" "0")
7356 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7360 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7361 (clobber (reg:CC FLAGS_REG))]
7362 "TARGET_QIMODE_MATH"
7364 [(set_attr "type" "idiv")
7365 (set_attr "mode" "QI")])
7367 ;; We cannot use div/idiv for double division, because it causes
7368 ;; "division by zero" on the overflow and that's not what we expect
7369 ;; from truncate. Because true (non truncating) double division is
7370 ;; never generated, we can't create this insn anyway.
7373 ; [(set (match_operand:SI 0 "register_operand" "=a")
7375 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7377 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7378 ; (set (match_operand:SI 3 "register_operand" "=d")
7380 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7381 ; (clobber (reg:CC FLAGS_REG))]
7383 ; "div{l}\t{%2, %0|%0, %2}"
7384 ; [(set_attr "type" "idiv")])
7386 ;;- Logical AND instructions
7388 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7389 ;; Note that this excludes ah.
7391 (define_expand "testsi_ccno_1"
7392 [(set (reg:CCNO FLAGS_REG)
7394 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7395 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7398 (define_expand "testqi_ccz_1"
7399 [(set (reg:CCZ FLAGS_REG)
7400 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7401 (match_operand:QI 1 "nonmemory_operand"))
7404 (define_expand "testdi_ccno_1"
7405 [(set (reg:CCNO FLAGS_REG)
7407 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7408 (match_operand:DI 1 "x86_64_szext_general_operand"))
7410 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7412 (define_insn "*testdi_1"
7413 [(set (reg FLAGS_REG)
7416 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7417 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7419 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7422 test{l}\t{%k1, %k0|%k0, %k1}
7423 test{l}\t{%k1, %k0|%k0, %k1}
7424 test{q}\t{%1, %0|%0, %1}
7425 test{q}\t{%1, %0|%0, %1}
7426 test{q}\t{%1, %0|%0, %1}"
7427 [(set_attr "type" "test")
7428 (set_attr "modrm" "0,1,0,1,1")
7429 (set_attr "mode" "SI,SI,DI,DI,DI")])
7431 (define_insn "*testqi_1_maybe_si"
7432 [(set (reg FLAGS_REG)
7435 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7436 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7438 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7439 && ix86_match_ccmode (insn,
7440 CONST_INT_P (operands[1])
7441 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7443 if (which_alternative == 3)
7445 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7446 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7447 return "test{l}\t{%1, %k0|%k0, %1}";
7449 return "test{b}\t{%1, %0|%0, %1}";
7451 [(set_attr "type" "test")
7452 (set_attr "modrm" "0,1,1,1")
7453 (set_attr "mode" "QI,QI,QI,SI")
7454 (set_attr "pent_pair" "uv,np,uv,np")])
7456 (define_insn "*test<mode>_1"
7457 [(set (reg FLAGS_REG)
7460 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7461 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7463 "ix86_match_ccmode (insn, CCNOmode)
7464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7465 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7466 [(set_attr "type" "test")
7467 (set_attr "modrm" "0,1,1")
7468 (set_attr "mode" "<MODE>")
7469 (set_attr "pent_pair" "uv,np,uv")])
7471 (define_expand "testqi_ext_ccno_0"
7472 [(set (reg:CCNO FLAGS_REG)
7476 (match_operand 0 "ext_register_operand")
7479 (match_operand 1 "const_int_operand"))
7482 (define_insn "*testqi_ext_0"
7483 [(set (reg FLAGS_REG)
7487 (match_operand 0 "ext_register_operand" "Q")
7490 (match_operand 1 "const_int_operand" "n"))
7492 "ix86_match_ccmode (insn, CCNOmode)"
7493 "test{b}\t{%1, %h0|%h0, %1}"
7494 [(set_attr "type" "test")
7495 (set_attr "mode" "QI")
7496 (set_attr "length_immediate" "1")
7497 (set_attr "modrm" "1")
7498 (set_attr "pent_pair" "np")])
7500 (define_insn "*testqi_ext_1"
7501 [(set (reg FLAGS_REG)
7505 (match_operand 0 "ext_register_operand" "Q,Q")
7509 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7511 "ix86_match_ccmode (insn, CCNOmode)"
7512 "test{b}\t{%1, %h0|%h0, %1}"
7513 [(set_attr "isa" "*,nox64")
7514 (set_attr "type" "test")
7515 (set_attr "mode" "QI")])
7517 (define_insn "*testqi_ext_2"
7518 [(set (reg FLAGS_REG)
7522 (match_operand 0 "ext_register_operand" "Q")
7526 (match_operand 1 "ext_register_operand" "Q")
7530 "ix86_match_ccmode (insn, CCNOmode)"
7531 "test{b}\t{%h1, %h0|%h0, %h1}"
7532 [(set_attr "type" "test")
7533 (set_attr "mode" "QI")])
7535 ;; Combine likes to form bit extractions for some tests. Humor it.
7536 (define_insn "*testqi_ext_3"
7537 [(set (reg FLAGS_REG)
7538 (compare (zero_extract:SWI48
7539 (match_operand 0 "nonimmediate_operand" "rm")
7540 (match_operand:SWI48 1 "const_int_operand")
7541 (match_operand:SWI48 2 "const_int_operand"))
7543 "ix86_match_ccmode (insn, CCNOmode)
7544 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7545 || GET_MODE (operands[0]) == SImode
7546 || GET_MODE (operands[0]) == HImode
7547 || GET_MODE (operands[0]) == QImode)
7548 /* Ensure that resulting mask is zero or sign extended operand. */
7549 && INTVAL (operands[2]) >= 0
7550 && ((INTVAL (operands[1]) > 0
7551 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7552 || (<MODE>mode == DImode
7553 && INTVAL (operands[1]) > 32
7554 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7558 [(set (match_operand 0 "flags_reg_operand")
7559 (match_operator 1 "compare_operator"
7561 (match_operand 2 "nonimmediate_operand")
7562 (match_operand 3 "const_int_operand")
7563 (match_operand 4 "const_int_operand"))
7565 "ix86_match_ccmode (insn, CCNOmode)"
7566 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7568 rtx val = operands[2];
7569 HOST_WIDE_INT len = INTVAL (operands[3]);
7570 HOST_WIDE_INT pos = INTVAL (operands[4]);
7572 machine_mode mode, submode;
7574 mode = GET_MODE (val);
7577 /* ??? Combine likes to put non-volatile mem extractions in QImode
7578 no matter the size of the test. So find a mode that works. */
7579 if (! MEM_VOLATILE_P (val))
7581 mode = smallest_mode_for_size (pos + len, MODE_INT);
7582 val = adjust_address (val, mode, 0);
7585 else if (GET_CODE (val) == SUBREG
7586 && (submode = GET_MODE (SUBREG_REG (val)),
7587 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7588 && pos + len <= GET_MODE_BITSIZE (submode)
7589 && GET_MODE_CLASS (submode) == MODE_INT)
7591 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7593 val = SUBREG_REG (val);
7595 else if (mode == HImode && pos + len <= 8)
7597 /* Small HImode tests can be converted to QImode. */
7599 val = gen_lowpart (QImode, val);
7602 if (len == HOST_BITS_PER_WIDE_INT)
7605 mask = ((HOST_WIDE_INT)1 << len) - 1;
7608 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7611 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7612 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7613 ;; this is relatively important trick.
7614 ;; Do the conversion only post-reload to avoid limiting of the register class
7617 [(set (match_operand 0 "flags_reg_operand")
7618 (match_operator 1 "compare_operator"
7619 [(and (match_operand 2 "register_operand")
7620 (match_operand 3 "const_int_operand"))
7623 && QI_REG_P (operands[2])
7624 && GET_MODE (operands[2]) != QImode
7625 && ((ix86_match_ccmode (insn, CCZmode)
7626 && !(INTVAL (operands[3]) & ~(255 << 8)))
7627 || (ix86_match_ccmode (insn, CCNOmode)
7628 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7631 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7635 operands[2] = gen_lowpart (SImode, operands[2]);
7636 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7640 [(set (match_operand 0 "flags_reg_operand")
7641 (match_operator 1 "compare_operator"
7642 [(and (match_operand 2 "nonimmediate_operand")
7643 (match_operand 3 "const_int_operand"))
7646 && GET_MODE (operands[2]) != QImode
7647 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7648 && ((ix86_match_ccmode (insn, CCZmode)
7649 && !(INTVAL (operands[3]) & ~255))
7650 || (ix86_match_ccmode (insn, CCNOmode)
7651 && !(INTVAL (operands[3]) & ~127)))"
7653 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7656 operands[2] = gen_lowpart (QImode, operands[2]);
7657 operands[3] = gen_lowpart (QImode, operands[3]);
7661 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7662 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7663 (match_operand:SWI1248x 2 "mask_reg_operand")))
7664 (clobber (reg:CC FLAGS_REG))]
7665 "TARGET_AVX512F && reload_completed"
7667 (any_logic:SWI1248x (match_dup 1)
7670 (define_insn "*k<logic><mode>"
7671 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7672 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7673 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7676 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7677 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7679 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7681 [(set_attr "mode" "<MODE>")
7682 (set_attr "type" "msklog")
7683 (set_attr "prefix" "vex")])
7685 ;; %%% This used to optimize known byte-wide and operations to memory,
7686 ;; and sometimes to QImode registers. If this is considered useful,
7687 ;; it should be done with splitters.
7689 (define_expand "and<mode>3"
7690 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7691 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7692 (match_operand:SWIM 2 "<general_szext_operand>")))]
7695 machine_mode mode = <MODE>mode;
7696 rtx (*insn) (rtx, rtx);
7698 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7700 HOST_WIDE_INT ival = INTVAL (operands[2]);
7702 if (ival == (HOST_WIDE_INT) 0xffffffff)
7704 else if (ival == 0xffff)
7706 else if (ival == 0xff)
7710 if (mode == <MODE>mode)
7712 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7716 if (<MODE>mode == DImode)
7717 insn = (mode == SImode)
7718 ? gen_zero_extendsidi2
7720 ? gen_zero_extendhidi2
7721 : gen_zero_extendqidi2;
7722 else if (<MODE>mode == SImode)
7723 insn = (mode == HImode)
7724 ? gen_zero_extendhisi2
7725 : gen_zero_extendqisi2;
7726 else if (<MODE>mode == HImode)
7727 insn = gen_zero_extendqihi2;
7731 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7735 (define_insn "*anddi_1"
7736 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7738 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7739 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7740 (clobber (reg:CC FLAGS_REG))]
7741 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7743 switch (get_attr_type (insn))
7749 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753 if (get_attr_mode (insn) == MODE_SI)
7754 return "and{l}\t{%k2, %k0|%k0, %k2}";
7756 return "and{q}\t{%2, %0|%0, %2}";
7759 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7760 (set_attr "length_immediate" "*,*,*,0,0")
7761 (set (attr "prefix_rex")
7763 (and (eq_attr "type" "imovx")
7764 (and (match_test "INTVAL (operands[2]) == 0xff")
7765 (match_operand 1 "ext_QIreg_operand")))
7767 (const_string "*")))
7768 (set_attr "mode" "SI,DI,DI,SI,DI")])
7770 (define_insn "*andsi_1"
7771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7772 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7773 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "ix86_binary_operator_ok (AND, SImode, operands)"
7777 switch (get_attr_type (insn))
7783 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7786 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7787 return "and{l}\t{%2, %0|%0, %2}";
7790 [(set_attr "type" "alu,alu,imovx,msklog")
7791 (set (attr "prefix_rex")
7793 (and (eq_attr "type" "imovx")
7794 (and (match_test "INTVAL (operands[2]) == 0xff")
7795 (match_operand 1 "ext_QIreg_operand")))
7797 (const_string "*")))
7798 (set_attr "length_immediate" "*,*,0,0")
7799 (set_attr "mode" "SI")])
7801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7802 (define_insn "*andsi_1_zext"
7803 [(set (match_operand:DI 0 "register_operand" "=r")
7805 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7806 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7809 "and{l}\t{%2, %k0|%k0, %2}"
7810 [(set_attr "type" "alu")
7811 (set_attr "mode" "SI")])
7813 (define_insn "*andhi_1"
7814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7815 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7816 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "ix86_binary_operator_ok (AND, HImode, operands)"
7820 switch (get_attr_type (insn))
7826 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7830 return "and{w}\t{%2, %0|%0, %2}";
7833 [(set_attr "type" "alu,alu,imovx,msklog")
7834 (set_attr "length_immediate" "*,*,0,*")
7835 (set (attr "prefix_rex")
7837 (and (eq_attr "type" "imovx")
7838 (match_operand 1 "ext_QIreg_operand"))
7840 (const_string "*")))
7841 (set_attr "mode" "HI,HI,SI,HI")])
7843 ;; %%% Potential partial reg stall on alternative 2. What to do?
7844 (define_insn "*andqi_1"
7845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7846 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7847 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, QImode, operands)"
7851 switch (which_alternative)
7855 return "and{b}\t{%2, %0|%0, %2}";
7857 return "and{l}\t{%k2, %k0|%k0, %k2}";
7859 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7860 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7865 [(set_attr "type" "alu,alu,alu,msklog")
7866 (set_attr "mode" "QI,QI,SI,HI")])
7868 (define_insn "*andqi_1_slp"
7869 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7870 (and:QI (match_dup 0)
7871 (match_operand:QI 1 "general_operand" "qn,qmn")))
7872 (clobber (reg:CC FLAGS_REG))]
7873 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7875 "and{b}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "alu1")
7877 (set_attr "mode" "QI")])
7879 (define_insn "kandn<mode>"
7880 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7883 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7884 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7885 (clobber (reg:CC FLAGS_REG))]
7888 switch (which_alternative)
7891 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7895 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7896 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7898 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7903 [(set_attr "isa" "bmi,*,avx512f")
7904 (set_attr "type" "bitmanip,*,msklog")
7905 (set_attr "prefix" "*,*,vex")
7906 (set_attr "btver2_decode" "direct,*,*")
7907 (set_attr "mode" "<MODE>")])
7910 [(set (match_operand:SWI12 0 "general_reg_operand")
7914 (match_operand:SWI12 1 "general_reg_operand")))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7918 (not:HI (match_dup 0)))
7919 (parallel [(set (match_dup 0)
7920 (and:HI (match_dup 0)
7922 (clobber (reg:CC FLAGS_REG))])])
7924 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7926 [(set (match_operand:DI 0 "register_operand")
7927 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7928 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7929 (clobber (reg:CC FLAGS_REG))]
7931 [(parallel [(set (match_dup 0)
7932 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7933 (clobber (reg:CC FLAGS_REG))])]
7934 "operands[2] = gen_lowpart (SImode, operands[2]);")
7937 [(set (match_operand:SWI248 0 "register_operand")
7938 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7939 (match_operand:SWI248 2 "const_int_operand")))
7940 (clobber (reg:CC FLAGS_REG))]
7942 && true_regnum (operands[0]) != true_regnum (operands[1])"
7945 HOST_WIDE_INT ival = INTVAL (operands[2]);
7947 rtx (*insn) (rtx, rtx);
7949 if (ival == (HOST_WIDE_INT) 0xffffffff)
7951 else if (ival == 0xffff)
7955 gcc_assert (ival == 0xff);
7959 if (<MODE>mode == DImode)
7960 insn = (mode == SImode)
7961 ? gen_zero_extendsidi2
7963 ? gen_zero_extendhidi2
7964 : gen_zero_extendqidi2;
7967 if (<MODE>mode != SImode)
7968 /* Zero extend to SImode to avoid partial register stalls. */
7969 operands[0] = gen_lowpart (SImode, operands[0]);
7971 insn = (mode == HImode)
7972 ? gen_zero_extendhisi2
7973 : gen_zero_extendqisi2;
7975 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7980 [(set (match_operand 0 "register_operand")
7982 (const_int -65536)))
7983 (clobber (reg:CC FLAGS_REG))]
7984 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7985 || optimize_function_for_size_p (cfun)"
7986 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7987 "operands[1] = gen_lowpart (HImode, operands[0]);")
7990 [(set (match_operand 0 "ext_register_operand")
7993 (clobber (reg:CC FLAGS_REG))]
7994 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7995 && reload_completed"
7996 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7997 "operands[1] = gen_lowpart (QImode, operands[0]);")
8000 [(set (match_operand 0 "ext_register_operand")
8002 (const_int -65281)))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && reload_completed"
8006 [(parallel [(set (zero_extract:SI (match_dup 0)
8010 (zero_extract:SI (match_dup 0)
8013 (zero_extract:SI (match_dup 0)
8016 (clobber (reg:CC FLAGS_REG))])]
8017 "operands[0] = gen_lowpart (SImode, operands[0]);")
8019 (define_insn "*anddi_2"
8020 [(set (reg FLAGS_REG)
8023 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8024 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8026 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8027 (and:DI (match_dup 1) (match_dup 2)))]
8029 && ix86_match_ccmode
8031 /* If we are going to emit andl instead of andq, and the operands[2]
8032 constant might have the SImode sign bit set, make sure the sign
8033 flag isn't tested, because the instruction will set the sign flag
8034 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8035 conservatively assume it might have bit 31 set. */
8036 (satisfies_constraint_Z (operands[2])
8037 && (!CONST_INT_P (operands[2])
8038 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8039 ? CCZmode : CCNOmode)
8040 && ix86_binary_operator_ok (AND, DImode, operands)"
8042 and{l}\t{%k2, %k0|%k0, %k2}
8043 and{q}\t{%2, %0|%0, %2}
8044 and{q}\t{%2, %0|%0, %2}"
8045 [(set_attr "type" "alu")
8046 (set_attr "mode" "SI,DI,DI")])
8048 (define_insn "*andqi_2_maybe_si"
8049 [(set (reg FLAGS_REG)
8051 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8052 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8054 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8055 (and:QI (match_dup 1) (match_dup 2)))]
8056 "ix86_binary_operator_ok (AND, QImode, operands)
8057 && ix86_match_ccmode (insn,
8058 CONST_INT_P (operands[2])
8059 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8061 if (which_alternative == 2)
8063 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8064 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8065 return "and{l}\t{%2, %k0|%k0, %2}";
8067 return "and{b}\t{%2, %0|%0, %2}";
8069 [(set_attr "type" "alu")
8070 (set_attr "mode" "QI,QI,SI")])
8072 (define_insn "*and<mode>_2"
8073 [(set (reg FLAGS_REG)
8074 (compare (and:SWI124
8075 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8076 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8078 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8079 (and:SWI124 (match_dup 1) (match_dup 2)))]
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8082 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8083 [(set_attr "type" "alu")
8084 (set_attr "mode" "<MODE>")])
8086 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8087 (define_insn "*andsi_2_zext"
8088 [(set (reg FLAGS_REG)
8090 (match_operand:SI 1 "nonimmediate_operand" "%0")
8091 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8093 (set (match_operand:DI 0 "register_operand" "=r")
8094 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8095 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8096 && ix86_binary_operator_ok (AND, SImode, operands)"
8097 "and{l}\t{%2, %k0|%k0, %2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "SI")])
8101 (define_insn "*andqi_2_slp"
8102 [(set (reg FLAGS_REG)
8104 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8105 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8107 (set (strict_low_part (match_dup 0))
8108 (and:QI (match_dup 0) (match_dup 1)))]
8109 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8110 && ix86_match_ccmode (insn, CCNOmode)
8111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8112 "and{b}\t{%1, %0|%0, %1}"
8113 [(set_attr "type" "alu1")
8114 (set_attr "mode" "QI")])
8116 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8117 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8118 ;; for a QImode operand, which of course failed.
8119 (define_insn "andqi_ext_0"
8120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8125 (match_operand 1 "ext_register_operand" "0")
8128 (match_operand 2 "const_int_operand" "n")))
8129 (clobber (reg:CC FLAGS_REG))]
8131 "and{b}\t{%2, %h0|%h0, %2}"
8132 [(set_attr "type" "alu")
8133 (set_attr "length_immediate" "1")
8134 (set_attr "modrm" "1")
8135 (set_attr "mode" "QI")])
8137 ;; Generated by peephole translating test to and. This shows up
8138 ;; often in fp comparisons.
8139 (define_insn "*andqi_ext_0_cc"
8140 [(set (reg FLAGS_REG)
8144 (match_operand 1 "ext_register_operand" "0")
8147 (match_operand 2 "const_int_operand" "n"))
8149 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8158 "ix86_match_ccmode (insn, CCNOmode)"
8159 "and{b}\t{%2, %h0|%h0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "length_immediate" "1")
8162 (set_attr "modrm" "1")
8163 (set_attr "mode" "QI")])
8165 (define_insn "*andqi_ext_1"
8166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8171 (match_operand 1 "ext_register_operand" "0,0")
8175 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8176 (clobber (reg:CC FLAGS_REG))]
8178 "and{b}\t{%2, %h0|%h0, %2}"
8179 [(set_attr "isa" "*,nox64")
8180 (set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_2"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "%0")
8194 (match_operand 2 "ext_register_operand" "Q")
8197 (clobber (reg:CC FLAGS_REG))]
8199 "and{b}\t{%h2, %h0|%h0, %h2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "length_immediate" "0")
8202 (set_attr "mode" "QI")])
8204 ;; Convert wide AND instructions with immediate operand to shorter QImode
8205 ;; equivalents when possible.
8206 ;; Don't do the splitting with memory operands, since it introduces risk
8207 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8208 ;; for size, but that can (should?) be handled by generic code instead.
8210 [(set (match_operand 0 "register_operand")
8211 (and (match_operand 1 "register_operand")
8212 (match_operand 2 "const_int_operand")))
8213 (clobber (reg:CC FLAGS_REG))]
8215 && QI_REG_P (operands[0])
8216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8217 && !(~INTVAL (operands[2]) & ~(255 << 8))
8218 && GET_MODE (operands[0]) != QImode"
8219 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8220 (and:SI (zero_extract:SI (match_dup 1)
8221 (const_int 8) (const_int 8))
8223 (clobber (reg:CC FLAGS_REG))])]
8225 operands[0] = gen_lowpart (SImode, operands[0]);
8226 operands[1] = gen_lowpart (SImode, operands[1]);
8227 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8230 ;; Since AND can be encoded with sign extended immediate, this is only
8231 ;; profitable when 7th bit is not set.
8233 [(set (match_operand 0 "register_operand")
8234 (and (match_operand 1 "general_operand")
8235 (match_operand 2 "const_int_operand")))
8236 (clobber (reg:CC FLAGS_REG))]
8238 && ANY_QI_REG_P (operands[0])
8239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8240 && !(~INTVAL (operands[2]) & ~255)
8241 && !(INTVAL (operands[2]) & 128)
8242 && GET_MODE (operands[0]) != QImode"
8243 [(parallel [(set (strict_low_part (match_dup 0))
8244 (and:QI (match_dup 1)
8246 (clobber (reg:CC FLAGS_REG))])]
8248 operands[0] = gen_lowpart (QImode, operands[0]);
8249 operands[1] = gen_lowpart (QImode, operands[1]);
8250 operands[2] = gen_lowpart (QImode, operands[2]);
8253 ;; Logical inclusive and exclusive OR instructions
8255 ;; %%% This used to optimize known byte-wide and operations to memory.
8256 ;; If this is considered useful, it should be done with splitters.
8258 (define_expand "<code><mode>3"
8259 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8260 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8261 (match_operand:SWIM 2 "<general_operand>")))]
8263 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8265 (define_insn "*<code><mode>_1"
8266 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8268 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8269 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8273 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8274 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8275 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8276 [(set_attr "type" "alu,alu,msklog")
8277 (set_attr "mode" "<MODE>")])
8279 (define_insn "*<code>hi_1"
8280 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8282 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8283 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8287 <logic>{w}\t{%2, %0|%0, %2}
8288 <logic>{w}\t{%2, %0|%0, %2}
8289 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8290 [(set_attr "type" "alu,alu,msklog")
8291 (set_attr "mode" "HI")])
8293 ;; %%% Potential partial reg stall on alternative 2. What to do?
8294 (define_insn "*<code>qi_1"
8295 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8296 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8297 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8301 <logic>{b}\t{%2, %0|%0, %2}
8302 <logic>{b}\t{%2, %0|%0, %2}
8303 <logic>{l}\t{%k2, %k0|%k0, %k2}
8304 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8305 [(set_attr "type" "alu,alu,alu,msklog")
8306 (set_attr "mode" "QI,QI,SI,HI")])
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316 "<logic>{l}\t{%2, %k0|%k0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "SI")])
8320 (define_insn "*<code>si_1_zext_imm"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*<code>qi_1_slp"
8332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333 (any_or:QI (match_dup 0)
8334 (match_operand:QI 1 "general_operand" "qmn,qn")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338 "<logic>{b}\t{%1, %0|%0, %1}"
8339 [(set_attr "type" "alu1")
8340 (set_attr "mode" "QI")])
8342 (define_insn "*<code><mode>_2"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SWI
8345 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8348 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349 (any_or:SWI (match_dup 1) (match_dup 2)))]
8350 "ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "<MODE>")])
8356 (define_insn "kxnor<mode>"
8357 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8360 (match_operand:SWI12 1 "register_operand" "0,k")
8361 (match_operand:SWI12 2 "register_operand" "r,k"))))
8362 (clobber (reg:CC FLAGS_REG))]
8365 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8366 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8367 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8369 [(set_attr "type" "*,msklog")
8370 (set_attr "prefix" "*,vex")
8371 (set_attr "mode" "<MODE>")])
8373 (define_insn "kxnor<mode>"
8374 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8377 (match_operand:SWI48x 1 "register_operand" "0,k")
8378 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8379 (clobber (reg:CC FLAGS_REG))]
8383 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8384 [(set_attr "type" "*,msklog")
8385 (set_attr "prefix" "*,vex")
8386 (set_attr "mode" "<MODE>")])
8389 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8393 (match_operand:SWI1248x 1 "general_reg_operand"))))
8394 (clobber (reg:CC FLAGS_REG))]
8395 "TARGET_AVX512F && reload_completed"
8396 [(parallel [(set (match_dup 0)
8397 (xor:HI (match_dup 0)
8399 (clobber (reg:CC FLAGS_REG))])
8401 (not:HI (match_dup 0)))])
8403 ;;There are kortrest[bdq] but no intrinsics for them.
8404 ;;We probably don't need to implement them.
8405 (define_insn "kortestzhi"
8406 [(set (reg:CCZ FLAGS_REG)
8409 (match_operand:HI 0 "register_operand" "k")
8410 (match_operand:HI 1 "register_operand" "k"))
8412 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8413 "kortestw\t{%1, %0|%0, %1}"
8414 [(set_attr "mode" "HI")
8415 (set_attr "type" "msklog")
8416 (set_attr "prefix" "vex")])
8418 (define_insn "kortestchi"
8419 [(set (reg:CCC FLAGS_REG)
8422 (match_operand:HI 0 "register_operand" "k")
8423 (match_operand:HI 1 "register_operand" "k"))
8425 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8426 "kortestw\t{%1, %0|%0, %1}"
8427 [(set_attr "mode" "HI")
8428 (set_attr "type" "msklog")
8429 (set_attr "prefix" "vex")])
8431 (define_insn "kunpckhi"
8432 [(set (match_operand:HI 0 "register_operand" "=k")
8435 (match_operand:HI 1 "register_operand" "k")
8437 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8439 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8440 [(set_attr "mode" "HI")
8441 (set_attr "type" "msklog")
8442 (set_attr "prefix" "vex")])
8444 (define_insn "kunpcksi"
8445 [(set (match_operand:SI 0 "register_operand" "=k")
8448 (match_operand:SI 1 "register_operand" "k")
8450 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8452 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8453 [(set_attr "mode" "SI")])
8455 (define_insn "kunpckdi"
8456 [(set (match_operand:DI 0 "register_operand" "=k")
8459 (match_operand:DI 1 "register_operand" "k")
8461 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8463 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8464 [(set_attr "mode" "DI")])
8466 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8467 ;; ??? Special case for immediate operand is missing - it is tricky.
8468 (define_insn "*<code>si_2_zext"
8469 [(set (reg FLAGS_REG)
8470 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8471 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8473 (set (match_operand:DI 0 "register_operand" "=r")
8474 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8475 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8476 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8477 "<logic>{l}\t{%2, %k0|%k0, %2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "mode" "SI")])
8481 (define_insn "*<code>si_2_zext_imm"
8482 [(set (reg FLAGS_REG)
8484 (match_operand:SI 1 "nonimmediate_operand" "%0")
8485 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8487 (set (match_operand:DI 0 "register_operand" "=r")
8488 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8489 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8490 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8491 "<logic>{l}\t{%2, %k0|%k0, %2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "mode" "SI")])
8495 (define_insn "*<code>qi_2_slp"
8496 [(set (reg FLAGS_REG)
8497 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8498 (match_operand:QI 1 "general_operand" "qmn,qn"))
8500 (set (strict_low_part (match_dup 0))
8501 (any_or:QI (match_dup 0) (match_dup 1)))]
8502 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8503 && ix86_match_ccmode (insn, CCNOmode)
8504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8505 "<logic>{b}\t{%1, %0|%0, %1}"
8506 [(set_attr "type" "alu1")
8507 (set_attr "mode" "QI")])
8509 (define_insn "*<code><mode>_3"
8510 [(set (reg FLAGS_REG)
8511 (compare (any_or:SWI
8512 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8513 (match_operand:SWI 2 "<general_operand>" "<g>"))
8515 (clobber (match_scratch:SWI 0 "=<r>"))]
8516 "ix86_match_ccmode (insn, CCNOmode)
8517 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8518 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "<MODE>")])
8522 (define_insn "*<code>qi_ext_0"
8523 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8528 (match_operand 1 "ext_register_operand" "0")
8531 (match_operand 2 "const_int_operand" "n")))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8534 "<logic>{b}\t{%2, %h0|%h0, %2}"
8535 [(set_attr "type" "alu")
8536 (set_attr "length_immediate" "1")
8537 (set_attr "modrm" "1")
8538 (set_attr "mode" "QI")])
8540 (define_insn "*<code>qi_ext_1"
8541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8546 (match_operand 1 "ext_register_operand" "0,0")
8550 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8553 "<logic>{b}\t{%2, %h0|%h0, %2}"
8554 [(set_attr "isa" "*,nox64")
8555 (set_attr "type" "alu")
8556 (set_attr "length_immediate" "0")
8557 (set_attr "mode" "QI")])
8559 (define_insn "*<code>qi_ext_2"
8560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8564 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8567 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8570 (clobber (reg:CC FLAGS_REG))]
8571 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8572 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "length_immediate" "0")
8575 (set_attr "mode" "QI")])
8578 [(set (match_operand 0 "register_operand")
8579 (any_or (match_operand 1 "register_operand")
8580 (match_operand 2 "const_int_operand")))
8581 (clobber (reg:CC FLAGS_REG))]
8583 && QI_REG_P (operands[0])
8584 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8585 && !(INTVAL (operands[2]) & ~(255 << 8))
8586 && GET_MODE (operands[0]) != QImode"
8587 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8588 (any_or:SI (zero_extract:SI (match_dup 1)
8589 (const_int 8) (const_int 8))
8591 (clobber (reg:CC FLAGS_REG))])]
8593 operands[0] = gen_lowpart (SImode, operands[0]);
8594 operands[1] = gen_lowpart (SImode, operands[1]);
8595 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8598 ;; Since OR can be encoded with sign extended immediate, this is only
8599 ;; profitable when 7th bit is set.
8601 [(set (match_operand 0 "register_operand")
8602 (any_or (match_operand 1 "general_operand")
8603 (match_operand 2 "const_int_operand")))
8604 (clobber (reg:CC FLAGS_REG))]
8606 && ANY_QI_REG_P (operands[0])
8607 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8608 && !(INTVAL (operands[2]) & ~255)
8609 && (INTVAL (operands[2]) & 128)
8610 && GET_MODE (operands[0]) != QImode"
8611 [(parallel [(set (strict_low_part (match_dup 0))
8612 (any_or:QI (match_dup 1)
8614 (clobber (reg:CC FLAGS_REG))])]
8616 operands[0] = gen_lowpart (QImode, operands[0]);
8617 operands[1] = gen_lowpart (QImode, operands[1]);
8618 operands[2] = gen_lowpart (QImode, operands[2]);
8621 (define_expand "xorqi_cc_ext_1"
8623 (set (reg:CCNO FLAGS_REG)
8627 (match_operand 1 "ext_register_operand")
8630 (match_operand:QI 2 "const_int_operand"))
8632 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8642 (define_insn "*xorqi_cc_ext_1"
8643 [(set (reg FLAGS_REG)
8647 (match_operand 1 "ext_register_operand" "0,0")
8650 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8652 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8661 "ix86_match_ccmode (insn, CCNOmode)"
8662 "xor{b}\t{%2, %h0|%h0, %2}"
8663 [(set_attr "isa" "*,nox64")
8664 (set_attr "type" "alu")
8665 (set_attr "modrm" "1")
8666 (set_attr "mode" "QI")])
8668 ;; Negation instructions
8670 (define_expand "neg<mode>2"
8671 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8672 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8674 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8676 (define_insn_and_split "*neg<dwi>2_doubleword"
8677 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8678 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8679 (clobber (reg:CC FLAGS_REG))]
8680 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8684 [(set (reg:CCZ FLAGS_REG)
8685 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8686 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8689 (plus:DWIH (match_dup 3)
8690 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8692 (clobber (reg:CC FLAGS_REG))])
8695 (neg:DWIH (match_dup 2)))
8696 (clobber (reg:CC FLAGS_REG))])]
8697 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8699 (define_insn "*neg<mode>2_1"
8700 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8701 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8704 "neg{<imodesuffix>}\t%0"
8705 [(set_attr "type" "negnot")
8706 (set_attr "mode" "<MODE>")])
8708 ;; Combine is quite creative about this pattern.
8709 (define_insn "*negsi2_1_zext"
8710 [(set (match_operand:DI 0 "register_operand" "=r")
8712 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8715 (clobber (reg:CC FLAGS_REG))]
8716 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8718 [(set_attr "type" "negnot")
8719 (set_attr "mode" "SI")])
8721 ;; The problem with neg is that it does not perform (compare x 0),
8722 ;; it really performs (compare 0 x), which leaves us with the zero
8723 ;; flag being the only useful item.
8725 (define_insn "*neg<mode>2_cmpz"
8726 [(set (reg:CCZ FLAGS_REG)
8728 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8730 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8731 (neg:SWI (match_dup 1)))]
8732 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8733 "neg{<imodesuffix>}\t%0"
8734 [(set_attr "type" "negnot")
8735 (set_attr "mode" "<MODE>")])
8737 (define_insn "*negsi2_cmpz_zext"
8738 [(set (reg:CCZ FLAGS_REG)
8742 (match_operand:DI 1 "register_operand" "0")
8746 (set (match_operand:DI 0 "register_operand" "=r")
8747 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8750 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8752 [(set_attr "type" "negnot")
8753 (set_attr "mode" "SI")])
8755 ;; Negate with jump on overflow.
8756 (define_expand "negv<mode>3"
8757 [(parallel [(set (reg:CCO FLAGS_REG)
8758 (ne:CCO (match_operand:SWI 1 "register_operand")
8760 (set (match_operand:SWI 0 "register_operand")
8761 (neg:SWI (match_dup 1)))])
8762 (set (pc) (if_then_else
8763 (eq (reg:CCO FLAGS_REG) (const_int 0))
8764 (label_ref (match_operand 2))
8769 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8773 (define_insn "*negv<mode>3"
8774 [(set (reg:CCO FLAGS_REG)
8775 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8776 (match_operand:SWI 2 "const_int_operand")))
8777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8778 (neg:SWI (match_dup 1)))]
8779 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8780 && mode_signbit_p (<MODE>mode, operands[2])"
8781 "neg{<imodesuffix>}\t%0"
8782 [(set_attr "type" "negnot")
8783 (set_attr "mode" "<MODE>")])
8785 ;; Changing of sign for FP values is doable using integer unit too.
8787 (define_expand "<code><mode>2"
8788 [(set (match_operand:X87MODEF 0 "register_operand")
8789 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8790 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8791 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8793 (define_insn "*absneg<mode>2_mixed"
8794 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8795 (match_operator:MODEF 3 "absneg_operator"
8796 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8797 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8802 (define_insn "*absneg<mode>2_sse"
8803 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8804 (match_operator:MODEF 3 "absneg_operator"
8805 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8806 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8807 (clobber (reg:CC FLAGS_REG))]
8808 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8811 (define_insn "*absneg<mode>2_i387"
8812 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8813 (match_operator:X87MODEF 3 "absneg_operator"
8814 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8815 (use (match_operand 2))
8816 (clobber (reg:CC FLAGS_REG))]
8817 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8820 (define_expand "<code>tf2"
8821 [(set (match_operand:TF 0 "register_operand")
8822 (absneg:TF (match_operand:TF 1 "register_operand")))]
8824 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8826 (define_insn "*absnegtf2_sse"
8827 [(set (match_operand:TF 0 "register_operand" "=x,x")
8828 (match_operator:TF 3 "absneg_operator"
8829 [(match_operand:TF 1 "register_operand" "0,x")]))
8830 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8831 (clobber (reg:CC FLAGS_REG))]
8835 ;; Splitters for fp abs and neg.
8838 [(set (match_operand 0 "fp_register_operand")
8839 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8840 (use (match_operand 2))
8841 (clobber (reg:CC FLAGS_REG))]
8843 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8846 [(set (match_operand 0 "register_operand")
8847 (match_operator 3 "absneg_operator"
8848 [(match_operand 1 "register_operand")]))
8849 (use (match_operand 2 "nonimmediate_operand"))
8850 (clobber (reg:CC FLAGS_REG))]
8851 "reload_completed && SSE_REG_P (operands[0])"
8852 [(set (match_dup 0) (match_dup 3))]
8854 machine_mode mode = GET_MODE (operands[0]);
8855 machine_mode vmode = GET_MODE (operands[2]);
8858 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8859 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8860 if (operands_match_p (operands[0], operands[2]))
8861 std::swap (operands[1], operands[2]);
8862 if (GET_CODE (operands[3]) == ABS)
8863 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8865 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8870 [(set (match_operand:SF 0 "register_operand")
8871 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8872 (use (match_operand:V4SF 2))
8873 (clobber (reg:CC FLAGS_REG))]
8875 [(parallel [(set (match_dup 0) (match_dup 1))
8876 (clobber (reg:CC FLAGS_REG))])]
8879 operands[0] = gen_lowpart (SImode, operands[0]);
8880 if (GET_CODE (operands[1]) == ABS)
8882 tmp = gen_int_mode (0x7fffffff, SImode);
8883 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8887 tmp = gen_int_mode (0x80000000, SImode);
8888 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8894 [(set (match_operand:DF 0 "register_operand")
8895 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8896 (use (match_operand 2))
8897 (clobber (reg:CC FLAGS_REG))]
8899 [(parallel [(set (match_dup 0) (match_dup 1))
8900 (clobber (reg:CC FLAGS_REG))])]
8905 tmp = gen_lowpart (DImode, operands[0]);
8906 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8909 if (GET_CODE (operands[1]) == ABS)
8912 tmp = gen_rtx_NOT (DImode, tmp);
8916 operands[0] = gen_highpart (SImode, operands[0]);
8917 if (GET_CODE (operands[1]) == ABS)
8919 tmp = gen_int_mode (0x7fffffff, SImode);
8920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8924 tmp = gen_int_mode (0x80000000, SImode);
8925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8932 [(set (match_operand:XF 0 "register_operand")
8933 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8934 (use (match_operand 2))
8935 (clobber (reg:CC FLAGS_REG))]
8937 [(parallel [(set (match_dup 0) (match_dup 1))
8938 (clobber (reg:CC FLAGS_REG))])]
8941 operands[0] = gen_rtx_REG (SImode,
8942 true_regnum (operands[0])
8943 + (TARGET_64BIT ? 1 : 2));
8944 if (GET_CODE (operands[1]) == ABS)
8946 tmp = GEN_INT (0x7fff);
8947 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8951 tmp = GEN_INT (0x8000);
8952 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8957 ;; Conditionalize these after reload. If they match before reload, we
8958 ;; lose the clobber and ability to use integer instructions.
8960 (define_insn "*<code><mode>2_1"
8961 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8962 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8964 && (reload_completed
8965 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8966 "f<absneg_mnemonic>"
8967 [(set_attr "type" "fsgn")
8968 (set_attr "mode" "<MODE>")])
8970 (define_insn "*<code>extendsfdf2"
8971 [(set (match_operand:DF 0 "register_operand" "=f")
8972 (absneg:DF (float_extend:DF
8973 (match_operand:SF 1 "register_operand" "0"))))]
8974 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8975 "f<absneg_mnemonic>"
8976 [(set_attr "type" "fsgn")
8977 (set_attr "mode" "DF")])
8979 (define_insn "*<code>extendsfxf2"
8980 [(set (match_operand:XF 0 "register_operand" "=f")
8981 (absneg:XF (float_extend:XF
8982 (match_operand:SF 1 "register_operand" "0"))))]
8984 "f<absneg_mnemonic>"
8985 [(set_attr "type" "fsgn")
8986 (set_attr "mode" "XF")])
8988 (define_insn "*<code>extenddfxf2"
8989 [(set (match_operand:XF 0 "register_operand" "=f")
8990 (absneg:XF (float_extend:XF
8991 (match_operand:DF 1 "register_operand" "0"))))]
8993 "f<absneg_mnemonic>"
8994 [(set_attr "type" "fsgn")
8995 (set_attr "mode" "XF")])
8997 ;; Copysign instructions
8999 (define_mode_iterator CSGNMODE [SF DF TF])
9000 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9002 (define_expand "copysign<mode>3"
9003 [(match_operand:CSGNMODE 0 "register_operand")
9004 (match_operand:CSGNMODE 1 "nonmemory_operand")
9005 (match_operand:CSGNMODE 2 "register_operand")]
9006 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9007 || (TARGET_SSE && (<MODE>mode == TFmode))"
9008 "ix86_expand_copysign (operands); DONE;")
9010 (define_insn_and_split "copysign<mode>3_const"
9011 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9013 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9014 (match_operand:CSGNMODE 2 "register_operand" "0")
9015 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9017 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9018 || (TARGET_SSE && (<MODE>mode == TFmode))"
9020 "&& reload_completed"
9022 "ix86_split_copysign_const (operands); DONE;")
9024 (define_insn "copysign<mode>3_var"
9025 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9027 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9028 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9029 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9030 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9032 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9033 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9034 || (TARGET_SSE && (<MODE>mode == TFmode))"
9038 [(set (match_operand:CSGNMODE 0 "register_operand")
9040 [(match_operand:CSGNMODE 2 "register_operand")
9041 (match_operand:CSGNMODE 3 "register_operand")
9042 (match_operand:<CSGNVMODE> 4)
9043 (match_operand:<CSGNVMODE> 5)]
9045 (clobber (match_scratch:<CSGNVMODE> 1))]
9046 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9047 || (TARGET_SSE && (<MODE>mode == TFmode)))
9048 && reload_completed"
9050 "ix86_split_copysign_var (operands); DONE;")
9052 ;; One complement instructions
9054 (define_expand "one_cmpl<mode>2"
9055 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9056 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9058 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9060 (define_insn "*one_cmpl<mode>2_1"
9061 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9062 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9063 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9065 not{<imodesuffix>}\t%0
9066 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9067 [(set_attr "isa" "*,avx512bw")
9068 (set_attr "type" "negnot,msklog")
9069 (set_attr "prefix" "*,vex")
9070 (set_attr "mode" "<MODE>")])
9072 (define_insn "*one_cmplhi2_1"
9073 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9074 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9075 "ix86_unary_operator_ok (NOT, HImode, operands)"
9078 knotw\t{%1, %0|%0, %1}"
9079 [(set_attr "isa" "*,avx512f")
9080 (set_attr "type" "negnot,msklog")
9081 (set_attr "prefix" "*,vex")
9082 (set_attr "mode" "HI")])
9084 ;; %%% Potential partial reg stall on alternative 1. What to do?
9085 (define_insn "*one_cmplqi2_1"
9086 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9087 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9088 "ix86_unary_operator_ok (NOT, QImode, operands)"
9090 switch (which_alternative)
9093 return "not{b}\t%0";
9095 return "not{l}\t%k0";
9097 if (TARGET_AVX512DQ)
9098 return "knotb\t{%1, %0|%0, %1}";
9099 return "knotw\t{%1, %0|%0, %1}";
9104 [(set_attr "isa" "*,*,avx512f")
9105 (set_attr "type" "negnot,negnot,msklog")
9106 (set_attr "prefix" "*,*,vex")
9107 (set_attr "mode" "QI,SI,QI")])
9109 ;; ??? Currently never generated - xor is used instead.
9110 (define_insn "*one_cmplsi2_1_zext"
9111 [(set (match_operand:DI 0 "register_operand" "=r")
9113 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9114 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9116 [(set_attr "type" "negnot")
9117 (set_attr "mode" "SI")])
9119 (define_insn "*one_cmpl<mode>2_2"
9120 [(set (reg FLAGS_REG)
9121 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9123 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9124 (not:SWI (match_dup 1)))]
9125 "ix86_match_ccmode (insn, CCNOmode)
9126 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9128 [(set_attr "type" "alu1")
9129 (set_attr "mode" "<MODE>")])
9132 [(set (match_operand 0 "flags_reg_operand")
9133 (match_operator 2 "compare_operator"
9134 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9136 (set (match_operand:SWI 1 "nonimmediate_operand")
9137 (not:SWI (match_dup 3)))]
9138 "ix86_match_ccmode (insn, CCNOmode)"
9139 [(parallel [(set (match_dup 0)
9140 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9143 (xor:SWI (match_dup 3) (const_int -1)))])])
9145 ;; ??? Currently never generated - xor is used instead.
9146 (define_insn "*one_cmplsi2_2_zext"
9147 [(set (reg FLAGS_REG)
9148 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9150 (set (match_operand:DI 0 "register_operand" "=r")
9151 (zero_extend:DI (not:SI (match_dup 1))))]
9152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9153 && ix86_unary_operator_ok (NOT, SImode, operands)"
9155 [(set_attr "type" "alu1")
9156 (set_attr "mode" "SI")])
9159 [(set (match_operand 0 "flags_reg_operand")
9160 (match_operator 2 "compare_operator"
9161 [(not:SI (match_operand:SI 3 "register_operand"))
9163 (set (match_operand:DI 1 "register_operand")
9164 (zero_extend:DI (not:SI (match_dup 3))))]
9165 "ix86_match_ccmode (insn, CCNOmode)"
9166 [(parallel [(set (match_dup 0)
9167 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9170 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9172 ;; Shift instructions
9174 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9175 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9176 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9177 ;; from the assembler input.
9179 ;; This instruction shifts the target reg/mem as usual, but instead of
9180 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9181 ;; is a left shift double, bits are taken from the high order bits of
9182 ;; reg, else if the insn is a shift right double, bits are taken from the
9183 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9184 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9186 ;; Since sh[lr]d does not change the `reg' operand, that is done
9187 ;; separately, making all shifts emit pairs of shift double and normal
9188 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9189 ;; support a 63 bit shift, each shift where the count is in a reg expands
9190 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9192 ;; If the shift count is a constant, we need never emit more than one
9193 ;; shift pair, instead using moves and sign extension for counts greater
9196 (define_expand "ashl<mode>3"
9197 [(set (match_operand:SDWIM 0 "<shift_operand>")
9198 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9199 (match_operand:QI 2 "nonmemory_operand")))]
9201 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9203 (define_insn "*ashl<mode>3_doubleword"
9204 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9205 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9206 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9207 (clobber (reg:CC FLAGS_REG))]
9210 [(set_attr "type" "multi")])
9213 [(set (match_operand:DWI 0 "register_operand")
9214 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9215 (match_operand:QI 2 "nonmemory_operand")))
9216 (clobber (reg:CC FLAGS_REG))]
9217 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9219 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9221 ;; By default we don't ask for a scratch register, because when DWImode
9222 ;; values are manipulated, registers are already at a premium. But if
9223 ;; we have one handy, we won't turn it away.
9226 [(match_scratch:DWIH 3 "r")
9227 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9229 (match_operand:<DWI> 1 "nonmemory_operand")
9230 (match_operand:QI 2 "nonmemory_operand")))
9231 (clobber (reg:CC FLAGS_REG))])
9235 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9237 (define_insn "x86_64_shld"
9238 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9239 (ior:DI (ashift:DI (match_dup 0)
9240 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9241 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9242 (minus:QI (const_int 64) (match_dup 2)))))
9243 (clobber (reg:CC FLAGS_REG))]
9245 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9246 [(set_attr "type" "ishift")
9247 (set_attr "prefix_0f" "1")
9248 (set_attr "mode" "DI")
9249 (set_attr "athlon_decode" "vector")
9250 (set_attr "amdfam10_decode" "vector")
9251 (set_attr "bdver1_decode" "vector")])
9253 (define_insn "x86_shld"
9254 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9255 (ior:SI (ashift:SI (match_dup 0)
9256 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9257 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9258 (minus:QI (const_int 32) (match_dup 2)))))
9259 (clobber (reg:CC FLAGS_REG))]
9261 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9262 [(set_attr "type" "ishift")
9263 (set_attr "prefix_0f" "1")
9264 (set_attr "mode" "SI")
9265 (set_attr "pent_pair" "np")
9266 (set_attr "athlon_decode" "vector")
9267 (set_attr "amdfam10_decode" "vector")
9268 (set_attr "bdver1_decode" "vector")])
9270 (define_expand "x86_shift<mode>_adj_1"
9271 [(set (reg:CCZ FLAGS_REG)
9272 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9275 (set (match_operand:SWI48 0 "register_operand")
9276 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9277 (match_operand:SWI48 1 "register_operand")
9280 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9281 (match_operand:SWI48 3 "register_operand")
9284 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9286 (define_expand "x86_shift<mode>_adj_2"
9287 [(use (match_operand:SWI48 0 "register_operand"))
9288 (use (match_operand:SWI48 1 "register_operand"))
9289 (use (match_operand:QI 2 "register_operand"))]
9292 rtx_code_label *label = gen_label_rtx ();
9295 emit_insn (gen_testqi_ccz_1 (operands[2],
9296 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9298 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9299 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9300 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9301 gen_rtx_LABEL_REF (VOIDmode, label),
9303 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9304 JUMP_LABEL (tmp) = label;
9306 emit_move_insn (operands[0], operands[1]);
9307 ix86_expand_clear (operands[1]);
9310 LABEL_NUSES (label) = 1;
9315 ;; Avoid useless masking of count operand.
9316 (define_insn "*ashl<mode>3_mask"
9317 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9319 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9322 (match_operand:SI 2 "register_operand" "c")
9323 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9326 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9327 == GET_MODE_BITSIZE (<MODE>mode)-1"
9329 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9331 [(set_attr "type" "ishift")
9332 (set_attr "mode" "<MODE>")])
9334 (define_insn "*bmi2_ashl<mode>3_1"
9335 [(set (match_operand:SWI48 0 "register_operand" "=r")
9336 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9337 (match_operand:SWI48 2 "register_operand" "r")))]
9339 "shlx\t{%2, %1, %0|%0, %1, %2}"
9340 [(set_attr "type" "ishiftx")
9341 (set_attr "mode" "<MODE>")])
9343 (define_insn "*ashl<mode>3_1"
9344 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9345 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9346 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9350 switch (get_attr_type (insn))
9357 gcc_assert (operands[2] == const1_rtx);
9358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9359 return "add{<imodesuffix>}\t%0, %0";
9362 if (operands[2] == const1_rtx
9363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9364 return "sal{<imodesuffix>}\t%0";
9366 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9369 [(set_attr "isa" "*,*,bmi2")
9371 (cond [(eq_attr "alternative" "1")
9372 (const_string "lea")
9373 (eq_attr "alternative" "2")
9374 (const_string "ishiftx")
9375 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376 (match_operand 0 "register_operand"))
9377 (match_operand 2 "const1_operand"))
9378 (const_string "alu")
9380 (const_string "ishift")))
9381 (set (attr "length_immediate")
9383 (ior (eq_attr "type" "alu")
9384 (and (eq_attr "type" "ishift")
9385 (and (match_operand 2 "const1_operand")
9386 (ior (match_test "TARGET_SHIFT1")
9387 (match_test "optimize_function_for_size_p (cfun)")))))
9389 (const_string "*")))
9390 (set_attr "mode" "<MODE>")])
9392 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9394 [(set (match_operand:SWI48 0 "register_operand")
9395 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9396 (match_operand:QI 2 "register_operand")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_BMI2 && reload_completed"
9400 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9401 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9403 (define_insn "*bmi2_ashlsi3_1_zext"
9404 [(set (match_operand:DI 0 "register_operand" "=r")
9406 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9407 (match_operand:SI 2 "register_operand" "r"))))]
9408 "TARGET_64BIT && TARGET_BMI2"
9409 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9410 [(set_attr "type" "ishiftx")
9411 (set_attr "mode" "SI")])
9413 (define_insn "*ashlsi3_1_zext"
9414 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9416 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9417 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9421 switch (get_attr_type (insn))
9428 gcc_assert (operands[2] == const1_rtx);
9429 return "add{l}\t%k0, %k0";
9432 if (operands[2] == const1_rtx
9433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9434 return "sal{l}\t%k0";
9436 return "sal{l}\t{%2, %k0|%k0, %2}";
9439 [(set_attr "isa" "*,*,bmi2")
9441 (cond [(eq_attr "alternative" "1")
9442 (const_string "lea")
9443 (eq_attr "alternative" "2")
9444 (const_string "ishiftx")
9445 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9446 (match_operand 2 "const1_operand"))
9447 (const_string "alu")
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand")
9455 (ior (match_test "TARGET_SHIFT1")
9456 (match_test "optimize_function_for_size_p (cfun)")))))
9458 (const_string "*")))
9459 (set_attr "mode" "SI")])
9461 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9463 [(set (match_operand:DI 0 "register_operand")
9465 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9466 (match_operand:QI 2 "register_operand"))))
9467 (clobber (reg:CC FLAGS_REG))]
9468 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9470 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9471 "operands[2] = gen_lowpart (SImode, operands[2]);")
9473 (define_insn "*ashlhi3_1"
9474 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9475 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9476 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9480 switch (get_attr_type (insn))
9486 gcc_assert (operands[2] == const1_rtx);
9487 return "add{w}\t%0, %0";
9490 if (operands[2] == const1_rtx
9491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492 return "sal{w}\t%0";
9494 return "sal{w}\t{%2, %0|%0, %2}";
9498 (cond [(eq_attr "alternative" "1")
9499 (const_string "lea")
9500 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9501 (match_operand 0 "register_operand"))
9502 (match_operand 2 "const1_operand"))
9503 (const_string "alu")
9505 (const_string "ishift")))
9506 (set (attr "length_immediate")
9508 (ior (eq_attr "type" "alu")
9509 (and (eq_attr "type" "ishift")
9510 (and (match_operand 2 "const1_operand")
9511 (ior (match_test "TARGET_SHIFT1")
9512 (match_test "optimize_function_for_size_p (cfun)")))))
9514 (const_string "*")))
9515 (set_attr "mode" "HI,SI")])
9517 ;; %%% Potential partial reg stall on alternative 1. What to do?
9518 (define_insn "*ashlqi3_1"
9519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9521 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9525 switch (get_attr_type (insn))
9531 gcc_assert (operands[2] == const1_rtx);
9532 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9533 return "add{l}\t%k0, %k0";
9535 return "add{b}\t%0, %0";
9538 if (operands[2] == const1_rtx
9539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9541 if (get_attr_mode (insn) == MODE_SI)
9542 return "sal{l}\t%k0";
9544 return "sal{b}\t%0";
9548 if (get_attr_mode (insn) == MODE_SI)
9549 return "sal{l}\t{%2, %k0|%k0, %2}";
9551 return "sal{b}\t{%2, %0|%0, %2}";
9556 (cond [(eq_attr "alternative" "2")
9557 (const_string "lea")
9558 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9559 (match_operand 0 "register_operand"))
9560 (match_operand 2 "const1_operand"))
9561 (const_string "alu")
9563 (const_string "ishift")))
9564 (set (attr "length_immediate")
9566 (ior (eq_attr "type" "alu")
9567 (and (eq_attr "type" "ishift")
9568 (and (match_operand 2 "const1_operand")
9569 (ior (match_test "TARGET_SHIFT1")
9570 (match_test "optimize_function_for_size_p (cfun)")))))
9572 (const_string "*")))
9573 (set_attr "mode" "QI,SI,SI")])
9575 (define_insn "*ashlqi3_1_slp"
9576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9577 (ashift:QI (match_dup 0)
9578 (match_operand:QI 1 "nonmemory_operand" "cI")))
9579 (clobber (reg:CC FLAGS_REG))]
9580 "(optimize_function_for_size_p (cfun)
9581 || !TARGET_PARTIAL_FLAG_REG_STALL
9582 || (operands[1] == const1_rtx
9584 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9586 switch (get_attr_type (insn))
9589 gcc_assert (operands[1] == const1_rtx);
9590 return "add{b}\t%0, %0";
9593 if (operands[1] == const1_rtx
9594 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9595 return "sal{b}\t%0";
9597 return "sal{b}\t{%1, %0|%0, %1}";
9601 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9602 (match_operand 0 "register_operand"))
9603 (match_operand 1 "const1_operand"))
9604 (const_string "alu")
9606 (const_string "ishift1")))
9607 (set (attr "length_immediate")
9609 (ior (eq_attr "type" "alu")
9610 (and (eq_attr "type" "ishift1")
9611 (and (match_operand 1 "const1_operand")
9612 (ior (match_test "TARGET_SHIFT1")
9613 (match_test "optimize_function_for_size_p (cfun)")))))
9615 (const_string "*")))
9616 (set_attr "mode" "QI")])
9618 ;; Convert ashift to the lea pattern to avoid flags dependency.
9620 [(set (match_operand 0 "register_operand")
9621 (ashift (match_operand 1 "index_register_operand")
9622 (match_operand:QI 2 "const_int_operand")))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9626 && true_regnum (operands[0]) != true_regnum (operands[1])"
9629 machine_mode mode = GET_MODE (operands[0]);
9632 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9635 operands[0] = gen_lowpart (mode, operands[0]);
9636 operands[1] = gen_lowpart (mode, operands[1]);
9639 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9641 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9643 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9647 ;; Convert ashift to the lea pattern to avoid flags dependency.
9649 [(set (match_operand:DI 0 "register_operand")
9651 (ashift:SI (match_operand:SI 1 "index_register_operand")
9652 (match_operand:QI 2 "const_int_operand"))))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "TARGET_64BIT && reload_completed
9655 && true_regnum (operands[0]) != true_regnum (operands[1])"
9657 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9659 operands[1] = gen_lowpart (SImode, operands[1]);
9660 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9663 ;; This pattern can't accept a variable shift count, since shifts by
9664 ;; zero don't affect the flags. We assume that shifts by constant
9665 ;; zero are optimized away.
9666 (define_insn "*ashl<mode>3_cmp"
9667 [(set (reg FLAGS_REG)
9669 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9670 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9673 (ashift:SWI (match_dup 1) (match_dup 2)))]
9674 "(optimize_function_for_size_p (cfun)
9675 || !TARGET_PARTIAL_FLAG_REG_STALL
9676 || (operands[2] == const1_rtx
9678 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9679 && ix86_match_ccmode (insn, CCGOCmode)
9680 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9682 switch (get_attr_type (insn))
9685 gcc_assert (operands[2] == const1_rtx);
9686 return "add{<imodesuffix>}\t%0, %0";
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "sal{<imodesuffix>}\t%0";
9693 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9697 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9698 (match_operand 0 "register_operand"))
9699 (match_operand 2 "const1_operand"))
9700 (const_string "alu")
9702 (const_string "ishift")))
9703 (set (attr "length_immediate")
9705 (ior (eq_attr "type" "alu")
9706 (and (eq_attr "type" "ishift")
9707 (and (match_operand 2 "const1_operand")
9708 (ior (match_test "TARGET_SHIFT1")
9709 (match_test "optimize_function_for_size_p (cfun)")))))
9711 (const_string "*")))
9712 (set_attr "mode" "<MODE>")])
9714 (define_insn "*ashlsi3_cmp_zext"
9715 [(set (reg FLAGS_REG)
9717 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9718 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9720 (set (match_operand:DI 0 "register_operand" "=r")
9721 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9723 && (optimize_function_for_size_p (cfun)
9724 || !TARGET_PARTIAL_FLAG_REG_STALL
9725 || (operands[2] == const1_rtx
9727 || TARGET_DOUBLE_WITH_ADD)))
9728 && ix86_match_ccmode (insn, CCGOCmode)
9729 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9731 switch (get_attr_type (insn))
9734 gcc_assert (operands[2] == const1_rtx);
9735 return "add{l}\t%k0, %k0";
9738 if (operands[2] == const1_rtx
9739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9740 return "sal{l}\t%k0";
9742 return "sal{l}\t{%2, %k0|%k0, %2}";
9746 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9747 (match_operand 2 "const1_operand"))
9748 (const_string "alu")
9750 (const_string "ishift")))
9751 (set (attr "length_immediate")
9753 (ior (eq_attr "type" "alu")
9754 (and (eq_attr "type" "ishift")
9755 (and (match_operand 2 "const1_operand")
9756 (ior (match_test "TARGET_SHIFT1")
9757 (match_test "optimize_function_for_size_p (cfun)")))))
9759 (const_string "*")))
9760 (set_attr "mode" "SI")])
9762 (define_insn "*ashl<mode>3_cconly"
9763 [(set (reg FLAGS_REG)
9765 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9766 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9768 (clobber (match_scratch:SWI 0 "=<r>"))]
9769 "(optimize_function_for_size_p (cfun)
9770 || !TARGET_PARTIAL_FLAG_REG_STALL
9771 || (operands[2] == const1_rtx
9773 || TARGET_DOUBLE_WITH_ADD)))
9774 && ix86_match_ccmode (insn, CCGOCmode)"
9776 switch (get_attr_type (insn))
9779 gcc_assert (operands[2] == const1_rtx);
9780 return "add{<imodesuffix>}\t%0, %0";
9783 if (operands[2] == const1_rtx
9784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9785 return "sal{<imodesuffix>}\t%0";
9787 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9791 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9792 (match_operand 0 "register_operand"))
9793 (match_operand 2 "const1_operand"))
9794 (const_string "alu")
9796 (const_string "ishift")))
9797 (set (attr "length_immediate")
9799 (ior (eq_attr "type" "alu")
9800 (and (eq_attr "type" "ishift")
9801 (and (match_operand 2 "const1_operand")
9802 (ior (match_test "TARGET_SHIFT1")
9803 (match_test "optimize_function_for_size_p (cfun)")))))
9805 (const_string "*")))
9806 (set_attr "mode" "<MODE>")])
9808 ;; See comment above `ashl<mode>3' about how this works.
9810 (define_expand "<shift_insn><mode>3"
9811 [(set (match_operand:SDWIM 0 "<shift_operand>")
9812 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9813 (match_operand:QI 2 "nonmemory_operand")))]
9815 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9817 ;; Avoid useless masking of count operand.
9818 (define_insn "*<shift_insn><mode>3_mask"
9819 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9821 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9824 (match_operand:SI 2 "register_operand" "c")
9825 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9828 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9829 == GET_MODE_BITSIZE (<MODE>mode)-1"
9831 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9833 [(set_attr "type" "ishift")
9834 (set_attr "mode" "<MODE>")])
9836 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9837 [(set (match_operand:DWI 0 "register_operand" "=r")
9838 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9839 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9840 (clobber (reg:CC FLAGS_REG))]
9843 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9845 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9846 [(set_attr "type" "multi")])
9848 ;; By default we don't ask for a scratch register, because when DWImode
9849 ;; values are manipulated, registers are already at a premium. But if
9850 ;; we have one handy, we won't turn it away.
9853 [(match_scratch:DWIH 3 "r")
9854 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9856 (match_operand:<DWI> 1 "register_operand")
9857 (match_operand:QI 2 "nonmemory_operand")))
9858 (clobber (reg:CC FLAGS_REG))])
9862 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9864 (define_insn "x86_64_shrd"
9865 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9866 (ior:DI (lshiftrt:DI (match_dup 0)
9867 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9868 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9869 (minus:QI (const_int 64) (match_dup 2)))))
9870 (clobber (reg:CC FLAGS_REG))]
9872 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9873 [(set_attr "type" "ishift")
9874 (set_attr "prefix_0f" "1")
9875 (set_attr "mode" "DI")
9876 (set_attr "athlon_decode" "vector")
9877 (set_attr "amdfam10_decode" "vector")
9878 (set_attr "bdver1_decode" "vector")])
9880 (define_insn "x86_shrd"
9881 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9882 (ior:SI (lshiftrt:SI (match_dup 0)
9883 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9884 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9885 (minus:QI (const_int 32) (match_dup 2)))))
9886 (clobber (reg:CC FLAGS_REG))]
9888 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9889 [(set_attr "type" "ishift")
9890 (set_attr "prefix_0f" "1")
9891 (set_attr "mode" "SI")
9892 (set_attr "pent_pair" "np")
9893 (set_attr "athlon_decode" "vector")
9894 (set_attr "amdfam10_decode" "vector")
9895 (set_attr "bdver1_decode" "vector")])
9897 (define_insn "ashrdi3_cvt"
9898 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9899 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "TARGET_64BIT && INTVAL (operands[2]) == 63
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9907 sar{q}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "DI")])
9914 (define_insn "ashrsi3_cvt"
9915 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9916 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9917 (match_operand:QI 2 "const_int_operand")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "INTVAL (operands[2]) == 31
9920 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9921 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9924 sar{l}\t{%2, %0|%0, %2}"
9925 [(set_attr "type" "imovx,ishift")
9926 (set_attr "prefix_0f" "0,*")
9927 (set_attr "length_immediate" "0,*")
9928 (set_attr "modrm" "0,1")
9929 (set_attr "mode" "SI")])
9931 (define_insn "*ashrsi3_cvt_zext"
9932 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9934 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9935 (match_operand:QI 2 "const_int_operand"))))
9936 (clobber (reg:CC FLAGS_REG))]
9937 "TARGET_64BIT && INTVAL (operands[2]) == 31
9938 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9939 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9942 sar{l}\t{%2, %k0|%k0, %2}"
9943 [(set_attr "type" "imovx,ishift")
9944 (set_attr "prefix_0f" "0,*")
9945 (set_attr "length_immediate" "0,*")
9946 (set_attr "modrm" "0,1")
9947 (set_attr "mode" "SI")])
9949 (define_expand "x86_shift<mode>_adj_3"
9950 [(use (match_operand:SWI48 0 "register_operand"))
9951 (use (match_operand:SWI48 1 "register_operand"))
9952 (use (match_operand:QI 2 "register_operand"))]
9955 rtx_code_label *label = gen_label_rtx ();
9958 emit_insn (gen_testqi_ccz_1 (operands[2],
9959 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9961 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9962 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9963 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9964 gen_rtx_LABEL_REF (VOIDmode, label),
9966 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9967 JUMP_LABEL (tmp) = label;
9969 emit_move_insn (operands[0], operands[1]);
9970 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9971 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9973 LABEL_NUSES (label) = 1;
9978 (define_insn "*bmi2_<shift_insn><mode>3_1"
9979 [(set (match_operand:SWI48 0 "register_operand" "=r")
9980 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9981 (match_operand:SWI48 2 "register_operand" "r")))]
9983 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9984 [(set_attr "type" "ishiftx")
9985 (set_attr "mode" "<MODE>")])
9987 (define_insn "*<shift_insn><mode>3_1"
9988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9990 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9991 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9992 (clobber (reg:CC FLAGS_REG))]
9993 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9995 switch (get_attr_type (insn))
10001 if (operands[2] == const1_rtx
10002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003 return "<shift>{<imodesuffix>}\t%0";
10005 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10008 [(set_attr "isa" "*,bmi2")
10009 (set_attr "type" "ishift,ishiftx")
10010 (set (attr "length_immediate")
10012 (and (match_operand 2 "const1_operand")
10013 (ior (match_test "TARGET_SHIFT1")
10014 (match_test "optimize_function_for_size_p (cfun)")))
10016 (const_string "*")))
10017 (set_attr "mode" "<MODE>")])
10019 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10021 [(set (match_operand:SWI48 0 "register_operand")
10022 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10023 (match_operand:QI 2 "register_operand")))
10024 (clobber (reg:CC FLAGS_REG))]
10025 "TARGET_BMI2 && reload_completed"
10026 [(set (match_dup 0)
10027 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10028 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10030 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10031 [(set (match_operand:DI 0 "register_operand" "=r")
10033 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10034 (match_operand:SI 2 "register_operand" "r"))))]
10035 "TARGET_64BIT && TARGET_BMI2"
10036 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10037 [(set_attr "type" "ishiftx")
10038 (set_attr "mode" "SI")])
10040 (define_insn "*<shift_insn>si3_1_zext"
10041 [(set (match_operand:DI 0 "register_operand" "=r,r")
10043 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10044 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10045 (clobber (reg:CC FLAGS_REG))]
10046 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10048 switch (get_attr_type (insn))
10054 if (operands[2] == const1_rtx
10055 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10056 return "<shift>{l}\t%k0";
10058 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10061 [(set_attr "isa" "*,bmi2")
10062 (set_attr "type" "ishift,ishiftx")
10063 (set (attr "length_immediate")
10065 (and (match_operand 2 "const1_operand")
10066 (ior (match_test "TARGET_SHIFT1")
10067 (match_test "optimize_function_for_size_p (cfun)")))
10069 (const_string "*")))
10070 (set_attr "mode" "SI")])
10072 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10074 [(set (match_operand:DI 0 "register_operand")
10076 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10077 (match_operand:QI 2 "register_operand"))))
10078 (clobber (reg:CC FLAGS_REG))]
10079 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10080 [(set (match_dup 0)
10081 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10082 "operands[2] = gen_lowpart (SImode, operands[2]);")
10084 (define_insn "*<shift_insn><mode>3_1"
10085 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10087 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10088 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10089 (clobber (reg:CC FLAGS_REG))]
10090 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10092 if (operands[2] == const1_rtx
10093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094 return "<shift>{<imodesuffix>}\t%0";
10096 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10098 [(set_attr "type" "ishift")
10099 (set (attr "length_immediate")
10101 (and (match_operand 2 "const1_operand")
10102 (ior (match_test "TARGET_SHIFT1")
10103 (match_test "optimize_function_for_size_p (cfun)")))
10105 (const_string "*")))
10106 (set_attr "mode" "<MODE>")])
10108 (define_insn "*<shift_insn>qi3_1_slp"
10109 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10110 (any_shiftrt:QI (match_dup 0)
10111 (match_operand:QI 1 "nonmemory_operand" "cI")))
10112 (clobber (reg:CC FLAGS_REG))]
10113 "(optimize_function_for_size_p (cfun)
10114 || !TARGET_PARTIAL_REG_STALL
10115 || (operands[1] == const1_rtx
10116 && TARGET_SHIFT1))"
10118 if (operands[1] == const1_rtx
10119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10120 return "<shift>{b}\t%0";
10122 return "<shift>{b}\t{%1, %0|%0, %1}";
10124 [(set_attr "type" "ishift1")
10125 (set (attr "length_immediate")
10127 (and (match_operand 1 "const1_operand")
10128 (ior (match_test "TARGET_SHIFT1")
10129 (match_test "optimize_function_for_size_p (cfun)")))
10131 (const_string "*")))
10132 (set_attr "mode" "QI")])
10134 ;; This pattern can't accept a variable shift count, since shifts by
10135 ;; zero don't affect the flags. We assume that shifts by constant
10136 ;; zero are optimized away.
10137 (define_insn "*<shift_insn><mode>3_cmp"
10138 [(set (reg FLAGS_REG)
10141 (match_operand:SWI 1 "nonimmediate_operand" "0")
10142 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10144 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10145 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10146 "(optimize_function_for_size_p (cfun)
10147 || !TARGET_PARTIAL_FLAG_REG_STALL
10148 || (operands[2] == const1_rtx
10150 && ix86_match_ccmode (insn, CCGOCmode)
10151 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10153 if (operands[2] == const1_rtx
10154 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10155 return "<shift>{<imodesuffix>}\t%0";
10157 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10159 [(set_attr "type" "ishift")
10160 (set (attr "length_immediate")
10162 (and (match_operand 2 "const1_operand")
10163 (ior (match_test "TARGET_SHIFT1")
10164 (match_test "optimize_function_for_size_p (cfun)")))
10166 (const_string "*")))
10167 (set_attr "mode" "<MODE>")])
10169 (define_insn "*<shift_insn>si3_cmp_zext"
10170 [(set (reg FLAGS_REG)
10172 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10173 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10175 (set (match_operand:DI 0 "register_operand" "=r")
10176 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10178 && (optimize_function_for_size_p (cfun)
10179 || !TARGET_PARTIAL_FLAG_REG_STALL
10180 || (operands[2] == const1_rtx
10182 && ix86_match_ccmode (insn, CCGOCmode)
10183 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10185 if (operands[2] == const1_rtx
10186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187 return "<shift>{l}\t%k0";
10189 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10191 [(set_attr "type" "ishift")
10192 (set (attr "length_immediate")
10194 (and (match_operand 2 "const1_operand")
10195 (ior (match_test "TARGET_SHIFT1")
10196 (match_test "optimize_function_for_size_p (cfun)")))
10198 (const_string "*")))
10199 (set_attr "mode" "SI")])
10201 (define_insn "*<shift_insn><mode>3_cconly"
10202 [(set (reg FLAGS_REG)
10205 (match_operand:SWI 1 "register_operand" "0")
10206 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10208 (clobber (match_scratch:SWI 0 "=<r>"))]
10209 "(optimize_function_for_size_p (cfun)
10210 || !TARGET_PARTIAL_FLAG_REG_STALL
10211 || (operands[2] == const1_rtx
10213 && ix86_match_ccmode (insn, CCGOCmode)"
10215 if (operands[2] == const1_rtx
10216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10217 return "<shift>{<imodesuffix>}\t%0";
10219 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10221 [(set_attr "type" "ishift")
10222 (set (attr "length_immediate")
10224 (and (match_operand 2 "const1_operand")
10225 (ior (match_test "TARGET_SHIFT1")
10226 (match_test "optimize_function_for_size_p (cfun)")))
10228 (const_string "*")))
10229 (set_attr "mode" "<MODE>")])
10231 ;; Rotate instructions
10233 (define_expand "<rotate_insn>ti3"
10234 [(set (match_operand:TI 0 "register_operand")
10235 (any_rotate:TI (match_operand:TI 1 "register_operand")
10236 (match_operand:QI 2 "nonmemory_operand")))]
10239 if (const_1_to_63_operand (operands[2], VOIDmode))
10240 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10241 (operands[0], operands[1], operands[2]));
10248 (define_expand "<rotate_insn>di3"
10249 [(set (match_operand:DI 0 "shiftdi_operand")
10250 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10251 (match_operand:QI 2 "nonmemory_operand")))]
10255 ix86_expand_binary_operator (<CODE>, DImode, operands);
10256 else if (const_1_to_31_operand (operands[2], VOIDmode))
10257 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10258 (operands[0], operands[1], operands[2]));
10265 (define_expand "<rotate_insn><mode>3"
10266 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10267 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10268 (match_operand:QI 2 "nonmemory_operand")))]
10270 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10272 ;; Avoid useless masking of count operand.
10273 (define_insn "*<rotate_insn><mode>3_mask"
10274 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10276 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10279 (match_operand:SI 2 "register_operand" "c")
10280 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10283 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10284 == GET_MODE_BITSIZE (<MODE>mode)-1"
10286 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10288 [(set_attr "type" "rotate")
10289 (set_attr "mode" "<MODE>")])
10291 ;; Implement rotation using two double-precision
10292 ;; shift instructions and a scratch register.
10294 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10295 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10296 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10297 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10298 (clobber (reg:CC FLAGS_REG))
10299 (clobber (match_scratch:DWIH 3 "=&r"))]
10303 [(set (match_dup 3) (match_dup 4))
10305 [(set (match_dup 4)
10306 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10307 (lshiftrt:DWIH (match_dup 5)
10308 (minus:QI (match_dup 6) (match_dup 2)))))
10309 (clobber (reg:CC FLAGS_REG))])
10311 [(set (match_dup 5)
10312 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10313 (lshiftrt:DWIH (match_dup 3)
10314 (minus:QI (match_dup 6) (match_dup 2)))))
10315 (clobber (reg:CC FLAGS_REG))])]
10317 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10319 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10322 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10323 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10324 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10325 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10326 (clobber (reg:CC FLAGS_REG))
10327 (clobber (match_scratch:DWIH 3 "=&r"))]
10331 [(set (match_dup 3) (match_dup 4))
10333 [(set (match_dup 4)
10334 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10335 (ashift:DWIH (match_dup 5)
10336 (minus:QI (match_dup 6) (match_dup 2)))))
10337 (clobber (reg:CC FLAGS_REG))])
10339 [(set (match_dup 5)
10340 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10341 (ashift:DWIH (match_dup 3)
10342 (minus:QI (match_dup 6) (match_dup 2)))))
10343 (clobber (reg:CC FLAGS_REG))])]
10345 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10347 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10350 (define_insn "*bmi2_rorx<mode>3_1"
10351 [(set (match_operand:SWI48 0 "register_operand" "=r")
10352 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10353 (match_operand:QI 2 "immediate_operand" "<S>")))]
10355 "rorx\t{%2, %1, %0|%0, %1, %2}"
10356 [(set_attr "type" "rotatex")
10357 (set_attr "mode" "<MODE>")])
10359 (define_insn "*<rotate_insn><mode>3_1"
10360 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10362 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10363 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10367 switch (get_attr_type (insn))
10373 if (operands[2] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "<rotate>{<imodesuffix>}\t%0";
10377 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10380 [(set_attr "isa" "*,bmi2")
10381 (set_attr "type" "rotate,rotatex")
10382 (set (attr "length_immediate")
10384 (and (eq_attr "type" "rotate")
10385 (and (match_operand 2 "const1_operand")
10386 (ior (match_test "TARGET_SHIFT1")
10387 (match_test "optimize_function_for_size_p (cfun)"))))
10389 (const_string "*")))
10390 (set_attr "mode" "<MODE>")])
10392 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10394 [(set (match_operand:SWI48 0 "register_operand")
10395 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10396 (match_operand:QI 2 "immediate_operand")))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_BMI2 && reload_completed"
10399 [(set (match_dup 0)
10400 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10403 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10407 [(set (match_operand:SWI48 0 "register_operand")
10408 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10409 (match_operand:QI 2 "immediate_operand")))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_BMI2 && reload_completed"
10412 [(set (match_dup 0)
10413 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10415 (define_insn "*bmi2_rorxsi3_1_zext"
10416 [(set (match_operand:DI 0 "register_operand" "=r")
10418 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10419 (match_operand:QI 2 "immediate_operand" "I"))))]
10420 "TARGET_64BIT && TARGET_BMI2"
10421 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10422 [(set_attr "type" "rotatex")
10423 (set_attr "mode" "SI")])
10425 (define_insn "*<rotate_insn>si3_1_zext"
10426 [(set (match_operand:DI 0 "register_operand" "=r,r")
10428 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10429 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10430 (clobber (reg:CC FLAGS_REG))]
10431 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10433 switch (get_attr_type (insn))
10439 if (operands[2] == const1_rtx
10440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10441 return "<rotate>{l}\t%k0";
10443 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10446 [(set_attr "isa" "*,bmi2")
10447 (set_attr "type" "rotate,rotatex")
10448 (set (attr "length_immediate")
10450 (and (eq_attr "type" "rotate")
10451 (and (match_operand 2 "const1_operand")
10452 (ior (match_test "TARGET_SHIFT1")
10453 (match_test "optimize_function_for_size_p (cfun)"))))
10455 (const_string "*")))
10456 (set_attr "mode" "SI")])
10458 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10460 [(set (match_operand:DI 0 "register_operand")
10462 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10463 (match_operand:QI 2 "immediate_operand"))))
10464 (clobber (reg:CC FLAGS_REG))]
10465 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10466 [(set (match_dup 0)
10467 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10470 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10474 [(set (match_operand:DI 0 "register_operand")
10476 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10477 (match_operand:QI 2 "immediate_operand"))))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10480 [(set (match_dup 0)
10481 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10483 (define_insn "*<rotate_insn><mode>3_1"
10484 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10485 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10486 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10487 (clobber (reg:CC FLAGS_REG))]
10488 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10490 if (operands[2] == const1_rtx
10491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10492 return "<rotate>{<imodesuffix>}\t%0";
10494 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10496 [(set_attr "type" "rotate")
10497 (set (attr "length_immediate")
10499 (and (match_operand 2 "const1_operand")
10500 (ior (match_test "TARGET_SHIFT1")
10501 (match_test "optimize_function_for_size_p (cfun)")))
10503 (const_string "*")))
10504 (set_attr "mode" "<MODE>")])
10506 (define_insn "*<rotate_insn>qi3_1_slp"
10507 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10508 (any_rotate:QI (match_dup 0)
10509 (match_operand:QI 1 "nonmemory_operand" "cI")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "(optimize_function_for_size_p (cfun)
10512 || !TARGET_PARTIAL_REG_STALL
10513 || (operands[1] == const1_rtx
10514 && TARGET_SHIFT1))"
10516 if (operands[1] == const1_rtx
10517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10518 return "<rotate>{b}\t%0";
10520 return "<rotate>{b}\t{%1, %0|%0, %1}";
10522 [(set_attr "type" "rotate1")
10523 (set (attr "length_immediate")
10525 (and (match_operand 1 "const1_operand")
10526 (ior (match_test "TARGET_SHIFT1")
10527 (match_test "optimize_function_for_size_p (cfun)")))
10529 (const_string "*")))
10530 (set_attr "mode" "QI")])
10533 [(set (match_operand:HI 0 "register_operand")
10534 (any_rotate:HI (match_dup 0) (const_int 8)))
10535 (clobber (reg:CC FLAGS_REG))]
10537 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10538 [(parallel [(set (strict_low_part (match_dup 0))
10539 (bswap:HI (match_dup 0)))
10540 (clobber (reg:CC FLAGS_REG))])])
10542 ;; Bit set / bit test instructions
10544 (define_expand "extv"
10545 [(set (match_operand:SI 0 "register_operand")
10546 (sign_extract:SI (match_operand:SI 1 "register_operand")
10547 (match_operand:SI 2 "const8_operand")
10548 (match_operand:SI 3 "const8_operand")))]
10551 /* Handle extractions from %ah et al. */
10552 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10555 /* From mips.md: extract_bit_field doesn't verify that our source
10556 matches the predicate, so check it again here. */
10557 if (! ext_register_operand (operands[1], VOIDmode))
10561 (define_expand "extzv"
10562 [(set (match_operand:SI 0 "register_operand")
10563 (zero_extract:SI (match_operand 1 "ext_register_operand")
10564 (match_operand:SI 2 "const8_operand")
10565 (match_operand:SI 3 "const8_operand")))]
10568 /* Handle extractions from %ah et al. */
10569 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10572 /* From mips.md: extract_bit_field doesn't verify that our source
10573 matches the predicate, so check it again here. */
10574 if (! ext_register_operand (operands[1], VOIDmode))
10578 (define_expand "insv"
10579 [(set (zero_extract (match_operand 0 "register_operand")
10580 (match_operand 1 "const_int_operand")
10581 (match_operand 2 "const_int_operand"))
10582 (match_operand 3 "register_operand"))]
10585 rtx (*gen_mov_insv_1) (rtx, rtx);
10587 if (ix86_expand_pinsr (operands))
10590 /* Handle insertions to %ah et al. */
10591 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10594 /* From mips.md: insert_bit_field doesn't verify that our source
10595 matches the predicate, so check it again here. */
10596 if (! ext_register_operand (operands[0], VOIDmode))
10599 gen_mov_insv_1 = (TARGET_64BIT
10600 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10602 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10606 ;; %%% bts, btr, btc, bt.
10607 ;; In general these instructions are *slow* when applied to memory,
10608 ;; since they enforce atomic operation. When applied to registers,
10609 ;; it depends on the cpu implementation. They're never faster than
10610 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10611 ;; no point. But in 64-bit, we can't hold the relevant immediates
10612 ;; within the instruction itself, so operating on bits in the high
10613 ;; 32-bits of a register becomes easier.
10615 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10616 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10617 ;; negdf respectively, so they can never be disabled entirely.
10619 (define_insn "*btsq"
10620 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10622 (match_operand:DI 1 "const_0_to_63_operand"))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10626 "bts{q}\t{%1, %0|%0, %1}"
10627 [(set_attr "type" "alu1")
10628 (set_attr "prefix_0f" "1")
10629 (set_attr "mode" "DI")])
10631 (define_insn "*btrq"
10632 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10634 (match_operand:DI 1 "const_0_to_63_operand"))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10638 "btr{q}\t{%1, %0|%0, %1}"
10639 [(set_attr "type" "alu1")
10640 (set_attr "prefix_0f" "1")
10641 (set_attr "mode" "DI")])
10643 (define_insn "*btcq"
10644 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10646 (match_operand:DI 1 "const_0_to_63_operand"))
10647 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10650 "btc{q}\t{%1, %0|%0, %1}"
10651 [(set_attr "type" "alu1")
10652 (set_attr "prefix_0f" "1")
10653 (set_attr "mode" "DI")])
10655 ;; Allow Nocona to avoid these instructions if a register is available.
10658 [(match_scratch:DI 2 "r")
10659 (parallel [(set (zero_extract:DI
10660 (match_operand:DI 0 "register_operand")
10662 (match_operand:DI 1 "const_0_to_63_operand"))
10664 (clobber (reg:CC FLAGS_REG))])]
10665 "TARGET_64BIT && !TARGET_USE_BT"
10668 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10671 if (HOST_BITS_PER_WIDE_INT >= 64)
10672 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10673 else if (i < HOST_BITS_PER_WIDE_INT)
10674 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10676 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10678 op1 = immed_double_const (lo, hi, DImode);
10681 emit_move_insn (operands[2], op1);
10685 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10690 [(match_scratch:DI 2 "r")
10691 (parallel [(set (zero_extract:DI
10692 (match_operand:DI 0 "register_operand")
10694 (match_operand:DI 1 "const_0_to_63_operand"))
10696 (clobber (reg:CC FLAGS_REG))])]
10697 "TARGET_64BIT && !TARGET_USE_BT"
10700 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10703 if (HOST_BITS_PER_WIDE_INT >= 64)
10704 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10705 else if (i < HOST_BITS_PER_WIDE_INT)
10706 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10708 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10710 op1 = immed_double_const (~lo, ~hi, DImode);
10713 emit_move_insn (operands[2], op1);
10717 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10722 [(match_scratch:DI 2 "r")
10723 (parallel [(set (zero_extract:DI
10724 (match_operand:DI 0 "register_operand")
10726 (match_operand:DI 1 "const_0_to_63_operand"))
10727 (not:DI (zero_extract:DI
10728 (match_dup 0) (const_int 1) (match_dup 1))))
10729 (clobber (reg:CC FLAGS_REG))])]
10730 "TARGET_64BIT && !TARGET_USE_BT"
10733 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10736 if (HOST_BITS_PER_WIDE_INT >= 64)
10737 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10738 else if (i < HOST_BITS_PER_WIDE_INT)
10739 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10741 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10743 op1 = immed_double_const (lo, hi, DImode);
10746 emit_move_insn (operands[2], op1);
10750 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10754 (define_insn "*bt<mode>"
10755 [(set (reg:CCC FLAGS_REG)
10757 (zero_extract:SWI48
10758 (match_operand:SWI48 0 "register_operand" "r")
10760 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10762 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10763 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10764 [(set_attr "type" "alu1")
10765 (set_attr "prefix_0f" "1")
10766 (set_attr "mode" "<MODE>")])
10768 ;; Store-flag instructions.
10770 ;; For all sCOND expanders, also expand the compare or test insn that
10771 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10773 (define_insn_and_split "*setcc_di_1"
10774 [(set (match_operand:DI 0 "register_operand" "=q")
10775 (match_operator:DI 1 "ix86_comparison_operator"
10776 [(reg FLAGS_REG) (const_int 0)]))]
10777 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10779 "&& reload_completed"
10780 [(set (match_dup 2) (match_dup 1))
10781 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10783 PUT_MODE (operands[1], QImode);
10784 operands[2] = gen_lowpart (QImode, operands[0]);
10787 (define_insn_and_split "*setcc_si_1_and"
10788 [(set (match_operand:SI 0 "register_operand" "=q")
10789 (match_operator:SI 1 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)]))
10791 (clobber (reg:CC FLAGS_REG))]
10792 "!TARGET_PARTIAL_REG_STALL
10793 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10795 "&& reload_completed"
10796 [(set (match_dup 2) (match_dup 1))
10797 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10798 (clobber (reg:CC FLAGS_REG))])]
10800 PUT_MODE (operands[1], QImode);
10801 operands[2] = gen_lowpart (QImode, operands[0]);
10804 (define_insn_and_split "*setcc_si_1_movzbl"
10805 [(set (match_operand:SI 0 "register_operand" "=q")
10806 (match_operator:SI 1 "ix86_comparison_operator"
10807 [(reg FLAGS_REG) (const_int 0)]))]
10808 "!TARGET_PARTIAL_REG_STALL
10809 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10811 "&& reload_completed"
10812 [(set (match_dup 2) (match_dup 1))
10813 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10815 PUT_MODE (operands[1], QImode);
10816 operands[2] = gen_lowpart (QImode, operands[0]);
10819 (define_insn "*setcc_qi"
10820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10821 (match_operator:QI 1 "ix86_comparison_operator"
10822 [(reg FLAGS_REG) (const_int 0)]))]
10825 [(set_attr "type" "setcc")
10826 (set_attr "mode" "QI")])
10828 (define_insn "*setcc_qi_slp"
10829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10830 (match_operator:QI 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)]))]
10834 [(set_attr "type" "setcc")
10835 (set_attr "mode" "QI")])
10837 ;; In general it is not safe to assume too much about CCmode registers,
10838 ;; so simplify-rtx stops when it sees a second one. Under certain
10839 ;; conditions this is safe on x86, so help combine not create
10846 [(set (match_operand:QI 0 "nonimmediate_operand")
10847 (ne:QI (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10851 [(set (match_dup 0) (match_dup 1))]
10852 "PUT_MODE (operands[1], QImode);")
10855 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10856 (ne:QI (match_operator 1 "ix86_comparison_operator"
10857 [(reg FLAGS_REG) (const_int 0)])
10860 [(set (match_dup 0) (match_dup 1))]
10861 "PUT_MODE (operands[1], QImode);")
10864 [(set (match_operand:QI 0 "nonimmediate_operand")
10865 (eq:QI (match_operator 1 "ix86_comparison_operator"
10866 [(reg FLAGS_REG) (const_int 0)])
10869 [(set (match_dup 0) (match_dup 1))]
10871 rtx new_op1 = copy_rtx (operands[1]);
10872 operands[1] = new_op1;
10873 PUT_MODE (new_op1, QImode);
10874 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10875 GET_MODE (XEXP (new_op1, 0))));
10877 /* Make sure that (a) the CCmode we have for the flags is strong
10878 enough for the reversed compare or (b) we have a valid FP compare. */
10879 if (! ix86_comparison_operator (new_op1, VOIDmode))
10884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10885 (eq:QI (match_operator 1 "ix86_comparison_operator"
10886 [(reg FLAGS_REG) (const_int 0)])
10889 [(set (match_dup 0) (match_dup 1))]
10891 rtx new_op1 = copy_rtx (operands[1]);
10892 operands[1] = new_op1;
10893 PUT_MODE (new_op1, QImode);
10894 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10895 GET_MODE (XEXP (new_op1, 0))));
10897 /* Make sure that (a) the CCmode we have for the flags is strong
10898 enough for the reversed compare or (b) we have a valid FP compare. */
10899 if (! ix86_comparison_operator (new_op1, VOIDmode))
10903 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10904 ;; subsequent logical operations are used to imitate conditional moves.
10905 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10908 (define_insn "setcc_<mode>_sse"
10909 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10910 (match_operator:MODEF 3 "sse_comparison_operator"
10911 [(match_operand:MODEF 1 "register_operand" "0,x")
10912 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10913 "SSE_FLOAT_MODE_P (<MODE>mode)"
10915 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10916 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10917 [(set_attr "isa" "noavx,avx")
10918 (set_attr "type" "ssecmp")
10919 (set_attr "length_immediate" "1")
10920 (set_attr "prefix" "orig,vex")
10921 (set_attr "mode" "<MODE>")])
10923 ;; Basic conditional jump instructions.
10924 ;; We ignore the overflow flag for signed branch instructions.
10926 (define_insn "*jcc_1"
10928 (if_then_else (match_operator 1 "ix86_comparison_operator"
10929 [(reg FLAGS_REG) (const_int 0)])
10930 (label_ref (match_operand 0))
10934 [(set_attr "type" "ibr")
10935 (set_attr "modrm" "0")
10936 (set (attr "length_nobnd")
10937 (if_then_else (and (ge (minus (match_dup 0) (pc))
10939 (lt (minus (match_dup 0) (pc))
10944 (define_insn "*jcc_2"
10946 (if_then_else (match_operator 1 "ix86_comparison_operator"
10947 [(reg FLAGS_REG) (const_int 0)])
10949 (label_ref (match_operand 0))))]
10952 [(set_attr "type" "ibr")
10953 (set_attr "modrm" "0")
10954 (set (attr "length_nobnd")
10955 (if_then_else (and (ge (minus (match_dup 0) (pc))
10957 (lt (minus (match_dup 0) (pc))
10962 ;; In general it is not safe to assume too much about CCmode registers,
10963 ;; so simplify-rtx stops when it sees a second one. Under certain
10964 ;; conditions this is safe on x86, so help combine not create
10972 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10973 [(reg FLAGS_REG) (const_int 0)])
10975 (label_ref (match_operand 1))
10979 (if_then_else (match_dup 0)
10980 (label_ref (match_dup 1))
10982 "PUT_MODE (operands[0], VOIDmode);")
10986 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10987 [(reg FLAGS_REG) (const_int 0)])
10989 (label_ref (match_operand 1))
10993 (if_then_else (match_dup 0)
10994 (label_ref (match_dup 1))
10997 rtx new_op0 = copy_rtx (operands[0]);
10998 operands[0] = new_op0;
10999 PUT_MODE (new_op0, VOIDmode);
11000 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11001 GET_MODE (XEXP (new_op0, 0))));
11003 /* Make sure that (a) the CCmode we have for the flags is strong
11004 enough for the reversed compare or (b) we have a valid FP compare. */
11005 if (! ix86_comparison_operator (new_op0, VOIDmode))
11009 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11010 ;; pass generates from shift insn with QImode operand. Actually, the mode
11011 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11012 ;; appropriate modulo of the bit offset value.
11014 (define_insn_and_split "*jcc_bt<mode>"
11016 (if_then_else (match_operator 0 "bt_comparison_operator"
11017 [(zero_extract:SWI48
11018 (match_operand:SWI48 1 "register_operand" "r")
11021 (match_operand:QI 2 "register_operand" "r")))
11023 (label_ref (match_operand 3))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11029 [(set (reg:CCC FLAGS_REG)
11031 (zero_extract:SWI48
11037 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11038 (label_ref (match_dup 3))
11041 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11043 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11046 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11047 ;; zero extended to SImode.
11048 (define_insn_and_split "*jcc_bt<mode>_1"
11050 (if_then_else (match_operator 0 "bt_comparison_operator"
11051 [(zero_extract:SWI48
11052 (match_operand:SWI48 1 "register_operand" "r")
11054 (match_operand:SI 2 "register_operand" "r"))
11056 (label_ref (match_operand 3))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11062 [(set (reg:CCC FLAGS_REG)
11064 (zero_extract:SWI48
11070 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11071 (label_ref (match_dup 3))
11074 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11076 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11079 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11080 ;; also for DImode, this is what combine produces.
11081 (define_insn_and_split "*jcc_bt<mode>_mask"
11083 (if_then_else (match_operator 0 "bt_comparison_operator"
11084 [(zero_extract:SWI48
11085 (match_operand:SWI48 1 "register_operand" "r")
11088 (match_operand:SI 2 "register_operand" "r")
11089 (match_operand:SI 3 "const_int_operand" "n")))])
11090 (label_ref (match_operand 4))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11094 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11095 == GET_MODE_BITSIZE (<MODE>mode)-1"
11098 [(set (reg:CCC FLAGS_REG)
11100 (zero_extract:SWI48
11106 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11107 (label_ref (match_dup 4))
11110 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11112 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11115 (define_insn_and_split "*jcc_btsi_1"
11117 (if_then_else (match_operator 0 "bt_comparison_operator"
11120 (match_operand:SI 1 "register_operand" "r")
11121 (match_operand:QI 2 "register_operand" "r"))
11124 (label_ref (match_operand 3))
11126 (clobber (reg:CC FLAGS_REG))]
11127 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11130 [(set (reg:CCC FLAGS_REG)
11138 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11139 (label_ref (match_dup 3))
11142 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11144 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11147 ;; avoid useless masking of bit offset operand
11148 (define_insn_and_split "*jcc_btsi_mask_1"
11151 (match_operator 0 "bt_comparison_operator"
11154 (match_operand:SI 1 "register_operand" "r")
11157 (match_operand:SI 2 "register_operand" "r")
11158 (match_operand:SI 3 "const_int_operand" "n")) 0))
11161 (label_ref (match_operand 4))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11165 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11168 [(set (reg:CCC FLAGS_REG)
11176 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11177 (label_ref (match_dup 4))
11179 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11181 ;; Define combination compare-and-branch fp compare instructions to help
11184 (define_insn "*jcc<mode>_0_i387"
11186 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11187 [(match_operand:X87MODEF 1 "register_operand" "f")
11188 (match_operand:X87MODEF 2 "const0_operand")])
11189 (label_ref (match_operand 3))
11191 (clobber (reg:CCFP FPSR_REG))
11192 (clobber (reg:CCFP FLAGS_REG))
11193 (clobber (match_scratch:HI 4 "=a"))]
11194 "TARGET_80387 && !TARGET_CMOVE"
11197 (define_insn "*jcc<mode>_0_r_i387"
11199 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11200 [(match_operand:X87MODEF 1 "register_operand" "f")
11201 (match_operand:X87MODEF 2 "const0_operand")])
11203 (label_ref (match_operand 3))))
11204 (clobber (reg:CCFP FPSR_REG))
11205 (clobber (reg:CCFP FLAGS_REG))
11206 (clobber (match_scratch:HI 4 "=a"))]
11207 "TARGET_80387 && !TARGET_CMOVE"
11210 (define_insn "*jccxf_i387"
11212 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11213 [(match_operand:XF 1 "register_operand" "f")
11214 (match_operand:XF 2 "register_operand" "f")])
11215 (label_ref (match_operand 3))
11217 (clobber (reg:CCFP FPSR_REG))
11218 (clobber (reg:CCFP FLAGS_REG))
11219 (clobber (match_scratch:HI 4 "=a"))]
11220 "TARGET_80387 && !TARGET_CMOVE"
11223 (define_insn "*jccxf_r_i387"
11225 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11226 [(match_operand:XF 1 "register_operand" "f")
11227 (match_operand:XF 2 "register_operand" "f")])
11229 (label_ref (match_operand 3))))
11230 (clobber (reg:CCFP FPSR_REG))
11231 (clobber (reg:CCFP FLAGS_REG))
11232 (clobber (match_scratch:HI 4 "=a"))]
11233 "TARGET_80387 && !TARGET_CMOVE"
11236 (define_insn "*jcc<mode>_i387"
11238 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11239 [(match_operand:MODEF 1 "register_operand" "f")
11240 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11241 (label_ref (match_operand 3))
11243 (clobber (reg:CCFP FPSR_REG))
11244 (clobber (reg:CCFP FLAGS_REG))
11245 (clobber (match_scratch:HI 4 "=a"))]
11246 "TARGET_80387 && !TARGET_CMOVE"
11249 (define_insn "*jcc<mode>_r_i387"
11251 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11252 [(match_operand:MODEF 1 "register_operand" "f")
11253 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11255 (label_ref (match_operand 3))))
11256 (clobber (reg:CCFP FPSR_REG))
11257 (clobber (reg:CCFP FLAGS_REG))
11258 (clobber (match_scratch:HI 4 "=a"))]
11259 "TARGET_80387 && !TARGET_CMOVE"
11262 (define_insn "*jccu<mode>_i387"
11264 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11265 [(match_operand:X87MODEF 1 "register_operand" "f")
11266 (match_operand:X87MODEF 2 "register_operand" "f")])
11267 (label_ref (match_operand 3))
11269 (clobber (reg:CCFP FPSR_REG))
11270 (clobber (reg:CCFP FLAGS_REG))
11271 (clobber (match_scratch:HI 4 "=a"))]
11272 "TARGET_80387 && !TARGET_CMOVE"
11275 (define_insn "*jccu<mode>_r_i387"
11277 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11278 [(match_operand:X87MODEF 1 "register_operand" "f")
11279 (match_operand:X87MODEF 2 "register_operand" "f")])
11281 (label_ref (match_operand 3))))
11282 (clobber (reg:CCFP FPSR_REG))
11283 (clobber (reg:CCFP FLAGS_REG))
11284 (clobber (match_scratch:HI 4 "=a"))]
11285 "TARGET_80387 && !TARGET_CMOVE"
11290 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11291 [(match_operand:X87MODEF 1 "register_operand")
11292 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11294 (match_operand 4)))
11295 (clobber (reg:CCFP FPSR_REG))
11296 (clobber (reg:CCFP FLAGS_REG))]
11297 "TARGET_80387 && !TARGET_CMOVE
11298 && reload_completed"
11301 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11302 operands[3], operands[4], NULL_RTX);
11308 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11309 [(match_operand:X87MODEF 1 "register_operand")
11310 (match_operand:X87MODEF 2 "general_operand")])
11312 (match_operand 4)))
11313 (clobber (reg:CCFP FPSR_REG))
11314 (clobber (reg:CCFP FLAGS_REG))
11315 (clobber (match_scratch:HI 5))]
11316 "TARGET_80387 && !TARGET_CMOVE
11317 && reload_completed"
11320 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11321 operands[3], operands[4], operands[5]);
11325 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11326 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11327 ;; with a precedence over other operators and is always put in the first
11328 ;; place. Swap condition and operands to match ficom instruction.
11330 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11333 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11334 [(match_operator:X87MODEF 1 "float_operator"
11335 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11336 (match_operand:X87MODEF 3 "register_operand" "f")])
11337 (label_ref (match_operand 4))
11339 (clobber (reg:CCFP FPSR_REG))
11340 (clobber (reg:CCFP FLAGS_REG))
11341 (clobber (match_scratch:HI 5 "=a"))]
11342 "TARGET_80387 && !TARGET_CMOVE
11343 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11344 || optimize_function_for_size_p (cfun))"
11347 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11350 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11351 [(match_operator:X87MODEF 1 "float_operator"
11352 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11353 (match_operand:X87MODEF 3 "register_operand" "f")])
11355 (label_ref (match_operand 4))))
11356 (clobber (reg:CCFP FPSR_REG))
11357 (clobber (reg:CCFP FLAGS_REG))
11358 (clobber (match_scratch:HI 5 "=a"))]
11359 "TARGET_80387 && !TARGET_CMOVE
11360 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11361 || optimize_function_for_size_p (cfun))"
11367 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11368 [(match_operator:X87MODEF 1 "float_operator"
11369 [(match_operand:SWI24 2 "memory_operand")])
11370 (match_operand:X87MODEF 3 "register_operand")])
11372 (match_operand 5)))
11373 (clobber (reg:CCFP FPSR_REG))
11374 (clobber (reg:CCFP FLAGS_REG))
11375 (clobber (match_scratch:HI 6))]
11376 "TARGET_80387 && !TARGET_CMOVE
11377 && reload_completed"
11380 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11381 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11382 operands[4], operands[5], operands[6]);
11386 ;; Unconditional and other jump instructions
11388 (define_insn "jump"
11390 (label_ref (match_operand 0)))]
11393 [(set_attr "type" "ibr")
11394 (set (attr "length_nobnd")
11395 (if_then_else (and (ge (minus (match_dup 0) (pc))
11397 (lt (minus (match_dup 0) (pc))
11401 (set_attr "modrm" "0")])
11403 (define_expand "indirect_jump"
11404 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11408 operands[0] = convert_memory_address (word_mode, operands[0]);
11411 (define_insn "*indirect_jump"
11412 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11415 [(set_attr "type" "ibr")
11416 (set_attr "length_immediate" "0")])
11418 (define_expand "tablejump"
11419 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11420 (use (label_ref (match_operand 1)))])]
11423 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11424 relative. Convert the relative address to an absolute address. */
11428 enum rtx_code code;
11430 /* We can't use @GOTOFF for text labels on VxWorks;
11431 see gotoff_operand. */
11432 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11436 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11438 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11442 op1 = pic_offset_table_rtx;
11447 op0 = pic_offset_table_rtx;
11451 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11456 operands[0] = convert_memory_address (word_mode, operands[0]);
11459 (define_insn "*tablejump_1"
11460 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11461 (use (label_ref (match_operand 1)))]
11464 [(set_attr "type" "ibr")
11465 (set_attr "length_immediate" "0")])
11467 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11470 [(set (reg FLAGS_REG) (match_operand 0))
11471 (set (match_operand:QI 1 "register_operand")
11472 (match_operator:QI 2 "ix86_comparison_operator"
11473 [(reg FLAGS_REG) (const_int 0)]))
11474 (set (match_operand 3 "q_regs_operand")
11475 (zero_extend (match_dup 1)))]
11476 "(peep2_reg_dead_p (3, operands[1])
11477 || operands_match_p (operands[1], operands[3]))
11478 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11479 [(set (match_dup 4) (match_dup 0))
11480 (set (strict_low_part (match_dup 5))
11483 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11484 operands[5] = gen_lowpart (QImode, operands[3]);
11485 ix86_expand_clear (operands[3]);
11489 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11490 (match_operand 4)])
11491 (set (match_operand:QI 1 "register_operand")
11492 (match_operator:QI 2 "ix86_comparison_operator"
11493 [(reg FLAGS_REG) (const_int 0)]))
11494 (set (match_operand 3 "q_regs_operand")
11495 (zero_extend (match_dup 1)))]
11496 "(peep2_reg_dead_p (3, operands[1])
11497 || operands_match_p (operands[1], operands[3]))
11498 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11499 [(parallel [(set (match_dup 5) (match_dup 0))
11501 (set (strict_low_part (match_dup 6))
11504 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11505 operands[6] = gen_lowpart (QImode, operands[3]);
11506 ix86_expand_clear (operands[3]);
11509 ;; Similar, but match zero extend with andsi3.
11512 [(set (reg FLAGS_REG) (match_operand 0))
11513 (set (match_operand:QI 1 "register_operand")
11514 (match_operator:QI 2 "ix86_comparison_operator"
11515 [(reg FLAGS_REG) (const_int 0)]))
11516 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11517 (and:SI (match_dup 3) (const_int 255)))
11518 (clobber (reg:CC FLAGS_REG))])]
11519 "REGNO (operands[1]) == REGNO (operands[3])
11520 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11521 [(set (match_dup 4) (match_dup 0))
11522 (set (strict_low_part (match_dup 5))
11525 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11526 operands[5] = gen_lowpart (QImode, operands[3]);
11527 ix86_expand_clear (operands[3]);
11531 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11532 (match_operand 4)])
11533 (set (match_operand:QI 1 "register_operand")
11534 (match_operator:QI 2 "ix86_comparison_operator"
11535 [(reg FLAGS_REG) (const_int 0)]))
11536 (parallel [(set (match_operand 3 "q_regs_operand")
11537 (zero_extend (match_dup 1)))
11538 (clobber (reg:CC FLAGS_REG))])]
11539 "(peep2_reg_dead_p (3, operands[1])
11540 || operands_match_p (operands[1], operands[3]))
11541 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11542 [(parallel [(set (match_dup 5) (match_dup 0))
11544 (set (strict_low_part (match_dup 6))
11547 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11548 operands[6] = gen_lowpart (QImode, operands[3]);
11549 ix86_expand_clear (operands[3]);
11552 ;; Call instructions.
11554 ;; The predicates normally associated with named expanders are not properly
11555 ;; checked for calls. This is a bug in the generic code, but it isn't that
11556 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11558 ;; P6 processors will jump to the address after the decrement when %esp
11559 ;; is used as a call operand, so they will execute return address as a code.
11560 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11562 ;; Register constraint for call instruction.
11563 (define_mode_attr c [(SI "l") (DI "r")])
11565 ;; Call subroutine returning no value.
11567 (define_expand "call"
11568 [(call (match_operand:QI 0)
11570 (use (match_operand 2))]
11573 ix86_expand_call (NULL, operands[0], operands[1],
11574 operands[2], NULL, false);
11578 (define_expand "sibcall"
11579 [(call (match_operand:QI 0)
11581 (use (match_operand 2))]
11584 ix86_expand_call (NULL, operands[0], operands[1],
11585 operands[2], NULL, true);
11589 (define_insn "*call"
11590 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11591 (match_operand 1))]
11592 "!SIBLING_CALL_P (insn)"
11593 "* return ix86_output_call_insn (insn, operands[0]);"
11594 [(set_attr "type" "call")])
11596 (define_insn "*sibcall"
11597 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11598 (match_operand 1))]
11599 "SIBLING_CALL_P (insn)"
11600 "* return ix86_output_call_insn (insn, operands[0]);"
11601 [(set_attr "type" "call")])
11603 (define_insn "*sibcall_memory"
11604 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11606 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11608 "* return ix86_output_call_insn (insn, operands[0]);"
11609 [(set_attr "type" "call")])
11612 [(set (match_operand:W 0 "register_operand")
11613 (match_operand:W 1 "memory_operand"))
11614 (call (mem:QI (match_dup 0))
11615 (match_operand 3))]
11616 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11617 && peep2_reg_dead_p (2, operands[0])"
11618 [(parallel [(call (mem:QI (match_dup 1))
11620 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11623 [(set (match_operand:W 0 "register_operand")
11624 (match_operand:W 1 "memory_operand"))
11625 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11626 (call (mem:QI (match_dup 0))
11627 (match_operand 3))]
11628 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11629 && peep2_reg_dead_p (3, operands[0])"
11630 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11631 (parallel [(call (mem:QI (match_dup 1))
11633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11635 (define_expand "call_pop"
11636 [(parallel [(call (match_operand:QI 0)
11637 (match_operand:SI 1))
11638 (set (reg:SI SP_REG)
11639 (plus:SI (reg:SI SP_REG)
11640 (match_operand:SI 3)))])]
11643 ix86_expand_call (NULL, operands[0], operands[1],
11644 operands[2], operands[3], false);
11648 (define_insn "*call_pop"
11649 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11651 (set (reg:SI SP_REG)
11652 (plus:SI (reg:SI SP_REG)
11653 (match_operand:SI 2 "immediate_operand" "i")))]
11654 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11655 "* return ix86_output_call_insn (insn, operands[0]);"
11656 [(set_attr "type" "call")])
11658 (define_insn "*sibcall_pop"
11659 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11661 (set (reg:SI SP_REG)
11662 (plus:SI (reg:SI SP_REG)
11663 (match_operand:SI 2 "immediate_operand" "i")))]
11664 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11665 "* return ix86_output_call_insn (insn, operands[0]);"
11666 [(set_attr "type" "call")])
11668 (define_insn "*sibcall_pop_memory"
11669 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11671 (set (reg:SI SP_REG)
11672 (plus:SI (reg:SI SP_REG)
11673 (match_operand:SI 2 "immediate_operand" "i")))
11674 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11676 "* return ix86_output_call_insn (insn, operands[0]);"
11677 [(set_attr "type" "call")])
11680 [(set (match_operand:SI 0 "register_operand")
11681 (match_operand:SI 1 "memory_operand"))
11682 (parallel [(call (mem:QI (match_dup 0))
11684 (set (reg:SI SP_REG)
11685 (plus:SI (reg:SI SP_REG)
11686 (match_operand:SI 4 "immediate_operand")))])]
11687 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11688 && peep2_reg_dead_p (2, operands[0])"
11689 [(parallel [(call (mem:QI (match_dup 1))
11691 (set (reg:SI SP_REG)
11692 (plus:SI (reg:SI SP_REG)
11694 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11697 [(set (match_operand:SI 0 "register_operand")
11698 (match_operand:SI 1 "memory_operand"))
11699 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11700 (parallel [(call (mem:QI (match_dup 0))
11702 (set (reg:SI SP_REG)
11703 (plus:SI (reg:SI SP_REG)
11704 (match_operand:SI 4 "immediate_operand")))])]
11705 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11706 && peep2_reg_dead_p (3, operands[0])"
11707 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11708 (parallel [(call (mem:QI (match_dup 1))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11713 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11715 ;; Combining simple memory jump instruction
11718 [(set (match_operand:W 0 "register_operand")
11719 (match_operand:W 1 "memory_operand"))
11720 (set (pc) (match_dup 0))]
11721 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11722 [(set (pc) (match_dup 1))])
11724 ;; Call subroutine, returning value in operand 0
11726 (define_expand "call_value"
11727 [(set (match_operand 0)
11728 (call (match_operand:QI 1)
11729 (match_operand 2)))
11730 (use (match_operand 3))]
11733 ix86_expand_call (operands[0], operands[1], operands[2],
11734 operands[3], NULL, false);
11738 (define_expand "sibcall_value"
11739 [(set (match_operand 0)
11740 (call (match_operand:QI 1)
11741 (match_operand 2)))
11742 (use (match_operand 3))]
11745 ix86_expand_call (operands[0], operands[1], operands[2],
11746 operands[3], NULL, true);
11750 (define_insn "*call_value"
11751 [(set (match_operand 0)
11752 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11753 (match_operand 2)))]
11754 "!SIBLING_CALL_P (insn)"
11755 "* return ix86_output_call_insn (insn, operands[1]);"
11756 [(set_attr "type" "callv")])
11758 (define_insn "*sibcall_value"
11759 [(set (match_operand 0)
11760 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11761 (match_operand 2)))]
11762 "SIBLING_CALL_P (insn)"
11763 "* return ix86_output_call_insn (insn, operands[1]);"
11764 [(set_attr "type" "callv")])
11766 (define_insn "*sibcall_value_memory"
11767 [(set (match_operand 0)
11768 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11769 (match_operand 2)))
11770 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11776 [(set (match_operand:W 0 "register_operand")
11777 (match_operand:W 1 "memory_operand"))
11778 (set (match_operand 2)
11779 (call (mem:QI (match_dup 0))
11780 (match_operand 3)))]
11781 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11782 && peep2_reg_dead_p (2, operands[0])"
11783 [(parallel [(set (match_dup 2)
11784 (call (mem:QI (match_dup 1))
11786 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11789 [(set (match_operand:W 0 "register_operand")
11790 (match_operand:W 1 "memory_operand"))
11791 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11792 (set (match_operand 2)
11793 (call (mem:QI (match_dup 0))
11794 (match_operand 3)))]
11795 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11796 && peep2_reg_dead_p (3, operands[0])"
11797 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11798 (parallel [(set (match_dup 2)
11799 (call (mem:QI (match_dup 1))
11801 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11803 (define_expand "call_value_pop"
11804 [(parallel [(set (match_operand 0)
11805 (call (match_operand:QI 1)
11806 (match_operand:SI 2)))
11807 (set (reg:SI SP_REG)
11808 (plus:SI (reg:SI SP_REG)
11809 (match_operand:SI 4)))])]
11812 ix86_expand_call (operands[0], operands[1], operands[2],
11813 operands[3], operands[4], false);
11817 (define_insn "*call_value_pop"
11818 [(set (match_operand 0)
11819 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11820 (match_operand 2)))
11821 (set (reg:SI SP_REG)
11822 (plus:SI (reg:SI SP_REG)
11823 (match_operand:SI 3 "immediate_operand" "i")))]
11824 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11825 "* return ix86_output_call_insn (insn, operands[1]);"
11826 [(set_attr "type" "callv")])
11828 (define_insn "*sibcall_value_pop"
11829 [(set (match_operand 0)
11830 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11831 (match_operand 2)))
11832 (set (reg:SI SP_REG)
11833 (plus:SI (reg:SI SP_REG)
11834 (match_operand:SI 3 "immediate_operand" "i")))]
11835 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11836 "* return ix86_output_call_insn (insn, operands[1]);"
11837 [(set_attr "type" "callv")])
11839 (define_insn "*sibcall_value_pop_memory"
11840 [(set (match_operand 0)
11841 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11842 (match_operand 2)))
11843 (set (reg:SI SP_REG)
11844 (plus:SI (reg:SI SP_REG)
11845 (match_operand:SI 3 "immediate_operand" "i")))
11846 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11848 "* return ix86_output_call_insn (insn, operands[1]);"
11849 [(set_attr "type" "callv")])
11852 [(set (match_operand:SI 0 "register_operand")
11853 (match_operand:SI 1 "memory_operand"))
11854 (parallel [(set (match_operand 2)
11855 (call (mem:QI (match_dup 0))
11856 (match_operand 3)))
11857 (set (reg:SI SP_REG)
11858 (plus:SI (reg:SI SP_REG)
11859 (match_operand:SI 4 "immediate_operand")))])]
11860 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11861 && peep2_reg_dead_p (2, operands[0])"
11862 [(parallel [(set (match_dup 2)
11863 (call (mem:QI (match_dup 1))
11865 (set (reg:SI SP_REG)
11866 (plus:SI (reg:SI SP_REG)
11868 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11871 [(set (match_operand:SI 0 "register_operand")
11872 (match_operand:SI 1 "memory_operand"))
11873 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11874 (parallel [(set (match_operand 2)
11875 (call (mem:QI (match_dup 0))
11876 (match_operand 3)))
11877 (set (reg:SI SP_REG)
11878 (plus:SI (reg:SI SP_REG)
11879 (match_operand:SI 4 "immediate_operand")))])]
11880 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11881 && peep2_reg_dead_p (3, operands[0])"
11882 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11883 (parallel [(set (match_dup 2)
11884 (call (mem:QI (match_dup 1))
11886 (set (reg:SI SP_REG)
11887 (plus:SI (reg:SI SP_REG)
11889 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11891 ;; Call subroutine returning any type.
11893 (define_expand "untyped_call"
11894 [(parallel [(call (match_operand 0)
11897 (match_operand 2)])]
11902 /* In order to give reg-stack an easier job in validating two
11903 coprocessor registers as containing a possible return value,
11904 simply pretend the untyped call returns a complex long double
11907 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11908 and should have the default ABI. */
11910 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11911 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11912 operands[0], const0_rtx,
11913 GEN_INT ((TARGET_64BIT
11914 ? (ix86_abi == SYSV_ABI
11915 ? X86_64_SSE_REGPARM_MAX
11916 : X86_64_MS_SSE_REGPARM_MAX)
11917 : X86_32_SSE_REGPARM_MAX)
11921 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11923 rtx set = XVECEXP (operands[2], 0, i);
11924 emit_move_insn (SET_DEST (set), SET_SRC (set));
11927 /* The optimizer does not know that the call sets the function value
11928 registers we stored in the result block. We avoid problems by
11929 claiming that all hard registers are used and clobbered at this
11931 emit_insn (gen_blockage ());
11936 ;; Prologue and epilogue instructions
11938 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11939 ;; all of memory. This blocks insns from being moved across this point.
11941 (define_insn "blockage"
11942 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11945 [(set_attr "length" "0")])
11947 ;; Do not schedule instructions accessing memory across this point.
11949 (define_expand "memory_blockage"
11950 [(set (match_dup 0)
11951 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11954 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11955 MEM_VOLATILE_P (operands[0]) = 1;
11958 (define_insn "*memory_blockage"
11959 [(set (match_operand:BLK 0)
11960 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11963 [(set_attr "length" "0")])
11965 ;; As USE insns aren't meaningful after reload, this is used instead
11966 ;; to prevent deleting instructions setting registers for PIC code
11967 (define_insn "prologue_use"
11968 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11971 [(set_attr "length" "0")])
11973 ;; Insn emitted into the body of a function to return from a function.
11974 ;; This is only done if the function's epilogue is known to be simple.
11975 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11977 (define_expand "return"
11979 "ix86_can_use_return_insn_p ()"
11981 if (crtl->args.pops_args)
11983 rtx popc = GEN_INT (crtl->args.pops_args);
11984 emit_jump_insn (gen_simple_return_pop_internal (popc));
11989 ;; We need to disable this for TARGET_SEH, as otherwise
11990 ;; shrink-wrapped prologue gets enabled too. This might exceed
11991 ;; the maximum size of prologue in unwind information.
11993 (define_expand "simple_return"
11997 if (crtl->args.pops_args)
11999 rtx popc = GEN_INT (crtl->args.pops_args);
12000 emit_jump_insn (gen_simple_return_pop_internal (popc));
12005 (define_insn "simple_return_internal"
12009 [(set_attr "length_nobnd" "1")
12010 (set_attr "atom_unit" "jeu")
12011 (set_attr "length_immediate" "0")
12012 (set_attr "modrm" "0")])
12014 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12015 ;; instruction Athlon and K8 have.
12017 (define_insn "simple_return_internal_long"
12019 (unspec [(const_int 0)] UNSPEC_REP)]
12022 if (ix86_bnd_prefixed_insn_p (insn))
12025 return "rep%; ret";
12027 [(set_attr "length" "2")
12028 (set_attr "atom_unit" "jeu")
12029 (set_attr "length_immediate" "0")
12030 (set_attr "prefix_rep" "1")
12031 (set_attr "modrm" "0")])
12033 (define_insn "simple_return_pop_internal"
12035 (use (match_operand:SI 0 "const_int_operand"))]
12038 [(set_attr "length_nobnd" "3")
12039 (set_attr "atom_unit" "jeu")
12040 (set_attr "length_immediate" "2")
12041 (set_attr "modrm" "0")])
12043 (define_insn "simple_return_indirect_internal"
12045 (use (match_operand:SI 0 "register_operand" "r"))]
12048 [(set_attr "type" "ibr")
12049 (set_attr "length_immediate" "0")])
12055 [(set_attr "length" "1")
12056 (set_attr "length_immediate" "0")
12057 (set_attr "modrm" "0")])
12059 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12060 (define_insn "nops"
12061 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12065 int num = INTVAL (operands[0]);
12067 gcc_assert (IN_RANGE (num, 1, 8));
12070 fputs ("\tnop\n", asm_out_file);
12074 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12075 (set_attr "length_immediate" "0")
12076 (set_attr "modrm" "0")])
12078 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12079 ;; branch prediction penalty for the third jump in a 16-byte
12083 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12086 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12087 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12089 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12090 The align insn is used to avoid 3 jump instructions in the row to improve
12091 branch prediction and the benefits hardly outweigh the cost of extra 8
12092 nops on the average inserted by full alignment pseudo operation. */
12096 [(set_attr "length" "16")])
12098 (define_expand "prologue"
12101 "ix86_expand_prologue (); DONE;")
12103 (define_insn "set_got"
12104 [(set (match_operand:SI 0 "register_operand" "=r")
12105 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12106 (clobber (reg:CC FLAGS_REG))]
12108 "* return output_set_got (operands[0], NULL_RTX);"
12109 [(set_attr "type" "multi")
12110 (set_attr "length" "12")])
12112 (define_insn "set_got_labelled"
12113 [(set (match_operand:SI 0 "register_operand" "=r")
12114 (unspec:SI [(label_ref (match_operand 1))]
12116 (clobber (reg:CC FLAGS_REG))]
12118 "* return output_set_got (operands[0], operands[1]);"
12119 [(set_attr "type" "multi")
12120 (set_attr "length" "12")])
12122 (define_insn "set_got_rex64"
12123 [(set (match_operand:DI 0 "register_operand" "=r")
12124 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12126 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12127 [(set_attr "type" "lea")
12128 (set_attr "length_address" "4")
12129 (set_attr "mode" "DI")])
12131 (define_insn "set_rip_rex64"
12132 [(set (match_operand:DI 0 "register_operand" "=r")
12133 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12135 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12136 [(set_attr "type" "lea")
12137 (set_attr "length_address" "4")
12138 (set_attr "mode" "DI")])
12140 (define_insn "set_got_offset_rex64"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12143 [(label_ref (match_operand 1))]
12144 UNSPEC_SET_GOT_OFFSET))]
12146 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12147 [(set_attr "type" "imov")
12148 (set_attr "length_immediate" "0")
12149 (set_attr "length_address" "8")
12150 (set_attr "mode" "DI")])
12152 (define_expand "epilogue"
12155 "ix86_expand_epilogue (1); DONE;")
12157 (define_expand "sibcall_epilogue"
12160 "ix86_expand_epilogue (0); DONE;")
12162 (define_expand "eh_return"
12163 [(use (match_operand 0 "register_operand"))]
12166 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12168 /* Tricky bit: we write the address of the handler to which we will
12169 be returning into someone else's stack frame, one word below the
12170 stack address we wish to restore. */
12171 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12172 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12173 tmp = gen_rtx_MEM (Pmode, tmp);
12174 emit_move_insn (tmp, ra);
12176 emit_jump_insn (gen_eh_return_internal ());
12181 (define_insn_and_split "eh_return_internal"
12185 "epilogue_completed"
12187 "ix86_expand_epilogue (2); DONE;")
12189 (define_insn "leave"
12190 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12191 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12192 (clobber (mem:BLK (scratch)))]
12195 [(set_attr "type" "leave")])
12197 (define_insn "leave_rex64"
12198 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12199 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12200 (clobber (mem:BLK (scratch)))]
12203 [(set_attr "type" "leave")])
12205 ;; Handle -fsplit-stack.
12207 (define_expand "split_stack_prologue"
12211 ix86_expand_split_stack_prologue ();
12215 ;; In order to support the call/return predictor, we use a return
12216 ;; instruction which the middle-end doesn't see.
12217 (define_insn "split_stack_return"
12218 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12219 UNSPECV_SPLIT_STACK_RETURN)]
12222 if (operands[0] == const0_rtx)
12227 [(set_attr "atom_unit" "jeu")
12228 (set_attr "modrm" "0")
12229 (set (attr "length")
12230 (if_then_else (match_operand:SI 0 "const0_operand")
12233 (set (attr "length_immediate")
12234 (if_then_else (match_operand:SI 0 "const0_operand")
12238 ;; If there are operand 0 bytes available on the stack, jump to
12241 (define_expand "split_stack_space_check"
12242 [(set (pc) (if_then_else
12243 (ltu (minus (reg SP_REG)
12244 (match_operand 0 "register_operand"))
12245 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12246 (label_ref (match_operand 1))
12250 rtx reg, size, limit;
12252 reg = gen_reg_rtx (Pmode);
12253 size = force_reg (Pmode, operands[0]);
12254 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12255 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12256 UNSPEC_STACK_CHECK);
12257 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12258 ix86_expand_branch (GEU, reg, limit, operands[1]);
12263 ;; Bit manipulation instructions.
12265 (define_expand "ffs<mode>2"
12266 [(set (match_dup 2) (const_int -1))
12267 (parallel [(set (match_dup 3) (match_dup 4))
12268 (set (match_operand:SWI48 0 "register_operand")
12270 (match_operand:SWI48 1 "nonimmediate_operand")))])
12271 (set (match_dup 0) (if_then_else:SWI48
12272 (eq (match_dup 3) (const_int 0))
12275 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12276 (clobber (reg:CC FLAGS_REG))])]
12279 machine_mode flags_mode;
12281 if (<MODE>mode == SImode && !TARGET_CMOVE)
12283 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12288 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12290 operands[2] = gen_reg_rtx (<MODE>mode);
12291 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12292 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12295 (define_insn_and_split "ffssi2_no_cmove"
12296 [(set (match_operand:SI 0 "register_operand" "=r")
12297 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12298 (clobber (match_scratch:SI 2 "=&q"))
12299 (clobber (reg:CC FLAGS_REG))]
12302 "&& reload_completed"
12303 [(parallel [(set (match_dup 4) (match_dup 5))
12304 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12305 (set (strict_low_part (match_dup 3))
12306 (eq:QI (match_dup 4) (const_int 0)))
12307 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12308 (clobber (reg:CC FLAGS_REG))])
12309 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12310 (clobber (reg:CC FLAGS_REG))])
12311 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12312 (clobber (reg:CC FLAGS_REG))])]
12314 machine_mode flags_mode
12315 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12317 operands[3] = gen_lowpart (QImode, operands[2]);
12318 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12319 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12321 ix86_expand_clear (operands[2]);
12324 (define_insn "*tzcnt<mode>_1"
12325 [(set (reg:CCC FLAGS_REG)
12326 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12328 (set (match_operand:SWI48 0 "register_operand" "=r")
12329 (ctz:SWI48 (match_dup 1)))]
12330 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12331 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12332 [(set_attr "type" "alu1")
12333 (set_attr "prefix_0f" "1")
12334 (set_attr "prefix_rep" "1")
12335 (set_attr "btver2_decode" "double")
12336 (set_attr "mode" "<MODE>")])
12338 (define_insn "*bsf<mode>_1"
12339 [(set (reg:CCZ FLAGS_REG)
12340 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12342 (set (match_operand:SWI48 0 "register_operand" "=r")
12343 (ctz:SWI48 (match_dup 1)))]
12345 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12346 [(set_attr "type" "alu1")
12347 (set_attr "prefix_0f" "1")
12348 (set_attr "btver2_decode" "double")
12349 (set_attr "mode" "<MODE>")])
12351 (define_expand "ctz<mode>2"
12353 [(set (match_operand:SWI248 0 "register_operand")
12355 (match_operand:SWI248 1 "nonimmediate_operand")))
12356 (clobber (reg:CC FLAGS_REG))])])
12358 ; False dependency happens when destination is only updated by tzcnt,
12359 ; lzcnt or popcnt. There is no false dependency when destination is
12360 ; also used in source.
12361 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12364 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "(TARGET_BMI || TARGET_GENERIC)
12367 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12369 "&& reload_completed"
12371 [(set (match_dup 0)
12372 (ctz:SWI48 (match_dup 1)))
12373 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12374 (clobber (reg:CC FLAGS_REG))])]
12376 if (!reg_mentioned_p (operands[0], operands[1]))
12377 ix86_expand_clear (operands[0]);
12380 (define_insn "*ctz<mode>2_falsedep"
12381 [(set (match_operand:SWI48 0 "register_operand" "=r")
12383 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12384 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12385 UNSPEC_INSN_FALSE_DEP)
12386 (clobber (reg:CC FLAGS_REG))]
12390 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12391 else if (TARGET_GENERIC)
12392 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12393 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12395 gcc_unreachable ();
12397 [(set_attr "type" "alu1")
12398 (set_attr "prefix_0f" "1")
12399 (set_attr "prefix_rep" "1")
12400 (set_attr "mode" "<MODE>")])
12402 (define_insn "*ctz<mode>2"
12403 [(set (match_operand:SWI248 0 "register_operand" "=r")
12404 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12405 (clobber (reg:CC FLAGS_REG))]
12409 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12410 else if (optimize_function_for_size_p (cfun))
12412 else if (TARGET_GENERIC)
12413 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12414 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12416 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12418 [(set_attr "type" "alu1")
12419 (set_attr "prefix_0f" "1")
12420 (set (attr "prefix_rep")
12422 (ior (match_test "TARGET_BMI")
12423 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12424 (match_test "TARGET_GENERIC")))
12426 (const_string "0")))
12427 (set_attr "mode" "<MODE>")])
12429 (define_expand "clz<mode>2"
12431 [(set (match_operand:SWI248 0 "register_operand")
12434 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12435 (clobber (reg:CC FLAGS_REG))])
12437 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12438 (clobber (reg:CC FLAGS_REG))])]
12443 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12446 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12449 (define_expand "clz<mode>2_lzcnt"
12451 [(set (match_operand:SWI248 0 "register_operand")
12453 (match_operand:SWI248 1 "nonimmediate_operand")))
12454 (clobber (reg:CC FLAGS_REG))])]
12457 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12458 [(set (match_operand:SWI48 0 "register_operand" "=r")
12460 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12461 (clobber (reg:CC FLAGS_REG))]
12463 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12465 "&& reload_completed"
12467 [(set (match_dup 0)
12468 (clz:SWI48 (match_dup 1)))
12469 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12470 (clobber (reg:CC FLAGS_REG))])]
12472 if (!reg_mentioned_p (operands[0], operands[1]))
12473 ix86_expand_clear (operands[0]);
12476 (define_insn "*clz<mode>2_lzcnt_falsedep"
12477 [(set (match_operand:SWI48 0 "register_operand" "=r")
12479 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12480 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12481 UNSPEC_INSN_FALSE_DEP)
12482 (clobber (reg:CC FLAGS_REG))]
12484 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12485 [(set_attr "prefix_rep" "1")
12486 (set_attr "type" "bitmanip")
12487 (set_attr "mode" "<MODE>")])
12489 (define_insn "*clz<mode>2_lzcnt"
12490 [(set (match_operand:SWI248 0 "register_operand" "=r")
12491 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12492 (clobber (reg:CC FLAGS_REG))]
12494 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12495 [(set_attr "prefix_rep" "1")
12496 (set_attr "type" "bitmanip")
12497 (set_attr "mode" "<MODE>")])
12499 ;; BMI instructions.
12500 (define_insn "*bmi_andn_<mode>"
12501 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12504 (match_operand:SWI48 1 "register_operand" "r,r"))
12505 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12506 (clobber (reg:CC FLAGS_REG))]
12508 "andn\t{%2, %1, %0|%0, %1, %2}"
12509 [(set_attr "type" "bitmanip")
12510 (set_attr "btver2_decode" "direct, double")
12511 (set_attr "mode" "<MODE>")])
12513 (define_insn "bmi_bextr_<mode>"
12514 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12515 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12516 (match_operand:SWI48 2 "register_operand" "r,r")]
12518 (clobber (reg:CC FLAGS_REG))]
12520 "bextr\t{%2, %1, %0|%0, %1, %2}"
12521 [(set_attr "type" "bitmanip")
12522 (set_attr "btver2_decode" "direct, double")
12523 (set_attr "mode" "<MODE>")])
12525 (define_insn "*bmi_blsi_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12531 (clobber (reg:CC FLAGS_REG))]
12533 "blsi\t{%1, %0|%0, %1}"
12534 [(set_attr "type" "bitmanip")
12535 (set_attr "btver2_decode" "double")
12536 (set_attr "mode" "<MODE>")])
12538 (define_insn "*bmi_blsmsk_<mode>"
12539 [(set (match_operand:SWI48 0 "register_operand" "=r")
12542 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12545 (clobber (reg:CC FLAGS_REG))]
12547 "blsmsk\t{%1, %0|%0, %1}"
12548 [(set_attr "type" "bitmanip")
12549 (set_attr "btver2_decode" "double")
12550 (set_attr "mode" "<MODE>")])
12552 (define_insn "*bmi_blsr_<mode>"
12553 [(set (match_operand:SWI48 0 "register_operand" "=r")
12556 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12559 (clobber (reg:CC FLAGS_REG))]
12561 "blsr\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "bitmanip")
12563 (set_attr "btver2_decode" "double")
12564 (set_attr "mode" "<MODE>")])
12566 ;; BMI2 instructions.
12567 (define_insn "bmi2_bzhi_<mode>3"
12568 [(set (match_operand:SWI48 0 "register_operand" "=r")
12569 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12570 (match_operand:SWI48 2 "register_operand" "r"))
12571 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12572 (clobber (reg:CC FLAGS_REG))]
12574 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12575 [(set_attr "type" "bitmanip")
12576 (set_attr "prefix" "vex")
12577 (set_attr "mode" "<MODE>")])
12579 (define_insn "bmi2_pdep_<mode>3"
12580 [(set (match_operand:SWI48 0 "register_operand" "=r")
12581 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12582 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12585 "pdep\t{%2, %1, %0|%0, %1, %2}"
12586 [(set_attr "type" "bitmanip")
12587 (set_attr "prefix" "vex")
12588 (set_attr "mode" "<MODE>")])
12590 (define_insn "bmi2_pext_<mode>3"
12591 [(set (match_operand:SWI48 0 "register_operand" "=r")
12592 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12593 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12596 "pext\t{%2, %1, %0|%0, %1, %2}"
12597 [(set_attr "type" "bitmanip")
12598 (set_attr "prefix" "vex")
12599 (set_attr "mode" "<MODE>")])
12601 ;; TBM instructions.
12602 (define_insn "tbm_bextri_<mode>"
12603 [(set (match_operand:SWI48 0 "register_operand" "=r")
12604 (zero_extract:SWI48
12605 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12606 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12607 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12608 (clobber (reg:CC FLAGS_REG))]
12611 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12612 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12614 [(set_attr "type" "bitmanip")
12615 (set_attr "mode" "<MODE>")])
12617 (define_insn "*tbm_blcfill_<mode>"
12618 [(set (match_operand:SWI48 0 "register_operand" "=r")
12621 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12624 (clobber (reg:CC FLAGS_REG))]
12626 "blcfill\t{%1, %0|%0, %1}"
12627 [(set_attr "type" "bitmanip")
12628 (set_attr "mode" "<MODE>")])
12630 (define_insn "*tbm_blci_<mode>"
12631 [(set (match_operand:SWI48 0 "register_operand" "=r")
12635 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12638 (clobber (reg:CC FLAGS_REG))]
12640 "blci\t{%1, %0|%0, %1}"
12641 [(set_attr "type" "bitmanip")
12642 (set_attr "mode" "<MODE>")])
12644 (define_insn "*tbm_blcic_<mode>"
12645 [(set (match_operand:SWI48 0 "register_operand" "=r")
12648 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12652 (clobber (reg:CC FLAGS_REG))]
12654 "blcic\t{%1, %0|%0, %1}"
12655 [(set_attr "type" "bitmanip")
12656 (set_attr "mode" "<MODE>")])
12658 (define_insn "*tbm_blcmsk_<mode>"
12659 [(set (match_operand:SWI48 0 "register_operand" "=r")
12662 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12665 (clobber (reg:CC FLAGS_REG))]
12667 "blcmsk\t{%1, %0|%0, %1}"
12668 [(set_attr "type" "bitmanip")
12669 (set_attr "mode" "<MODE>")])
12671 (define_insn "*tbm_blcs_<mode>"
12672 [(set (match_operand:SWI48 0 "register_operand" "=r")
12675 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12678 (clobber (reg:CC FLAGS_REG))]
12680 "blcs\t{%1, %0|%0, %1}"
12681 [(set_attr "type" "bitmanip")
12682 (set_attr "mode" "<MODE>")])
12684 (define_insn "*tbm_blsfill_<mode>"
12685 [(set (match_operand:SWI48 0 "register_operand" "=r")
12688 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12691 (clobber (reg:CC FLAGS_REG))]
12693 "blsfill\t{%1, %0|%0, %1}"
12694 [(set_attr "type" "bitmanip")
12695 (set_attr "mode" "<MODE>")])
12697 (define_insn "*tbm_blsic_<mode>"
12698 [(set (match_operand:SWI48 0 "register_operand" "=r")
12701 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12705 (clobber (reg:CC FLAGS_REG))]
12707 "blsic\t{%1, %0|%0, %1}"
12708 [(set_attr "type" "bitmanip")
12709 (set_attr "mode" "<MODE>")])
12711 (define_insn "*tbm_t1mskc_<mode>"
12712 [(set (match_operand:SWI48 0 "register_operand" "=r")
12715 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12719 (clobber (reg:CC FLAGS_REG))]
12721 "t1mskc\t{%1, %0|%0, %1}"
12722 [(set_attr "type" "bitmanip")
12723 (set_attr "mode" "<MODE>")])
12725 (define_insn "*tbm_tzmsk_<mode>"
12726 [(set (match_operand:SWI48 0 "register_operand" "=r")
12729 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12733 (clobber (reg:CC FLAGS_REG))]
12735 "tzmsk\t{%1, %0|%0, %1}"
12736 [(set_attr "type" "bitmanip")
12737 (set_attr "mode" "<MODE>")])
12739 (define_insn "bsr_rex64"
12740 [(set (match_operand:DI 0 "register_operand" "=r")
12741 (minus:DI (const_int 63)
12742 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12743 (clobber (reg:CC FLAGS_REG))]
12745 "bsr{q}\t{%1, %0|%0, %1}"
12746 [(set_attr "type" "alu1")
12747 (set_attr "prefix_0f" "1")
12748 (set_attr "mode" "DI")])
12751 [(set (match_operand:SI 0 "register_operand" "=r")
12752 (minus:SI (const_int 31)
12753 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12754 (clobber (reg:CC FLAGS_REG))]
12756 "bsr{l}\t{%1, %0|%0, %1}"
12757 [(set_attr "type" "alu1")
12758 (set_attr "prefix_0f" "1")
12759 (set_attr "mode" "SI")])
12761 (define_insn "*bsrhi"
12762 [(set (match_operand:HI 0 "register_operand" "=r")
12763 (minus:HI (const_int 15)
12764 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12765 (clobber (reg:CC FLAGS_REG))]
12767 "bsr{w}\t{%1, %0|%0, %1}"
12768 [(set_attr "type" "alu1")
12769 (set_attr "prefix_0f" "1")
12770 (set_attr "mode" "HI")])
12772 (define_expand "popcount<mode>2"
12774 [(set (match_operand:SWI248 0 "register_operand")
12776 (match_operand:SWI248 1 "nonimmediate_operand")))
12777 (clobber (reg:CC FLAGS_REG))])]
12780 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12781 [(set (match_operand:SWI48 0 "register_operand" "=r")
12783 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12784 (clobber (reg:CC FLAGS_REG))]
12786 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12788 "&& reload_completed"
12790 [(set (match_dup 0)
12791 (popcount:SWI48 (match_dup 1)))
12792 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12793 (clobber (reg:CC FLAGS_REG))])]
12795 if (!reg_mentioned_p (operands[0], operands[1]))
12796 ix86_expand_clear (operands[0]);
12799 (define_insn "*popcount<mode>2_falsedep"
12800 [(set (match_operand:SWI48 0 "register_operand" "=r")
12802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12803 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12804 UNSPEC_INSN_FALSE_DEP)
12805 (clobber (reg:CC FLAGS_REG))]
12809 return "popcnt\t{%1, %0|%0, %1}";
12811 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12814 [(set_attr "prefix_rep" "1")
12815 (set_attr "type" "bitmanip")
12816 (set_attr "mode" "<MODE>")])
12818 (define_insn "*popcount<mode>2"
12819 [(set (match_operand:SWI248 0 "register_operand" "=r")
12821 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12822 (clobber (reg:CC FLAGS_REG))]
12826 return "popcnt\t{%1, %0|%0, %1}";
12828 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12831 [(set_attr "prefix_rep" "1")
12832 (set_attr "type" "bitmanip")
12833 (set_attr "mode" "<MODE>")])
12835 (define_expand "bswapdi2"
12836 [(set (match_operand:DI 0 "register_operand")
12837 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12841 operands[1] = force_reg (DImode, operands[1]);
12844 (define_expand "bswapsi2"
12845 [(set (match_operand:SI 0 "register_operand")
12846 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12851 else if (TARGET_BSWAP)
12852 operands[1] = force_reg (SImode, operands[1]);
12855 rtx x = operands[0];
12857 emit_move_insn (x, operands[1]);
12858 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12859 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12860 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12865 (define_insn "*bswap<mode>2_movbe"
12866 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12867 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12872 movbe\t{%1, %0|%0, %1}
12873 movbe\t{%1, %0|%0, %1}"
12874 [(set_attr "type" "bitmanip,imov,imov")
12875 (set_attr "modrm" "0,1,1")
12876 (set_attr "prefix_0f" "*,1,1")
12877 (set_attr "prefix_extra" "*,1,1")
12878 (set_attr "mode" "<MODE>")])
12880 (define_insn "*bswap<mode>2"
12881 [(set (match_operand:SWI48 0 "register_operand" "=r")
12882 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12885 [(set_attr "type" "bitmanip")
12886 (set_attr "modrm" "0")
12887 (set_attr "mode" "<MODE>")])
12889 (define_insn "*bswaphi_lowpart_1"
12890 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12891 (bswap:HI (match_dup 0)))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12895 xchg{b}\t{%h0, %b0|%b0, %h0}
12896 rol{w}\t{$8, %0|%0, 8}"
12897 [(set_attr "length" "2,4")
12898 (set_attr "mode" "QI,HI")])
12900 (define_insn "bswaphi_lowpart"
12901 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12902 (bswap:HI (match_dup 0)))
12903 (clobber (reg:CC FLAGS_REG))]
12905 "rol{w}\t{$8, %0|%0, 8}"
12906 [(set_attr "length" "4")
12907 (set_attr "mode" "HI")])
12909 (define_expand "paritydi2"
12910 [(set (match_operand:DI 0 "register_operand")
12911 (parity:DI (match_operand:DI 1 "register_operand")))]
12914 rtx scratch = gen_reg_rtx (QImode);
12917 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12918 NULL_RTX, operands[1]));
12920 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12921 gen_rtx_REG (CCmode, FLAGS_REG),
12923 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12926 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12929 rtx tmp = gen_reg_rtx (SImode);
12931 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12932 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12937 (define_expand "paritysi2"
12938 [(set (match_operand:SI 0 "register_operand")
12939 (parity:SI (match_operand:SI 1 "register_operand")))]
12942 rtx scratch = gen_reg_rtx (QImode);
12945 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12947 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12948 gen_rtx_REG (CCmode, FLAGS_REG),
12950 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12952 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12956 (define_insn_and_split "paritydi2_cmp"
12957 [(set (reg:CC FLAGS_REG)
12958 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12960 (clobber (match_scratch:DI 0 "=r"))
12961 (clobber (match_scratch:SI 1 "=&r"))
12962 (clobber (match_scratch:HI 2 "=Q"))]
12965 "&& reload_completed"
12967 [(set (match_dup 1)
12968 (xor:SI (match_dup 1) (match_dup 4)))
12969 (clobber (reg:CC FLAGS_REG))])
12971 [(set (reg:CC FLAGS_REG)
12972 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12973 (clobber (match_dup 1))
12974 (clobber (match_dup 2))])]
12976 operands[4] = gen_lowpart (SImode, operands[3]);
12980 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12981 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12984 operands[1] = gen_highpart (SImode, operands[3]);
12987 (define_insn_and_split "paritysi2_cmp"
12988 [(set (reg:CC FLAGS_REG)
12989 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12991 (clobber (match_scratch:SI 0 "=r"))
12992 (clobber (match_scratch:HI 1 "=&Q"))]
12995 "&& reload_completed"
12997 [(set (match_dup 1)
12998 (xor:HI (match_dup 1) (match_dup 3)))
12999 (clobber (reg:CC FLAGS_REG))])
13001 [(set (reg:CC FLAGS_REG)
13002 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13003 (clobber (match_dup 1))])]
13005 operands[3] = gen_lowpart (HImode, operands[2]);
13007 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13008 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13011 (define_insn "*parityhi2_cmp"
13012 [(set (reg:CC FLAGS_REG)
13013 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13015 (clobber (match_scratch:HI 0 "=Q"))]
13017 "xor{b}\t{%h0, %b0|%b0, %h0}"
13018 [(set_attr "length" "2")
13019 (set_attr "mode" "HI")])
13022 ;; Thread-local storage patterns for ELF.
13024 ;; Note that these code sequences must appear exactly as shown
13025 ;; in order to allow linker relaxation.
13027 (define_insn "*tls_global_dynamic_32_gnu"
13028 [(set (match_operand:SI 0 "register_operand" "=a")
13030 [(match_operand:SI 1 "register_operand" "b")
13031 (match_operand 2 "tls_symbolic_operand")
13032 (match_operand 3 "constant_call_address_operand" "Bz")
13035 (clobber (match_scratch:SI 4 "=d"))
13036 (clobber (match_scratch:SI 5 "=c"))
13037 (clobber (reg:CC FLAGS_REG))]
13038 "!TARGET_64BIT && TARGET_GNU_TLS"
13041 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13042 if (TARGET_SUN_TLS)
13043 #ifdef HAVE_AS_IX86_TLSGDPLT
13044 return "call\t%a2@tlsgdplt";
13046 return "call\t%p3@plt";
13048 return "call\t%P3";
13050 [(set_attr "type" "multi")
13051 (set_attr "length" "12")])
13053 (define_expand "tls_global_dynamic_32"
13055 [(set (match_operand:SI 0 "register_operand")
13056 (unspec:SI [(match_operand:SI 2 "register_operand")
13057 (match_operand 1 "tls_symbolic_operand")
13058 (match_operand 3 "constant_call_address_operand")
13061 (clobber (match_scratch:SI 4))
13062 (clobber (match_scratch:SI 5))
13063 (clobber (reg:CC FLAGS_REG))])]
13065 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13067 (define_insn "*tls_global_dynamic_64_<mode>"
13068 [(set (match_operand:P 0 "register_operand" "=a")
13070 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13071 (match_operand 3)))
13072 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13077 fputs (ASM_BYTE "0x66\n", asm_out_file);
13079 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13080 fputs (ASM_SHORT "0x6666\n", asm_out_file);
13081 fputs ("\trex64\n", asm_out_file);
13082 if (TARGET_SUN_TLS)
13083 return "call\t%p2@plt";
13084 return "call\t%P2";
13086 [(set_attr "type" "multi")
13087 (set (attr "length")
13088 (symbol_ref "TARGET_X32 ? 15 : 16"))])
13090 (define_insn "*tls_global_dynamic_64_largepic"
13091 [(set (match_operand:DI 0 "register_operand" "=a")
13093 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13094 (match_operand:DI 3 "immediate_operand" "i")))
13095 (match_operand 4)))
13096 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13098 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13099 && GET_CODE (operands[3]) == CONST
13100 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13101 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13104 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13105 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13106 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13107 return "call\t{*%%rax|rax}";
13109 [(set_attr "type" "multi")
13110 (set_attr "length" "22")])
13112 (define_expand "tls_global_dynamic_64_<mode>"
13114 [(set (match_operand:P 0 "register_operand")
13116 (mem:QI (match_operand 2))
13118 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13121 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13123 (define_insn "*tls_local_dynamic_base_32_gnu"
13124 [(set (match_operand:SI 0 "register_operand" "=a")
13126 [(match_operand:SI 1 "register_operand" "b")
13127 (match_operand 2 "constant_call_address_operand" "Bz")
13129 UNSPEC_TLS_LD_BASE))
13130 (clobber (match_scratch:SI 3 "=d"))
13131 (clobber (match_scratch:SI 4 "=c"))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "!TARGET_64BIT && TARGET_GNU_TLS"
13136 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13137 if (TARGET_SUN_TLS)
13139 if (HAVE_AS_IX86_TLSLDMPLT)
13140 return "call\t%&@tlsldmplt";
13142 return "call\t%p2@plt";
13144 return "call\t%P2";
13146 [(set_attr "type" "multi")
13147 (set_attr "length" "11")])
13149 (define_expand "tls_local_dynamic_base_32"
13151 [(set (match_operand:SI 0 "register_operand")
13153 [(match_operand:SI 1 "register_operand")
13154 (match_operand 2 "constant_call_address_operand")
13156 UNSPEC_TLS_LD_BASE))
13157 (clobber (match_scratch:SI 3))
13158 (clobber (match_scratch:SI 4))
13159 (clobber (reg:CC FLAGS_REG))])]
13161 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13163 (define_insn "*tls_local_dynamic_base_64_<mode>"
13164 [(set (match_operand:P 0 "register_operand" "=a")
13166 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13167 (match_operand 2)))
13168 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13172 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13173 if (TARGET_SUN_TLS)
13174 return "call\t%p1@plt";
13175 return "call\t%P1";
13177 [(set_attr "type" "multi")
13178 (set_attr "length" "12")])
13180 (define_insn "*tls_local_dynamic_base_64_largepic"
13181 [(set (match_operand:DI 0 "register_operand" "=a")
13183 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13184 (match_operand:DI 2 "immediate_operand" "i")))
13185 (match_operand 3)))
13186 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13187 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13188 && GET_CODE (operands[2]) == CONST
13189 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13190 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13193 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13194 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13195 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13196 return "call\t{*%%rax|rax}";
13198 [(set_attr "type" "multi")
13199 (set_attr "length" "22")])
13201 (define_expand "tls_local_dynamic_base_64_<mode>"
13203 [(set (match_operand:P 0 "register_operand")
13205 (mem:QI (match_operand 1))
13207 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13209 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13211 ;; Local dynamic of a single variable is a lose. Show combine how
13212 ;; to convert that back to global dynamic.
13214 (define_insn_and_split "*tls_local_dynamic_32_once"
13215 [(set (match_operand:SI 0 "register_operand" "=a")
13217 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13218 (match_operand 2 "constant_call_address_operand" "Bz")
13220 UNSPEC_TLS_LD_BASE)
13221 (const:SI (unspec:SI
13222 [(match_operand 3 "tls_symbolic_operand")]
13224 (clobber (match_scratch:SI 4 "=d"))
13225 (clobber (match_scratch:SI 5 "=c"))
13226 (clobber (reg:CC FLAGS_REG))]
13231 [(set (match_dup 0)
13232 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13235 (clobber (match_dup 4))
13236 (clobber (match_dup 5))
13237 (clobber (reg:CC FLAGS_REG))])])
13239 ;; Segment register for the thread base ptr load
13240 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13242 ;; Load and add the thread base pointer from %<tp_seg>:0.
13243 (define_insn "*load_tp_x32"
13244 [(set (match_operand:SI 0 "register_operand" "=r")
13245 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13247 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13248 [(set_attr "type" "imov")
13249 (set_attr "modrm" "0")
13250 (set_attr "length" "7")
13251 (set_attr "memory" "load")
13252 (set_attr "imm_disp" "false")])
13254 (define_insn "*load_tp_x32_zext"
13255 [(set (match_operand:DI 0 "register_operand" "=r")
13256 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13258 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13259 [(set_attr "type" "imov")
13260 (set_attr "modrm" "0")
13261 (set_attr "length" "7")
13262 (set_attr "memory" "load")
13263 (set_attr "imm_disp" "false")])
13265 (define_insn "*load_tp_<mode>"
13266 [(set (match_operand:P 0 "register_operand" "=r")
13267 (unspec:P [(const_int 0)] UNSPEC_TP))]
13269 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13270 [(set_attr "type" "imov")
13271 (set_attr "modrm" "0")
13272 (set_attr "length" "7")
13273 (set_attr "memory" "load")
13274 (set_attr "imm_disp" "false")])
13276 (define_insn "*add_tp_x32"
13277 [(set (match_operand:SI 0 "register_operand" "=r")
13278 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13279 (match_operand:SI 1 "register_operand" "0")))
13280 (clobber (reg:CC FLAGS_REG))]
13282 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13283 [(set_attr "type" "alu")
13284 (set_attr "modrm" "0")
13285 (set_attr "length" "7")
13286 (set_attr "memory" "load")
13287 (set_attr "imm_disp" "false")])
13289 (define_insn "*add_tp_x32_zext"
13290 [(set (match_operand:DI 0 "register_operand" "=r")
13292 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13293 (match_operand:SI 1 "register_operand" "0"))))
13294 (clobber (reg:CC FLAGS_REG))]
13296 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13297 [(set_attr "type" "alu")
13298 (set_attr "modrm" "0")
13299 (set_attr "length" "7")
13300 (set_attr "memory" "load")
13301 (set_attr "imm_disp" "false")])
13303 (define_insn "*add_tp_<mode>"
13304 [(set (match_operand:P 0 "register_operand" "=r")
13305 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13306 (match_operand:P 1 "register_operand" "0")))
13307 (clobber (reg:CC FLAGS_REG))]
13309 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13310 [(set_attr "type" "alu")
13311 (set_attr "modrm" "0")
13312 (set_attr "length" "7")
13313 (set_attr "memory" "load")
13314 (set_attr "imm_disp" "false")])
13316 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13317 ;; %rax as destination of the initial executable code sequence.
13318 (define_insn "tls_initial_exec_64_sun"
13319 [(set (match_operand:DI 0 "register_operand" "=a")
13321 [(match_operand 1 "tls_symbolic_operand")]
13322 UNSPEC_TLS_IE_SUN))
13323 (clobber (reg:CC FLAGS_REG))]
13324 "TARGET_64BIT && TARGET_SUN_TLS"
13327 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13328 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13330 [(set_attr "type" "multi")])
13332 ;; GNU2 TLS patterns can be split.
13334 (define_expand "tls_dynamic_gnu2_32"
13335 [(set (match_dup 3)
13336 (plus:SI (match_operand:SI 2 "register_operand")
13338 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13341 [(set (match_operand:SI 0 "register_operand")
13342 (unspec:SI [(match_dup 1) (match_dup 3)
13343 (match_dup 2) (reg:SI SP_REG)]
13345 (clobber (reg:CC FLAGS_REG))])]
13346 "!TARGET_64BIT && TARGET_GNU2_TLS"
13348 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13349 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13352 (define_insn "*tls_dynamic_gnu2_lea_32"
13353 [(set (match_operand:SI 0 "register_operand" "=r")
13354 (plus:SI (match_operand:SI 1 "register_operand" "b")
13356 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13357 UNSPEC_TLSDESC))))]
13358 "!TARGET_64BIT && TARGET_GNU2_TLS"
13359 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13360 [(set_attr "type" "lea")
13361 (set_attr "mode" "SI")
13362 (set_attr "length" "6")
13363 (set_attr "length_address" "4")])
13365 (define_insn "*tls_dynamic_gnu2_call_32"
13366 [(set (match_operand:SI 0 "register_operand" "=a")
13367 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13368 (match_operand:SI 2 "register_operand" "0")
13369 ;; we have to make sure %ebx still points to the GOT
13370 (match_operand:SI 3 "register_operand" "b")
13373 (clobber (reg:CC FLAGS_REG))]
13374 "!TARGET_64BIT && TARGET_GNU2_TLS"
13375 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13376 [(set_attr "type" "call")
13377 (set_attr "length" "2")
13378 (set_attr "length_address" "0")])
13380 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13381 [(set (match_operand:SI 0 "register_operand" "=&a")
13383 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13384 (match_operand:SI 4)
13385 (match_operand:SI 2 "register_operand" "b")
13388 (const:SI (unspec:SI
13389 [(match_operand 1 "tls_symbolic_operand")]
13391 (clobber (reg:CC FLAGS_REG))]
13392 "!TARGET_64BIT && TARGET_GNU2_TLS"
13395 [(set (match_dup 0) (match_dup 5))]
13397 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13398 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13401 (define_expand "tls_dynamic_gnu2_64"
13402 [(set (match_dup 2)
13403 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13406 [(set (match_operand:DI 0 "register_operand")
13407 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13409 (clobber (reg:CC FLAGS_REG))])]
13410 "TARGET_64BIT && TARGET_GNU2_TLS"
13412 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13413 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13416 (define_insn "*tls_dynamic_gnu2_lea_64"
13417 [(set (match_operand:DI 0 "register_operand" "=r")
13418 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13420 "TARGET_64BIT && TARGET_GNU2_TLS"
13421 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13422 [(set_attr "type" "lea")
13423 (set_attr "mode" "DI")
13424 (set_attr "length" "7")
13425 (set_attr "length_address" "4")])
13427 (define_insn "*tls_dynamic_gnu2_call_64"
13428 [(set (match_operand:DI 0 "register_operand" "=a")
13429 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13430 (match_operand:DI 2 "register_operand" "0")
13433 (clobber (reg:CC FLAGS_REG))]
13434 "TARGET_64BIT && TARGET_GNU2_TLS"
13435 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13436 [(set_attr "type" "call")
13437 (set_attr "length" "2")
13438 (set_attr "length_address" "0")])
13440 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13441 [(set (match_operand:DI 0 "register_operand" "=&a")
13443 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13444 (match_operand:DI 3)
13447 (const:DI (unspec:DI
13448 [(match_operand 1 "tls_symbolic_operand")]
13450 (clobber (reg:CC FLAGS_REG))]
13451 "TARGET_64BIT && TARGET_GNU2_TLS"
13454 [(set (match_dup 0) (match_dup 4))]
13456 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13457 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13460 ;; These patterns match the binary 387 instructions for addM3, subM3,
13461 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13462 ;; SFmode. The first is the normal insn, the second the same insn but
13463 ;; with one operand a conversion, and the third the same insn but with
13464 ;; the other operand a conversion. The conversion may be SFmode or
13465 ;; SImode if the target mode DFmode, but only SImode if the target mode
13468 ;; Gcc is slightly more smart about handling normal two address instructions
13469 ;; so use special patterns for add and mull.
13471 (define_insn "*fop_<mode>_comm_mixed"
13472 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13473 (match_operator:MODEF 3 "binary_fp_operator"
13474 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13475 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13476 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13477 && COMMUTATIVE_ARITH_P (operands[3])
13478 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13479 "* return output_387_binary_op (insn, operands);"
13480 [(set (attr "type")
13481 (if_then_else (eq_attr "alternative" "1,2")
13482 (if_then_else (match_operand:MODEF 3 "mult_operator")
13483 (const_string "ssemul")
13484 (const_string "sseadd"))
13485 (if_then_else (match_operand:MODEF 3 "mult_operator")
13486 (const_string "fmul")
13487 (const_string "fop"))))
13488 (set_attr "isa" "*,noavx,avx")
13489 (set_attr "prefix" "orig,orig,vex")
13490 (set_attr "mode" "<MODE>")])
13492 (define_insn "*fop_<mode>_comm_sse"
13493 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13494 (match_operator:MODEF 3 "binary_fp_operator"
13495 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13496 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13498 && COMMUTATIVE_ARITH_P (operands[3])
13499 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13500 "* return output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (if_then_else (match_operand:MODEF 3 "mult_operator")
13503 (const_string "ssemul")
13504 (const_string "sseadd")))
13505 (set_attr "isa" "noavx,avx")
13506 (set_attr "prefix" "orig,vex")
13507 (set_attr "mode" "<MODE>")])
13509 (define_insn "*fop_<mode>_comm_i387"
13510 [(set (match_operand:MODEF 0 "register_operand" "=f")
13511 (match_operator:MODEF 3 "binary_fp_operator"
13512 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13513 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13514 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13515 && COMMUTATIVE_ARITH_P (operands[3])
13516 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13517 "* return output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (if_then_else (match_operand:MODEF 3 "mult_operator")
13520 (const_string "fmul")
13521 (const_string "fop")))
13522 (set_attr "mode" "<MODE>")])
13524 (define_insn "*fop_<mode>_1_mixed"
13525 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13526 (match_operator:MODEF 3 "binary_fp_operator"
13527 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13528 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13530 && !COMMUTATIVE_ARITH_P (operands[3])
13531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13532 "* return output_387_binary_op (insn, operands);"
13533 [(set (attr "type")
13534 (cond [(and (eq_attr "alternative" "2,3")
13535 (match_operand:MODEF 3 "mult_operator"))
13536 (const_string "ssemul")
13537 (and (eq_attr "alternative" "2,3")
13538 (match_operand:MODEF 3 "div_operator"))
13539 (const_string "ssediv")
13540 (eq_attr "alternative" "2,3")
13541 (const_string "sseadd")
13542 (match_operand:MODEF 3 "mult_operator")
13543 (const_string "fmul")
13544 (match_operand:MODEF 3 "div_operator")
13545 (const_string "fdiv")
13547 (const_string "fop")))
13548 (set_attr "isa" "*,*,noavx,avx")
13549 (set_attr "prefix" "orig,orig,orig,vex")
13550 (set_attr "mode" "<MODE>")])
13552 (define_insn "*rcpsf2_sse"
13553 [(set (match_operand:SF 0 "register_operand" "=x")
13554 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13557 "%vrcpss\t{%1, %d0|%d0, %1}"
13558 [(set_attr "type" "sse")
13559 (set_attr "atom_sse_attr" "rcp")
13560 (set_attr "btver2_sse_attr" "rcp")
13561 (set_attr "prefix" "maybe_vex")
13562 (set_attr "mode" "SF")])
13564 (define_insn "*fop_<mode>_1_sse"
13565 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13566 (match_operator:MODEF 3 "binary_fp_operator"
13567 [(match_operand:MODEF 1 "register_operand" "0,x")
13568 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13569 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13570 && !COMMUTATIVE_ARITH_P (operands[3])"
13571 "* return output_387_binary_op (insn, operands);"
13572 [(set (attr "type")
13573 (cond [(match_operand:MODEF 3 "mult_operator")
13574 (const_string "ssemul")
13575 (match_operand:MODEF 3 "div_operator")
13576 (const_string "ssediv")
13578 (const_string "sseadd")))
13579 (set_attr "isa" "noavx,avx")
13580 (set_attr "prefix" "orig,vex")
13581 (set_attr "mode" "<MODE>")])
13583 ;; This pattern is not fully shadowed by the pattern above.
13584 (define_insn "*fop_<mode>_1_i387"
13585 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13586 (match_operator:MODEF 3 "binary_fp_operator"
13587 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13588 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13589 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13590 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13591 && !COMMUTATIVE_ARITH_P (operands[3])
13592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13593 "* return output_387_binary_op (insn, operands);"
13594 [(set (attr "type")
13595 (cond [(match_operand:MODEF 3 "mult_operator")
13596 (const_string "fmul")
13597 (match_operand:MODEF 3 "div_operator")
13598 (const_string "fdiv")
13600 (const_string "fop")))
13601 (set_attr "mode" "<MODE>")])
13603 ;; ??? Add SSE splitters for these!
13604 (define_insn "*fop_<MODEF:mode>_2_i387"
13605 [(set (match_operand:MODEF 0 "register_operand" "=f")
13606 (match_operator:MODEF 3 "binary_fp_operator"
13608 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13609 (match_operand:MODEF 2 "register_operand" "0")]))]
13610 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13611 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13612 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13613 || optimize_function_for_size_p (cfun))"
13614 { return output_387_binary_op (insn, operands); }
13615 [(set (attr "type")
13616 (cond [(match_operand:MODEF 3 "mult_operator")
13617 (const_string "fmul")
13618 (match_operand:MODEF 3 "div_operator")
13619 (const_string "fdiv")
13621 (const_string "fop")))
13622 (set_attr "fp_int_src" "true")
13623 (set_attr "mode" "<SWI24:MODE>")])
13625 (define_insn "*fop_<MODEF:mode>_3_i387"
13626 [(set (match_operand:MODEF 0 "register_operand" "=f")
13627 (match_operator:MODEF 3 "binary_fp_operator"
13628 [(match_operand:MODEF 1 "register_operand" "0")
13630 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13631 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13632 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13633 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13634 || optimize_function_for_size_p (cfun))"
13635 { return output_387_binary_op (insn, operands); }
13636 [(set (attr "type")
13637 (cond [(match_operand:MODEF 3 "mult_operator")
13638 (const_string "fmul")
13639 (match_operand:MODEF 3 "div_operator")
13640 (const_string "fdiv")
13642 (const_string "fop")))
13643 (set_attr "fp_int_src" "true")
13644 (set_attr "mode" "<MODE>")])
13646 (define_insn "*fop_df_4_i387"
13647 [(set (match_operand:DF 0 "register_operand" "=f,f")
13648 (match_operator:DF 3 "binary_fp_operator"
13650 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13651 (match_operand:DF 2 "register_operand" "0,f")]))]
13652 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13653 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13654 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13655 "* return output_387_binary_op (insn, operands);"
13656 [(set (attr "type")
13657 (cond [(match_operand:DF 3 "mult_operator")
13658 (const_string "fmul")
13659 (match_operand:DF 3 "div_operator")
13660 (const_string "fdiv")
13662 (const_string "fop")))
13663 (set_attr "mode" "SF")])
13665 (define_insn "*fop_df_5_i387"
13666 [(set (match_operand:DF 0 "register_operand" "=f,f")
13667 (match_operator:DF 3 "binary_fp_operator"
13668 [(match_operand:DF 1 "register_operand" "0,f")
13670 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13671 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13672 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13673 "* return output_387_binary_op (insn, operands);"
13674 [(set (attr "type")
13675 (cond [(match_operand:DF 3 "mult_operator")
13676 (const_string "fmul")
13677 (match_operand:DF 3 "div_operator")
13678 (const_string "fdiv")
13680 (const_string "fop")))
13681 (set_attr "mode" "SF")])
13683 (define_insn "*fop_df_6_i387"
13684 [(set (match_operand:DF 0 "register_operand" "=f,f")
13685 (match_operator:DF 3 "binary_fp_operator"
13687 (match_operand:SF 1 "register_operand" "0,f"))
13689 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13690 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13691 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13692 "* return output_387_binary_op (insn, operands);"
13693 [(set (attr "type")
13694 (cond [(match_operand:DF 3 "mult_operator")
13695 (const_string "fmul")
13696 (match_operand:DF 3 "div_operator")
13697 (const_string "fdiv")
13699 (const_string "fop")))
13700 (set_attr "mode" "SF")])
13702 (define_insn "*fop_xf_comm_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (match_operator:XF 3 "binary_fp_operator"
13705 [(match_operand:XF 1 "register_operand" "%0")
13706 (match_operand:XF 2 "register_operand" "f")]))]
13708 && COMMUTATIVE_ARITH_P (operands[3])"
13709 "* return output_387_binary_op (insn, operands);"
13710 [(set (attr "type")
13711 (if_then_else (match_operand:XF 3 "mult_operator")
13712 (const_string "fmul")
13713 (const_string "fop")))
13714 (set_attr "mode" "XF")])
13716 (define_insn "*fop_xf_1_i387"
13717 [(set (match_operand:XF 0 "register_operand" "=f,f")
13718 (match_operator:XF 3 "binary_fp_operator"
13719 [(match_operand:XF 1 "register_operand" "0,f")
13720 (match_operand:XF 2 "register_operand" "f,0")]))]
13722 && !COMMUTATIVE_ARITH_P (operands[3])"
13723 "* return output_387_binary_op (insn, operands);"
13724 [(set (attr "type")
13725 (cond [(match_operand:XF 3 "mult_operator")
13726 (const_string "fmul")
13727 (match_operand:XF 3 "div_operator")
13728 (const_string "fdiv")
13730 (const_string "fop")))
13731 (set_attr "mode" "XF")])
13733 (define_insn "*fop_xf_2_i387"
13734 [(set (match_operand:XF 0 "register_operand" "=f")
13735 (match_operator:XF 3 "binary_fp_operator"
13737 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13738 (match_operand:XF 2 "register_operand" "0")]))]
13740 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13741 { return output_387_binary_op (insn, operands); }
13742 [(set (attr "type")
13743 (cond [(match_operand:XF 3 "mult_operator")
13744 (const_string "fmul")
13745 (match_operand:XF 3 "div_operator")
13746 (const_string "fdiv")
13748 (const_string "fop")))
13749 (set_attr "fp_int_src" "true")
13750 (set_attr "mode" "<MODE>")])
13752 (define_insn "*fop_xf_3_i387"
13753 [(set (match_operand:XF 0 "register_operand" "=f")
13754 (match_operator:XF 3 "binary_fp_operator"
13755 [(match_operand:XF 1 "register_operand" "0")
13757 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13759 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13760 { return output_387_binary_op (insn, operands); }
13761 [(set (attr "type")
13762 (cond [(match_operand:XF 3 "mult_operator")
13763 (const_string "fmul")
13764 (match_operand:XF 3 "div_operator")
13765 (const_string "fdiv")
13767 (const_string "fop")))
13768 (set_attr "fp_int_src" "true")
13769 (set_attr "mode" "<MODE>")])
13771 (define_insn "*fop_xf_4_i387"
13772 [(set (match_operand:XF 0 "register_operand" "=f,f")
13773 (match_operator:XF 3 "binary_fp_operator"
13775 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13776 (match_operand:XF 2 "register_operand" "0,f")]))]
13778 "* return output_387_binary_op (insn, operands);"
13779 [(set (attr "type")
13780 (cond [(match_operand:XF 3 "mult_operator")
13781 (const_string "fmul")
13782 (match_operand:XF 3 "div_operator")
13783 (const_string "fdiv")
13785 (const_string "fop")))
13786 (set_attr "mode" "<MODE>")])
13788 (define_insn "*fop_xf_5_i387"
13789 [(set (match_operand:XF 0 "register_operand" "=f,f")
13790 (match_operator:XF 3 "binary_fp_operator"
13791 [(match_operand:XF 1 "register_operand" "0,f")
13793 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13795 "* return output_387_binary_op (insn, operands);"
13796 [(set (attr "type")
13797 (cond [(match_operand:XF 3 "mult_operator")
13798 (const_string "fmul")
13799 (match_operand:XF 3 "div_operator")
13800 (const_string "fdiv")
13802 (const_string "fop")))
13803 (set_attr "mode" "<MODE>")])
13805 (define_insn "*fop_xf_6_i387"
13806 [(set (match_operand:XF 0 "register_operand" "=f,f")
13807 (match_operator:XF 3 "binary_fp_operator"
13809 (match_operand:MODEF 1 "register_operand" "0,f"))
13811 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13813 "* return output_387_binary_op (insn, operands);"
13814 [(set (attr "type")
13815 (cond [(match_operand:XF 3 "mult_operator")
13816 (const_string "fmul")
13817 (match_operand:XF 3 "div_operator")
13818 (const_string "fdiv")
13820 (const_string "fop")))
13821 (set_attr "mode" "<MODE>")])
13823 ;; FPU special functions.
13825 ;; This pattern implements a no-op XFmode truncation for
13826 ;; all fancy i386 XFmode math functions.
13828 (define_insn "truncxf<mode>2_i387_noop_unspec"
13829 [(set (match_operand:MODEF 0 "register_operand" "=f")
13830 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13831 UNSPEC_TRUNC_NOOP))]
13832 "TARGET_USE_FANCY_MATH_387"
13833 "* return output_387_reg_move (insn, operands);"
13834 [(set_attr "type" "fmov")
13835 (set_attr "mode" "<MODE>")])
13837 (define_insn "sqrtxf2"
13838 [(set (match_operand:XF 0 "register_operand" "=f")
13839 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13840 "TARGET_USE_FANCY_MATH_387"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")
13844 (set_attr "athlon_decode" "direct")
13845 (set_attr "amdfam10_decode" "direct")
13846 (set_attr "bdver1_decode" "direct")])
13848 (define_insn "sqrt_extend<mode>xf2_i387"
13849 [(set (match_operand:XF 0 "register_operand" "=f")
13852 (match_operand:MODEF 1 "register_operand" "0"))))]
13853 "TARGET_USE_FANCY_MATH_387"
13855 [(set_attr "type" "fpspc")
13856 (set_attr "mode" "XF")
13857 (set_attr "athlon_decode" "direct")
13858 (set_attr "amdfam10_decode" "direct")
13859 (set_attr "bdver1_decode" "direct")])
13861 (define_insn "*rsqrtsf2_sse"
13862 [(set (match_operand:SF 0 "register_operand" "=x")
13863 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13866 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13867 [(set_attr "type" "sse")
13868 (set_attr "atom_sse_attr" "rcp")
13869 (set_attr "btver2_sse_attr" "rcp")
13870 (set_attr "prefix" "maybe_vex")
13871 (set_attr "mode" "SF")])
13873 (define_expand "rsqrtsf2"
13874 [(set (match_operand:SF 0 "register_operand")
13875 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13879 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13883 (define_insn "*sqrt<mode>2_sse"
13884 [(set (match_operand:MODEF 0 "register_operand" "=x")
13886 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13887 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13888 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13889 [(set_attr "type" "sse")
13890 (set_attr "atom_sse_attr" "sqrt")
13891 (set_attr "btver2_sse_attr" "sqrt")
13892 (set_attr "prefix" "maybe_vex")
13893 (set_attr "mode" "<MODE>")
13894 (set_attr "athlon_decode" "*")
13895 (set_attr "amdfam10_decode" "*")
13896 (set_attr "bdver1_decode" "*")])
13898 (define_expand "sqrt<mode>2"
13899 [(set (match_operand:MODEF 0 "register_operand")
13901 (match_operand:MODEF 1 "nonimmediate_operand")))]
13902 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13905 if (<MODE>mode == SFmode
13907 && TARGET_RECIP_SQRT
13908 && !optimize_function_for_size_p (cfun)
13909 && flag_finite_math_only && !flag_trapping_math
13910 && flag_unsafe_math_optimizations)
13912 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13916 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13918 rtx op0 = gen_reg_rtx (XFmode);
13919 rtx op1 = force_reg (<MODE>mode, operands[1]);
13921 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13922 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13927 (define_insn "fpremxf4_i387"
13928 [(set (match_operand:XF 0 "register_operand" "=f")
13929 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13930 (match_operand:XF 3 "register_operand" "1")]
13932 (set (match_operand:XF 1 "register_operand" "=u")
13933 (unspec:XF [(match_dup 2) (match_dup 3)]
13935 (set (reg:CCFP FPSR_REG)
13936 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13938 "TARGET_USE_FANCY_MATH_387
13939 && flag_finite_math_only"
13941 [(set_attr "type" "fpspc")
13942 (set_attr "mode" "XF")])
13944 (define_expand "fmodxf3"
13945 [(use (match_operand:XF 0 "register_operand"))
13946 (use (match_operand:XF 1 "general_operand"))
13947 (use (match_operand:XF 2 "general_operand"))]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_finite_math_only"
13951 rtx_code_label *label = gen_label_rtx ();
13953 rtx op1 = gen_reg_rtx (XFmode);
13954 rtx op2 = gen_reg_rtx (XFmode);
13956 emit_move_insn (op2, operands[2]);
13957 emit_move_insn (op1, operands[1]);
13959 emit_label (label);
13960 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13961 ix86_emit_fp_unordered_jump (label);
13962 LABEL_NUSES (label) = 1;
13964 emit_move_insn (operands[0], op1);
13968 (define_expand "fmod<mode>3"
13969 [(use (match_operand:MODEF 0 "register_operand"))
13970 (use (match_operand:MODEF 1 "general_operand"))
13971 (use (match_operand:MODEF 2 "general_operand"))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_finite_math_only"
13975 rtx (*gen_truncxf) (rtx, rtx);
13977 rtx_code_label *label = gen_label_rtx ();
13979 rtx op1 = gen_reg_rtx (XFmode);
13980 rtx op2 = gen_reg_rtx (XFmode);
13982 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13983 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13985 emit_label (label);
13986 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13987 ix86_emit_fp_unordered_jump (label);
13988 LABEL_NUSES (label) = 1;
13990 /* Truncate the result properly for strict SSE math. */
13991 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13992 && !TARGET_MIX_SSE_I387)
13993 gen_truncxf = gen_truncxf<mode>2;
13995 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13997 emit_insn (gen_truncxf (operands[0], op1));
14001 (define_insn "fprem1xf4_i387"
14002 [(set (match_operand:XF 0 "register_operand" "=f")
14003 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14004 (match_operand:XF 3 "register_operand" "1")]
14006 (set (match_operand:XF 1 "register_operand" "=u")
14007 (unspec:XF [(match_dup 2) (match_dup 3)]
14009 (set (reg:CCFP FPSR_REG)
14010 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14012 "TARGET_USE_FANCY_MATH_387
14013 && flag_finite_math_only"
14015 [(set_attr "type" "fpspc")
14016 (set_attr "mode" "XF")])
14018 (define_expand "remainderxf3"
14019 [(use (match_operand:XF 0 "register_operand"))
14020 (use (match_operand:XF 1 "general_operand"))
14021 (use (match_operand:XF 2 "general_operand"))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && flag_finite_math_only"
14025 rtx_code_label *label = gen_label_rtx ();
14027 rtx op1 = gen_reg_rtx (XFmode);
14028 rtx op2 = gen_reg_rtx (XFmode);
14030 emit_move_insn (op2, operands[2]);
14031 emit_move_insn (op1, operands[1]);
14033 emit_label (label);
14034 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14035 ix86_emit_fp_unordered_jump (label);
14036 LABEL_NUSES (label) = 1;
14038 emit_move_insn (operands[0], op1);
14042 (define_expand "remainder<mode>3"
14043 [(use (match_operand:MODEF 0 "register_operand"))
14044 (use (match_operand:MODEF 1 "general_operand"))
14045 (use (match_operand:MODEF 2 "general_operand"))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_finite_math_only"
14049 rtx (*gen_truncxf) (rtx, rtx);
14051 rtx_code_label *label = gen_label_rtx ();
14053 rtx op1 = gen_reg_rtx (XFmode);
14054 rtx op2 = gen_reg_rtx (XFmode);
14056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14057 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14059 emit_label (label);
14061 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14062 ix86_emit_fp_unordered_jump (label);
14063 LABEL_NUSES (label) = 1;
14065 /* Truncate the result properly for strict SSE math. */
14066 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14067 && !TARGET_MIX_SSE_I387)
14068 gen_truncxf = gen_truncxf<mode>2;
14070 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14072 emit_insn (gen_truncxf (operands[0], op1));
14076 (define_int_iterator SINCOS
14080 (define_int_attr sincos
14081 [(UNSPEC_SIN "sin")
14082 (UNSPEC_COS "cos")])
14084 (define_insn "*<sincos>xf2_i387"
14085 [(set (match_operand:XF 0 "register_operand" "=f")
14086 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations"
14091 [(set_attr "type" "fpspc")
14092 (set_attr "mode" "XF")])
14094 (define_insn "*<sincos>_extend<mode>xf2_i387"
14095 [(set (match_operand:XF 0 "register_operand" "=f")
14096 (unspec:XF [(float_extend:XF
14097 (match_operand:MODEF 1 "register_operand" "0"))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101 || TARGET_MIX_SSE_I387)
14102 && flag_unsafe_math_optimizations"
14104 [(set_attr "type" "fpspc")
14105 (set_attr "mode" "XF")])
14107 ;; When sincos pattern is defined, sin and cos builtin functions will be
14108 ;; expanded to sincos pattern with one of its outputs left unused.
14109 ;; CSE pass will figure out if two sincos patterns can be combined,
14110 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14111 ;; depending on the unused output.
14113 (define_insn "sincosxf3"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14116 UNSPEC_SINCOS_COS))
14117 (set (match_operand:XF 1 "register_operand" "=u")
14118 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && flag_unsafe_math_optimizations"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14126 [(set (match_operand:XF 0 "register_operand")
14127 (unspec:XF [(match_operand:XF 2 "register_operand")]
14128 UNSPEC_SINCOS_COS))
14129 (set (match_operand:XF 1 "register_operand")
14130 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14131 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14132 && can_create_pseudo_p ()"
14133 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14136 [(set (match_operand:XF 0 "register_operand")
14137 (unspec:XF [(match_operand:XF 2 "register_operand")]
14138 UNSPEC_SINCOS_COS))
14139 (set (match_operand:XF 1 "register_operand")
14140 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14141 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14142 && can_create_pseudo_p ()"
14143 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14145 (define_insn "sincos_extend<mode>xf3_i387"
14146 [(set (match_operand:XF 0 "register_operand" "=f")
14147 (unspec:XF [(float_extend:XF
14148 (match_operand:MODEF 2 "register_operand" "0"))]
14149 UNSPEC_SINCOS_COS))
14150 (set (match_operand:XF 1 "register_operand" "=u")
14151 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14152 "TARGET_USE_FANCY_MATH_387
14153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14154 || TARGET_MIX_SSE_I387)
14155 && flag_unsafe_math_optimizations"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14161 [(set (match_operand:XF 0 "register_operand")
14162 (unspec:XF [(float_extend:XF
14163 (match_operand:MODEF 2 "register_operand"))]
14164 UNSPEC_SINCOS_COS))
14165 (set (match_operand:XF 1 "register_operand")
14166 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14168 && can_create_pseudo_p ()"
14169 [(set (match_dup 1)
14170 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14173 [(set (match_operand:XF 0 "register_operand")
14174 (unspec:XF [(float_extend:XF
14175 (match_operand:MODEF 2 "register_operand"))]
14176 UNSPEC_SINCOS_COS))
14177 (set (match_operand:XF 1 "register_operand")
14178 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14179 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14180 && can_create_pseudo_p ()"
14181 [(set (match_dup 0)
14182 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14184 (define_expand "sincos<mode>3"
14185 [(use (match_operand:MODEF 0 "register_operand"))
14186 (use (match_operand:MODEF 1 "register_operand"))
14187 (use (match_operand:MODEF 2 "register_operand"))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190 || TARGET_MIX_SSE_I387)
14191 && flag_unsafe_math_optimizations"
14193 rtx op0 = gen_reg_rtx (XFmode);
14194 rtx op1 = gen_reg_rtx (XFmode);
14196 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14202 (define_insn "fptanxf4_i387"
14203 [(set (match_operand:XF 0 "register_operand" "=f")
14204 (match_operand:XF 3 "const_double_operand" "F"))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations
14210 && standard_80387_constant_p (operands[3]) == 2"
14212 [(set_attr "type" "fpspc")
14213 (set_attr "mode" "XF")])
14215 (define_insn "fptan_extend<mode>xf4_i387"
14216 [(set (match_operand:MODEF 0 "register_operand" "=f")
14217 (match_operand:MODEF 3 "const_double_operand" "F"))
14218 (set (match_operand:XF 1 "register_operand" "=u")
14219 (unspec:XF [(float_extend:XF
14220 (match_operand:MODEF 2 "register_operand" "0"))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224 || TARGET_MIX_SSE_I387)
14225 && flag_unsafe_math_optimizations
14226 && standard_80387_constant_p (operands[3]) == 2"
14228 [(set_attr "type" "fpspc")
14229 (set_attr "mode" "XF")])
14231 (define_expand "tanxf2"
14232 [(use (match_operand:XF 0 "register_operand"))
14233 (use (match_operand:XF 1 "register_operand"))]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14237 rtx one = gen_reg_rtx (XFmode);
14238 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14240 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14244 (define_expand "tan<mode>2"
14245 [(use (match_operand:MODEF 0 "register_operand"))
14246 (use (match_operand:MODEF 1 "register_operand"))]
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 rtx op0 = gen_reg_rtx (XFmode);
14254 rtx one = gen_reg_rtx (<MODE>mode);
14255 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14257 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14258 operands[1], op2));
14259 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14263 (define_insn "*fpatanxf3_i387"
14264 [(set (match_operand:XF 0 "register_operand" "=f")
14265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14266 (match_operand:XF 2 "register_operand" "u")]
14268 (clobber (match_scratch:XF 3 "=2"))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && flag_unsafe_math_optimizations"
14272 [(set_attr "type" "fpspc")
14273 (set_attr "mode" "XF")])
14275 (define_insn "fpatan_extend<mode>xf3_i387"
14276 [(set (match_operand:XF 0 "register_operand" "=f")
14277 (unspec:XF [(float_extend:XF
14278 (match_operand:MODEF 1 "register_operand" "0"))
14280 (match_operand:MODEF 2 "register_operand" "u"))]
14282 (clobber (match_scratch:XF 3 "=2"))]
14283 "TARGET_USE_FANCY_MATH_387
14284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14285 || TARGET_MIX_SSE_I387)
14286 && flag_unsafe_math_optimizations"
14288 [(set_attr "type" "fpspc")
14289 (set_attr "mode" "XF")])
14291 (define_expand "atan2xf3"
14292 [(parallel [(set (match_operand:XF 0 "register_operand")
14293 (unspec:XF [(match_operand:XF 2 "register_operand")
14294 (match_operand:XF 1 "register_operand")]
14296 (clobber (match_scratch:XF 3))])]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations")
14300 (define_expand "atan2<mode>3"
14301 [(use (match_operand:MODEF 0 "register_operand"))
14302 (use (match_operand:MODEF 1 "register_operand"))
14303 (use (match_operand:MODEF 2 "register_operand"))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14306 || TARGET_MIX_SSE_I387)
14307 && flag_unsafe_math_optimizations"
14309 rtx op0 = gen_reg_rtx (XFmode);
14311 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14316 (define_expand "atanxf2"
14317 [(parallel [(set (match_operand:XF 0 "register_operand")
14318 (unspec:XF [(match_dup 2)
14319 (match_operand:XF 1 "register_operand")]
14321 (clobber (match_scratch:XF 3))])]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14325 operands[2] = gen_reg_rtx (XFmode);
14326 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14329 (define_expand "atan<mode>2"
14330 [(use (match_operand:MODEF 0 "register_operand"))
14331 (use (match_operand:MODEF 1 "register_operand"))]
14332 "TARGET_USE_FANCY_MATH_387
14333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334 || TARGET_MIX_SSE_I387)
14335 && flag_unsafe_math_optimizations"
14337 rtx op0 = gen_reg_rtx (XFmode);
14339 rtx op2 = gen_reg_rtx (<MODE>mode);
14340 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14342 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14347 (define_expand "asinxf2"
14348 [(set (match_dup 2)
14349 (mult:XF (match_operand:XF 1 "register_operand")
14351 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14352 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14353 (parallel [(set (match_operand:XF 0 "register_operand")
14354 (unspec:XF [(match_dup 5) (match_dup 1)]
14356 (clobber (match_scratch:XF 6))])]
14357 "TARGET_USE_FANCY_MATH_387
14358 && flag_unsafe_math_optimizations"
14362 if (optimize_insn_for_size_p ())
14365 for (i = 2; i < 6; i++)
14366 operands[i] = gen_reg_rtx (XFmode);
14368 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14371 (define_expand "asin<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand"))
14373 (use (match_operand:MODEF 1 "general_operand"))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations"
14379 rtx op0 = gen_reg_rtx (XFmode);
14380 rtx op1 = gen_reg_rtx (XFmode);
14382 if (optimize_insn_for_size_p ())
14385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14386 emit_insn (gen_asinxf2 (op0, op1));
14387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14391 (define_expand "acosxf2"
14392 [(set (match_dup 2)
14393 (mult:XF (match_operand:XF 1 "register_operand")
14395 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14396 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14397 (parallel [(set (match_operand:XF 0 "register_operand")
14398 (unspec:XF [(match_dup 1) (match_dup 5)]
14400 (clobber (match_scratch:XF 6))])]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14406 if (optimize_insn_for_size_p ())
14409 for (i = 2; i < 6; i++)
14410 operands[i] = gen_reg_rtx (XFmode);
14412 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14415 (define_expand "acos<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand"))
14417 (use (match_operand:MODEF 1 "general_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14423 rtx op0 = gen_reg_rtx (XFmode);
14424 rtx op1 = gen_reg_rtx (XFmode);
14426 if (optimize_insn_for_size_p ())
14429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14430 emit_insn (gen_acosxf2 (op0, op1));
14431 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14435 (define_insn "fyl2xxf3_i387"
14436 [(set (match_operand:XF 0 "register_operand" "=f")
14437 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14438 (match_operand:XF 2 "register_operand" "u")]
14440 (clobber (match_scratch:XF 3 "=2"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && flag_unsafe_math_optimizations"
14444 [(set_attr "type" "fpspc")
14445 (set_attr "mode" "XF")])
14447 (define_insn "fyl2x_extend<mode>xf3_i387"
14448 [(set (match_operand:XF 0 "register_operand" "=f")
14449 (unspec:XF [(float_extend:XF
14450 (match_operand:MODEF 1 "register_operand" "0"))
14451 (match_operand:XF 2 "register_operand" "u")]
14453 (clobber (match_scratch:XF 3 "=2"))]
14454 "TARGET_USE_FANCY_MATH_387
14455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14456 || TARGET_MIX_SSE_I387)
14457 && flag_unsafe_math_optimizations"
14459 [(set_attr "type" "fpspc")
14460 (set_attr "mode" "XF")])
14462 (define_expand "logxf2"
14463 [(parallel [(set (match_operand:XF 0 "register_operand")
14464 (unspec:XF [(match_operand:XF 1 "register_operand")
14465 (match_dup 2)] UNSPEC_FYL2X))
14466 (clobber (match_scratch:XF 3))])]
14467 "TARGET_USE_FANCY_MATH_387
14468 && flag_unsafe_math_optimizations"
14470 operands[2] = gen_reg_rtx (XFmode);
14471 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14474 (define_expand "log<mode>2"
14475 [(use (match_operand:MODEF 0 "register_operand"))
14476 (use (match_operand:MODEF 1 "register_operand"))]
14477 "TARGET_USE_FANCY_MATH_387
14478 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14479 || TARGET_MIX_SSE_I387)
14480 && flag_unsafe_math_optimizations"
14482 rtx op0 = gen_reg_rtx (XFmode);
14484 rtx op2 = gen_reg_rtx (XFmode);
14485 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14487 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14488 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14492 (define_expand "log10xf2"
14493 [(parallel [(set (match_operand:XF 0 "register_operand")
14494 (unspec:XF [(match_operand:XF 1 "register_operand")
14495 (match_dup 2)] UNSPEC_FYL2X))
14496 (clobber (match_scratch:XF 3))])]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14500 operands[2] = gen_reg_rtx (XFmode);
14501 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14504 (define_expand "log10<mode>2"
14505 [(use (match_operand:MODEF 0 "register_operand"))
14506 (use (match_operand:MODEF 1 "register_operand"))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14512 rtx op0 = gen_reg_rtx (XFmode);
14514 rtx op2 = gen_reg_rtx (XFmode);
14515 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14517 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14518 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14522 (define_expand "log2xf2"
14523 [(parallel [(set (match_operand:XF 0 "register_operand")
14524 (unspec:XF [(match_operand:XF 1 "register_operand")
14525 (match_dup 2)] UNSPEC_FYL2X))
14526 (clobber (match_scratch:XF 3))])]
14527 "TARGET_USE_FANCY_MATH_387
14528 && flag_unsafe_math_optimizations"
14530 operands[2] = gen_reg_rtx (XFmode);
14531 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14534 (define_expand "log2<mode>2"
14535 [(use (match_operand:MODEF 0 "register_operand"))
14536 (use (match_operand:MODEF 1 "register_operand"))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539 || TARGET_MIX_SSE_I387)
14540 && flag_unsafe_math_optimizations"
14542 rtx op0 = gen_reg_rtx (XFmode);
14544 rtx op2 = gen_reg_rtx (XFmode);
14545 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14547 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14552 (define_insn "fyl2xp1xf3_i387"
14553 [(set (match_operand:XF 0 "register_operand" "=f")
14554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14555 (match_operand:XF 2 "register_operand" "u")]
14557 (clobber (match_scratch:XF 3 "=2"))]
14558 "TARGET_USE_FANCY_MATH_387
14559 && flag_unsafe_math_optimizations"
14561 [(set_attr "type" "fpspc")
14562 (set_attr "mode" "XF")])
14564 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14565 [(set (match_operand:XF 0 "register_operand" "=f")
14566 (unspec:XF [(float_extend:XF
14567 (match_operand:MODEF 1 "register_operand" "0"))
14568 (match_operand:XF 2 "register_operand" "u")]
14570 (clobber (match_scratch:XF 3 "=2"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573 || TARGET_MIX_SSE_I387)
14574 && flag_unsafe_math_optimizations"
14576 [(set_attr "type" "fpspc")
14577 (set_attr "mode" "XF")])
14579 (define_expand "log1pxf2"
14580 [(use (match_operand:XF 0 "register_operand"))
14581 (use (match_operand:XF 1 "register_operand"))]
14582 "TARGET_USE_FANCY_MATH_387
14583 && flag_unsafe_math_optimizations"
14585 if (optimize_insn_for_size_p ())
14588 ix86_emit_i387_log1p (operands[0], operands[1]);
14592 (define_expand "log1p<mode>2"
14593 [(use (match_operand:MODEF 0 "register_operand"))
14594 (use (match_operand:MODEF 1 "register_operand"))]
14595 "TARGET_USE_FANCY_MATH_387
14596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14597 || TARGET_MIX_SSE_I387)
14598 && flag_unsafe_math_optimizations"
14602 if (optimize_insn_for_size_p ())
14605 op0 = gen_reg_rtx (XFmode);
14607 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14609 ix86_emit_i387_log1p (op0, operands[1]);
14610 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14614 (define_insn "fxtractxf3_i387"
14615 [(set (match_operand:XF 0 "register_operand" "=f")
14616 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14617 UNSPEC_XTRACT_FRACT))
14618 (set (match_operand:XF 1 "register_operand" "=u")
14619 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14620 "TARGET_USE_FANCY_MATH_387
14621 && flag_unsafe_math_optimizations"
14623 [(set_attr "type" "fpspc")
14624 (set_attr "mode" "XF")])
14626 (define_insn "fxtract_extend<mode>xf3_i387"
14627 [(set (match_operand:XF 0 "register_operand" "=f")
14628 (unspec:XF [(float_extend:XF
14629 (match_operand:MODEF 2 "register_operand" "0"))]
14630 UNSPEC_XTRACT_FRACT))
14631 (set (match_operand:XF 1 "register_operand" "=u")
14632 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14635 || TARGET_MIX_SSE_I387)
14636 && flag_unsafe_math_optimizations"
14638 [(set_attr "type" "fpspc")
14639 (set_attr "mode" "XF")])
14641 (define_expand "logbxf2"
14642 [(parallel [(set (match_dup 2)
14643 (unspec:XF [(match_operand:XF 1 "register_operand")]
14644 UNSPEC_XTRACT_FRACT))
14645 (set (match_operand:XF 0 "register_operand")
14646 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14647 "TARGET_USE_FANCY_MATH_387
14648 && flag_unsafe_math_optimizations"
14649 "operands[2] = gen_reg_rtx (XFmode);")
14651 (define_expand "logb<mode>2"
14652 [(use (match_operand:MODEF 0 "register_operand"))
14653 (use (match_operand:MODEF 1 "register_operand"))]
14654 "TARGET_USE_FANCY_MATH_387
14655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14656 || TARGET_MIX_SSE_I387)
14657 && flag_unsafe_math_optimizations"
14659 rtx op0 = gen_reg_rtx (XFmode);
14660 rtx op1 = gen_reg_rtx (XFmode);
14662 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14663 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14667 (define_expand "ilogbxf2"
14668 [(use (match_operand:SI 0 "register_operand"))
14669 (use (match_operand:XF 1 "register_operand"))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations"
14675 if (optimize_insn_for_size_p ())
14678 op0 = gen_reg_rtx (XFmode);
14679 op1 = gen_reg_rtx (XFmode);
14681 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14682 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14686 (define_expand "ilogb<mode>2"
14687 [(use (match_operand:SI 0 "register_operand"))
14688 (use (match_operand:MODEF 1 "register_operand"))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14691 || TARGET_MIX_SSE_I387)
14692 && flag_unsafe_math_optimizations"
14696 if (optimize_insn_for_size_p ())
14699 op0 = gen_reg_rtx (XFmode);
14700 op1 = gen_reg_rtx (XFmode);
14702 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14703 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14707 (define_insn "*f2xm1xf2_i387"
14708 [(set (match_operand:XF 0 "register_operand" "=f")
14709 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14711 "TARGET_USE_FANCY_MATH_387
14712 && flag_unsafe_math_optimizations"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "XF")])
14717 (define_insn "fscalexf4_i387"
14718 [(set (match_operand:XF 0 "register_operand" "=f")
14719 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14720 (match_operand:XF 3 "register_operand" "1")]
14721 UNSPEC_FSCALE_FRACT))
14722 (set (match_operand:XF 1 "register_operand" "=u")
14723 (unspec:XF [(match_dup 2) (match_dup 3)]
14724 UNSPEC_FSCALE_EXP))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && flag_unsafe_math_optimizations"
14728 [(set_attr "type" "fpspc")
14729 (set_attr "mode" "XF")])
14731 (define_expand "expNcorexf3"
14732 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14733 (match_operand:XF 2 "register_operand")))
14734 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14735 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14736 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14737 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14738 (parallel [(set (match_operand:XF 0 "register_operand")
14739 (unspec:XF [(match_dup 8) (match_dup 4)]
14740 UNSPEC_FSCALE_FRACT))
14742 (unspec:XF [(match_dup 8) (match_dup 4)]
14743 UNSPEC_FSCALE_EXP))])]
14744 "TARGET_USE_FANCY_MATH_387
14745 && flag_unsafe_math_optimizations"
14749 if (optimize_insn_for_size_p ())
14752 for (i = 3; i < 10; i++)
14753 operands[i] = gen_reg_rtx (XFmode);
14755 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14758 (define_expand "expxf2"
14759 [(use (match_operand:XF 0 "register_operand"))
14760 (use (match_operand:XF 1 "register_operand"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && flag_unsafe_math_optimizations"
14766 if (optimize_insn_for_size_p ())
14769 op2 = gen_reg_rtx (XFmode);
14770 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14772 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14776 (define_expand "exp<mode>2"
14777 [(use (match_operand:MODEF 0 "register_operand"))
14778 (use (match_operand:MODEF 1 "general_operand"))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14781 || TARGET_MIX_SSE_I387)
14782 && flag_unsafe_math_optimizations"
14786 if (optimize_insn_for_size_p ())
14789 op0 = gen_reg_rtx (XFmode);
14790 op1 = gen_reg_rtx (XFmode);
14792 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14793 emit_insn (gen_expxf2 (op0, op1));
14794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14798 (define_expand "exp10xf2"
14799 [(use (match_operand:XF 0 "register_operand"))
14800 (use (match_operand:XF 1 "register_operand"))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && flag_unsafe_math_optimizations"
14806 if (optimize_insn_for_size_p ())
14809 op2 = gen_reg_rtx (XFmode);
14810 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14812 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14816 (define_expand "exp10<mode>2"
14817 [(use (match_operand:MODEF 0 "register_operand"))
14818 (use (match_operand:MODEF 1 "general_operand"))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14821 || TARGET_MIX_SSE_I387)
14822 && flag_unsafe_math_optimizations"
14826 if (optimize_insn_for_size_p ())
14829 op0 = gen_reg_rtx (XFmode);
14830 op1 = gen_reg_rtx (XFmode);
14832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14833 emit_insn (gen_exp10xf2 (op0, op1));
14834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14838 (define_expand "exp2xf2"
14839 [(use (match_operand:XF 0 "register_operand"))
14840 (use (match_operand:XF 1 "register_operand"))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations"
14846 if (optimize_insn_for_size_p ())
14849 op2 = gen_reg_rtx (XFmode);
14850 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14852 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14856 (define_expand "exp2<mode>2"
14857 [(use (match_operand:MODEF 0 "register_operand"))
14858 (use (match_operand:MODEF 1 "general_operand"))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14861 || TARGET_MIX_SSE_I387)
14862 && flag_unsafe_math_optimizations"
14866 if (optimize_insn_for_size_p ())
14869 op0 = gen_reg_rtx (XFmode);
14870 op1 = gen_reg_rtx (XFmode);
14872 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14873 emit_insn (gen_exp2xf2 (op0, op1));
14874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14878 (define_expand "expm1xf2"
14879 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14881 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14882 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14883 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14885 (parallel [(set (match_dup 7)
14886 (unspec:XF [(match_dup 6) (match_dup 4)]
14887 UNSPEC_FSCALE_FRACT))
14889 (unspec:XF [(match_dup 6) (match_dup 4)]
14890 UNSPEC_FSCALE_EXP))])
14891 (parallel [(set (match_dup 10)
14892 (unspec:XF [(match_dup 9) (match_dup 8)]
14893 UNSPEC_FSCALE_FRACT))
14894 (set (match_dup 11)
14895 (unspec:XF [(match_dup 9) (match_dup 8)]
14896 UNSPEC_FSCALE_EXP))])
14897 (set (match_dup 12) (minus:XF (match_dup 10)
14898 (float_extend:XF (match_dup 13))))
14899 (set (match_operand:XF 0 "register_operand")
14900 (plus:XF (match_dup 12) (match_dup 7)))]
14901 "TARGET_USE_FANCY_MATH_387
14902 && flag_unsafe_math_optimizations"
14906 if (optimize_insn_for_size_p ())
14909 for (i = 2; i < 13; i++)
14910 operands[i] = gen_reg_rtx (XFmode);
14913 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14915 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14918 (define_expand "expm1<mode>2"
14919 [(use (match_operand:MODEF 0 "register_operand"))
14920 (use (match_operand:MODEF 1 "general_operand"))]
14921 "TARGET_USE_FANCY_MATH_387
14922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14923 || TARGET_MIX_SSE_I387)
14924 && flag_unsafe_math_optimizations"
14928 if (optimize_insn_for_size_p ())
14931 op0 = gen_reg_rtx (XFmode);
14932 op1 = gen_reg_rtx (XFmode);
14934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14935 emit_insn (gen_expm1xf2 (op0, op1));
14936 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14940 (define_expand "ldexpxf3"
14941 [(match_operand:XF 0 "register_operand")
14942 (match_operand:XF 1 "register_operand")
14943 (match_operand:SI 2 "register_operand")]
14944 "TARGET_USE_FANCY_MATH_387
14945 && flag_unsafe_math_optimizations"
14948 if (optimize_insn_for_size_p ())
14951 tmp1 = gen_reg_rtx (XFmode);
14952 tmp2 = gen_reg_rtx (XFmode);
14954 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14955 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14956 operands[1], tmp1));
14960 (define_expand "ldexp<mode>3"
14961 [(use (match_operand:MODEF 0 "register_operand"))
14962 (use (match_operand:MODEF 1 "general_operand"))
14963 (use (match_operand:SI 2 "register_operand"))]
14964 "TARGET_USE_FANCY_MATH_387
14965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966 || TARGET_MIX_SSE_I387)
14967 && flag_unsafe_math_optimizations"
14971 if (optimize_insn_for_size_p ())
14974 op0 = gen_reg_rtx (XFmode);
14975 op1 = gen_reg_rtx (XFmode);
14977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14978 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14979 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14983 (define_expand "scalbxf3"
14984 [(parallel [(set (match_operand:XF 0 " register_operand")
14985 (unspec:XF [(match_operand:XF 1 "register_operand")
14986 (match_operand:XF 2 "register_operand")]
14987 UNSPEC_FSCALE_FRACT))
14989 (unspec:XF [(match_dup 1) (match_dup 2)]
14990 UNSPEC_FSCALE_EXP))])]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14994 if (optimize_insn_for_size_p ())
14997 operands[3] = gen_reg_rtx (XFmode);
15000 (define_expand "scalb<mode>3"
15001 [(use (match_operand:MODEF 0 "register_operand"))
15002 (use (match_operand:MODEF 1 "general_operand"))
15003 (use (match_operand:MODEF 2 "general_operand"))]
15004 "TARGET_USE_FANCY_MATH_387
15005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15006 || TARGET_MIX_SSE_I387)
15007 && flag_unsafe_math_optimizations"
15011 if (optimize_insn_for_size_p ())
15014 op0 = gen_reg_rtx (XFmode);
15015 op1 = gen_reg_rtx (XFmode);
15016 op2 = gen_reg_rtx (XFmode);
15018 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15019 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15020 emit_insn (gen_scalbxf3 (op0, op1, op2));
15021 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15025 (define_expand "significandxf2"
15026 [(parallel [(set (match_operand:XF 0 "register_operand")
15027 (unspec:XF [(match_operand:XF 1 "register_operand")]
15028 UNSPEC_XTRACT_FRACT))
15030 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15031 "TARGET_USE_FANCY_MATH_387
15032 && flag_unsafe_math_optimizations"
15033 "operands[2] = gen_reg_rtx (XFmode);")
15035 (define_expand "significand<mode>2"
15036 [(use (match_operand:MODEF 0 "register_operand"))
15037 (use (match_operand:MODEF 1 "register_operand"))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15040 || TARGET_MIX_SSE_I387)
15041 && flag_unsafe_math_optimizations"
15043 rtx op0 = gen_reg_rtx (XFmode);
15044 rtx op1 = gen_reg_rtx (XFmode);
15046 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15047 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15052 (define_insn "sse4_1_round<mode>2"
15053 [(set (match_operand:MODEF 0 "register_operand" "=x")
15054 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15055 (match_operand:SI 2 "const_0_to_15_operand" "n")]
15058 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15059 [(set_attr "type" "ssecvt")
15060 (set_attr "prefix_extra" "1")
15061 (set_attr "prefix" "maybe_vex")
15062 (set_attr "mode" "<MODE>")])
15064 (define_insn "rintxf2"
15065 [(set (match_operand:XF 0 "register_operand" "=f")
15066 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15068 "TARGET_USE_FANCY_MATH_387
15069 && flag_unsafe_math_optimizations"
15071 [(set_attr "type" "fpspc")
15072 (set_attr "mode" "XF")])
15074 (define_expand "rint<mode>2"
15075 [(use (match_operand:MODEF 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "register_operand"))]
15077 "(TARGET_USE_FANCY_MATH_387
15078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15079 || TARGET_MIX_SSE_I387)
15080 && flag_unsafe_math_optimizations)
15081 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15082 && !flag_trapping_math)"
15084 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15085 && !flag_trapping_math)
15088 emit_insn (gen_sse4_1_round<mode>2
15089 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15090 else if (optimize_insn_for_size_p ())
15093 ix86_expand_rint (operands[0], operands[1]);
15097 rtx op0 = gen_reg_rtx (XFmode);
15098 rtx op1 = gen_reg_rtx (XFmode);
15100 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15101 emit_insn (gen_rintxf2 (op0, op1));
15103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15108 (define_expand "round<mode>2"
15109 [(match_operand:X87MODEF 0 "register_operand")
15110 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15111 "(TARGET_USE_FANCY_MATH_387
15112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15113 || TARGET_MIX_SSE_I387)
15114 && flag_unsafe_math_optimizations)
15115 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15116 && !flag_trapping_math && !flag_rounding_math)"
15118 if (optimize_insn_for_size_p ())
15121 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15122 && !flag_trapping_math && !flag_rounding_math)
15126 operands[1] = force_reg (<MODE>mode, operands[1]);
15127 ix86_expand_round_sse4 (operands[0], operands[1]);
15129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130 ix86_expand_round (operands[0], operands[1]);
15132 ix86_expand_rounddf_32 (operands[0], operands[1]);
15136 operands[1] = force_reg (<MODE>mode, operands[1]);
15137 ix86_emit_i387_round (operands[0], operands[1]);
15142 (define_insn_and_split "*fistdi2_1"
15143 [(set (match_operand:DI 0 "nonimmediate_operand")
15144 (unspec:DI [(match_operand:XF 1 "register_operand")]
15146 "TARGET_USE_FANCY_MATH_387
15147 && can_create_pseudo_p ()"
15152 if (memory_operand (operands[0], VOIDmode))
15153 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15156 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15157 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15162 [(set_attr "type" "fpspc")
15163 (set_attr "mode" "DI")])
15165 (define_insn "fistdi2"
15166 [(set (match_operand:DI 0 "memory_operand" "=m")
15167 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15169 (clobber (match_scratch:XF 2 "=&1f"))]
15170 "TARGET_USE_FANCY_MATH_387"
15171 "* return output_fix_trunc (insn, operands, false);"
15172 [(set_attr "type" "fpspc")
15173 (set_attr "mode" "DI")])
15175 (define_insn "fistdi2_with_temp"
15176 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15177 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15179 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15180 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15181 "TARGET_USE_FANCY_MATH_387"
15183 [(set_attr "type" "fpspc")
15184 (set_attr "mode" "DI")])
15187 [(set (match_operand:DI 0 "register_operand")
15188 (unspec:DI [(match_operand:XF 1 "register_operand")]
15190 (clobber (match_operand:DI 2 "memory_operand"))
15191 (clobber (match_scratch 3))]
15193 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15194 (clobber (match_dup 3))])
15195 (set (match_dup 0) (match_dup 2))])
15198 [(set (match_operand:DI 0 "memory_operand")
15199 (unspec:DI [(match_operand:XF 1 "register_operand")]
15201 (clobber (match_operand:DI 2 "memory_operand"))
15202 (clobber (match_scratch 3))]
15204 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15205 (clobber (match_dup 3))])])
15207 (define_insn_and_split "*fist<mode>2_1"
15208 [(set (match_operand:SWI24 0 "register_operand")
15209 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15211 "TARGET_USE_FANCY_MATH_387
15212 && can_create_pseudo_p ()"
15217 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15218 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15222 [(set_attr "type" "fpspc")
15223 (set_attr "mode" "<MODE>")])
15225 (define_insn "fist<mode>2"
15226 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15227 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15229 "TARGET_USE_FANCY_MATH_387"
15230 "* return output_fix_trunc (insn, operands, false);"
15231 [(set_attr "type" "fpspc")
15232 (set_attr "mode" "<MODE>")])
15234 (define_insn "fist<mode>2_with_temp"
15235 [(set (match_operand:SWI24 0 "register_operand" "=r")
15236 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15238 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15239 "TARGET_USE_FANCY_MATH_387"
15241 [(set_attr "type" "fpspc")
15242 (set_attr "mode" "<MODE>")])
15245 [(set (match_operand:SWI24 0 "register_operand")
15246 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15248 (clobber (match_operand:SWI24 2 "memory_operand"))]
15250 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15251 (set (match_dup 0) (match_dup 2))])
15254 [(set (match_operand:SWI24 0 "memory_operand")
15255 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15257 (clobber (match_operand:SWI24 2 "memory_operand"))]
15259 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15261 (define_expand "lrintxf<mode>2"
15262 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15263 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15265 "TARGET_USE_FANCY_MATH_387")
15267 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15268 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15269 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15270 UNSPEC_FIX_NOTRUNC))]
15271 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15273 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15274 [(match_operand:SWI248x 0 "nonimmediate_operand")
15275 (match_operand:X87MODEF 1 "register_operand")]
15276 "(TARGET_USE_FANCY_MATH_387
15277 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15278 || TARGET_MIX_SSE_I387)
15279 && flag_unsafe_math_optimizations)
15280 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15281 && <SWI248x:MODE>mode != HImode
15282 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15283 && !flag_trapping_math && !flag_rounding_math)"
15285 if (optimize_insn_for_size_p ())
15288 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15289 && <SWI248x:MODE>mode != HImode
15290 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15291 && !flag_trapping_math && !flag_rounding_math)
15292 ix86_expand_lround (operands[0], operands[1]);
15294 ix86_emit_i387_round (operands[0], operands[1]);
15298 (define_int_iterator FRNDINT_ROUNDING
15299 [UNSPEC_FRNDINT_FLOOR
15300 UNSPEC_FRNDINT_CEIL
15301 UNSPEC_FRNDINT_TRUNC])
15303 (define_int_iterator FIST_ROUNDING
15307 ;; Base name for define_insn
15308 (define_int_attr rounding_insn
15309 [(UNSPEC_FRNDINT_FLOOR "floor")
15310 (UNSPEC_FRNDINT_CEIL "ceil")
15311 (UNSPEC_FRNDINT_TRUNC "btrunc")
15312 (UNSPEC_FIST_FLOOR "floor")
15313 (UNSPEC_FIST_CEIL "ceil")])
15315 (define_int_attr rounding
15316 [(UNSPEC_FRNDINT_FLOOR "floor")
15317 (UNSPEC_FRNDINT_CEIL "ceil")
15318 (UNSPEC_FRNDINT_TRUNC "trunc")
15319 (UNSPEC_FIST_FLOOR "floor")
15320 (UNSPEC_FIST_CEIL "ceil")])
15322 (define_int_attr ROUNDING
15323 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15324 (UNSPEC_FRNDINT_CEIL "CEIL")
15325 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15326 (UNSPEC_FIST_FLOOR "FLOOR")
15327 (UNSPEC_FIST_CEIL "CEIL")])
15329 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15330 (define_insn_and_split "frndintxf2_<rounding>"
15331 [(set (match_operand:XF 0 "register_operand")
15332 (unspec:XF [(match_operand:XF 1 "register_operand")]
15334 (clobber (reg:CC FLAGS_REG))]
15335 "TARGET_USE_FANCY_MATH_387
15336 && flag_unsafe_math_optimizations
15337 && can_create_pseudo_p ()"
15342 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15344 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15345 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15347 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15348 operands[2], operands[3]));
15351 [(set_attr "type" "frndint")
15352 (set_attr "i387_cw" "<rounding>")
15353 (set_attr "mode" "XF")])
15355 (define_insn "frndintxf2_<rounding>_i387"
15356 [(set (match_operand:XF 0 "register_operand" "=f")
15357 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15359 (use (match_operand:HI 2 "memory_operand" "m"))
15360 (use (match_operand:HI 3 "memory_operand" "m"))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations"
15363 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15364 [(set_attr "type" "frndint")
15365 (set_attr "i387_cw" "<rounding>")
15366 (set_attr "mode" "XF")])
15368 (define_expand "<rounding_insn>xf2"
15369 [(parallel [(set (match_operand:XF 0 "register_operand")
15370 (unspec:XF [(match_operand:XF 1 "register_operand")]
15372 (clobber (reg:CC FLAGS_REG))])]
15373 "TARGET_USE_FANCY_MATH_387
15374 && flag_unsafe_math_optimizations
15375 && !optimize_insn_for_size_p ()")
15377 (define_expand "<rounding_insn><mode>2"
15378 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15379 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15381 (clobber (reg:CC FLAGS_REG))])]
15382 "(TARGET_USE_FANCY_MATH_387
15383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15384 || TARGET_MIX_SSE_I387)
15385 && flag_unsafe_math_optimizations)
15386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15387 && !flag_trapping_math)"
15389 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15390 && !flag_trapping_math)
15393 emit_insn (gen_sse4_1_round<mode>2
15394 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15395 else if (optimize_insn_for_size_p ())
15397 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15399 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15400 ix86_expand_floorceil (operands[0], operands[1], true);
15401 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15402 ix86_expand_floorceil (operands[0], operands[1], false);
15403 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15404 ix86_expand_trunc (operands[0], operands[1]);
15406 gcc_unreachable ();
15410 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15411 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15412 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15413 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15414 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15415 ix86_expand_truncdf_32 (operands[0], operands[1]);
15417 gcc_unreachable ();
15424 if (optimize_insn_for_size_p ())
15427 op0 = gen_reg_rtx (XFmode);
15428 op1 = gen_reg_rtx (XFmode);
15429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15430 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15432 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15437 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15438 (define_insn_and_split "frndintxf2_mask_pm"
15439 [(set (match_operand:XF 0 "register_operand")
15440 (unspec:XF [(match_operand:XF 1 "register_operand")]
15441 UNSPEC_FRNDINT_MASK_PM))
15442 (clobber (reg:CC FLAGS_REG))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_unsafe_math_optimizations
15445 && can_create_pseudo_p ()"
15450 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15452 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15453 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15455 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15456 operands[2], operands[3]));
15459 [(set_attr "type" "frndint")
15460 (set_attr "i387_cw" "mask_pm")
15461 (set_attr "mode" "XF")])
15463 (define_insn "frndintxf2_mask_pm_i387"
15464 [(set (match_operand:XF 0 "register_operand" "=f")
15465 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15466 UNSPEC_FRNDINT_MASK_PM))
15467 (use (match_operand:HI 2 "memory_operand" "m"))
15468 (use (match_operand:HI 3 "memory_operand" "m"))]
15469 "TARGET_USE_FANCY_MATH_387
15470 && flag_unsafe_math_optimizations"
15471 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15472 [(set_attr "type" "frndint")
15473 (set_attr "i387_cw" "mask_pm")
15474 (set_attr "mode" "XF")])
15476 (define_expand "nearbyintxf2"
15477 [(parallel [(set (match_operand:XF 0 "register_operand")
15478 (unspec:XF [(match_operand:XF 1 "register_operand")]
15479 UNSPEC_FRNDINT_MASK_PM))
15480 (clobber (reg:CC FLAGS_REG))])]
15481 "TARGET_USE_FANCY_MATH_387
15482 && flag_unsafe_math_optimizations")
15484 (define_expand "nearbyint<mode>2"
15485 [(use (match_operand:MODEF 0 "register_operand"))
15486 (use (match_operand:MODEF 1 "register_operand"))]
15487 "TARGET_USE_FANCY_MATH_387
15488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15489 || TARGET_MIX_SSE_I387)
15490 && flag_unsafe_math_optimizations"
15492 rtx op0 = gen_reg_rtx (XFmode);
15493 rtx op1 = gen_reg_rtx (XFmode);
15495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15496 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15502 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15503 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15504 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15505 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15507 (clobber (reg:CC FLAGS_REG))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && flag_unsafe_math_optimizations
15510 && can_create_pseudo_p ()"
15515 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15517 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15518 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15519 if (memory_operand (operands[0], VOIDmode))
15520 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15521 operands[2], operands[3]));
15524 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15525 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15526 (operands[0], operands[1], operands[2],
15527 operands[3], operands[4]));
15531 [(set_attr "type" "fistp")
15532 (set_attr "i387_cw" "<rounding>")
15533 (set_attr "mode" "<MODE>")])
15535 (define_insn "fistdi2_<rounding>"
15536 [(set (match_operand:DI 0 "memory_operand" "=m")
15537 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15539 (use (match_operand:HI 2 "memory_operand" "m"))
15540 (use (match_operand:HI 3 "memory_operand" "m"))
15541 (clobber (match_scratch:XF 4 "=&1f"))]
15542 "TARGET_USE_FANCY_MATH_387
15543 && flag_unsafe_math_optimizations"
15544 "* return output_fix_trunc (insn, operands, false);"
15545 [(set_attr "type" "fistp")
15546 (set_attr "i387_cw" "<rounding>")
15547 (set_attr "mode" "DI")])
15549 (define_insn "fistdi2_<rounding>_with_temp"
15550 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15551 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15553 (use (match_operand:HI 2 "memory_operand" "m,m"))
15554 (use (match_operand:HI 3 "memory_operand" "m,m"))
15555 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15556 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && flag_unsafe_math_optimizations"
15560 [(set_attr "type" "fistp")
15561 (set_attr "i387_cw" "<rounding>")
15562 (set_attr "mode" "DI")])
15565 [(set (match_operand:DI 0 "register_operand")
15566 (unspec:DI [(match_operand:XF 1 "register_operand")]
15568 (use (match_operand:HI 2 "memory_operand"))
15569 (use (match_operand:HI 3 "memory_operand"))
15570 (clobber (match_operand:DI 4 "memory_operand"))
15571 (clobber (match_scratch 5))]
15573 [(parallel [(set (match_dup 4)
15574 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15575 (use (match_dup 2))
15576 (use (match_dup 3))
15577 (clobber (match_dup 5))])
15578 (set (match_dup 0) (match_dup 4))])
15581 [(set (match_operand:DI 0 "memory_operand")
15582 (unspec:DI [(match_operand:XF 1 "register_operand")]
15584 (use (match_operand:HI 2 "memory_operand"))
15585 (use (match_operand:HI 3 "memory_operand"))
15586 (clobber (match_operand:DI 4 "memory_operand"))
15587 (clobber (match_scratch 5))]
15589 [(parallel [(set (match_dup 0)
15590 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15591 (use (match_dup 2))
15592 (use (match_dup 3))
15593 (clobber (match_dup 5))])])
15595 (define_insn "fist<mode>2_<rounding>"
15596 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15597 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15599 (use (match_operand:HI 2 "memory_operand" "m"))
15600 (use (match_operand:HI 3 "memory_operand" "m"))]
15601 "TARGET_USE_FANCY_MATH_387
15602 && flag_unsafe_math_optimizations"
15603 "* return output_fix_trunc (insn, operands, false);"
15604 [(set_attr "type" "fistp")
15605 (set_attr "i387_cw" "<rounding>")
15606 (set_attr "mode" "<MODE>")])
15608 (define_insn "fist<mode>2_<rounding>_with_temp"
15609 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15610 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15612 (use (match_operand:HI 2 "memory_operand" "m,m"))
15613 (use (match_operand:HI 3 "memory_operand" "m,m"))
15614 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15618 [(set_attr "type" "fistp")
15619 (set_attr "i387_cw" "<rounding>")
15620 (set_attr "mode" "<MODE>")])
15623 [(set (match_operand:SWI24 0 "register_operand")
15624 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15626 (use (match_operand:HI 2 "memory_operand"))
15627 (use (match_operand:HI 3 "memory_operand"))
15628 (clobber (match_operand:SWI24 4 "memory_operand"))]
15630 [(parallel [(set (match_dup 4)
15631 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15632 (use (match_dup 2))
15633 (use (match_dup 3))])
15634 (set (match_dup 0) (match_dup 4))])
15637 [(set (match_operand:SWI24 0 "memory_operand")
15638 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15640 (use (match_operand:HI 2 "memory_operand"))
15641 (use (match_operand:HI 3 "memory_operand"))
15642 (clobber (match_operand:SWI24 4 "memory_operand"))]
15644 [(parallel [(set (match_dup 0)
15645 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15646 (use (match_dup 2))
15647 (use (match_dup 3))])])
15649 (define_expand "l<rounding_insn>xf<mode>2"
15650 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15651 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15653 (clobber (reg:CC FLAGS_REG))])]
15654 "TARGET_USE_FANCY_MATH_387
15655 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15656 && flag_unsafe_math_optimizations")
15658 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15659 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15660 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15662 (clobber (reg:CC FLAGS_REG))])]
15663 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15664 && !flag_trapping_math"
15666 if (TARGET_64BIT && optimize_insn_for_size_p ())
15669 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15670 ix86_expand_lfloorceil (operands[0], operands[1], true);
15671 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15672 ix86_expand_lfloorceil (operands[0], operands[1], false);
15674 gcc_unreachable ();
15679 (define_insn "fxam<mode>2_i387"
15680 [(set (match_operand:HI 0 "register_operand" "=a")
15682 [(match_operand:X87MODEF 1 "register_operand" "f")]
15684 "TARGET_USE_FANCY_MATH_387"
15685 "fxam\n\tfnstsw\t%0"
15686 [(set_attr "type" "multi")
15687 (set_attr "length" "4")
15688 (set_attr "unit" "i387")
15689 (set_attr "mode" "<MODE>")])
15691 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15692 [(set (match_operand:HI 0 "register_operand")
15694 [(match_operand:MODEF 1 "memory_operand")]
15696 "TARGET_USE_FANCY_MATH_387
15697 && can_create_pseudo_p ()"
15700 [(set (match_dup 2)(match_dup 1))
15702 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15704 operands[2] = gen_reg_rtx (<MODE>mode);
15706 MEM_VOLATILE_P (operands[1]) = 1;
15708 [(set_attr "type" "multi")
15709 (set_attr "unit" "i387")
15710 (set_attr "mode" "<MODE>")])
15712 (define_expand "isinfxf2"
15713 [(use (match_operand:SI 0 "register_operand"))
15714 (use (match_operand:XF 1 "register_operand"))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && ix86_libc_has_function (function_c99_misc)"
15718 rtx mask = GEN_INT (0x45);
15719 rtx val = GEN_INT (0x05);
15723 rtx scratch = gen_reg_rtx (HImode);
15724 rtx res = gen_reg_rtx (QImode);
15726 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15728 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15729 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15730 cond = gen_rtx_fmt_ee (EQ, QImode,
15731 gen_rtx_REG (CCmode, FLAGS_REG),
15733 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15734 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15738 (define_expand "isinf<mode>2"
15739 [(use (match_operand:SI 0 "register_operand"))
15740 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && ix86_libc_has_function (function_c99_misc)
15743 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15745 rtx mask = GEN_INT (0x45);
15746 rtx val = GEN_INT (0x05);
15750 rtx scratch = gen_reg_rtx (HImode);
15751 rtx res = gen_reg_rtx (QImode);
15753 /* Remove excess precision by forcing value through memory. */
15754 if (memory_operand (operands[1], VOIDmode))
15755 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15758 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15760 emit_move_insn (temp, operands[1]);
15761 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15764 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15765 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15766 cond = gen_rtx_fmt_ee (EQ, QImode,
15767 gen_rtx_REG (CCmode, FLAGS_REG),
15769 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15770 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15774 (define_expand "signbitxf2"
15775 [(use (match_operand:SI 0 "register_operand"))
15776 (use (match_operand:XF 1 "register_operand"))]
15777 "TARGET_USE_FANCY_MATH_387"
15779 rtx scratch = gen_reg_rtx (HImode);
15781 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15782 emit_insn (gen_andsi3 (operands[0],
15783 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15787 (define_insn "movmsk_df"
15788 [(set (match_operand:SI 0 "register_operand" "=r")
15790 [(match_operand:DF 1 "register_operand" "x")]
15792 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15793 "%vmovmskpd\t{%1, %0|%0, %1}"
15794 [(set_attr "type" "ssemov")
15795 (set_attr "prefix" "maybe_vex")
15796 (set_attr "mode" "DF")])
15798 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15799 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15800 (define_expand "signbitdf2"
15801 [(use (match_operand:SI 0 "register_operand"))
15802 (use (match_operand:DF 1 "register_operand"))]
15803 "TARGET_USE_FANCY_MATH_387
15804 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15806 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15808 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15809 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15813 rtx scratch = gen_reg_rtx (HImode);
15815 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15816 emit_insn (gen_andsi3 (operands[0],
15817 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15822 (define_expand "signbitsf2"
15823 [(use (match_operand:SI 0 "register_operand"))
15824 (use (match_operand:SF 1 "register_operand"))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15828 rtx scratch = gen_reg_rtx (HImode);
15830 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15831 emit_insn (gen_andsi3 (operands[0],
15832 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15836 ;; Block operation instructions
15839 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15842 [(set_attr "length" "1")
15843 (set_attr "length_immediate" "0")
15844 (set_attr "modrm" "0")])
15846 (define_expand "movmem<mode>"
15847 [(use (match_operand:BLK 0 "memory_operand"))
15848 (use (match_operand:BLK 1 "memory_operand"))
15849 (use (match_operand:SWI48 2 "nonmemory_operand"))
15850 (use (match_operand:SWI48 3 "const_int_operand"))
15851 (use (match_operand:SI 4 "const_int_operand"))
15852 (use (match_operand:SI 5 "const_int_operand"))
15853 (use (match_operand:SI 6 ""))
15854 (use (match_operand:SI 7 ""))
15855 (use (match_operand:SI 8 ""))]
15858 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15859 operands[2], NULL, operands[3],
15860 operands[4], operands[5],
15861 operands[6], operands[7],
15862 operands[8], false))
15868 ;; Most CPUs don't like single string operations
15869 ;; Handle this case here to simplify previous expander.
15871 (define_expand "strmov"
15872 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15873 (set (match_operand 1 "memory_operand") (match_dup 4))
15874 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15875 (clobber (reg:CC FLAGS_REG))])
15876 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15877 (clobber (reg:CC FLAGS_REG))])]
15880 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15882 /* If .md ever supports :P for Pmode, these can be directly
15883 in the pattern above. */
15884 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15885 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15887 /* Can't use this if the user has appropriated esi or edi. */
15888 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15889 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15891 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[5], operands[6]));
15897 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15900 (define_expand "strmov_singleop"
15901 [(parallel [(set (match_operand 1 "memory_operand")
15902 (match_operand 3 "memory_operand"))
15903 (set (match_operand 0 "register_operand")
15905 (set (match_operand 2 "register_operand")
15906 (match_operand 5))])]
15908 "ix86_current_function_needs_cld = 1;")
15910 (define_insn "*strmovdi_rex_1"
15911 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15912 (mem:DI (match_operand:P 3 "register_operand" "1")))
15913 (set (match_operand:P 0 "register_operand" "=D")
15914 (plus:P (match_dup 2)
15916 (set (match_operand:P 1 "register_operand" "=S")
15917 (plus:P (match_dup 3)
15920 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15922 [(set_attr "type" "str")
15923 (set_attr "memory" "both")
15924 (set_attr "mode" "DI")])
15926 (define_insn "*strmovsi_1"
15927 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15928 (mem:SI (match_operand:P 3 "register_operand" "1")))
15929 (set (match_operand:P 0 "register_operand" "=D")
15930 (plus:P (match_dup 2)
15932 (set (match_operand:P 1 "register_operand" "=S")
15933 (plus:P (match_dup 3)
15935 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15937 [(set_attr "type" "str")
15938 (set_attr "memory" "both")
15939 (set_attr "mode" "SI")])
15941 (define_insn "*strmovhi_1"
15942 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15943 (mem:HI (match_operand:P 3 "register_operand" "1")))
15944 (set (match_operand:P 0 "register_operand" "=D")
15945 (plus:P (match_dup 2)
15947 (set (match_operand:P 1 "register_operand" "=S")
15948 (plus:P (match_dup 3)
15950 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "both")
15954 (set_attr "mode" "HI")])
15956 (define_insn "*strmovqi_1"
15957 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15958 (mem:QI (match_operand:P 3 "register_operand" "1")))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (match_dup 2)
15962 (set (match_operand:P 1 "register_operand" "=S")
15963 (plus:P (match_dup 3)
15965 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "both")
15969 (set (attr "prefix_rex")
15971 (match_test "<P:MODE>mode == DImode")
15973 (const_string "*")))
15974 (set_attr "mode" "QI")])
15976 (define_expand "rep_mov"
15977 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15978 (set (match_operand 0 "register_operand")
15980 (set (match_operand 2 "register_operand")
15982 (set (match_operand 1 "memory_operand")
15983 (match_operand 3 "memory_operand"))
15984 (use (match_dup 4))])]
15986 "ix86_current_function_needs_cld = 1;")
15988 (define_insn "*rep_movdi_rex64"
15989 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15993 (match_operand:P 3 "register_operand" "0")))
15994 (set (match_operand:P 1 "register_operand" "=S")
15995 (plus:P (ashift:P (match_dup 5) (const_int 3))
15996 (match_operand:P 4 "register_operand" "1")))
15997 (set (mem:BLK (match_dup 3))
15998 (mem:BLK (match_dup 4)))
15999 (use (match_dup 5))]
16001 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16003 [(set_attr "type" "str")
16004 (set_attr "prefix_rep" "1")
16005 (set_attr "memory" "both")
16006 (set_attr "mode" "DI")])
16008 (define_insn "*rep_movsi"
16009 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16010 (set (match_operand:P 0 "register_operand" "=D")
16011 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16013 (match_operand:P 3 "register_operand" "0")))
16014 (set (match_operand:P 1 "register_operand" "=S")
16015 (plus:P (ashift:P (match_dup 5) (const_int 2))
16016 (match_operand:P 4 "register_operand" "1")))
16017 (set (mem:BLK (match_dup 3))
16018 (mem:BLK (match_dup 4)))
16019 (use (match_dup 5))]
16020 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16021 "%^rep{%;} movs{l|d}"
16022 [(set_attr "type" "str")
16023 (set_attr "prefix_rep" "1")
16024 (set_attr "memory" "both")
16025 (set_attr "mode" "SI")])
16027 (define_insn "*rep_movqi"
16028 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16029 (set (match_operand:P 0 "register_operand" "=D")
16030 (plus:P (match_operand:P 3 "register_operand" "0")
16031 (match_operand:P 5 "register_operand" "2")))
16032 (set (match_operand:P 1 "register_operand" "=S")
16033 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16034 (set (mem:BLK (match_dup 3))
16035 (mem:BLK (match_dup 4)))
16036 (use (match_dup 5))]
16037 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16039 [(set_attr "type" "str")
16040 (set_attr "prefix_rep" "1")
16041 (set_attr "memory" "both")
16042 (set_attr "mode" "QI")])
16044 (define_expand "setmem<mode>"
16045 [(use (match_operand:BLK 0 "memory_operand"))
16046 (use (match_operand:SWI48 1 "nonmemory_operand"))
16047 (use (match_operand:QI 2 "nonmemory_operand"))
16048 (use (match_operand 3 "const_int_operand"))
16049 (use (match_operand:SI 4 "const_int_operand"))
16050 (use (match_operand:SI 5 "const_int_operand"))
16051 (use (match_operand:SI 6 ""))
16052 (use (match_operand:SI 7 ""))
16053 (use (match_operand:SI 8 ""))]
16056 if (ix86_expand_set_or_movmem (operands[0], NULL,
16057 operands[1], operands[2],
16058 operands[3], operands[4],
16059 operands[5], operands[6],
16060 operands[7], operands[8], true))
16066 ;; Most CPUs don't like single string operations
16067 ;; Handle this case here to simplify previous expander.
16069 (define_expand "strset"
16070 [(set (match_operand 1 "memory_operand")
16071 (match_operand 2 "register_operand"))
16072 (parallel [(set (match_operand 0 "register_operand")
16074 (clobber (reg:CC FLAGS_REG))])]
16077 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16078 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16080 /* If .md ever supports :P for Pmode, this can be directly
16081 in the pattern above. */
16082 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16083 GEN_INT (GET_MODE_SIZE (GET_MODE
16085 /* Can't use this if the user has appropriated eax or edi. */
16086 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16087 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16089 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16095 (define_expand "strset_singleop"
16096 [(parallel [(set (match_operand 1 "memory_operand")
16097 (match_operand 2 "register_operand"))
16098 (set (match_operand 0 "register_operand")
16100 (unspec [(const_int 0)] UNSPEC_STOS)])]
16102 "ix86_current_function_needs_cld = 1;")
16104 (define_insn "*strsetdi_rex_1"
16105 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16106 (match_operand:DI 2 "register_operand" "a"))
16107 (set (match_operand:P 0 "register_operand" "=D")
16108 (plus:P (match_dup 1)
16110 (unspec [(const_int 0)] UNSPEC_STOS)]
16112 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16114 [(set_attr "type" "str")
16115 (set_attr "memory" "store")
16116 (set_attr "mode" "DI")])
16118 (define_insn "*strsetsi_1"
16119 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16120 (match_operand:SI 2 "register_operand" "a"))
16121 (set (match_operand:P 0 "register_operand" "=D")
16122 (plus:P (match_dup 1)
16124 (unspec [(const_int 0)] UNSPEC_STOS)]
16125 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16127 [(set_attr "type" "str")
16128 (set_attr "memory" "store")
16129 (set_attr "mode" "SI")])
16131 (define_insn "*strsethi_1"
16132 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16133 (match_operand:HI 2 "register_operand" "a"))
16134 (set (match_operand:P 0 "register_operand" "=D")
16135 (plus:P (match_dup 1)
16137 (unspec [(const_int 0)] UNSPEC_STOS)]
16138 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16140 [(set_attr "type" "str")
16141 (set_attr "memory" "store")
16142 (set_attr "mode" "HI")])
16144 (define_insn "*strsetqi_1"
16145 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16146 (match_operand:QI 2 "register_operand" "a"))
16147 (set (match_operand:P 0 "register_operand" "=D")
16148 (plus:P (match_dup 1)
16150 (unspec [(const_int 0)] UNSPEC_STOS)]
16151 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16153 [(set_attr "type" "str")
16154 (set_attr "memory" "store")
16155 (set (attr "prefix_rex")
16157 (match_test "<P:MODE>mode == DImode")
16159 (const_string "*")))
16160 (set_attr "mode" "QI")])
16162 (define_expand "rep_stos"
16163 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16164 (set (match_operand 0 "register_operand")
16166 (set (match_operand 2 "memory_operand") (const_int 0))
16167 (use (match_operand 3 "register_operand"))
16168 (use (match_dup 1))])]
16170 "ix86_current_function_needs_cld = 1;")
16172 (define_insn "*rep_stosdi_rex64"
16173 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16174 (set (match_operand:P 0 "register_operand" "=D")
16175 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16177 (match_operand:P 3 "register_operand" "0")))
16178 (set (mem:BLK (match_dup 3))
16180 (use (match_operand:DI 2 "register_operand" "a"))
16181 (use (match_dup 4))]
16183 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16185 [(set_attr "type" "str")
16186 (set_attr "prefix_rep" "1")
16187 (set_attr "memory" "store")
16188 (set_attr "mode" "DI")])
16190 (define_insn "*rep_stossi"
16191 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16192 (set (match_operand:P 0 "register_operand" "=D")
16193 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16195 (match_operand:P 3 "register_operand" "0")))
16196 (set (mem:BLK (match_dup 3))
16198 (use (match_operand:SI 2 "register_operand" "a"))
16199 (use (match_dup 4))]
16200 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16201 "%^rep{%;} stos{l|d}"
16202 [(set_attr "type" "str")
16203 (set_attr "prefix_rep" "1")
16204 (set_attr "memory" "store")
16205 (set_attr "mode" "SI")])
16207 (define_insn "*rep_stosqi"
16208 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16209 (set (match_operand:P 0 "register_operand" "=D")
16210 (plus:P (match_operand:P 3 "register_operand" "0")
16211 (match_operand:P 4 "register_operand" "1")))
16212 (set (mem:BLK (match_dup 3))
16214 (use (match_operand:QI 2 "register_operand" "a"))
16215 (use (match_dup 4))]
16216 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16218 [(set_attr "type" "str")
16219 (set_attr "prefix_rep" "1")
16220 (set_attr "memory" "store")
16221 (set (attr "prefix_rex")
16223 (match_test "<P:MODE>mode == DImode")
16225 (const_string "*")))
16226 (set_attr "mode" "QI")])
16228 (define_expand "cmpstrnsi"
16229 [(set (match_operand:SI 0 "register_operand")
16230 (compare:SI (match_operand:BLK 1 "general_operand")
16231 (match_operand:BLK 2 "general_operand")))
16232 (use (match_operand 3 "general_operand"))
16233 (use (match_operand 4 "immediate_operand"))]
16236 rtx addr1, addr2, out, outlow, count, countreg, align;
16238 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16241 /* Can't use this if the user has appropriated ecx, esi or edi. */
16242 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16247 out = gen_reg_rtx (SImode);
16249 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16250 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16251 if (addr1 != XEXP (operands[1], 0))
16252 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16253 if (addr2 != XEXP (operands[2], 0))
16254 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16256 count = operands[3];
16257 countreg = ix86_zero_extend_to_Pmode (count);
16259 /* %%% Iff we are testing strict equality, we can use known alignment
16260 to good advantage. This may be possible with combine, particularly
16261 once cc0 is dead. */
16262 align = operands[4];
16264 if (CONST_INT_P (count))
16266 if (INTVAL (count) == 0)
16268 emit_move_insn (operands[0], const0_rtx);
16271 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16272 operands[1], operands[2]));
16276 rtx (*gen_cmp) (rtx, rtx);
16278 gen_cmp = (TARGET_64BIT
16279 ? gen_cmpdi_1 : gen_cmpsi_1);
16281 emit_insn (gen_cmp (countreg, countreg));
16282 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16283 operands[1], operands[2]));
16286 outlow = gen_lowpart (QImode, out);
16287 emit_insn (gen_cmpintqi (outlow));
16288 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16290 if (operands[0] != out)
16291 emit_move_insn (operands[0], out);
16296 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16298 (define_expand "cmpintqi"
16299 [(set (match_dup 1)
16300 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16302 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16303 (parallel [(set (match_operand:QI 0 "register_operand")
16304 (minus:QI (match_dup 1)
16306 (clobber (reg:CC FLAGS_REG))])]
16309 operands[1] = gen_reg_rtx (QImode);
16310 operands[2] = gen_reg_rtx (QImode);
16313 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16314 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16316 (define_expand "cmpstrnqi_nz_1"
16317 [(parallel [(set (reg:CC FLAGS_REG)
16318 (compare:CC (match_operand 4 "memory_operand")
16319 (match_operand 5 "memory_operand")))
16320 (use (match_operand 2 "register_operand"))
16321 (use (match_operand:SI 3 "immediate_operand"))
16322 (clobber (match_operand 0 "register_operand"))
16323 (clobber (match_operand 1 "register_operand"))
16324 (clobber (match_dup 2))])]
16326 "ix86_current_function_needs_cld = 1;")
16328 (define_insn "*cmpstrnqi_nz_1"
16329 [(set (reg:CC FLAGS_REG)
16330 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16331 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16332 (use (match_operand:P 6 "register_operand" "2"))
16333 (use (match_operand:SI 3 "immediate_operand" "i"))
16334 (clobber (match_operand:P 0 "register_operand" "=S"))
16335 (clobber (match_operand:P 1 "register_operand" "=D"))
16336 (clobber (match_operand:P 2 "register_operand" "=c"))]
16337 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16339 [(set_attr "type" "str")
16340 (set_attr "mode" "QI")
16341 (set (attr "prefix_rex")
16343 (match_test "<P:MODE>mode == DImode")
16345 (const_string "*")))
16346 (set_attr "prefix_rep" "1")])
16348 ;; The same, but the count is not known to not be zero.
16350 (define_expand "cmpstrnqi_1"
16351 [(parallel [(set (reg:CC FLAGS_REG)
16352 (if_then_else:CC (ne (match_operand 2 "register_operand")
16354 (compare:CC (match_operand 4 "memory_operand")
16355 (match_operand 5 "memory_operand"))
16357 (use (match_operand:SI 3 "immediate_operand"))
16358 (use (reg:CC FLAGS_REG))
16359 (clobber (match_operand 0 "register_operand"))
16360 (clobber (match_operand 1 "register_operand"))
16361 (clobber (match_dup 2))])]
16363 "ix86_current_function_needs_cld = 1;")
16365 (define_insn "*cmpstrnqi_1"
16366 [(set (reg:CC FLAGS_REG)
16367 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16369 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16370 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16372 (use (match_operand:SI 3 "immediate_operand" "i"))
16373 (use (reg:CC FLAGS_REG))
16374 (clobber (match_operand:P 0 "register_operand" "=S"))
16375 (clobber (match_operand:P 1 "register_operand" "=D"))
16376 (clobber (match_operand:P 2 "register_operand" "=c"))]
16377 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16379 [(set_attr "type" "str")
16380 (set_attr "mode" "QI")
16381 (set (attr "prefix_rex")
16383 (match_test "<P:MODE>mode == DImode")
16385 (const_string "*")))
16386 (set_attr "prefix_rep" "1")])
16388 (define_expand "strlen<mode>"
16389 [(set (match_operand:P 0 "register_operand")
16390 (unspec:P [(match_operand:BLK 1 "general_operand")
16391 (match_operand:QI 2 "immediate_operand")
16392 (match_operand 3 "immediate_operand")]
16396 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16402 (define_expand "strlenqi_1"
16403 [(parallel [(set (match_operand 0 "register_operand")
16405 (clobber (match_operand 1 "register_operand"))
16406 (clobber (reg:CC FLAGS_REG))])]
16408 "ix86_current_function_needs_cld = 1;")
16410 (define_insn "*strlenqi_1"
16411 [(set (match_operand:P 0 "register_operand" "=&c")
16412 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16413 (match_operand:QI 2 "register_operand" "a")
16414 (match_operand:P 3 "immediate_operand" "i")
16415 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16416 (clobber (match_operand:P 1 "register_operand" "=D"))
16417 (clobber (reg:CC FLAGS_REG))]
16418 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16419 "%^repnz{%;} scasb"
16420 [(set_attr "type" "str")
16421 (set_attr "mode" "QI")
16422 (set (attr "prefix_rex")
16424 (match_test "<P:MODE>mode == DImode")
16426 (const_string "*")))
16427 (set_attr "prefix_rep" "1")])
16429 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16430 ;; handled in combine, but it is not currently up to the task.
16431 ;; When used for their truth value, the cmpstrn* expanders generate
16440 ;; The intermediate three instructions are unnecessary.
16442 ;; This one handles cmpstrn*_nz_1...
16445 (set (reg:CC FLAGS_REG)
16446 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16447 (mem:BLK (match_operand 5 "register_operand"))))
16448 (use (match_operand 6 "register_operand"))
16449 (use (match_operand:SI 3 "immediate_operand"))
16450 (clobber (match_operand 0 "register_operand"))
16451 (clobber (match_operand 1 "register_operand"))
16452 (clobber (match_operand 2 "register_operand"))])
16453 (set (match_operand:QI 7 "register_operand")
16454 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16455 (set (match_operand:QI 8 "register_operand")
16456 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16457 (set (reg FLAGS_REG)
16458 (compare (match_dup 7) (match_dup 8)))
16460 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16462 (set (reg:CC FLAGS_REG)
16463 (compare:CC (mem:BLK (match_dup 4))
16464 (mem:BLK (match_dup 5))))
16465 (use (match_dup 6))
16466 (use (match_dup 3))
16467 (clobber (match_dup 0))
16468 (clobber (match_dup 1))
16469 (clobber (match_dup 2))])])
16471 ;; ...and this one handles cmpstrn*_1.
16474 (set (reg:CC FLAGS_REG)
16475 (if_then_else:CC (ne (match_operand 6 "register_operand")
16477 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16478 (mem:BLK (match_operand 5 "register_operand")))
16480 (use (match_operand:SI 3 "immediate_operand"))
16481 (use (reg:CC FLAGS_REG))
16482 (clobber (match_operand 0 "register_operand"))
16483 (clobber (match_operand 1 "register_operand"))
16484 (clobber (match_operand 2 "register_operand"))])
16485 (set (match_operand:QI 7 "register_operand")
16486 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16487 (set (match_operand:QI 8 "register_operand")
16488 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16489 (set (reg FLAGS_REG)
16490 (compare (match_dup 7) (match_dup 8)))
16492 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16494 (set (reg:CC FLAGS_REG)
16495 (if_then_else:CC (ne (match_dup 6)
16497 (compare:CC (mem:BLK (match_dup 4))
16498 (mem:BLK (match_dup 5)))
16500 (use (match_dup 3))
16501 (use (reg:CC FLAGS_REG))
16502 (clobber (match_dup 0))
16503 (clobber (match_dup 1))
16504 (clobber (match_dup 2))])])
16506 ;; Conditional move instructions.
16508 (define_expand "mov<mode>cc"
16509 [(set (match_operand:SWIM 0 "register_operand")
16510 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16511 (match_operand:SWIM 2 "<general_operand>")
16512 (match_operand:SWIM 3 "<general_operand>")))]
16514 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16516 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16517 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16518 ;; So just document what we're doing explicitly.
16520 (define_expand "x86_mov<mode>cc_0_m1"
16522 [(set (match_operand:SWI48 0 "register_operand")
16523 (if_then_else:SWI48
16524 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16525 [(match_operand 1 "flags_reg_operand")
16529 (clobber (reg:CC FLAGS_REG))])])
16531 (define_insn "*x86_mov<mode>cc_0_m1"
16532 [(set (match_operand:SWI48 0 "register_operand" "=r")
16533 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16534 [(reg FLAGS_REG) (const_int 0)])
16537 (clobber (reg:CC FLAGS_REG))]
16539 "sbb{<imodesuffix>}\t%0, %0"
16540 ; Since we don't have the proper number of operands for an alu insn,
16541 ; fill in all the blanks.
16542 [(set_attr "type" "alu")
16543 (set_attr "use_carry" "1")
16544 (set_attr "pent_pair" "pu")
16545 (set_attr "memory" "none")
16546 (set_attr "imm_disp" "false")
16547 (set_attr "mode" "<MODE>")
16548 (set_attr "length_immediate" "0")])
16550 (define_insn "*x86_mov<mode>cc_0_m1_se"
16551 [(set (match_operand:SWI48 0 "register_operand" "=r")
16552 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16556 (clobber (reg:CC FLAGS_REG))]
16558 "sbb{<imodesuffix>}\t%0, %0"
16559 [(set_attr "type" "alu")
16560 (set_attr "use_carry" "1")
16561 (set_attr "pent_pair" "pu")
16562 (set_attr "memory" "none")
16563 (set_attr "imm_disp" "false")
16564 (set_attr "mode" "<MODE>")
16565 (set_attr "length_immediate" "0")])
16567 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16568 [(set (match_operand:SWI48 0 "register_operand" "=r")
16569 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16570 [(reg FLAGS_REG) (const_int 0)])))
16571 (clobber (reg:CC FLAGS_REG))]
16573 "sbb{<imodesuffix>}\t%0, %0"
16574 [(set_attr "type" "alu")
16575 (set_attr "use_carry" "1")
16576 (set_attr "pent_pair" "pu")
16577 (set_attr "memory" "none")
16578 (set_attr "imm_disp" "false")
16579 (set_attr "mode" "<MODE>")
16580 (set_attr "length_immediate" "0")])
16582 (define_insn "*mov<mode>cc_noc"
16583 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16584 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16585 [(reg FLAGS_REG) (const_int 0)])
16586 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16587 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16588 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16590 cmov%O2%C1\t{%2, %0|%0, %2}
16591 cmov%O2%c1\t{%3, %0|%0, %3}"
16592 [(set_attr "type" "icmov")
16593 (set_attr "mode" "<MODE>")])
16595 ;; Don't do conditional moves with memory inputs. This splitter helps
16596 ;; register starved x86_32 by forcing inputs into registers before reload.
16598 [(set (match_operand:SWI248 0 "register_operand")
16599 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16600 [(reg FLAGS_REG) (const_int 0)])
16601 (match_operand:SWI248 2 "nonimmediate_operand")
16602 (match_operand:SWI248 3 "nonimmediate_operand")))]
16603 "!TARGET_64BIT && TARGET_CMOVE
16604 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16605 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16606 && can_create_pseudo_p ()
16607 && optimize_insn_for_speed_p ()"
16608 [(set (match_dup 0)
16609 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16611 if (MEM_P (operands[2]))
16612 operands[2] = force_reg (<MODE>mode, operands[2]);
16613 if (MEM_P (operands[3]))
16614 operands[3] = force_reg (<MODE>mode, operands[3]);
16617 (define_insn "*movqicc_noc"
16618 [(set (match_operand:QI 0 "register_operand" "=r,r")
16619 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16620 [(reg FLAGS_REG) (const_int 0)])
16621 (match_operand:QI 2 "register_operand" "r,0")
16622 (match_operand:QI 3 "register_operand" "0,r")))]
16623 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16625 [(set_attr "type" "icmov")
16626 (set_attr "mode" "QI")])
16629 [(set (match_operand:SWI12 0 "register_operand")
16630 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16631 [(reg FLAGS_REG) (const_int 0)])
16632 (match_operand:SWI12 2 "register_operand")
16633 (match_operand:SWI12 3 "register_operand")))]
16634 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16635 && reload_completed"
16636 [(set (match_dup 0)
16637 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16639 operands[0] = gen_lowpart (SImode, operands[0]);
16640 operands[2] = gen_lowpart (SImode, operands[2]);
16641 operands[3] = gen_lowpart (SImode, operands[3]);
16644 ;; Don't do conditional moves with memory inputs
16646 [(match_scratch:SWI248 2 "r")
16647 (set (match_operand:SWI248 0 "register_operand")
16648 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16649 [(reg FLAGS_REG) (const_int 0)])
16651 (match_operand:SWI248 3 "memory_operand")))]
16652 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16653 && optimize_insn_for_speed_p ()"
16654 [(set (match_dup 2) (match_dup 3))
16656 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16659 [(match_scratch:SWI248 2 "r")
16660 (set (match_operand:SWI248 0 "register_operand")
16661 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16662 [(reg FLAGS_REG) (const_int 0)])
16663 (match_operand:SWI248 3 "memory_operand")
16665 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16666 && optimize_insn_for_speed_p ()"
16667 [(set (match_dup 2) (match_dup 3))
16669 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16671 (define_expand "mov<mode>cc"
16672 [(set (match_operand:X87MODEF 0 "register_operand")
16673 (if_then_else:X87MODEF
16674 (match_operand 1 "comparison_operator")
16675 (match_operand:X87MODEF 2 "register_operand")
16676 (match_operand:X87MODEF 3 "register_operand")))]
16677 "(TARGET_80387 && TARGET_CMOVE)
16678 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16679 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16681 (define_insn "*movxfcc_1"
16682 [(set (match_operand:XF 0 "register_operand" "=f,f")
16683 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16684 [(reg FLAGS_REG) (const_int 0)])
16685 (match_operand:XF 2 "register_operand" "f,0")
16686 (match_operand:XF 3 "register_operand" "0,f")))]
16687 "TARGET_80387 && TARGET_CMOVE"
16689 fcmov%F1\t{%2, %0|%0, %2}
16690 fcmov%f1\t{%3, %0|%0, %3}"
16691 [(set_attr "type" "fcmov")
16692 (set_attr "mode" "XF")])
16694 (define_insn "*movdfcc_1"
16695 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16696 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16697 [(reg FLAGS_REG) (const_int 0)])
16698 (match_operand:DF 2 "nonimmediate_operand"
16700 (match_operand:DF 3 "nonimmediate_operand"
16701 "0 ,f,0 ,rm,0, rm")))]
16702 "TARGET_80387 && TARGET_CMOVE
16703 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16705 fcmov%F1\t{%2, %0|%0, %2}
16706 fcmov%f1\t{%3, %0|%0, %3}
16709 cmov%O2%C1\t{%2, %0|%0, %2}
16710 cmov%O2%c1\t{%3, %0|%0, %3}"
16711 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16712 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16713 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16716 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16717 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16718 [(reg FLAGS_REG) (const_int 0)])
16719 (match_operand:DF 2 "nonimmediate_operand")
16720 (match_operand:DF 3 "nonimmediate_operand")))]
16721 "!TARGET_64BIT && reload_completed"
16722 [(set (match_dup 2)
16723 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16725 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16727 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16728 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16731 (define_insn "*movsfcc_1_387"
16732 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16733 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16734 [(reg FLAGS_REG) (const_int 0)])
16735 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16736 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16737 "TARGET_80387 && TARGET_CMOVE
16738 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16740 fcmov%F1\t{%2, %0|%0, %2}
16741 fcmov%f1\t{%3, %0|%0, %3}
16742 cmov%O2%C1\t{%2, %0|%0, %2}
16743 cmov%O2%c1\t{%3, %0|%0, %3}"
16744 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16745 (set_attr "mode" "SF,SF,SI,SI")])
16747 ;; Don't do conditional moves with memory inputs. This splitter helps
16748 ;; register starved x86_32 by forcing inputs into registers before reload.
16750 [(set (match_operand:MODEF 0 "register_operand")
16751 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16752 [(reg FLAGS_REG) (const_int 0)])
16753 (match_operand:MODEF 2 "nonimmediate_operand")
16754 (match_operand:MODEF 3 "nonimmediate_operand")))]
16755 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16756 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16757 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16758 && can_create_pseudo_p ()
16759 && optimize_insn_for_speed_p ()"
16760 [(set (match_dup 0)
16761 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16763 if (MEM_P (operands[2]))
16764 operands[2] = force_reg (<MODE>mode, operands[2]);
16765 if (MEM_P (operands[3]))
16766 operands[3] = force_reg (<MODE>mode, operands[3]);
16769 ;; Don't do conditional moves with memory inputs
16771 [(match_scratch:MODEF 2 "r")
16772 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16773 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16774 [(reg FLAGS_REG) (const_int 0)])
16776 (match_operand:MODEF 3 "memory_operand")))]
16777 "(<MODE>mode != DFmode || TARGET_64BIT)
16778 && TARGET_80387 && TARGET_CMOVE
16779 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16780 && optimize_insn_for_speed_p ()"
16781 [(set (match_dup 2) (match_dup 3))
16783 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16786 [(match_scratch:MODEF 2 "r")
16787 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16788 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16789 [(reg FLAGS_REG) (const_int 0)])
16790 (match_operand:MODEF 3 "memory_operand")
16792 "(<MODE>mode != DFmode || TARGET_64BIT)
16793 && TARGET_80387 && TARGET_CMOVE
16794 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16795 && optimize_insn_for_speed_p ()"
16796 [(set (match_dup 2) (match_dup 3))
16798 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16800 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16801 ;; the scalar versions to have only XMM registers as operands.
16803 ;; XOP conditional move
16804 (define_insn "*xop_pcmov_<mode>"
16805 [(set (match_operand:MODEF 0 "register_operand" "=x")
16806 (if_then_else:MODEF
16807 (match_operand:MODEF 1 "register_operand" "x")
16808 (match_operand:MODEF 2 "register_operand" "x")
16809 (match_operand:MODEF 3 "register_operand" "x")))]
16811 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16812 [(set_attr "type" "sse4arg")])
16814 ;; These versions of the min/max patterns are intentionally ignorant of
16815 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16816 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16817 ;; are undefined in this condition, we're certain this is correct.
16819 (define_insn "<code><mode>3"
16820 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16822 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16823 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16824 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16826 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16827 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16828 [(set_attr "isa" "noavx,avx")
16829 (set_attr "prefix" "orig,vex")
16830 (set_attr "type" "sseadd")
16831 (set_attr "mode" "<MODE>")])
16833 ;; These versions of the min/max patterns implement exactly the operations
16834 ;; min = (op1 < op2 ? op1 : op2)
16835 ;; max = (!(op1 < op2) ? op1 : op2)
16836 ;; Their operands are not commutative, and thus they may be used in the
16837 ;; presence of -0.0 and NaN.
16839 (define_int_iterator IEEE_MAXMIN
16843 (define_int_attr ieee_maxmin
16844 [(UNSPEC_IEEE_MAX "max")
16845 (UNSPEC_IEEE_MIN "min")])
16847 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16848 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16850 [(match_operand:MODEF 1 "register_operand" "0,x")
16851 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16853 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16855 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16856 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16857 [(set_attr "isa" "noavx,avx")
16858 (set_attr "prefix" "orig,vex")
16859 (set_attr "type" "sseadd")
16860 (set_attr "mode" "<MODE>")])
16862 ;; Make two stack loads independent:
16864 ;; fld %st(0) -> fld bb
16865 ;; fmul bb fmul %st(1), %st
16867 ;; Actually we only match the last two instructions for simplicity.
16869 [(set (match_operand 0 "fp_register_operand")
16870 (match_operand 1 "fp_register_operand"))
16872 (match_operator 2 "binary_fp_operator"
16874 (match_operand 3 "memory_operand")]))]
16875 "REGNO (operands[0]) != REGNO (operands[1])"
16876 [(set (match_dup 0) (match_dup 3))
16877 (set (match_dup 0) (match_dup 4))]
16879 ;; The % modifier is not operational anymore in peephole2's, so we have to
16880 ;; swap the operands manually in the case of addition and multiplication.
16884 if (COMMUTATIVE_ARITH_P (operands[2]))
16885 op0 = operands[0], op1 = operands[1];
16887 op0 = operands[1], op1 = operands[0];
16889 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16890 GET_MODE (operands[2]),
16894 ;; Conditional addition patterns
16895 (define_expand "add<mode>cc"
16896 [(match_operand:SWI 0 "register_operand")
16897 (match_operand 1 "ordered_comparison_operator")
16898 (match_operand:SWI 2 "register_operand")
16899 (match_operand:SWI 3 "const_int_operand")]
16901 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16903 ;; Misc patterns (?)
16905 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16906 ;; Otherwise there will be nothing to keep
16908 ;; [(set (reg ebp) (reg esp))]
16909 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16910 ;; (clobber (eflags)]
16911 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16913 ;; in proper program order.
16915 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16916 [(set (match_operand:P 0 "register_operand" "=r,r")
16917 (plus:P (match_operand:P 1 "register_operand" "0,r")
16918 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16919 (clobber (reg:CC FLAGS_REG))
16920 (clobber (mem:BLK (scratch)))]
16923 switch (get_attr_type (insn))
16926 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16930 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16931 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16933 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16936 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16937 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16940 [(set (attr "type")
16941 (cond [(and (eq_attr "alternative" "0")
16942 (not (match_test "TARGET_OPT_AGU")))
16943 (const_string "alu")
16944 (match_operand:<MODE> 2 "const0_operand")
16945 (const_string "imov")
16947 (const_string "lea")))
16948 (set (attr "length_immediate")
16949 (cond [(eq_attr "type" "imov")
16951 (and (eq_attr "type" "alu")
16952 (match_operand 2 "const128_operand"))
16955 (const_string "*")))
16956 (set_attr "mode" "<MODE>")])
16958 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16959 [(set (match_operand:P 0 "register_operand" "=r")
16960 (minus:P (match_operand:P 1 "register_operand" "0")
16961 (match_operand:P 2 "register_operand" "r")))
16962 (clobber (reg:CC FLAGS_REG))
16963 (clobber (mem:BLK (scratch)))]
16965 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16966 [(set_attr "type" "alu")
16967 (set_attr "mode" "<MODE>")])
16969 (define_insn "allocate_stack_worker_probe_<mode>"
16970 [(set (match_operand:P 0 "register_operand" "=a")
16971 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16972 UNSPECV_STACK_PROBE))
16973 (clobber (reg:CC FLAGS_REG))]
16974 "ix86_target_stack_probe ()"
16975 "call\t___chkstk_ms"
16976 [(set_attr "type" "multi")
16977 (set_attr "length" "5")])
16979 (define_expand "allocate_stack"
16980 [(match_operand 0 "register_operand")
16981 (match_operand 1 "general_operand")]
16982 "ix86_target_stack_probe ()"
16986 #ifndef CHECK_STACK_LIMIT
16987 #define CHECK_STACK_LIMIT 0
16990 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16991 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16995 rtx (*insn) (rtx, rtx);
16997 x = copy_to_mode_reg (Pmode, operands[1]);
16999 insn = (TARGET_64BIT
17000 ? gen_allocate_stack_worker_probe_di
17001 : gen_allocate_stack_worker_probe_si);
17003 emit_insn (insn (x, x));
17006 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17007 stack_pointer_rtx, 0, OPTAB_DIRECT);
17009 if (x != stack_pointer_rtx)
17010 emit_move_insn (stack_pointer_rtx, x);
17012 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17016 ;; Use IOR for stack probes, this is shorter.
17017 (define_expand "probe_stack"
17018 [(match_operand 0 "memory_operand")]
17021 rtx (*gen_ior3) (rtx, rtx, rtx);
17023 gen_ior3 = (GET_MODE (operands[0]) == DImode
17024 ? gen_iordi3 : gen_iorsi3);
17026 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17030 (define_insn "adjust_stack_and_probe<mode>"
17031 [(set (match_operand:P 0 "register_operand" "=r")
17032 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17033 UNSPECV_PROBE_STACK_RANGE))
17034 (set (reg:P SP_REG)
17035 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17036 (clobber (reg:CC FLAGS_REG))
17037 (clobber (mem:BLK (scratch)))]
17039 "* return output_adjust_stack_and_probe (operands[0]);"
17040 [(set_attr "type" "multi")])
17042 (define_insn "probe_stack_range<mode>"
17043 [(set (match_operand:P 0 "register_operand" "=r")
17044 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17045 (match_operand:P 2 "const_int_operand" "n")]
17046 UNSPECV_PROBE_STACK_RANGE))
17047 (clobber (reg:CC FLAGS_REG))]
17049 "* return output_probe_stack_range (operands[0], operands[2]);"
17050 [(set_attr "type" "multi")])
17052 (define_expand "builtin_setjmp_receiver"
17053 [(label_ref (match_operand 0))]
17054 "!TARGET_64BIT && flag_pic"
17060 rtx_code_label *label_rtx = gen_label_rtx ();
17061 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17062 xops[0] = xops[1] = pic_offset_table_rtx;
17063 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17064 ix86_expand_binary_operator (MINUS, SImode, xops);
17068 emit_insn (gen_set_got (pic_offset_table_rtx));
17072 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17073 ;; Do not split instructions with mask registers.
17075 [(set (match_operand 0 "general_reg_operand")
17076 (match_operator 3 "promotable_binary_operator"
17077 [(match_operand 1 "general_reg_operand")
17078 (match_operand 2 "aligned_operand")]))
17079 (clobber (reg:CC FLAGS_REG))]
17080 "! TARGET_PARTIAL_REG_STALL && reload_completed
17081 && ((GET_MODE (operands[0]) == HImode
17082 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17083 /* ??? next two lines just !satisfies_constraint_K (...) */
17084 || !CONST_INT_P (operands[2])
17085 || satisfies_constraint_K (operands[2])))
17086 || (GET_MODE (operands[0]) == QImode
17087 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17088 [(parallel [(set (match_dup 0)
17089 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17090 (clobber (reg:CC FLAGS_REG))])]
17092 operands[0] = gen_lowpart (SImode, operands[0]);
17093 operands[1] = gen_lowpart (SImode, operands[1]);
17094 if (GET_CODE (operands[3]) != ASHIFT)
17095 operands[2] = gen_lowpart (SImode, operands[2]);
17096 PUT_MODE (operands[3], SImode);
17099 ; Promote the QImode tests, as i386 has encoding of the AND
17100 ; instruction with 32-bit sign-extended immediate and thus the
17101 ; instruction size is unchanged, except in the %eax case for
17102 ; which it is increased by one byte, hence the ! optimize_size.
17104 [(set (match_operand 0 "flags_reg_operand")
17105 (match_operator 2 "compare_operator"
17106 [(and (match_operand 3 "aligned_operand")
17107 (match_operand 4 "const_int_operand"))
17109 (set (match_operand 1 "register_operand")
17110 (and (match_dup 3) (match_dup 4)))]
17111 "! TARGET_PARTIAL_REG_STALL && reload_completed
17112 && optimize_insn_for_speed_p ()
17113 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17114 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17115 /* Ensure that the operand will remain sign-extended immediate. */
17116 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17117 [(parallel [(set (match_dup 0)
17118 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17121 (and:SI (match_dup 3) (match_dup 4)))])]
17124 = gen_int_mode (INTVAL (operands[4])
17125 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17126 operands[1] = gen_lowpart (SImode, operands[1]);
17127 operands[3] = gen_lowpart (SImode, operands[3]);
17130 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17131 ; the TEST instruction with 32-bit sign-extended immediate and thus
17132 ; the instruction size would at least double, which is not what we
17133 ; want even with ! optimize_size.
17135 [(set (match_operand 0 "flags_reg_operand")
17136 (match_operator 1 "compare_operator"
17137 [(and (match_operand:HI 2 "aligned_operand")
17138 (match_operand:HI 3 "const_int_operand"))
17140 "! TARGET_PARTIAL_REG_STALL && reload_completed
17141 && ! TARGET_FAST_PREFIX
17142 && optimize_insn_for_speed_p ()
17143 /* Ensure that the operand will remain sign-extended immediate. */
17144 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17145 [(set (match_dup 0)
17146 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17150 = gen_int_mode (INTVAL (operands[3])
17151 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17152 operands[2] = gen_lowpart (SImode, operands[2]);
17156 [(set (match_operand 0 "register_operand")
17157 (neg (match_operand 1 "register_operand")))
17158 (clobber (reg:CC FLAGS_REG))]
17159 "! TARGET_PARTIAL_REG_STALL && reload_completed
17160 && (GET_MODE (operands[0]) == HImode
17161 || (GET_MODE (operands[0]) == QImode
17162 && (TARGET_PROMOTE_QImode
17163 || optimize_insn_for_size_p ())))"
17164 [(parallel [(set (match_dup 0)
17165 (neg:SI (match_dup 1)))
17166 (clobber (reg:CC FLAGS_REG))])]
17168 operands[0] = gen_lowpart (SImode, operands[0]);
17169 operands[1] = gen_lowpart (SImode, operands[1]);
17172 ;; Do not split instructions with mask regs.
17174 [(set (match_operand 0 "general_reg_operand")
17175 (not (match_operand 1 "general_reg_operand")))]
17176 "! TARGET_PARTIAL_REG_STALL && reload_completed
17177 && (GET_MODE (operands[0]) == HImode
17178 || (GET_MODE (operands[0]) == QImode
17179 && (TARGET_PROMOTE_QImode
17180 || optimize_insn_for_size_p ())))"
17181 [(set (match_dup 0)
17182 (not:SI (match_dup 1)))]
17184 operands[0] = gen_lowpart (SImode, operands[0]);
17185 operands[1] = gen_lowpart (SImode, operands[1]);
17188 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17189 ;; transform a complex memory operation into two memory to register operations.
17191 ;; Don't push memory operands
17193 [(set (match_operand:SWI 0 "push_operand")
17194 (match_operand:SWI 1 "memory_operand"))
17195 (match_scratch:SWI 2 "<r>")]
17196 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17197 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17198 [(set (match_dup 2) (match_dup 1))
17199 (set (match_dup 0) (match_dup 2))])
17201 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17204 [(set (match_operand:SF 0 "push_operand")
17205 (match_operand:SF 1 "memory_operand"))
17206 (match_scratch:SF 2 "r")]
17207 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17208 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17209 [(set (match_dup 2) (match_dup 1))
17210 (set (match_dup 0) (match_dup 2))])
17212 ;; Don't move an immediate directly to memory when the instruction
17213 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17215 [(match_scratch:SWI124 1 "<r>")
17216 (set (match_operand:SWI124 0 "memory_operand")
17218 "optimize_insn_for_speed_p ()
17219 && ((<MODE>mode == HImode
17220 && TARGET_LCP_STALL)
17221 || (!TARGET_USE_MOV0
17222 && TARGET_SPLIT_LONG_MOVES
17223 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17224 && peep2_regno_dead_p (0, FLAGS_REG)"
17225 [(parallel [(set (match_dup 2) (const_int 0))
17226 (clobber (reg:CC FLAGS_REG))])
17227 (set (match_dup 0) (match_dup 1))]
17228 "operands[2] = gen_lowpart (SImode, operands[1]);")
17231 [(match_scratch:SWI124 2 "<r>")
17232 (set (match_operand:SWI124 0 "memory_operand")
17233 (match_operand:SWI124 1 "immediate_operand"))]
17234 "optimize_insn_for_speed_p ()
17235 && ((<MODE>mode == HImode
17236 && TARGET_LCP_STALL)
17237 || (TARGET_SPLIT_LONG_MOVES
17238 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17239 [(set (match_dup 2) (match_dup 1))
17240 (set (match_dup 0) (match_dup 2))])
17242 ;; Don't compare memory with zero, load and use a test instead.
17244 [(set (match_operand 0 "flags_reg_operand")
17245 (match_operator 1 "compare_operator"
17246 [(match_operand:SI 2 "memory_operand")
17248 (match_scratch:SI 3 "r")]
17249 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17250 [(set (match_dup 3) (match_dup 2))
17251 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17253 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17254 ;; Don't split NOTs with a displacement operand, because resulting XOR
17255 ;; will not be pairable anyway.
17257 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17258 ;; represented using a modRM byte. The XOR replacement is long decoded,
17259 ;; so this split helps here as well.
17261 ;; Note: Can't do this as a regular split because we can't get proper
17262 ;; lifetime information then.
17265 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17266 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17267 "optimize_insn_for_speed_p ()
17268 && ((TARGET_NOT_UNPAIRABLE
17269 && (!MEM_P (operands[0])
17270 || !memory_displacement_operand (operands[0], <MODE>mode)))
17271 || (TARGET_NOT_VECTORMODE
17272 && long_memory_operand (operands[0], <MODE>mode)))
17273 && peep2_regno_dead_p (0, FLAGS_REG)"
17274 [(parallel [(set (match_dup 0)
17275 (xor:SWI124 (match_dup 1) (const_int -1)))
17276 (clobber (reg:CC FLAGS_REG))])])
17278 ;; Non pairable "test imm, reg" instructions can be translated to
17279 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17280 ;; byte opcode instead of two, have a short form for byte operands),
17281 ;; so do it for other CPUs as well. Given that the value was dead,
17282 ;; this should not create any new dependencies. Pass on the sub-word
17283 ;; versions if we're concerned about partial register stalls.
17286 [(set (match_operand 0 "flags_reg_operand")
17287 (match_operator 1 "compare_operator"
17288 [(and:SI (match_operand:SI 2 "register_operand")
17289 (match_operand:SI 3 "immediate_operand"))
17291 "ix86_match_ccmode (insn, CCNOmode)
17292 && (true_regnum (operands[2]) != AX_REG
17293 || satisfies_constraint_K (operands[3]))
17294 && peep2_reg_dead_p (1, operands[2])"
17296 [(set (match_dup 0)
17297 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17300 (and:SI (match_dup 2) (match_dup 3)))])])
17302 ;; We don't need to handle HImode case, because it will be promoted to SImode
17303 ;; on ! TARGET_PARTIAL_REG_STALL
17306 [(set (match_operand 0 "flags_reg_operand")
17307 (match_operator 1 "compare_operator"
17308 [(and:QI (match_operand:QI 2 "register_operand")
17309 (match_operand:QI 3 "immediate_operand"))
17311 "! TARGET_PARTIAL_REG_STALL
17312 && ix86_match_ccmode (insn, CCNOmode)
17313 && true_regnum (operands[2]) != AX_REG
17314 && peep2_reg_dead_p (1, operands[2])"
17316 [(set (match_dup 0)
17317 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17320 (and:QI (match_dup 2) (match_dup 3)))])])
17323 [(set (match_operand 0 "flags_reg_operand")
17324 (match_operator 1 "compare_operator"
17327 (match_operand 2 "ext_register_operand")
17330 (match_operand 3 "const_int_operand"))
17332 "! TARGET_PARTIAL_REG_STALL
17333 && ix86_match_ccmode (insn, CCNOmode)
17334 && true_regnum (operands[2]) != AX_REG
17335 && peep2_reg_dead_p (1, operands[2])"
17336 [(parallel [(set (match_dup 0)
17345 (set (zero_extract:SI (match_dup 2)
17353 (match_dup 3)))])])
17355 ;; Don't do logical operations with memory inputs.
17357 [(match_scratch:SI 2 "r")
17358 (parallel [(set (match_operand:SI 0 "register_operand")
17359 (match_operator:SI 3 "arith_or_logical_operator"
17361 (match_operand:SI 1 "memory_operand")]))
17362 (clobber (reg:CC FLAGS_REG))])]
17363 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17364 [(set (match_dup 2) (match_dup 1))
17365 (parallel [(set (match_dup 0)
17366 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17367 (clobber (reg:CC FLAGS_REG))])])
17370 [(match_scratch:SI 2 "r")
17371 (parallel [(set (match_operand:SI 0 "register_operand")
17372 (match_operator:SI 3 "arith_or_logical_operator"
17373 [(match_operand:SI 1 "memory_operand")
17375 (clobber (reg:CC FLAGS_REG))])]
17376 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17377 [(set (match_dup 2) (match_dup 1))
17378 (parallel [(set (match_dup 0)
17379 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17380 (clobber (reg:CC FLAGS_REG))])])
17382 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17383 ;; refers to the destination of the load!
17386 [(set (match_operand:SI 0 "register_operand")
17387 (match_operand:SI 1 "register_operand"))
17388 (parallel [(set (match_dup 0)
17389 (match_operator:SI 3 "commutative_operator"
17391 (match_operand:SI 2 "memory_operand")]))
17392 (clobber (reg:CC FLAGS_REG))])]
17393 "REGNO (operands[0]) != REGNO (operands[1])
17394 && GENERAL_REGNO_P (REGNO (operands[0]))
17395 && GENERAL_REGNO_P (REGNO (operands[1]))"
17396 [(set (match_dup 0) (match_dup 4))
17397 (parallel [(set (match_dup 0)
17398 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17403 [(set (match_operand 0 "register_operand")
17404 (match_operand 1 "register_operand"))
17406 (match_operator 3 "commutative_operator"
17408 (match_operand 2 "memory_operand")]))]
17409 "REGNO (operands[0]) != REGNO (operands[1])
17410 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17411 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17412 [(set (match_dup 0) (match_dup 2))
17414 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17416 ; Don't do logical operations with memory outputs
17418 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17419 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17420 ; the same decoder scheduling characteristics as the original.
17423 [(match_scratch:SI 2 "r")
17424 (parallel [(set (match_operand:SI 0 "memory_operand")
17425 (match_operator:SI 3 "arith_or_logical_operator"
17427 (match_operand:SI 1 "nonmemory_operand")]))
17428 (clobber (reg:CC FLAGS_REG))])]
17429 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17430 /* Do not split stack checking probes. */
17431 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17432 [(set (match_dup 2) (match_dup 0))
17433 (parallel [(set (match_dup 2)
17434 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17435 (clobber (reg:CC FLAGS_REG))])
17436 (set (match_dup 0) (match_dup 2))])
17439 [(match_scratch:SI 2 "r")
17440 (parallel [(set (match_operand:SI 0 "memory_operand")
17441 (match_operator:SI 3 "arith_or_logical_operator"
17442 [(match_operand:SI 1 "nonmemory_operand")
17444 (clobber (reg:CC FLAGS_REG))])]
17445 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17446 /* Do not split stack checking probes. */
17447 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17448 [(set (match_dup 2) (match_dup 0))
17449 (parallel [(set (match_dup 2)
17450 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17451 (clobber (reg:CC FLAGS_REG))])
17452 (set (match_dup 0) (match_dup 2))])
17454 ;; Attempt to use arith or logical operations with memory outputs with
17455 ;; setting of flags.
17457 [(set (match_operand:SWI 0 "register_operand")
17458 (match_operand:SWI 1 "memory_operand"))
17459 (parallel [(set (match_dup 0)
17460 (match_operator:SWI 3 "plusminuslogic_operator"
17462 (match_operand:SWI 2 "<nonmemory_operand>")]))
17463 (clobber (reg:CC FLAGS_REG))])
17464 (set (match_dup 1) (match_dup 0))
17465 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17466 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17467 && peep2_reg_dead_p (4, operands[0])
17468 && !reg_overlap_mentioned_p (operands[0], operands[1])
17469 && !reg_overlap_mentioned_p (operands[0], operands[2])
17470 && (<MODE>mode != QImode
17471 || immediate_operand (operands[2], QImode)
17472 || q_regs_operand (operands[2], QImode))
17473 && ix86_match_ccmode (peep2_next_insn (3),
17474 (GET_CODE (operands[3]) == PLUS
17475 || GET_CODE (operands[3]) == MINUS)
17476 ? CCGOCmode : CCNOmode)"
17477 [(parallel [(set (match_dup 4) (match_dup 5))
17478 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17479 (match_dup 2)]))])]
17481 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17482 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17483 copy_rtx (operands[1]),
17484 copy_rtx (operands[2]));
17485 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17486 operands[5], const0_rtx);
17490 [(parallel [(set (match_operand:SWI 0 "register_operand")
17491 (match_operator:SWI 2 "plusminuslogic_operator"
17493 (match_operand:SWI 1 "memory_operand")]))
17494 (clobber (reg:CC FLAGS_REG))])
17495 (set (match_dup 1) (match_dup 0))
17496 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17497 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17498 && GET_CODE (operands[2]) != MINUS
17499 && peep2_reg_dead_p (3, operands[0])
17500 && !reg_overlap_mentioned_p (operands[0], operands[1])
17501 && ix86_match_ccmode (peep2_next_insn (2),
17502 GET_CODE (operands[2]) == PLUS
17503 ? CCGOCmode : CCNOmode)"
17504 [(parallel [(set (match_dup 3) (match_dup 4))
17505 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17506 (match_dup 0)]))])]
17508 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17509 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17510 copy_rtx (operands[1]),
17511 copy_rtx (operands[0]));
17512 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17513 operands[4], const0_rtx);
17517 [(set (match_operand:SWI12 0 "register_operand")
17518 (match_operand:SWI12 1 "memory_operand"))
17519 (parallel [(set (match_operand:SI 4 "register_operand")
17520 (match_operator:SI 3 "plusminuslogic_operator"
17522 (match_operand:SI 2 "nonmemory_operand")]))
17523 (clobber (reg:CC FLAGS_REG))])
17524 (set (match_dup 1) (match_dup 0))
17525 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17526 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17527 && REG_P (operands[0]) && REG_P (operands[4])
17528 && REGNO (operands[0]) == REGNO (operands[4])
17529 && peep2_reg_dead_p (4, operands[0])
17530 && (<MODE>mode != QImode
17531 || immediate_operand (operands[2], SImode)
17532 || q_regs_operand (operands[2], SImode))
17533 && !reg_overlap_mentioned_p (operands[0], operands[1])
17534 && !reg_overlap_mentioned_p (operands[0], operands[2])
17535 && ix86_match_ccmode (peep2_next_insn (3),
17536 (GET_CODE (operands[3]) == PLUS
17537 || GET_CODE (operands[3]) == MINUS)
17538 ? CCGOCmode : CCNOmode)"
17539 [(parallel [(set (match_dup 4) (match_dup 5))
17540 (set (match_dup 1) (match_dup 6))])]
17542 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17543 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17544 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17545 copy_rtx (operands[1]), operands[2]);
17546 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17547 operands[5], const0_rtx);
17548 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17549 copy_rtx (operands[1]),
17550 copy_rtx (operands[2]));
17553 ;; Attempt to always use XOR for zeroing registers.
17555 [(set (match_operand 0 "register_operand")
17556 (match_operand 1 "const0_operand"))]
17557 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17558 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17559 && GENERAL_REG_P (operands[0])
17560 && peep2_regno_dead_p (0, FLAGS_REG)"
17561 [(parallel [(set (match_dup 0) (const_int 0))
17562 (clobber (reg:CC FLAGS_REG))])]
17563 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17566 [(set (strict_low_part (match_operand 0 "register_operand"))
17568 "(GET_MODE (operands[0]) == QImode
17569 || GET_MODE (operands[0]) == HImode)
17570 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17571 && peep2_regno_dead_p (0, FLAGS_REG)"
17572 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17573 (clobber (reg:CC FLAGS_REG))])])
17575 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17577 [(set (match_operand:SWI248 0 "register_operand")
17579 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17580 && peep2_regno_dead_p (0, FLAGS_REG)"
17581 [(parallel [(set (match_dup 0) (const_int -1))
17582 (clobber (reg:CC FLAGS_REG))])]
17584 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17585 operands[0] = gen_lowpart (SImode, operands[0]);
17588 ;; Attempt to convert simple lea to add/shift.
17589 ;; These can be created by move expanders.
17590 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17591 ;; relevant lea instructions were already split.
17594 [(set (match_operand:SWI48 0 "register_operand")
17595 (plus:SWI48 (match_dup 0)
17596 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17598 && peep2_regno_dead_p (0, FLAGS_REG)"
17599 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17600 (clobber (reg:CC FLAGS_REG))])])
17603 [(set (match_operand:SWI48 0 "register_operand")
17604 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17607 && peep2_regno_dead_p (0, FLAGS_REG)"
17608 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17609 (clobber (reg:CC FLAGS_REG))])])
17612 [(set (match_operand:DI 0 "register_operand")
17614 (plus:SI (match_operand:SI 1 "register_operand")
17615 (match_operand:SI 2 "nonmemory_operand"))))]
17616 "TARGET_64BIT && !TARGET_OPT_AGU
17617 && REGNO (operands[0]) == REGNO (operands[1])
17618 && peep2_regno_dead_p (0, FLAGS_REG)"
17619 [(parallel [(set (match_dup 0)
17620 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17621 (clobber (reg:CC FLAGS_REG))])])
17624 [(set (match_operand:DI 0 "register_operand")
17626 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17627 (match_operand:SI 2 "register_operand"))))]
17628 "TARGET_64BIT && !TARGET_OPT_AGU
17629 && REGNO (operands[0]) == REGNO (operands[2])
17630 && peep2_regno_dead_p (0, FLAGS_REG)"
17631 [(parallel [(set (match_dup 0)
17632 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17633 (clobber (reg:CC FLAGS_REG))])])
17636 [(set (match_operand:SWI48 0 "register_operand")
17637 (mult:SWI48 (match_dup 0)
17638 (match_operand:SWI48 1 "const_int_operand")))]
17639 "exact_log2 (INTVAL (operands[1])) >= 0
17640 && peep2_regno_dead_p (0, FLAGS_REG)"
17641 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17642 (clobber (reg:CC FLAGS_REG))])]
17643 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17646 [(set (match_operand:DI 0 "register_operand")
17648 (mult:SI (match_operand:SI 1 "register_operand")
17649 (match_operand:SI 2 "const_int_operand"))))]
17651 && exact_log2 (INTVAL (operands[2])) >= 0
17652 && REGNO (operands[0]) == REGNO (operands[1])
17653 && peep2_regno_dead_p (0, FLAGS_REG)"
17654 [(parallel [(set (match_dup 0)
17655 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17659 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17660 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17661 ;; On many CPUs it is also faster, since special hardware to avoid esp
17662 ;; dependencies is present.
17664 ;; While some of these conversions may be done using splitters, we use
17665 ;; peepholes in order to allow combine_stack_adjustments pass to see
17666 ;; nonobfuscated RTL.
17668 ;; Convert prologue esp subtractions to push.
17669 ;; We need register to push. In order to keep verify_flow_info happy we have
17671 ;; - use scratch and clobber it in order to avoid dependencies
17672 ;; - use already live register
17673 ;; We can't use the second way right now, since there is no reliable way how to
17674 ;; verify that given register is live. First choice will also most likely in
17675 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17676 ;; call clobbered registers are dead. We may want to use base pointer as an
17677 ;; alternative when no register is available later.
17680 [(match_scratch:W 1 "r")
17681 (parallel [(set (reg:P SP_REG)
17682 (plus:P (reg:P SP_REG)
17683 (match_operand:P 0 "const_int_operand")))
17684 (clobber (reg:CC FLAGS_REG))
17685 (clobber (mem:BLK (scratch)))])]
17686 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17687 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17688 [(clobber (match_dup 1))
17689 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17690 (clobber (mem:BLK (scratch)))])])
17693 [(match_scratch:W 1 "r")
17694 (parallel [(set (reg:P SP_REG)
17695 (plus:P (reg:P SP_REG)
17696 (match_operand:P 0 "const_int_operand")))
17697 (clobber (reg:CC FLAGS_REG))
17698 (clobber (mem:BLK (scratch)))])]
17699 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17700 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17701 [(clobber (match_dup 1))
17702 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17703 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17704 (clobber (mem:BLK (scratch)))])])
17706 ;; Convert esp subtractions to push.
17708 [(match_scratch:W 1 "r")
17709 (parallel [(set (reg:P SP_REG)
17710 (plus:P (reg:P SP_REG)
17711 (match_operand:P 0 "const_int_operand")))
17712 (clobber (reg:CC FLAGS_REG))])]
17713 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17714 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17715 [(clobber (match_dup 1))
17716 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17719 [(match_scratch:W 1 "r")
17720 (parallel [(set (reg:P SP_REG)
17721 (plus:P (reg:P SP_REG)
17722 (match_operand:P 0 "const_int_operand")))
17723 (clobber (reg:CC FLAGS_REG))])]
17724 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17725 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17726 [(clobber (match_dup 1))
17727 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17728 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17730 ;; Convert epilogue deallocator to pop.
17732 [(match_scratch:W 1 "r")
17733 (parallel [(set (reg:P SP_REG)
17734 (plus:P (reg:P SP_REG)
17735 (match_operand:P 0 "const_int_operand")))
17736 (clobber (reg:CC FLAGS_REG))
17737 (clobber (mem:BLK (scratch)))])]
17738 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17739 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17740 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17741 (clobber (mem:BLK (scratch)))])])
17743 ;; Two pops case is tricky, since pop causes dependency
17744 ;; on destination register. We use two registers if available.
17746 [(match_scratch:W 1 "r")
17747 (match_scratch:W 2 "r")
17748 (parallel [(set (reg:P SP_REG)
17749 (plus:P (reg:P SP_REG)
17750 (match_operand:P 0 "const_int_operand")))
17751 (clobber (reg:CC FLAGS_REG))
17752 (clobber (mem:BLK (scratch)))])]
17753 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17754 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17755 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17756 (clobber (mem:BLK (scratch)))])
17757 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17760 [(match_scratch:W 1 "r")
17761 (parallel [(set (reg:P SP_REG)
17762 (plus:P (reg:P SP_REG)
17763 (match_operand:P 0 "const_int_operand")))
17764 (clobber (reg:CC FLAGS_REG))
17765 (clobber (mem:BLK (scratch)))])]
17766 "optimize_insn_for_size_p ()
17767 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17768 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17769 (clobber (mem:BLK (scratch)))])
17770 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17772 ;; Convert esp additions to pop.
17774 [(match_scratch:W 1 "r")
17775 (parallel [(set (reg:P SP_REG)
17776 (plus:P (reg:P SP_REG)
17777 (match_operand:P 0 "const_int_operand")))
17778 (clobber (reg:CC FLAGS_REG))])]
17779 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17780 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17782 ;; Two pops case is tricky, since pop causes dependency
17783 ;; on destination register. We use two registers if available.
17785 [(match_scratch:W 1 "r")
17786 (match_scratch:W 2 "r")
17787 (parallel [(set (reg:P SP_REG)
17788 (plus:P (reg:P SP_REG)
17789 (match_operand:P 0 "const_int_operand")))
17790 (clobber (reg:CC FLAGS_REG))])]
17791 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17792 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17793 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17796 [(match_scratch:W 1 "r")
17797 (parallel [(set (reg:P SP_REG)
17798 (plus:P (reg:P SP_REG)
17799 (match_operand:P 0 "const_int_operand")))
17800 (clobber (reg:CC FLAGS_REG))])]
17801 "optimize_insn_for_size_p ()
17802 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17803 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17804 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17806 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17807 ;; required and register dies. Similarly for 128 to -128.
17809 [(set (match_operand 0 "flags_reg_operand")
17810 (match_operator 1 "compare_operator"
17811 [(match_operand 2 "register_operand")
17812 (match_operand 3 "const_int_operand")]))]
17813 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17814 && incdec_operand (operands[3], GET_MODE (operands[3])))
17815 || (!TARGET_FUSE_CMP_AND_BRANCH
17816 && INTVAL (operands[3]) == 128))
17817 && ix86_match_ccmode (insn, CCGCmode)
17818 && peep2_reg_dead_p (1, operands[2])"
17819 [(parallel [(set (match_dup 0)
17820 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17821 (clobber (match_dup 2))])])
17823 ;; Convert imul by three, five and nine into lea
17826 [(set (match_operand:SWI48 0 "register_operand")
17827 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17828 (match_operand:SWI48 2 "const359_operand")))
17829 (clobber (reg:CC FLAGS_REG))])]
17830 "!TARGET_PARTIAL_REG_STALL
17831 || <MODE>mode == SImode
17832 || optimize_function_for_size_p (cfun)"
17833 [(set (match_dup 0)
17834 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17836 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17840 [(set (match_operand:SWI48 0 "register_operand")
17841 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17842 (match_operand:SWI48 2 "const359_operand")))
17843 (clobber (reg:CC FLAGS_REG))])]
17844 "optimize_insn_for_speed_p ()
17845 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17846 [(set (match_dup 0) (match_dup 1))
17848 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17850 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17852 ;; imul $32bit_imm, mem, reg is vector decoded, while
17853 ;; imul $32bit_imm, reg, reg is direct decoded.
17855 [(match_scratch:SWI48 3 "r")
17856 (parallel [(set (match_operand:SWI48 0 "register_operand")
17857 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17858 (match_operand:SWI48 2 "immediate_operand")))
17859 (clobber (reg:CC FLAGS_REG))])]
17860 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17861 && !satisfies_constraint_K (operands[2])"
17862 [(set (match_dup 3) (match_dup 1))
17863 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17864 (clobber (reg:CC FLAGS_REG))])])
17867 [(match_scratch:SI 3 "r")
17868 (parallel [(set (match_operand:DI 0 "register_operand")
17870 (mult:SI (match_operand:SI 1 "memory_operand")
17871 (match_operand:SI 2 "immediate_operand"))))
17872 (clobber (reg:CC FLAGS_REG))])]
17874 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17875 && !satisfies_constraint_K (operands[2])"
17876 [(set (match_dup 3) (match_dup 1))
17877 (parallel [(set (match_dup 0)
17878 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17879 (clobber (reg:CC FLAGS_REG))])])
17881 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17882 ;; Convert it into imul reg, reg
17883 ;; It would be better to force assembler to encode instruction using long
17884 ;; immediate, but there is apparently no way to do so.
17886 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17888 (match_operand:SWI248 1 "nonimmediate_operand")
17889 (match_operand:SWI248 2 "const_int_operand")))
17890 (clobber (reg:CC FLAGS_REG))])
17891 (match_scratch:SWI248 3 "r")]
17892 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17893 && satisfies_constraint_K (operands[2])"
17894 [(set (match_dup 3) (match_dup 2))
17895 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17896 (clobber (reg:CC FLAGS_REG))])]
17898 if (!rtx_equal_p (operands[0], operands[1]))
17899 emit_move_insn (operands[0], operands[1]);
17902 ;; After splitting up read-modify operations, array accesses with memory
17903 ;; operands might end up in form:
17905 ;; movl 4(%esp), %edx
17907 ;; instead of pre-splitting:
17909 ;; addl 4(%esp), %eax
17911 ;; movl 4(%esp), %edx
17912 ;; leal (%edx,%eax,4), %eax
17915 [(match_scratch:W 5 "r")
17916 (parallel [(set (match_operand 0 "register_operand")
17917 (ashift (match_operand 1 "register_operand")
17918 (match_operand 2 "const_int_operand")))
17919 (clobber (reg:CC FLAGS_REG))])
17920 (parallel [(set (match_operand 3 "register_operand")
17921 (plus (match_dup 0)
17922 (match_operand 4 "x86_64_general_operand")))
17923 (clobber (reg:CC FLAGS_REG))])]
17924 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17925 /* Validate MODE for lea. */
17926 && ((!TARGET_PARTIAL_REG_STALL
17927 && (GET_MODE (operands[0]) == QImode
17928 || GET_MODE (operands[0]) == HImode))
17929 || GET_MODE (operands[0]) == SImode
17930 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17931 && (rtx_equal_p (operands[0], operands[3])
17932 || peep2_reg_dead_p (2, operands[0]))
17933 /* We reorder load and the shift. */
17934 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17935 [(set (match_dup 5) (match_dup 4))
17936 (set (match_dup 0) (match_dup 1))]
17938 machine_mode op1mode = GET_MODE (operands[1]);
17939 machine_mode mode = op1mode == DImode ? DImode : SImode;
17940 int scale = 1 << INTVAL (operands[2]);
17941 rtx index = gen_lowpart (word_mode, operands[1]);
17942 rtx base = gen_lowpart (word_mode, operands[5]);
17943 rtx dest = gen_lowpart (mode, operands[3]);
17945 operands[1] = gen_rtx_PLUS (word_mode, base,
17946 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17947 operands[5] = base;
17948 if (mode != word_mode)
17949 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17950 if (op1mode != word_mode)
17951 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17952 operands[0] = dest;
17955 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17956 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17957 ;; caught for use by garbage collectors and the like. Using an insn that
17958 ;; maps to SIGILL makes it more likely the program will rightfully die.
17959 ;; Keeping with tradition, "6" is in honor of #UD.
17960 (define_insn "trap"
17961 [(trap_if (const_int 1) (const_int 6))]
17964 #ifdef HAVE_AS_IX86_UD2
17967 return ASM_SHORT "0x0b0f";
17970 [(set_attr "length" "2")])
17972 (define_expand "prefetch"
17973 [(prefetch (match_operand 0 "address_operand")
17974 (match_operand:SI 1 "const_int_operand")
17975 (match_operand:SI 2 "const_int_operand"))]
17976 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17978 bool write = INTVAL (operands[1]) != 0;
17979 int locality = INTVAL (operands[2]);
17981 gcc_assert (IN_RANGE (locality, 0, 3));
17983 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17984 supported by SSE counterpart or the SSE prefetch is not available
17985 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17987 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17988 operands[2] = const2_rtx;
17989 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17990 operands[2] = GEN_INT (3);
17992 operands[1] = const0_rtx;
17995 (define_insn "*prefetch_sse"
17996 [(prefetch (match_operand 0 "address_operand" "p")
17998 (match_operand:SI 1 "const_int_operand"))]
17999 "TARGET_PREFETCH_SSE"
18001 static const char * const patterns[4] = {
18002 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18005 int locality = INTVAL (operands[1]);
18006 gcc_assert (IN_RANGE (locality, 0, 3));
18008 return patterns[locality];
18010 [(set_attr "type" "sse")
18011 (set_attr "atom_sse_attr" "prefetch")
18012 (set (attr "length_address")
18013 (symbol_ref "memory_address_length (operands[0], false)"))
18014 (set_attr "memory" "none")])
18016 (define_insn "*prefetch_3dnow"
18017 [(prefetch (match_operand 0 "address_operand" "p")
18018 (match_operand:SI 1 "const_int_operand" "n")
18022 if (INTVAL (operands[1]) == 0)
18023 return "prefetch\t%a0";
18025 return "prefetchw\t%a0";
18027 [(set_attr "type" "mmx")
18028 (set (attr "length_address")
18029 (symbol_ref "memory_address_length (operands[0], false)"))
18030 (set_attr "memory" "none")])
18032 (define_insn "*prefetch_prefetchwt1_<mode>"
18033 [(prefetch (match_operand:P 0 "address_operand" "p")
18036 "TARGET_PREFETCHWT1"
18037 "prefetchwt1\t%a0";
18038 [(set_attr "type" "sse")
18039 (set (attr "length_address")
18040 (symbol_ref "memory_address_length (operands[0], false)"))
18041 (set_attr "memory" "none")])
18043 (define_expand "stack_protect_set"
18044 [(match_operand 0 "memory_operand")
18045 (match_operand 1 "memory_operand")]
18046 "TARGET_SSP_TLS_GUARD"
18048 rtx (*insn)(rtx, rtx);
18050 #ifdef TARGET_THREAD_SSP_OFFSET
18051 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18052 insn = (TARGET_LP64
18053 ? gen_stack_tls_protect_set_di
18054 : gen_stack_tls_protect_set_si);
18056 insn = (TARGET_LP64
18057 ? gen_stack_protect_set_di
18058 : gen_stack_protect_set_si);
18061 emit_insn (insn (operands[0], operands[1]));
18065 (define_insn "stack_protect_set_<mode>"
18066 [(set (match_operand:PTR 0 "memory_operand" "=m")
18067 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18069 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18070 (clobber (reg:CC FLAGS_REG))]
18071 "TARGET_SSP_TLS_GUARD"
18072 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18073 [(set_attr "type" "multi")])
18075 (define_insn "stack_tls_protect_set_<mode>"
18076 [(set (match_operand:PTR 0 "memory_operand" "=m")
18077 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18078 UNSPEC_SP_TLS_SET))
18079 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18080 (clobber (reg:CC FLAGS_REG))]
18082 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18083 [(set_attr "type" "multi")])
18085 (define_expand "stack_protect_test"
18086 [(match_operand 0 "memory_operand")
18087 (match_operand 1 "memory_operand")
18089 "TARGET_SSP_TLS_GUARD"
18091 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18093 rtx (*insn)(rtx, rtx, rtx);
18095 #ifdef TARGET_THREAD_SSP_OFFSET
18096 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18097 insn = (TARGET_LP64
18098 ? gen_stack_tls_protect_test_di
18099 : gen_stack_tls_protect_test_si);
18101 insn = (TARGET_LP64
18102 ? gen_stack_protect_test_di
18103 : gen_stack_protect_test_si);
18106 emit_insn (insn (flags, operands[0], operands[1]));
18108 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18109 flags, const0_rtx, operands[2]));
18113 (define_insn "stack_protect_test_<mode>"
18114 [(set (match_operand:CCZ 0 "flags_reg_operand")
18115 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18116 (match_operand:PTR 2 "memory_operand" "m")]
18118 (clobber (match_scratch:PTR 3 "=&r"))]
18119 "TARGET_SSP_TLS_GUARD"
18120 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18121 [(set_attr "type" "multi")])
18123 (define_insn "stack_tls_protect_test_<mode>"
18124 [(set (match_operand:CCZ 0 "flags_reg_operand")
18125 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18126 (match_operand:PTR 2 "const_int_operand" "i")]
18127 UNSPEC_SP_TLS_TEST))
18128 (clobber (match_scratch:PTR 3 "=r"))]
18130 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18131 [(set_attr "type" "multi")])
18133 (define_insn "sse4_2_crc32<mode>"
18134 [(set (match_operand:SI 0 "register_operand" "=r")
18136 [(match_operand:SI 1 "register_operand" "0")
18137 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18139 "TARGET_SSE4_2 || TARGET_CRC32"
18140 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18141 [(set_attr "type" "sselog1")
18142 (set_attr "prefix_rep" "1")
18143 (set_attr "prefix_extra" "1")
18144 (set (attr "prefix_data16")
18145 (if_then_else (match_operand:HI 2)
18147 (const_string "*")))
18148 (set (attr "prefix_rex")
18149 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18151 (const_string "*")))
18152 (set_attr "mode" "SI")])
18154 (define_insn "sse4_2_crc32di"
18155 [(set (match_operand:DI 0 "register_operand" "=r")
18157 [(match_operand:DI 1 "register_operand" "0")
18158 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18160 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18161 "crc32{q}\t{%2, %0|%0, %2}"
18162 [(set_attr "type" "sselog1")
18163 (set_attr "prefix_rep" "1")
18164 (set_attr "prefix_extra" "1")
18165 (set_attr "mode" "DI")])
18167 (define_insn "rdpmc"
18168 [(set (match_operand:DI 0 "register_operand" "=A")
18169 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18173 [(set_attr "type" "other")
18174 (set_attr "length" "2")])
18176 (define_insn "rdpmc_rex64"
18177 [(set (match_operand:DI 0 "register_operand" "=a")
18178 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18180 (set (match_operand:DI 1 "register_operand" "=d")
18181 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18184 [(set_attr "type" "other")
18185 (set_attr "length" "2")])
18187 (define_insn "rdtsc"
18188 [(set (match_operand:DI 0 "register_operand" "=A")
18189 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18192 [(set_attr "type" "other")
18193 (set_attr "length" "2")])
18195 (define_insn "rdtsc_rex64"
18196 [(set (match_operand:DI 0 "register_operand" "=a")
18197 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18198 (set (match_operand:DI 1 "register_operand" "=d")
18199 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18202 [(set_attr "type" "other")
18203 (set_attr "length" "2")])
18205 (define_insn "rdtscp"
18206 [(set (match_operand:DI 0 "register_operand" "=A")
18207 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18208 (set (match_operand:SI 1 "register_operand" "=c")
18209 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18212 [(set_attr "type" "other")
18213 (set_attr "length" "3")])
18215 (define_insn "rdtscp_rex64"
18216 [(set (match_operand:DI 0 "register_operand" "=a")
18217 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18218 (set (match_operand:DI 1 "register_operand" "=d")
18219 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18220 (set (match_operand:SI 2 "register_operand" "=c")
18221 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18224 [(set_attr "type" "other")
18225 (set_attr "length" "3")])
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18229 ;; FXSR, XSAVE and XSAVEOPT instructions
18231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18233 (define_insn "fxsave"
18234 [(set (match_operand:BLK 0 "memory_operand" "=m")
18235 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18238 [(set_attr "type" "other")
18239 (set_attr "memory" "store")
18240 (set (attr "length")
18241 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18243 (define_insn "fxsave64"
18244 [(set (match_operand:BLK 0 "memory_operand" "=m")
18245 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18246 "TARGET_64BIT && TARGET_FXSR"
18248 [(set_attr "type" "other")
18249 (set_attr "memory" "store")
18250 (set (attr "length")
18251 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18253 (define_insn "fxrstor"
18254 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18258 [(set_attr "type" "other")
18259 (set_attr "memory" "load")
18260 (set (attr "length")
18261 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18263 (define_insn "fxrstor64"
18264 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18265 UNSPECV_FXRSTOR64)]
18266 "TARGET_64BIT && TARGET_FXSR"
18268 [(set_attr "type" "other")
18269 (set_attr "memory" "load")
18270 (set (attr "length")
18271 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18273 (define_int_iterator ANY_XSAVE
18275 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18276 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18277 (UNSPECV_XSAVES "TARGET_XSAVES")])
18279 (define_int_iterator ANY_XSAVE64
18281 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18282 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18283 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18285 (define_int_attr xsave
18286 [(UNSPECV_XSAVE "xsave")
18287 (UNSPECV_XSAVE64 "xsave64")
18288 (UNSPECV_XSAVEOPT "xsaveopt")
18289 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18290 (UNSPECV_XSAVEC "xsavec")
18291 (UNSPECV_XSAVEC64 "xsavec64")
18292 (UNSPECV_XSAVES "xsaves")
18293 (UNSPECV_XSAVES64 "xsaves64")])
18295 (define_int_iterator ANY_XRSTOR
18297 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18299 (define_int_iterator ANY_XRSTOR64
18301 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18303 (define_int_attr xrstor
18304 [(UNSPECV_XRSTOR "xrstor")
18305 (UNSPECV_XRSTOR64 "xrstor")
18306 (UNSPECV_XRSTORS "xrstors")
18307 (UNSPECV_XRSTORS64 "xrstors")])
18309 (define_insn "<xsave>"
18310 [(set (match_operand:BLK 0 "memory_operand" "=m")
18311 (unspec_volatile:BLK
18312 [(match_operand:DI 1 "register_operand" "A")]
18314 "!TARGET_64BIT && TARGET_XSAVE"
18316 [(set_attr "type" "other")
18317 (set_attr "memory" "store")
18318 (set (attr "length")
18319 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18321 (define_insn "<xsave>_rex64"
18322 [(set (match_operand:BLK 0 "memory_operand" "=m")
18323 (unspec_volatile:BLK
18324 [(match_operand:SI 1 "register_operand" "a")
18325 (match_operand:SI 2 "register_operand" "d")]
18327 "TARGET_64BIT && TARGET_XSAVE"
18329 [(set_attr "type" "other")
18330 (set_attr "memory" "store")
18331 (set (attr "length")
18332 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18334 (define_insn "<xsave>"
18335 [(set (match_operand:BLK 0 "memory_operand" "=m")
18336 (unspec_volatile:BLK
18337 [(match_operand:SI 1 "register_operand" "a")
18338 (match_operand:SI 2 "register_operand" "d")]
18340 "TARGET_64BIT && TARGET_XSAVE"
18342 [(set_attr "type" "other")
18343 (set_attr "memory" "store")
18344 (set (attr "length")
18345 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18347 (define_insn "<xrstor>"
18348 [(unspec_volatile:BLK
18349 [(match_operand:BLK 0 "memory_operand" "m")
18350 (match_operand:DI 1 "register_operand" "A")]
18352 "!TARGET_64BIT && TARGET_XSAVE"
18354 [(set_attr "type" "other")
18355 (set_attr "memory" "load")
18356 (set (attr "length")
18357 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18359 (define_insn "<xrstor>_rex64"
18360 [(unspec_volatile:BLK
18361 [(match_operand:BLK 0 "memory_operand" "m")
18362 (match_operand:SI 1 "register_operand" "a")
18363 (match_operand:SI 2 "register_operand" "d")]
18365 "TARGET_64BIT && TARGET_XSAVE"
18367 [(set_attr "type" "other")
18368 (set_attr "memory" "load")
18369 (set (attr "length")
18370 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18372 (define_insn "<xrstor>64"
18373 [(unspec_volatile:BLK
18374 [(match_operand:BLK 0 "memory_operand" "m")
18375 (match_operand:SI 1 "register_operand" "a")
18376 (match_operand:SI 2 "register_operand" "d")]
18378 "TARGET_64BIT && TARGET_XSAVE"
18380 [(set_attr "type" "other")
18381 (set_attr "memory" "load")
18382 (set (attr "length")
18383 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18385 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18387 ;; Floating-point instructions for atomic compound assignments
18389 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18391 ; Clobber all floating-point registers on environment save and restore
18392 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18393 (define_insn "fnstenv"
18394 [(set (match_operand:BLK 0 "memory_operand" "=m")
18395 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18396 (clobber (reg:HI FPCR_REG))
18397 (clobber (reg:XF ST0_REG))
18398 (clobber (reg:XF ST1_REG))
18399 (clobber (reg:XF ST2_REG))
18400 (clobber (reg:XF ST3_REG))
18401 (clobber (reg:XF ST4_REG))
18402 (clobber (reg:XF ST5_REG))
18403 (clobber (reg:XF ST6_REG))
18404 (clobber (reg:XF ST7_REG))]
18407 [(set_attr "type" "other")
18408 (set_attr "memory" "store")
18409 (set (attr "length")
18410 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18412 (define_insn "fldenv"
18413 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18415 (clobber (reg:CCFP FPSR_REG))
18416 (clobber (reg:HI FPCR_REG))
18417 (clobber (reg:XF ST0_REG))
18418 (clobber (reg:XF ST1_REG))
18419 (clobber (reg:XF ST2_REG))
18420 (clobber (reg:XF ST3_REG))
18421 (clobber (reg:XF ST4_REG))
18422 (clobber (reg:XF ST5_REG))
18423 (clobber (reg:XF ST6_REG))
18424 (clobber (reg:XF ST7_REG))]
18427 [(set_attr "type" "other")
18428 (set_attr "memory" "load")
18429 (set (attr "length")
18430 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18432 (define_insn "fnstsw"
18433 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18434 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18437 [(set_attr "type" "other,other")
18438 (set_attr "memory" "none,store")
18439 (set (attr "length")
18440 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18442 (define_insn "fnclex"
18443 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18446 [(set_attr "type" "other")
18447 (set_attr "memory" "none")
18448 (set_attr "length" "2")])
18450 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18452 ;; LWP instructions
18454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18456 (define_expand "lwp_llwpcb"
18457 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18458 UNSPECV_LLWP_INTRINSIC)]
18461 (define_insn "*lwp_llwpcb<mode>1"
18462 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18463 UNSPECV_LLWP_INTRINSIC)]
18466 [(set_attr "type" "lwp")
18467 (set_attr "mode" "<MODE>")
18468 (set_attr "length" "5")])
18470 (define_expand "lwp_slwpcb"
18471 [(set (match_operand 0 "register_operand" "=r")
18472 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18477 insn = (Pmode == DImode
18479 : gen_lwp_slwpcbsi);
18481 emit_insn (insn (operands[0]));
18485 (define_insn "lwp_slwpcb<mode>"
18486 [(set (match_operand:P 0 "register_operand" "=r")
18487 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18490 [(set_attr "type" "lwp")
18491 (set_attr "mode" "<MODE>")
18492 (set_attr "length" "5")])
18494 (define_expand "lwp_lwpval<mode>3"
18495 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18496 (match_operand:SI 2 "nonimmediate_operand" "rm")
18497 (match_operand:SI 3 "const_int_operand" "i")]
18498 UNSPECV_LWPVAL_INTRINSIC)]
18500 ;; Avoid unused variable warning.
18501 "(void) operands[0];")
18503 (define_insn "*lwp_lwpval<mode>3_1"
18504 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18505 (match_operand:SI 1 "nonimmediate_operand" "rm")
18506 (match_operand:SI 2 "const_int_operand" "i")]
18507 UNSPECV_LWPVAL_INTRINSIC)]
18509 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18510 [(set_attr "type" "lwp")
18511 (set_attr "mode" "<MODE>")
18512 (set (attr "length")
18513 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18515 (define_expand "lwp_lwpins<mode>3"
18516 [(set (reg:CCC FLAGS_REG)
18517 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18518 (match_operand:SI 2 "nonimmediate_operand" "rm")
18519 (match_operand:SI 3 "const_int_operand" "i")]
18520 UNSPECV_LWPINS_INTRINSIC))
18521 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18522 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18525 (define_insn "*lwp_lwpins<mode>3_1"
18526 [(set (reg:CCC FLAGS_REG)
18527 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18528 (match_operand:SI 1 "nonimmediate_operand" "rm")
18529 (match_operand:SI 2 "const_int_operand" "i")]
18530 UNSPECV_LWPINS_INTRINSIC))]
18532 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18533 [(set_attr "type" "lwp")
18534 (set_attr "mode" "<MODE>")
18535 (set (attr "length")
18536 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18538 (define_int_iterator RDFSGSBASE
18542 (define_int_iterator WRFSGSBASE
18546 (define_int_attr fsgs
18547 [(UNSPECV_RDFSBASE "fs")
18548 (UNSPECV_RDGSBASE "gs")
18549 (UNSPECV_WRFSBASE "fs")
18550 (UNSPECV_WRGSBASE "gs")])
18552 (define_insn "rd<fsgs>base<mode>"
18553 [(set (match_operand:SWI48 0 "register_operand" "=r")
18554 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18555 "TARGET_64BIT && TARGET_FSGSBASE"
18557 [(set_attr "type" "other")
18558 (set_attr "prefix_extra" "2")])
18560 (define_insn "wr<fsgs>base<mode>"
18561 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18563 "TARGET_64BIT && TARGET_FSGSBASE"
18565 [(set_attr "type" "other")
18566 (set_attr "prefix_extra" "2")])
18568 (define_insn "rdrand<mode>_1"
18569 [(set (match_operand:SWI248 0 "register_operand" "=r")
18570 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18571 (set (reg:CCC FLAGS_REG)
18572 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18575 [(set_attr "type" "other")
18576 (set_attr "prefix_extra" "1")])
18578 (define_insn "rdseed<mode>_1"
18579 [(set (match_operand:SWI248 0 "register_operand" "=r")
18580 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18581 (set (reg:CCC FLAGS_REG)
18582 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18585 [(set_attr "type" "other")
18586 (set_attr "prefix_extra" "1")])
18588 (define_expand "pause"
18589 [(set (match_dup 0)
18590 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18593 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18594 MEM_VOLATILE_P (operands[0]) = 1;
18597 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18598 ;; They have the same encoding.
18599 (define_insn "*pause"
18600 [(set (match_operand:BLK 0)
18601 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18604 [(set_attr "length" "2")
18605 (set_attr "memory" "unknown")])
18607 (define_expand "xbegin"
18608 [(set (match_operand:SI 0 "register_operand")
18609 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18612 rtx_code_label *label = gen_label_rtx ();
18614 /* xbegin is emitted as jump_insn, so reload won't be able
18615 to reload its operand. Force the value into AX hard register. */
18616 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18617 emit_move_insn (ax_reg, constm1_rtx);
18619 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18621 emit_label (label);
18622 LABEL_NUSES (label) = 1;
18624 emit_move_insn (operands[0], ax_reg);
18629 (define_insn "xbegin_1"
18631 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18633 (label_ref (match_operand 1))
18635 (set (match_operand:SI 0 "register_operand" "+a")
18636 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18639 [(set_attr "type" "other")
18640 (set_attr "length" "6")])
18642 (define_insn "xend"
18643 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18646 [(set_attr "type" "other")
18647 (set_attr "length" "3")])
18649 (define_insn "xabort"
18650 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18654 [(set_attr "type" "other")
18655 (set_attr "length" "3")])
18657 (define_expand "xtest"
18658 [(set (match_operand:QI 0 "register_operand")
18659 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18662 emit_insn (gen_xtest_1 ());
18664 ix86_expand_setcc (operands[0], NE,
18665 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18669 (define_insn "xtest_1"
18670 [(set (reg:CCZ FLAGS_REG)
18671 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18674 [(set_attr "type" "other")
18675 (set_attr "length" "3")])
18677 (define_insn "pcommit"
18678 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18681 [(set_attr "type" "other")
18682 (set_attr "length" "4")])
18684 (define_insn "clwb"
18685 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18689 [(set_attr "type" "sse")
18690 (set_attr "atom_sse_attr" "fence")
18691 (set_attr "memory" "unknown")])
18693 (define_insn "clflushopt"
18694 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18695 UNSPECV_CLFLUSHOPT)]
18696 "TARGET_CLFLUSHOPT"
18698 [(set_attr "type" "sse")
18699 (set_attr "atom_sse_attr" "fence")
18700 (set_attr "memory" "unknown")])
18702 ;; MPX instructions
18704 (define_expand "<mode>_mk"
18705 [(set (match_operand:BND 0 "register_operand")
18709 [(match_operand:<bnd_ptr> 1 "register_operand")
18710 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18714 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18716 UNSPEC_BNDMK_ADDR);
18719 (define_insn "*<mode>_mk"
18720 [(set (match_operand:BND 0 "register_operand" "=w")
18722 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18724 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18725 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18726 UNSPEC_BNDMK_ADDR)])]
18729 "bndmk\t{%3, %0|%0, %3}"
18730 [(set_attr "type" "mpxmk")])
18732 (define_expand "mov<mode>"
18733 [(set (match_operand:BND 0 "general_operand")
18734 (match_operand:BND 1 "general_operand"))]
18737 ix86_expand_move (<MODE>mode, operands);DONE;
18740 (define_insn "*mov<mode>_internal_mpx"
18741 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18742 (match_operand:BND 1 "general_operand" "wm,w"))]
18744 "bndmov\t{%1, %0|%0, %1}"
18745 [(set_attr "type" "mpxmov")])
18747 (define_expand "<mode>_<bndcheck>"
18748 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18749 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18751 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18754 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18755 MEM_VOLATILE_P (operands[2]) = 1;
18758 (define_insn "*<mode>_<bndcheck>"
18759 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18760 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18761 (set (match_operand:BLK 2 "bnd_mem_operator")
18762 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18764 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18765 [(set_attr "type" "mpxchk")])
18767 (define_expand "<mode>_ldx"
18768 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18772 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18773 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18775 (use (mem:BLK (match_dup 1)))])]
18778 /* Avoid registers which connot be used as index. */
18779 if (!index_register_operand (operands[2], Pmode))
18781 rtx temp = gen_reg_rtx (Pmode);
18782 emit_move_insn (temp, operands[2]);
18783 operands[2] = temp;
18786 /* If it was a register originally then it may have
18787 mode other than Pmode. We need to extend in such
18788 case because bndldx may work only with Pmode regs. */
18789 if (GET_MODE (operands[2]) != Pmode)
18790 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18792 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18794 UNSPEC_BNDLDX_ADDR);
18797 (define_insn "*<mode>_ldx"
18798 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18800 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18802 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18803 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18804 UNSPEC_BNDLDX_ADDR)])]
18806 (use (mem:BLK (match_dup 1)))])]
18808 "bndldx\t{%3, %0|%0, %3}"
18809 [(set_attr "type" "mpxld")])
18811 (define_expand "<mode>_stx"
18812 [(parallel [(unspec [(mem:<bnd_ptr>
18814 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18815 (match_operand:<bnd_ptr> 1 "register_operand")]))
18816 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18818 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18821 /* Avoid registers which connot be used as index. */
18822 if (!index_register_operand (operands[1], Pmode))
18824 rtx temp = gen_reg_rtx (Pmode);
18825 emit_move_insn (temp, operands[1]);
18826 operands[1] = temp;
18829 /* If it was a register originally then it may have
18830 mode other than Pmode. We need to extend in such
18831 case because bndstx may work only with Pmode regs. */
18832 if (GET_MODE (operands[1]) != Pmode)
18833 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18835 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18837 UNSPEC_BNDLDX_ADDR);
18838 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18839 MEM_VOLATILE_P (operands[4]) = 1;
18842 (define_insn "*<mode>_stx"
18843 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18845 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18846 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18847 UNSPEC_BNDLDX_ADDR)])
18848 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18849 (set (match_operand:BLK 4 "bnd_mem_operator")
18850 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18852 "bndstx\t{%2, %3|%3, %2}"
18853 [(set_attr "type" "mpxst")])
18855 (define_insn "move_size_reloc_<mode>"
18856 [(set (match_operand:SWI48 0 "register_operand" "=r")
18858 [(match_operand:SWI48 1 "symbol_operand")]
18862 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18863 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18865 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18867 [(set_attr "type" "imov")
18868 (set_attr "mode" "<MODE>")])
18872 (include "sync.md")