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
256 ;; For CLFLUSHOPT support
260 ;; Constants to represent rounding modes in the ROUND instruction
269 ;; Constants to represent AVX512F embeded rounding
271 [(ROUND_NEAREST_INT 0)
279 ;; Constants to represent pcomtrue/pcomfalse variants
289 ;; Constants used in the XOP pperm instruction
291 [(PPERM_SRC 0x00) /* copy source */
292 (PPERM_INVERT 0x20) /* invert source */
293 (PPERM_REVERSE 0x40) /* bit reverse source */
294 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
295 (PPERM_ZERO 0x80) /* all 0's */
296 (PPERM_ONES 0xa0) /* all 1's */
297 (PPERM_SIGN 0xc0) /* propagate sign bit */
298 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
299 (PPERM_SRC1 0x00) /* use first source byte */
300 (PPERM_SRC2 0x10) /* use second source byte */
303 ;; Registers by name.
384 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
387 ;; In C guard expressions, put expressions which may be compile-time
388 ;; constants first. This allows for better optimization. For
389 ;; example, write "TARGET_64BIT && reload_completed", not
390 ;; "reload_completed && TARGET_64BIT".
394 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
395 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
397 (const (symbol_ref "ix86_schedule")))
399 ;; A basic instruction type. Refinements due to arguments to be
400 ;; provided in other attributes.
403 alu,alu1,negnot,imov,imovx,lea,
404 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
405 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
406 push,pop,call,callv,leave,
408 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
409 fxch,fistp,fisttp,frndint,
410 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
411 ssemul,sseimul,ssediv,sselog,sselog1,
412 sseishft,sseishft1,ssecmp,ssecomi,
413 ssecvt,ssecvt1,sseicvt,sseins,
414 sseshuf,sseshuf1,ssemuladd,sse4arg,
416 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
417 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
418 (const_string "other"))
420 ;; Main data type used by the insn
422 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
424 (const_string "unknown"))
426 ;; The CPU unit operations uses.
427 (define_attr "unit" "integer,i387,sse,mmx,unknown"
428 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
429 fxch,fistp,fisttp,frndint")
430 (const_string "i387")
431 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
432 ssemul,sseimul,ssediv,sselog,sselog1,
433 sseishft,sseishft1,ssecmp,ssecomi,
434 ssecvt,ssecvt1,sseicvt,sseins,
435 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
437 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
439 (eq_attr "type" "other")
440 (const_string "unknown")]
441 (const_string "integer")))
443 ;; The minimum required alignment of vector mode memory operands of the SSE
444 ;; (non-VEX/EVEX) instruction in bits, if it is different from
445 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
446 ;; multiple alternatives, this should be conservative maximum of those minimum
447 ;; required alignments.
448 (define_attr "ssememalign" "" (const_int 0))
450 ;; The (bounding maximum) length of an instruction immediate.
451 (define_attr "length_immediate" ""
452 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
453 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
456 (eq_attr "unit" "i387,sse,mmx")
458 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
459 rotate,rotatex,rotate1,imul,icmp,push,pop")
460 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
461 (eq_attr "type" "imov,test")
462 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
463 (eq_attr "type" "call")
464 (if_then_else (match_operand 0 "constant_call_address_operand")
467 (eq_attr "type" "callv")
468 (if_then_else (match_operand 1 "constant_call_address_operand")
471 ;; We don't know the size before shorten_branches. Expect
472 ;; the instruction to fit for better scheduling.
473 (eq_attr "type" "ibr")
476 (symbol_ref "/* Update immediate_length and other attributes! */
477 gcc_unreachable (),1")))
479 ;; The (bounding maximum) length of an instruction address.
480 (define_attr "length_address" ""
481 (cond [(eq_attr "type" "str,other,multi,fxch")
483 (and (eq_attr "type" "call")
484 (match_operand 0 "constant_call_address_operand"))
486 (and (eq_attr "type" "callv")
487 (match_operand 1 "constant_call_address_operand"))
490 (symbol_ref "ix86_attr_length_address_default (insn)")))
492 ;; Set when length prefix is used.
493 (define_attr "prefix_data16" ""
494 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
496 (eq_attr "mode" "HI")
498 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
503 ;; Set when string REP prefix is used.
504 (define_attr "prefix_rep" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
507 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
509 (and (eq_attr "type" "ibr,call,callv")
510 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
515 ;; Set when 0f opcode prefix is used.
516 (define_attr "prefix_0f" ""
518 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
519 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
520 (eq_attr "unit" "sse,mmx"))
524 ;; Set when REX opcode prefix is used.
525 (define_attr "prefix_rex" ""
526 (cond [(not (match_test "TARGET_64BIT"))
528 (and (eq_attr "mode" "DI")
529 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
530 (eq_attr "unit" "!mmx")))
532 (and (eq_attr "mode" "QI")
533 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
535 (match_test "x86_extended_reg_mentioned_p (insn)")
537 (and (eq_attr "type" "imovx")
538 (match_operand:QI 1 "ext_QIreg_operand"))
543 ;; There are also additional prefixes in 3DNOW, SSSE3.
544 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
545 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
546 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
547 (define_attr "prefix_extra" ""
548 (cond [(eq_attr "type" "ssemuladd,sse4arg")
550 (eq_attr "type" "sseiadd1,ssecvt1")
555 ;; Prefix used: original, VEX or maybe VEX.
556 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
557 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
559 (eq_attr "mode" "XI,V16SF,V8DF")
560 (const_string "evex")
562 (const_string "orig")))
564 ;; VEX W bit is used.
565 (define_attr "prefix_vex_w" "" (const_int 0))
567 ;; The length of VEX prefix
568 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
569 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
570 ;; still prefix_0f 1, with prefix_extra 1.
571 (define_attr "length_vex" ""
572 (if_then_else (and (eq_attr "prefix_0f" "1")
573 (eq_attr "prefix_extra" "0"))
574 (if_then_else (eq_attr "prefix_vex_w" "1")
575 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
576 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
577 (if_then_else (eq_attr "prefix_vex_w" "1")
578 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
579 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
581 ;; 4-bytes evex prefix and 1 byte opcode.
582 (define_attr "length_evex" "" (const_int 5))
584 ;; Set when modrm byte is used.
585 (define_attr "modrm" ""
586 (cond [(eq_attr "type" "str,leave")
588 (eq_attr "unit" "i387")
590 (and (eq_attr "type" "incdec")
591 (and (not (match_test "TARGET_64BIT"))
592 (ior (match_operand:SI 1 "register_operand")
593 (match_operand:HI 1 "register_operand"))))
595 (and (eq_attr "type" "push")
596 (not (match_operand 1 "memory_operand")))
598 (and (eq_attr "type" "pop")
599 (not (match_operand 0 "memory_operand")))
601 (and (eq_attr "type" "imov")
602 (and (not (eq_attr "mode" "DI"))
603 (ior (and (match_operand 0 "register_operand")
604 (match_operand 1 "immediate_operand"))
605 (ior (and (match_operand 0 "ax_reg_operand")
606 (match_operand 1 "memory_displacement_only_operand"))
607 (and (match_operand 0 "memory_displacement_only_operand")
608 (match_operand 1 "ax_reg_operand"))))))
610 (and (eq_attr "type" "call")
611 (match_operand 0 "constant_call_address_operand"))
613 (and (eq_attr "type" "callv")
614 (match_operand 1 "constant_call_address_operand"))
616 (and (eq_attr "type" "alu,alu1,icmp,test")
617 (match_operand 0 "ax_reg_operand"))
618 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
622 ;; When this attribute is set, calculate total insn length from
623 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
624 (define_attr "length_nobnd" "" (const_int 0))
626 ;; The (bounding maximum) length of an instruction in bytes.
627 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
628 ;; Later we may want to split them and compute proper length as for
630 (define_attr "length" ""
631 (cond [(eq_attr "length_nobnd" "!0")
632 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
633 (attr "length_nobnd"))
634 (eq_attr "type" "other,multi,fistp,frndint")
636 (eq_attr "type" "fcmp")
638 (eq_attr "unit" "i387")
640 (plus (attr "prefix_data16")
641 (attr "length_address")))
642 (ior (eq_attr "prefix" "evex")
643 (and (ior (eq_attr "prefix" "maybe_evex")
644 (eq_attr "prefix" "maybe_vex"))
645 (match_test "TARGET_AVX512F")))
646 (plus (attr "length_evex")
647 (plus (attr "length_immediate")
649 (attr "length_address"))))
650 (ior (eq_attr "prefix" "vex")
651 (and (ior (eq_attr "prefix" "maybe_vex")
652 (eq_attr "prefix" "maybe_evex"))
653 (match_test "TARGET_AVX")))
654 (plus (attr "length_vex")
655 (plus (attr "length_immediate")
657 (attr "length_address"))))]
658 (plus (plus (attr "modrm")
659 (plus (attr "prefix_0f")
660 (plus (attr "prefix_rex")
661 (plus (attr "prefix_extra")
663 (plus (attr "prefix_rep")
664 (plus (attr "prefix_data16")
665 (plus (attr "length_immediate")
666 (attr "length_address")))))))
668 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
669 ;; `store' if there is a simple memory reference therein, or `unknown'
670 ;; if the instruction is complex.
672 (define_attr "memory" "none,load,store,both,unknown"
673 (cond [(eq_attr "type" "other,multi,str,lwp")
674 (const_string "unknown")
675 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
676 (const_string "none")
677 (eq_attr "type" "fistp,leave")
678 (const_string "both")
679 (eq_attr "type" "frndint")
680 (const_string "load")
681 (eq_attr "type" "mpxld")
682 (const_string "load")
683 (eq_attr "type" "mpxst")
684 (const_string "store")
685 (eq_attr "type" "push")
686 (if_then_else (match_operand 1 "memory_operand")
687 (const_string "both")
688 (const_string "store"))
689 (eq_attr "type" "pop")
690 (if_then_else (match_operand 0 "memory_operand")
691 (const_string "both")
692 (const_string "load"))
693 (eq_attr "type" "setcc")
694 (if_then_else (match_operand 0 "memory_operand")
695 (const_string "store")
696 (const_string "none"))
697 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
698 (if_then_else (ior (match_operand 0 "memory_operand")
699 (match_operand 1 "memory_operand"))
700 (const_string "load")
701 (const_string "none"))
702 (eq_attr "type" "ibr")
703 (if_then_else (match_operand 0 "memory_operand")
704 (const_string "load")
705 (const_string "none"))
706 (eq_attr "type" "call")
707 (if_then_else (match_operand 0 "constant_call_address_operand")
708 (const_string "none")
709 (const_string "load"))
710 (eq_attr "type" "callv")
711 (if_then_else (match_operand 1 "constant_call_address_operand")
712 (const_string "none")
713 (const_string "load"))
714 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
715 (match_operand 1 "memory_operand"))
716 (const_string "both")
717 (and (match_operand 0 "memory_operand")
718 (match_operand 1 "memory_operand"))
719 (const_string "both")
720 (match_operand 0 "memory_operand")
721 (const_string "store")
722 (match_operand 1 "memory_operand")
723 (const_string "load")
725 "!alu1,negnot,ishift1,
726 imov,imovx,icmp,test,bitmanip,
728 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
729 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
730 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
731 (match_operand 2 "memory_operand"))
732 (const_string "load")
733 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
734 (match_operand 3 "memory_operand"))
735 (const_string "load")
737 (const_string "none")))
739 ;; Indicates if an instruction has both an immediate and a displacement.
741 (define_attr "imm_disp" "false,true,unknown"
742 (cond [(eq_attr "type" "other,multi")
743 (const_string "unknown")
744 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
745 (and (match_operand 0 "memory_displacement_operand")
746 (match_operand 1 "immediate_operand")))
747 (const_string "true")
748 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
749 (and (match_operand 0 "memory_displacement_operand")
750 (match_operand 2 "immediate_operand")))
751 (const_string "true")
753 (const_string "false")))
755 ;; Indicates if an FP operation has an integer source.
757 (define_attr "fp_int_src" "false,true"
758 (const_string "false"))
760 ;; Defines rounding mode of an FP operation.
762 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
763 (const_string "any"))
765 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
766 (define_attr "use_carry" "0,1" (const_string "0"))
768 ;; Define attribute to indicate unaligned ssemov insns
769 (define_attr "movu" "0,1" (const_string "0"))
771 ;; Used to control the "enabled" attribute on a per-instruction basis.
772 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
773 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
774 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
775 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
776 (const_string "base"))
778 (define_attr "enabled" ""
779 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
780 (eq_attr "isa" "x64_sse4")
781 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
782 (eq_attr "isa" "x64_sse4_noavx")
783 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
784 (eq_attr "isa" "x64_avx")
785 (symbol_ref "TARGET_64BIT && TARGET_AVX")
786 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
787 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
788 (eq_attr "isa" "sse2_noavx")
789 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
790 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
791 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
792 (eq_attr "isa" "sse4_noavx")
793 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
794 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
795 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
796 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
797 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
798 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
799 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
800 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
801 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
802 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
803 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
804 (eq_attr "isa" "fma_avx512f")
805 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
806 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
807 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
808 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
809 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
813 (define_attr "preferred_for_speed" "" (const_int 1))
815 ;; Describe a user's asm statement.
816 (define_asm_attributes
817 [(set_attr "length" "128")
818 (set_attr "type" "multi")])
820 (define_code_iterator plusminus [plus minus])
822 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
824 (define_code_iterator multdiv [mult div])
826 ;; Base name for define_insn
827 (define_code_attr plusminus_insn
828 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
829 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
831 ;; Base name for insn mnemonic.
832 (define_code_attr plusminus_mnemonic
833 [(plus "add") (ss_plus "adds") (us_plus "addus")
834 (minus "sub") (ss_minus "subs") (us_minus "subus")])
835 (define_code_attr plusminus_carry_mnemonic
836 [(plus "adc") (minus "sbb")])
837 (define_code_attr multdiv_mnemonic
838 [(mult "mul") (div "div")])
840 ;; Mark commutative operators as such in constraints.
841 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
842 (minus "") (ss_minus "") (us_minus "")])
844 ;; Mapping of max and min
845 (define_code_iterator maxmin [smax smin umax umin])
847 ;; Mapping of signed max and min
848 (define_code_iterator smaxmin [smax smin])
850 ;; Mapping of unsigned max and min
851 (define_code_iterator umaxmin [umax umin])
853 ;; Base name for integer and FP insn mnemonic
854 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
855 (umax "maxu") (umin "minu")])
856 (define_code_attr maxmin_float [(smax "max") (smin "min")])
858 ;; Mapping of logic operators
859 (define_code_iterator any_logic [and ior xor])
860 (define_code_iterator any_or [ior xor])
861 (define_code_iterator fpint_logic [and xor])
863 ;; Base name for insn mnemonic.
864 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
866 ;; Mapping of logic-shift operators
867 (define_code_iterator any_lshift [ashift lshiftrt])
869 ;; Mapping of shift-right operators
870 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
872 ;; Mapping of all shift operators
873 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
875 ;; Base name for define_insn
876 (define_code_attr shift_insn
877 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
879 ;; Base name for insn mnemonic.
880 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
881 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
883 ;; Mapping of rotate operators
884 (define_code_iterator any_rotate [rotate rotatert])
886 ;; Base name for define_insn
887 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
889 ;; Base name for insn mnemonic.
890 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
892 ;; Mapping of abs neg operators
893 (define_code_iterator absneg [abs neg])
895 ;; Base name for x87 insn mnemonic.
896 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
898 ;; Used in signed and unsigned widening multiplications.
899 (define_code_iterator any_extend [sign_extend zero_extend])
901 ;; Prefix for insn menmonic.
902 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
904 ;; Prefix for define_insn
905 (define_code_attr u [(sign_extend "") (zero_extend "u")])
906 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
907 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
909 ;; Used in signed and unsigned truncations.
910 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
911 ;; Instruction suffix for truncations.
912 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
914 ;; Used in signed and unsigned fix.
915 (define_code_iterator any_fix [fix unsigned_fix])
916 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
918 ;; Used in signed and unsigned float.
919 (define_code_iterator any_float [float unsigned_float])
920 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
922 ;; All integer modes.
923 (define_mode_iterator SWI1248x [QI HI SI DI])
925 ;; All integer modes with AVX512BW.
926 (define_mode_iterator SWI1248_AVX512BW
927 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
929 ;; All integer modes without QImode.
930 (define_mode_iterator SWI248x [HI SI DI])
932 ;; All integer modes without QImode and HImode.
933 (define_mode_iterator SWI48x [SI DI])
935 ;; All integer modes without SImode and DImode.
936 (define_mode_iterator SWI12 [QI HI])
938 ;; All integer modes without DImode.
939 (define_mode_iterator SWI124 [QI HI SI])
941 ;; All integer modes without QImode and DImode.
942 (define_mode_iterator SWI24 [HI SI])
944 ;; Single word integer modes.
945 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
947 ;; Single word integer modes without QImode.
948 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
950 ;; Single word integer modes without QImode and HImode.
951 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
953 ;; All math-dependant single and double word integer modes.
954 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
955 (HI "TARGET_HIMODE_MATH")
956 SI DI (TI "TARGET_64BIT")])
958 ;; Math-dependant single word integer modes.
959 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
960 (HI "TARGET_HIMODE_MATH")
961 SI (DI "TARGET_64BIT")])
963 ;; Math-dependant integer modes without DImode.
964 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
965 (HI "TARGET_HIMODE_MATH")
968 ;; Math-dependant single word integer modes without QImode.
969 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
970 SI (DI "TARGET_64BIT")])
972 ;; Double word integer modes.
973 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
974 (TI "TARGET_64BIT")])
976 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
977 ;; compile time constant, it is faster to use <MODE_SIZE> than
978 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
979 ;; command line options just use GET_MODE_SIZE macro.
980 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
981 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
982 (V16QI "16") (V32QI "32") (V64QI "64")
983 (V8HI "16") (V16HI "32") (V32HI "64")
984 (V4SI "16") (V8SI "32") (V16SI "64")
985 (V2DI "16") (V4DI "32") (V8DI "64")
986 (V1TI "16") (V2TI "32") (V4TI "64")
987 (V2DF "16") (V4DF "32") (V8DF "64")
988 (V4SF "16") (V8SF "32") (V16SF "64")])
990 ;; Double word integer modes as mode attribute.
991 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
992 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
994 ;; Half mode for double word integer modes.
995 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
996 (DI "TARGET_64BIT")])
999 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1000 (BND64 "TARGET_LP64")])
1002 ;; Pointer mode corresponding to bound mode.
1003 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1006 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1009 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1011 (UNSPEC_BNDCN "cn")])
1013 ;; Instruction suffix for integer modes.
1014 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1016 ;; Instruction suffix for masks.
1017 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1019 ;; Pointer size prefix for integer modes (Intel asm dialect)
1020 (define_mode_attr iptrsize [(QI "BYTE")
1025 ;; Register class for integer modes.
1026 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1028 ;; Immediate operand constraint for integer modes.
1029 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1031 ;; General operand constraint for word modes.
1032 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1034 ;; Immediate operand constraint for double integer modes.
1035 (define_mode_attr di [(SI "nF") (DI "e")])
1037 ;; Immediate operand constraint for shifts.
1038 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1040 ;; General operand predicate for integer modes.
1041 (define_mode_attr general_operand
1042 [(QI "general_operand")
1043 (HI "general_operand")
1044 (SI "x86_64_general_operand")
1045 (DI "x86_64_general_operand")
1046 (TI "x86_64_general_operand")])
1048 ;; General sign extend operand predicate for integer modes,
1049 ;; which disallows VOIDmode operands and thus it is suitable
1050 ;; for use inside sign_extend.
1051 (define_mode_attr general_sext_operand
1052 [(QI "sext_operand")
1054 (SI "x86_64_sext_operand")
1055 (DI "x86_64_sext_operand")])
1057 ;; General sign/zero extend operand predicate for integer modes.
1058 (define_mode_attr general_szext_operand
1059 [(QI "general_operand")
1060 (HI "general_operand")
1061 (SI "x86_64_szext_general_operand")
1062 (DI "x86_64_szext_general_operand")])
1064 ;; Immediate operand predicate for integer modes.
1065 (define_mode_attr immediate_operand
1066 [(QI "immediate_operand")
1067 (HI "immediate_operand")
1068 (SI "x86_64_immediate_operand")
1069 (DI "x86_64_immediate_operand")])
1071 ;; Nonmemory operand predicate for integer modes.
1072 (define_mode_attr nonmemory_operand
1073 [(QI "nonmemory_operand")
1074 (HI "nonmemory_operand")
1075 (SI "x86_64_nonmemory_operand")
1076 (DI "x86_64_nonmemory_operand")])
1078 ;; Operand predicate for shifts.
1079 (define_mode_attr shift_operand
1080 [(QI "nonimmediate_operand")
1081 (HI "nonimmediate_operand")
1082 (SI "nonimmediate_operand")
1083 (DI "shiftdi_operand")
1084 (TI "register_operand")])
1086 ;; Operand predicate for shift argument.
1087 (define_mode_attr shift_immediate_operand
1088 [(QI "const_1_to_31_operand")
1089 (HI "const_1_to_31_operand")
1090 (SI "const_1_to_31_operand")
1091 (DI "const_1_to_63_operand")])
1093 ;; Input operand predicate for arithmetic left shifts.
1094 (define_mode_attr ashl_input_operand
1095 [(QI "nonimmediate_operand")
1096 (HI "nonimmediate_operand")
1097 (SI "nonimmediate_operand")
1098 (DI "ashldi_input_operand")
1099 (TI "reg_or_pm1_operand")])
1101 ;; SSE and x87 SFmode and DFmode floating point modes
1102 (define_mode_iterator MODEF [SF DF])
1104 ;; All x87 floating point modes
1105 (define_mode_iterator X87MODEF [SF DF XF])
1107 ;; SSE instruction suffix for various modes
1108 (define_mode_attr ssemodesuffix
1109 [(SF "ss") (DF "sd")
1110 (V16SF "ps") (V8DF "pd")
1111 (V8SF "ps") (V4DF "pd")
1112 (V4SF "ps") (V2DF "pd")
1113 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1114 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1115 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1117 ;; SSE vector suffix for floating point modes
1118 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1120 ;; SSE vector mode corresponding to a scalar mode
1121 (define_mode_attr ssevecmode
1122 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1123 (define_mode_attr ssevecmodelower
1124 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1126 ;; Instruction suffix for REX 64bit operators.
1127 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1129 ;; This mode iterator allows :P to be used for patterns that operate on
1130 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1131 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1133 ;; This mode iterator allows :W to be used for patterns that operate on
1134 ;; word_mode sized quantities.
1135 (define_mode_iterator W
1136 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1138 ;; This mode iterator allows :PTR to be used for patterns that operate on
1139 ;; ptr_mode sized quantities.
1140 (define_mode_iterator PTR
1141 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1143 ;; Scheduling descriptions
1145 (include "pentium.md")
1148 (include "athlon.md")
1149 (include "bdver1.md")
1150 (include "bdver3.md")
1151 (include "btver2.md")
1152 (include "geode.md")
1155 (include "core2.md")
1158 ;; Operand and operator predicates and constraints
1160 (include "predicates.md")
1161 (include "constraints.md")
1164 ;; Compare and branch/compare and store instructions.
1166 (define_expand "cbranch<mode>4"
1167 [(set (reg:CC FLAGS_REG)
1168 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1169 (match_operand:SDWIM 2 "<general_operand>")))
1170 (set (pc) (if_then_else
1171 (match_operator 0 "ordered_comparison_operator"
1172 [(reg:CC FLAGS_REG) (const_int 0)])
1173 (label_ref (match_operand 3))
1177 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1178 operands[1] = force_reg (<MODE>mode, operands[1]);
1179 ix86_expand_branch (GET_CODE (operands[0]),
1180 operands[1], operands[2], operands[3]);
1184 (define_expand "cstore<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1187 (match_operand:SWIM 3 "<general_operand>")))
1188 (set (match_operand:QI 0 "register_operand")
1189 (match_operator 1 "ordered_comparison_operator"
1190 [(reg:CC FLAGS_REG) (const_int 0)]))]
1193 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1194 operands[2] = force_reg (<MODE>mode, operands[2]);
1195 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1196 operands[2], operands[3]);
1200 (define_expand "cmp<mode>_1"
1201 [(set (reg:CC FLAGS_REG)
1202 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1203 (match_operand:SWI48 1 "<general_operand>")))])
1205 (define_insn "*cmp<mode>_ccno_1"
1206 [(set (reg FLAGS_REG)
1207 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1208 (match_operand:SWI 1 "const0_operand")))]
1209 "ix86_match_ccmode (insn, CCNOmode)"
1211 test{<imodesuffix>}\t%0, %0
1212 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1213 [(set_attr "type" "test,icmp")
1214 (set_attr "length_immediate" "0,1")
1215 (set_attr "mode" "<MODE>")])
1217 (define_insn "*cmp<mode>_1"
1218 [(set (reg FLAGS_REG)
1219 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1220 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1221 "ix86_match_ccmode (insn, CCmode)"
1222 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1223 [(set_attr "type" "icmp")
1224 (set_attr "mode" "<MODE>")])
1226 (define_insn "*cmp<mode>_minus_1"
1227 [(set (reg FLAGS_REG)
1229 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1230 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1232 "ix86_match_ccmode (insn, CCGOCmode)"
1233 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1234 [(set_attr "type" "icmp")
1235 (set_attr "mode" "<MODE>")])
1237 (define_insn "*cmpqi_ext_1"
1238 [(set (reg FLAGS_REG)
1240 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1243 (match_operand 1 "ext_register_operand" "Q,Q")
1245 (const_int 8)) 0)))]
1246 "ix86_match_ccmode (insn, CCmode)"
1247 "cmp{b}\t{%h1, %0|%0, %h1}"
1248 [(set_attr "isa" "*,nox64")
1249 (set_attr "type" "icmp")
1250 (set_attr "mode" "QI")])
1252 (define_insn "*cmpqi_ext_2"
1253 [(set (reg FLAGS_REG)
1257 (match_operand 0 "ext_register_operand" "Q")
1260 (match_operand:QI 1 "const0_operand")))]
1261 "ix86_match_ccmode (insn, CCNOmode)"
1263 [(set_attr "type" "test")
1264 (set_attr "length_immediate" "0")
1265 (set_attr "mode" "QI")])
1267 (define_expand "cmpqi_ext_3"
1268 [(set (reg:CC FLAGS_REG)
1272 (match_operand 0 "ext_register_operand")
1275 (match_operand:QI 1 "const_int_operand")))])
1277 (define_insn "*cmpqi_ext_3"
1278 [(set (reg FLAGS_REG)
1282 (match_operand 0 "ext_register_operand" "Q,Q")
1285 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1286 "ix86_match_ccmode (insn, CCmode)"
1287 "cmp{b}\t{%1, %h0|%h0, %1}"
1288 [(set_attr "isa" "*,nox64")
1289 (set_attr "type" "icmp")
1290 (set_attr "modrm" "1")
1291 (set_attr "mode" "QI")])
1293 (define_insn "*cmpqi_ext_4"
1294 [(set (reg FLAGS_REG)
1298 (match_operand 0 "ext_register_operand" "Q")
1303 (match_operand 1 "ext_register_operand" "Q")
1305 (const_int 8)) 0)))]
1306 "ix86_match_ccmode (insn, CCmode)"
1307 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1308 [(set_attr "type" "icmp")
1309 (set_attr "mode" "QI")])
1311 ;; These implement float point compares.
1312 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1313 ;; which would allow mix and match FP modes on the compares. Which is what
1314 ;; the old patterns did, but with many more of them.
1316 (define_expand "cbranchxf4"
1317 [(set (reg:CC FLAGS_REG)
1318 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1319 (match_operand:XF 2 "nonmemory_operand")))
1320 (set (pc) (if_then_else
1321 (match_operator 0 "ix86_fp_comparison_operator"
1324 (label_ref (match_operand 3))
1328 ix86_expand_branch (GET_CODE (operands[0]),
1329 operands[1], operands[2], operands[3]);
1333 (define_expand "cstorexf4"
1334 [(set (reg:CC FLAGS_REG)
1335 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1336 (match_operand:XF 3 "nonmemory_operand")))
1337 (set (match_operand:QI 0 "register_operand")
1338 (match_operator 1 "ix86_fp_comparison_operator"
1343 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1344 operands[2], operands[3]);
1348 (define_expand "cbranch<mode>4"
1349 [(set (reg:CC FLAGS_REG)
1350 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1351 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1352 (set (pc) (if_then_else
1353 (match_operator 0 "ix86_fp_comparison_operator"
1356 (label_ref (match_operand 3))
1358 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1360 ix86_expand_branch (GET_CODE (operands[0]),
1361 operands[1], operands[2], operands[3]);
1365 (define_expand "cstore<mode>4"
1366 [(set (reg:CC FLAGS_REG)
1367 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1368 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1369 (set (match_operand:QI 0 "register_operand")
1370 (match_operator 1 "ix86_fp_comparison_operator"
1373 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1375 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1376 operands[2], operands[3]);
1380 (define_expand "cbranchcc4"
1381 [(set (pc) (if_then_else
1382 (match_operator 0 "comparison_operator"
1383 [(match_operand 1 "flags_reg_operand")
1384 (match_operand 2 "const0_operand")])
1385 (label_ref (match_operand 3))
1389 ix86_expand_branch (GET_CODE (operands[0]),
1390 operands[1], operands[2], operands[3]);
1394 (define_expand "cstorecc4"
1395 [(set (match_operand:QI 0 "register_operand")
1396 (match_operator 1 "comparison_operator"
1397 [(match_operand 2 "flags_reg_operand")
1398 (match_operand 3 "const0_operand")]))]
1401 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1402 operands[2], operands[3]);
1407 ;; FP compares, step 1:
1408 ;; Set the FP condition codes.
1410 ;; CCFPmode compare with exceptions
1411 ;; CCFPUmode compare with no exceptions
1413 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1414 ;; used to manage the reg stack popping would not be preserved.
1416 (define_insn "*cmp<mode>_0_i387"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (match_operand:X87MODEF 1 "register_operand" "f")
1421 (match_operand:X87MODEF 2 "const0_operand"))]
1424 "* return output_fp_compare (insn, operands, false, false);"
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "mode" "<MODE>")])
1429 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1430 [(set (reg:CCFP FLAGS_REG)
1432 (match_operand:X87MODEF 1 "register_operand" "f")
1433 (match_operand:X87MODEF 2 "const0_operand")))
1434 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1435 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1437 "&& reload_completed"
1440 [(compare:CCFP (match_dup 1)(match_dup 2))]
1442 (set (reg:CC FLAGS_REG)
1443 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1449 (define_insn "*cmpxf_i387"
1450 [(set (match_operand:HI 0 "register_operand" "=a")
1453 (match_operand:XF 1 "register_operand" "f")
1454 (match_operand:XF 2 "register_operand" "f"))]
1457 "* return output_fp_compare (insn, operands, false, false);"
1458 [(set_attr "type" "multi")
1459 (set_attr "unit" "i387")
1460 (set_attr "mode" "XF")])
1462 (define_insn_and_split "*cmpxf_cc_i387"
1463 [(set (reg:CCFP FLAGS_REG)
1465 (match_operand:XF 1 "register_operand" "f")
1466 (match_operand:XF 2 "register_operand" "f")))
1467 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1470 "&& reload_completed"
1473 [(compare:CCFP (match_dup 1)(match_dup 2))]
1475 (set (reg:CC FLAGS_REG)
1476 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1478 [(set_attr "type" "multi")
1479 (set_attr "unit" "i387")
1480 (set_attr "mode" "XF")])
1482 (define_insn "*cmp<mode>_i387"
1483 [(set (match_operand:HI 0 "register_operand" "=a")
1486 (match_operand:MODEF 1 "register_operand" "f")
1487 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1490 "* return output_fp_compare (insn, operands, false, false);"
1491 [(set_attr "type" "multi")
1492 (set_attr "unit" "i387")
1493 (set_attr "mode" "<MODE>")])
1495 (define_insn_and_split "*cmp<mode>_cc_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1498 (match_operand:MODEF 1 "register_operand" "f")
1499 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1500 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1501 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1503 "&& reload_completed"
1506 [(compare:CCFP (match_dup 1)(match_dup 2))]
1508 (set (reg:CC FLAGS_REG)
1509 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1511 [(set_attr "type" "multi")
1512 (set_attr "unit" "i387")
1513 (set_attr "mode" "<MODE>")])
1515 (define_insn "*cmpu<mode>_i387"
1516 [(set (match_operand:HI 0 "register_operand" "=a")
1519 (match_operand:X87MODEF 1 "register_operand" "f")
1520 (match_operand:X87MODEF 2 "register_operand" "f"))]
1523 "* return output_fp_compare (insn, operands, false, true);"
1524 [(set_attr "type" "multi")
1525 (set_attr "unit" "i387")
1526 (set_attr "mode" "<MODE>")])
1528 (define_insn_and_split "*cmpu<mode>_cc_i387"
1529 [(set (reg:CCFPU FLAGS_REG)
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1532 (match_operand:X87MODEF 2 "register_operand" "f")))
1533 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1534 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1536 "&& reload_completed"
1539 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1541 (set (reg:CC FLAGS_REG)
1542 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1544 [(set_attr "type" "multi")
1545 (set_attr "unit" "i387")
1546 (set_attr "mode" "<MODE>")])
1548 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1549 [(set (match_operand:HI 0 "register_operand" "=a")
1552 (match_operand:X87MODEF 1 "register_operand" "f")
1553 (match_operator:X87MODEF 3 "float_operator"
1554 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1557 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1558 || optimize_function_for_size_p (cfun))"
1559 "* return output_fp_compare (insn, operands, false, false);"
1560 [(set_attr "type" "multi")
1561 (set_attr "unit" "i387")
1562 (set_attr "fp_int_src" "true")
1563 (set_attr "mode" "<SWI24:MODE>")])
1565 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1566 [(set (reg:CCFP FLAGS_REG)
1568 (match_operand:X87MODEF 1 "register_operand" "f")
1569 (match_operator:X87MODEF 3 "float_operator"
1570 [(match_operand:SWI24 2 "memory_operand" "m")])))
1571 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1572 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1573 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1574 || optimize_function_for_size_p (cfun))"
1576 "&& reload_completed"
1581 (match_op_dup 3 [(match_dup 2)]))]
1583 (set (reg:CC FLAGS_REG)
1584 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1586 [(set_attr "type" "multi")
1587 (set_attr "unit" "i387")
1588 (set_attr "fp_int_src" "true")
1589 (set_attr "mode" "<SWI24:MODE>")])
1591 ;; FP compares, step 2
1592 ;; Move the fpsw to ax.
1594 (define_insn "x86_fnstsw_1"
1595 [(set (match_operand:HI 0 "register_operand" "=a")
1596 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1599 [(set_attr "length" "2")
1600 (set_attr "mode" "SI")
1601 (set_attr "unit" "i387")])
1603 ;; FP compares, step 3
1604 ;; Get ax into flags, general case.
1606 (define_insn "x86_sahf_1"
1607 [(set (reg:CC FLAGS_REG)
1608 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1612 #ifndef HAVE_AS_IX86_SAHF
1614 return ASM_BYTE "0x9e";
1619 [(set_attr "length" "1")
1620 (set_attr "athlon_decode" "vector")
1621 (set_attr "amdfam10_decode" "direct")
1622 (set_attr "bdver1_decode" "direct")
1623 (set_attr "mode" "SI")])
1625 ;; Pentium Pro can do steps 1 through 3 in one go.
1626 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1627 ;; (these i387 instructions set flags directly)
1629 (define_mode_iterator FPCMP [CCFP CCFPU])
1630 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1632 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1633 [(set (reg:FPCMP FLAGS_REG)
1635 (match_operand:MODEF 0 "register_operand" "f,x")
1636 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1637 "TARGET_MIX_SSE_I387
1638 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1639 "* return output_fp_compare (insn, operands, true,
1640 <FPCMP:MODE>mode == CCFPUmode);"
1641 [(set_attr "type" "fcmp,ssecomi")
1642 (set_attr "prefix" "orig,maybe_vex")
1643 (set_attr "mode" "<MODEF:MODE>")
1644 (set (attr "prefix_rep")
1645 (if_then_else (eq_attr "type" "ssecomi")
1647 (const_string "*")))
1648 (set (attr "prefix_data16")
1649 (cond [(eq_attr "type" "fcmp")
1651 (eq_attr "mode" "DF")
1654 (const_string "0")))
1655 (set_attr "athlon_decode" "vector")
1656 (set_attr "amdfam10_decode" "direct")
1657 (set_attr "bdver1_decode" "double")])
1659 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1660 [(set (reg:FPCMP FLAGS_REG)
1662 (match_operand:MODEF 0 "register_operand" "x")
1663 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1665 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1666 "* return output_fp_compare (insn, operands, true,
1667 <FPCMP:MODE>mode == CCFPUmode);"
1668 [(set_attr "type" "ssecomi")
1669 (set_attr "prefix" "maybe_vex")
1670 (set_attr "mode" "<MODEF:MODE>")
1671 (set_attr "prefix_rep" "0")
1672 (set (attr "prefix_data16")
1673 (if_then_else (eq_attr "mode" "DF")
1675 (const_string "0")))
1676 (set_attr "athlon_decode" "vector")
1677 (set_attr "amdfam10_decode" "direct")
1678 (set_attr "bdver1_decode" "double")])
1680 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1681 [(set (reg:FPCMP FLAGS_REG)
1683 (match_operand:X87MODEF 0 "register_operand" "f")
1684 (match_operand:X87MODEF 1 "register_operand" "f")))]
1685 "TARGET_80387 && TARGET_CMOVE
1686 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1687 "* return output_fp_compare (insn, operands, true,
1688 <FPCMP:MODE>mode == CCFPUmode);"
1689 [(set_attr "type" "fcmp")
1690 (set_attr "mode" "<X87MODEF:MODE>")
1691 (set_attr "athlon_decode" "vector")
1692 (set_attr "amdfam10_decode" "direct")
1693 (set_attr "bdver1_decode" "double")])
1695 ;; Push/pop instructions.
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:DWI 0 "push_operand" "=<")
1699 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1702 [(set_attr "type" "multi")
1703 (set_attr "mode" "<MODE>")])
1706 [(set (match_operand:TI 0 "push_operand")
1707 (match_operand:TI 1 "general_operand"))]
1708 "TARGET_64BIT && reload_completed
1709 && !SSE_REG_P (operands[1])"
1711 "ix86_split_long_move (operands); DONE;")
1713 (define_insn "*pushdi2_rex64"
1714 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1715 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1720 [(set_attr "type" "push,multi")
1721 (set_attr "mode" "DI")])
1723 ;; Convert impossible pushes of immediate to existing instructions.
1724 ;; First try to get scratch register and go through it. In case this
1725 ;; fails, push sign extended lower part first and then overwrite
1726 ;; upper part by 32bit move.
1728 [(match_scratch:DI 2 "r")
1729 (set (match_operand:DI 0 "push_operand")
1730 (match_operand:DI 1 "immediate_operand"))]
1731 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1732 && !x86_64_immediate_operand (operands[1], DImode)"
1733 [(set (match_dup 2) (match_dup 1))
1734 (set (match_dup 0) (match_dup 2))])
1736 ;; We need to define this as both peepholer and splitter for case
1737 ;; peephole2 pass is not run.
1738 ;; "&& 1" is needed to keep it from matching the previous pattern.
1740 [(set (match_operand:DI 0 "push_operand")
1741 (match_operand:DI 1 "immediate_operand"))]
1742 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1743 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1744 [(set (match_dup 0) (match_dup 1))
1745 (set (match_dup 2) (match_dup 3))]
1747 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1749 operands[1] = gen_lowpart (DImode, operands[2]);
1750 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1755 [(set (match_operand:DI 0 "push_operand")
1756 (match_operand:DI 1 "immediate_operand"))]
1757 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1758 ? epilogue_completed : reload_completed)
1759 && !symbolic_operand (operands[1], DImode)
1760 && !x86_64_immediate_operand (operands[1], DImode)"
1761 [(set (match_dup 0) (match_dup 1))
1762 (set (match_dup 2) (match_dup 3))]
1764 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1766 operands[1] = gen_lowpart (DImode, operands[2]);
1767 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1772 [(set (match_operand:DI 0 "push_operand")
1773 (match_operand:DI 1 "general_operand"))]
1774 "!TARGET_64BIT && reload_completed
1775 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1777 "ix86_split_long_move (operands); DONE;")
1779 (define_insn "*pushsi2"
1780 [(set (match_operand:SI 0 "push_operand" "=<")
1781 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1784 [(set_attr "type" "push")
1785 (set_attr "mode" "SI")])
1787 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1788 ;; "push a byte/word". But actually we use pushl, which has the effect
1789 ;; of rounding the amount pushed up to a word.
1791 ;; For TARGET_64BIT we always round up to 8 bytes.
1792 (define_insn "*push<mode>2_rex64"
1793 [(set (match_operand:SWI124 0 "push_operand" "=X")
1794 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1797 [(set_attr "type" "push")
1798 (set_attr "mode" "DI")])
1800 (define_insn "*push<mode>2"
1801 [(set (match_operand:SWI12 0 "push_operand" "=X")
1802 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1805 [(set_attr "type" "push")
1806 (set_attr "mode" "SI")])
1808 (define_insn "*push<mode>2_prologue"
1809 [(set (match_operand:W 0 "push_operand" "=<")
1810 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1811 (clobber (mem:BLK (scratch)))]
1813 "push{<imodesuffix>}\t%1"
1814 [(set_attr "type" "push")
1815 (set_attr "mode" "<MODE>")])
1817 (define_insn "*pop<mode>1"
1818 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1819 (match_operand:W 1 "pop_operand" ">"))]
1821 "pop{<imodesuffix>}\t%0"
1822 [(set_attr "type" "pop")
1823 (set_attr "mode" "<MODE>")])
1825 (define_insn "*pop<mode>1_epilogue"
1826 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1827 (match_operand:W 1 "pop_operand" ">"))
1828 (clobber (mem:BLK (scratch)))]
1830 "pop{<imodesuffix>}\t%0"
1831 [(set_attr "type" "pop")
1832 (set_attr "mode" "<MODE>")])
1834 (define_insn "*pushfl<mode>2"
1835 [(set (match_operand:W 0 "push_operand" "=<")
1836 (match_operand:W 1 "flags_reg_operand"))]
1838 "pushf{<imodesuffix>}"
1839 [(set_attr "type" "push")
1840 (set_attr "mode" "<MODE>")])
1842 (define_insn "*popfl<mode>1"
1843 [(set (match_operand:W 0 "flags_reg_operand")
1844 (match_operand:W 1 "pop_operand" ">"))]
1846 "popf{<imodesuffix>}"
1847 [(set_attr "type" "pop")
1848 (set_attr "mode" "<MODE>")])
1851 ;; Move instructions.
1853 (define_expand "movxi"
1854 [(set (match_operand:XI 0 "nonimmediate_operand")
1855 (match_operand:XI 1 "general_operand"))]
1857 "ix86_expand_move (XImode, operands); DONE;")
1859 ;; Reload patterns to support multi-word load/store
1860 ;; with non-offsetable address.
1861 (define_expand "reload_noff_store"
1862 [(parallel [(match_operand 0 "memory_operand" "=m")
1863 (match_operand 1 "register_operand" "r")
1864 (match_operand:DI 2 "register_operand" "=&r")])]
1867 rtx mem = operands[0];
1868 rtx addr = XEXP (mem, 0);
1870 emit_move_insn (operands[2], addr);
1871 mem = replace_equiv_address_nv (mem, operands[2]);
1873 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1877 (define_expand "reload_noff_load"
1878 [(parallel [(match_operand 0 "register_operand" "=r")
1879 (match_operand 1 "memory_operand" "m")
1880 (match_operand:DI 2 "register_operand" "=r")])]
1883 rtx mem = operands[1];
1884 rtx addr = XEXP (mem, 0);
1886 emit_move_insn (operands[2], addr);
1887 mem = replace_equiv_address_nv (mem, operands[2]);
1889 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1893 (define_expand "movoi"
1894 [(set (match_operand:OI 0 "nonimmediate_operand")
1895 (match_operand:OI 1 "general_operand"))]
1897 "ix86_expand_move (OImode, operands); DONE;")
1899 (define_expand "movti"
1900 [(set (match_operand:TI 0 "nonimmediate_operand")
1901 (match_operand:TI 1 "nonimmediate_operand"))]
1902 "TARGET_64BIT || TARGET_SSE"
1905 ix86_expand_move (TImode, operands);
1907 ix86_expand_vector_move (TImode, operands);
1911 ;; This expands to what emit_move_complex would generate if we didn't
1912 ;; have a movti pattern. Having this avoids problems with reload on
1913 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1914 ;; to have around all the time.
1915 (define_expand "movcdi"
1916 [(set (match_operand:CDI 0 "nonimmediate_operand")
1917 (match_operand:CDI 1 "general_operand"))]
1920 if (push_operand (operands[0], CDImode))
1921 emit_move_complex_push (CDImode, operands[0], operands[1]);
1923 emit_move_complex_parts (operands[0], operands[1]);
1927 (define_expand "mov<mode>"
1928 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1929 (match_operand:SWI1248x 1 "general_operand"))]
1931 "ix86_expand_move (<MODE>mode, operands); DONE;")
1933 (define_insn "*mov<mode>_xor"
1934 [(set (match_operand:SWI48 0 "register_operand" "=r")
1935 (match_operand:SWI48 1 "const0_operand"))
1936 (clobber (reg:CC FLAGS_REG))]
1939 [(set_attr "type" "alu1")
1940 (set_attr "mode" "SI")
1941 (set_attr "length_immediate" "0")])
1943 (define_insn "*mov<mode>_or"
1944 [(set (match_operand:SWI48 0 "register_operand" "=r")
1945 (match_operand:SWI48 1 "const_int_operand"))
1946 (clobber (reg:CC FLAGS_REG))]
1948 && operands[1] == constm1_rtx"
1949 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1950 [(set_attr "type" "alu1")
1951 (set_attr "mode" "<MODE>")
1952 (set_attr "length_immediate" "1")])
1954 (define_insn "*movxi_internal_avx512f"
1955 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1956 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1957 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1959 switch (which_alternative)
1962 return standard_sse_constant_opcode (insn, operands[1]);
1965 if (misaligned_operand (operands[0], XImode)
1966 || misaligned_operand (operands[1], XImode))
1967 return "vmovdqu32\t{%1, %0|%0, %1}";
1969 return "vmovdqa32\t{%1, %0|%0, %1}";
1974 [(set_attr "type" "sselog1,ssemov,ssemov")
1975 (set_attr "prefix" "evex")
1976 (set_attr "mode" "XI")])
1978 (define_insn "*movoi_internal_avx"
1979 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1980 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1981 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 return standard_sse_constant_opcode (insn, operands[1]);
1989 if (misaligned_operand (operands[0], OImode)
1990 || misaligned_operand (operands[1], OImode))
1992 if (get_attr_mode (insn) == MODE_V8SF)
1993 return "vmovups\t{%1, %0|%0, %1}";
1994 else if (get_attr_mode (insn) == MODE_XI)
1995 return "vmovdqu32\t{%1, %0|%0, %1}";
1997 return "vmovdqu\t{%1, %0|%0, %1}";
2001 if (get_attr_mode (insn) == MODE_V8SF)
2002 return "vmovaps\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqa32\t{%1, %0|%0, %1}";
2006 return "vmovdqa\t{%1, %0|%0, %1}";
2013 [(set_attr "type" "sselog1,ssemov,ssemov")
2014 (set_attr "prefix" "vex")
2016 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2017 (match_operand 1 "ext_sse_reg_operand"))
2019 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2020 (const_string "V8SF")
2021 (and (eq_attr "alternative" "2")
2022 (match_test "TARGET_SSE_TYPELESS_STORES"))
2023 (const_string "V8SF")
2025 (const_string "OI")))])
2027 (define_insn "*movti_internal"
2028 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2029 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2030 "(TARGET_64BIT || TARGET_SSE)
2031 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2033 switch (get_attr_type (insn))
2039 return standard_sse_constant_opcode (insn, operands[1]);
2042 /* TDmode values are passed as TImode on the stack. Moving them
2043 to stack may result in unaligned memory access. */
2044 if (misaligned_operand (operands[0], TImode)
2045 || misaligned_operand (operands[1], TImode))
2047 if (get_attr_mode (insn) == MODE_V4SF)
2048 return "%vmovups\t{%1, %0|%0, %1}";
2049 else if (get_attr_mode (insn) == MODE_XI)
2050 return "vmovdqu32\t{%1, %0|%0, %1}";
2052 return "%vmovdqu\t{%1, %0|%0, %1}";
2056 if (get_attr_mode (insn) == MODE_V4SF)
2057 return "%vmovaps\t{%1, %0|%0, %1}";
2058 else if (get_attr_mode (insn) == MODE_XI)
2059 return "vmovdqa32\t{%1, %0|%0, %1}";
2061 return "%vmovdqa\t{%1, %0|%0, %1}";
2068 [(set_attr "isa" "x64,x64,*,*,*")
2069 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2070 (set (attr "prefix")
2071 (if_then_else (eq_attr "type" "sselog1,ssemov")
2072 (const_string "maybe_vex")
2073 (const_string "orig")))
2075 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2076 (match_operand 1 "ext_sse_reg_operand"))
2078 (eq_attr "alternative" "0,1")
2080 (ior (not (match_test "TARGET_SSE2"))
2081 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2082 (const_string "V4SF")
2083 (and (eq_attr "alternative" "4")
2084 (match_test "TARGET_SSE_TYPELESS_STORES"))
2085 (const_string "V4SF")
2086 (match_test "TARGET_AVX")
2088 (match_test "optimize_function_for_size_p (cfun)")
2089 (const_string "V4SF")
2091 (const_string "TI")))])
2094 [(set (match_operand:TI 0 "nonimmediate_operand")
2095 (match_operand:TI 1 "general_operand"))]
2097 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2099 "ix86_split_long_move (operands); DONE;")
2101 (define_insn "*movdi_internal"
2102 [(set (match_operand:DI 0 "nonimmediate_operand"
2103 "=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")
2104 (match_operand:DI 1 "general_operand"
2105 "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"))]
2106 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2108 switch (get_attr_type (insn))
2111 return "kmovq\t{%1, %0|%0, %1}";
2117 return "pxor\t%0, %0";
2120 /* Handle broken assemblers that require movd instead of movq. */
2121 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2122 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2123 return "movd\t{%1, %0|%0, %1}";
2124 return "movq\t{%1, %0|%0, %1}";
2127 if (GENERAL_REG_P (operands[0]))
2128 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2130 return standard_sse_constant_opcode (insn, operands[1]);
2133 switch (get_attr_mode (insn))
2136 /* Handle broken assemblers that require movd instead of movq. */
2137 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2138 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2139 return "%vmovd\t{%1, %0|%0, %1}";
2140 return "%vmovq\t{%1, %0|%0, %1}";
2142 return "%vmovdqa\t{%1, %0|%0, %1}";
2144 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2147 gcc_assert (!TARGET_AVX);
2148 return "movlps\t{%1, %0|%0, %1}";
2150 return "%vmovaps\t{%1, %0|%0, %1}";
2157 if (SSE_REG_P (operands[0]))
2158 return "movq2dq\t{%1, %0|%0, %1}";
2160 return "movdq2q\t{%1, %0|%0, %1}";
2163 return "lea{q}\t{%E1, %0|%0, %E1}";
2166 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2167 if (get_attr_mode (insn) == MODE_SI)
2168 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2169 else if (which_alternative == 4)
2170 return "movabs{q}\t{%1, %0|%0, %1}";
2171 else if (ix86_use_lea_for_mov (insn, operands))
2172 return "lea{q}\t{%E1, %0|%0, %E1}";
2174 return "mov{q}\t{%1, %0|%0, %1}";
2181 (cond [(eq_attr "alternative" "0,1")
2182 (const_string "nox64")
2183 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2184 (const_string "x64")
2185 (eq_attr "alternative" "17")
2186 (const_string "x64_sse4")
2188 (const_string "*")))
2190 (cond [(eq_attr "alternative" "0,1")
2191 (const_string "multi")
2192 (eq_attr "alternative" "6")
2193 (const_string "mmx")
2194 (eq_attr "alternative" "7,8,9,10,11")
2195 (const_string "mmxmov")
2196 (eq_attr "alternative" "12,17")
2197 (const_string "sselog1")
2198 (eq_attr "alternative" "13,14,15,16,18")
2199 (const_string "ssemov")
2200 (eq_attr "alternative" "19,20")
2201 (const_string "ssecvt")
2202 (eq_attr "alternative" "21,22,23,24")
2203 (const_string "mskmov")
2204 (match_operand 1 "pic_32bit_operand")
2205 (const_string "lea")
2207 (const_string "imov")))
2210 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2212 (const_string "*")))
2213 (set (attr "length_immediate")
2214 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2216 (eq_attr "alternative" "17")
2219 (const_string "*")))
2220 (set (attr "prefix_rex")
2221 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2223 (const_string "*")))
2224 (set (attr "prefix_extra")
2225 (if_then_else (eq_attr "alternative" "17")
2227 (const_string "*")))
2228 (set (attr "prefix")
2229 (if_then_else (eq_attr "type" "sselog1,ssemov")
2230 (const_string "maybe_vex")
2231 (const_string "orig")))
2232 (set (attr "prefix_data16")
2233 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2235 (const_string "*")))
2237 (cond [(eq_attr "alternative" "2")
2239 (eq_attr "alternative" "12,13")
2240 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2241 (match_operand 1 "ext_sse_reg_operand"))
2243 (ior (not (match_test "TARGET_SSE2"))
2244 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2245 (const_string "V4SF")
2246 (match_test "TARGET_AVX")
2248 (match_test "optimize_function_for_size_p (cfun)")
2249 (const_string "V4SF")
2251 (const_string "TI"))
2253 (and (eq_attr "alternative" "14,15")
2254 (not (match_test "TARGET_SSE2")))
2255 (const_string "V2SF")
2256 (eq_attr "alternative" "17")
2259 (const_string "DI")))])
2262 [(set (match_operand:DI 0 "nonimmediate_operand")
2263 (match_operand:DI 1 "general_operand"))]
2264 "!TARGET_64BIT && reload_completed
2265 && !(MMX_REG_P (operands[0])
2266 || SSE_REG_P (operands[0])
2267 || MASK_REG_P (operands[0]))
2268 && !(MMX_REG_P (operands[1])
2269 || SSE_REG_P (operands[1])
2270 || MASK_REG_P (operands[1]))"
2272 "ix86_split_long_move (operands); DONE;")
2274 (define_insn "*movsi_internal"
2275 [(set (match_operand:SI 0 "nonimmediate_operand"
2276 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2277 (match_operand:SI 1 "general_operand"
2278 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2281 switch (get_attr_type (insn))
2284 if (GENERAL_REG_P (operands[0]))
2285 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2287 return standard_sse_constant_opcode (insn, operands[1]);
2290 return "kmovd\t{%1, %0|%0, %1}";
2293 switch (get_attr_mode (insn))
2296 return "%vmovd\t{%1, %0|%0, %1}";
2298 return "%vmovdqa\t{%1, %0|%0, %1}";
2300 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2303 return "%vmovaps\t{%1, %0|%0, %1}";
2306 gcc_assert (!TARGET_AVX);
2307 return "movss\t{%1, %0|%0, %1}";
2314 return "pxor\t%0, %0";
2317 switch (get_attr_mode (insn))
2320 return "movq\t{%1, %0|%0, %1}";
2322 return "movd\t{%1, %0|%0, %1}";
2329 return "lea{l}\t{%E1, %0|%0, %E1}";
2332 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2333 if (ix86_use_lea_for_mov (insn, operands))
2334 return "lea{l}\t{%E1, %0|%0, %E1}";
2336 return "mov{l}\t{%1, %0|%0, %1}";
2343 (if_then_else (eq_attr "alternative" "11")
2344 (const_string "sse4")
2345 (const_string "*")))
2347 (cond [(eq_attr "alternative" "2")
2348 (const_string "mmx")
2349 (eq_attr "alternative" "3,4,5")
2350 (const_string "mmxmov")
2351 (eq_attr "alternative" "6,11")
2352 (const_string "sselog1")
2353 (eq_attr "alternative" "7,8,9,10,12")
2354 (const_string "ssemov")
2355 (eq_attr "alternative" "13,14")
2356 (const_string "mskmov")
2357 (match_operand 1 "pic_32bit_operand")
2358 (const_string "lea")
2360 (const_string "imov")))
2361 (set (attr "length_immediate")
2362 (if_then_else (eq_attr "alternative" "11")
2364 (const_string "*")))
2365 (set (attr "prefix_extra")
2366 (if_then_else (eq_attr "alternative" "11")
2368 (const_string "*")))
2369 (set (attr "prefix")
2370 (if_then_else (eq_attr "type" "sselog1,ssemov")
2371 (const_string "maybe_vex")
2372 (const_string "orig")))
2373 (set (attr "prefix_data16")
2374 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2376 (const_string "*")))
2378 (cond [(eq_attr "alternative" "2,3")
2380 (eq_attr "alternative" "6,7")
2381 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2382 (match_operand 1 "ext_sse_reg_operand"))
2384 (ior (not (match_test "TARGET_SSE2"))
2385 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2386 (const_string "V4SF")
2387 (match_test "TARGET_AVX")
2389 (match_test "optimize_function_for_size_p (cfun)")
2390 (const_string "V4SF")
2392 (const_string "TI"))
2394 (and (eq_attr "alternative" "8,9")
2395 (not (match_test "TARGET_SSE2")))
2397 (eq_attr "alternative" "11")
2400 (const_string "SI")))])
2402 (define_insn "kmovw"
2403 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2405 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2407 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2409 kmovw\t{%k1, %0|%0, %k1}
2410 kmovw\t{%1, %0|%0, %1}";
2411 [(set_attr "mode" "HI")
2412 (set_attr "type" "mskmov")
2413 (set_attr "prefix" "vex")])
2416 (define_insn "*movhi_internal"
2417 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2418 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2419 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2421 switch (get_attr_type (insn))
2424 /* movzwl is faster than movw on p2 due to partial word stalls,
2425 though not as fast as an aligned movl. */
2426 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2429 switch (which_alternative)
2431 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2432 case 5: return "kmovw\t{%1, %0|%0, %1}";
2433 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2434 default: gcc_unreachable ();
2438 if (get_attr_mode (insn) == MODE_SI)
2439 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2441 return "mov{w}\t{%1, %0|%0, %1}";
2445 (cond [(eq_attr "alternative" "4,5,6")
2446 (const_string "mskmov")
2447 (match_test "optimize_function_for_size_p (cfun)")
2448 (const_string "imov")
2449 (and (eq_attr "alternative" "0")
2450 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2451 (not (match_test "TARGET_HIMODE_MATH"))))
2452 (const_string "imov")
2453 (and (eq_attr "alternative" "1,2")
2454 (match_operand:HI 1 "aligned_operand"))
2455 (const_string "imov")
2456 (and (match_test "TARGET_MOVX")
2457 (eq_attr "alternative" "0,2"))
2458 (const_string "imovx")
2460 (const_string "imov")))
2461 (set (attr "prefix")
2462 (if_then_else (eq_attr "alternative" "4,5,6")
2463 (const_string "vex")
2464 (const_string "orig")))
2466 (cond [(eq_attr "type" "imovx")
2468 (and (eq_attr "alternative" "1,2")
2469 (match_operand:HI 1 "aligned_operand"))
2471 (and (eq_attr "alternative" "0")
2472 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2473 (not (match_test "TARGET_HIMODE_MATH"))))
2476 (const_string "HI")))])
2478 ;; Situation is quite tricky about when to choose full sized (SImode) move
2479 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2480 ;; partial register dependency machines (such as AMD Athlon), where QImode
2481 ;; moves issue extra dependency and for partial register stalls machines
2482 ;; that don't use QImode patterns (and QImode move cause stall on the next
2485 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2486 ;; register stall machines with, where we use QImode instructions, since
2487 ;; partial register stall can be caused there. Then we use movzx.
2489 (define_insn "*movqi_internal"
2490 [(set (match_operand:QI 0 "nonimmediate_operand"
2491 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2492 (match_operand:QI 1 "general_operand"
2493 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2494 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2496 switch (get_attr_type (insn))
2499 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2500 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2503 switch (which_alternative)
2505 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2506 : "kmovw\t{%k1, %0|%0, %k1}";
2507 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2508 : "kmovw\t{%1, %0|%0, %1}";
2509 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2510 : "kmovw\t{%1, %k0|%k0, %1}";
2513 gcc_assert (TARGET_AVX512DQ);
2514 return "kmovb\t{%1, %0|%0, %1}";
2515 default: gcc_unreachable ();
2519 if (get_attr_mode (insn) == MODE_SI)
2520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522 return "mov{b}\t{%1, %0|%0, %1}";
2525 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2527 (cond [(eq_attr "alternative" "3,5")
2528 (const_string "imovx")
2529 (eq_attr "alternative" "7,8,9,10,11")
2530 (const_string "mskmov")
2531 (and (eq_attr "alternative" "5")
2532 (not (match_operand:QI 1 "aligned_operand")))
2533 (const_string "imovx")
2534 (match_test "optimize_function_for_size_p (cfun)")
2535 (const_string "imov")
2536 (and (eq_attr "alternative" "3")
2537 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2538 (not (match_test "TARGET_QIMODE_MATH"))))
2539 (const_string "imov")
2540 (and (match_test "TARGET_MOVX")
2541 (eq_attr "alternative" "2"))
2542 (const_string "imovx")
2544 (const_string "imov")))
2545 (set (attr "prefix")
2546 (if_then_else (eq_attr "alternative" "7,8,9")
2547 (const_string "vex")
2548 (const_string "orig")))
2550 (cond [(eq_attr "alternative" "3,4,5")
2552 (eq_attr "alternative" "6")
2554 (eq_attr "type" "imovx")
2556 (and (eq_attr "type" "imov")
2557 (and (eq_attr "alternative" "0,1")
2558 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2559 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2560 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2562 ;; Avoid partial register stalls when not using QImode arithmetic
2563 (and (eq_attr "type" "imov")
2564 (and (eq_attr "alternative" "0,1")
2565 (and (match_test "TARGET_PARTIAL_REG_STALL")
2566 (not (match_test "TARGET_QIMODE_MATH")))))
2569 (const_string "QI")))])
2571 ;; Stores and loads of ax to arbitrary constant address.
2572 ;; We fake an second form of instruction to force reload to load address
2573 ;; into register when rax is not available
2574 (define_insn "*movabs<mode>_1"
2575 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2576 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2577 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2579 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2580 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "modrm" "0,*")
2583 (set_attr "length_address" "8,0")
2584 (set_attr "length_immediate" "0,*")
2585 (set_attr "memory" "store")
2586 (set_attr "mode" "<MODE>")])
2588 (define_insn "*movabs<mode>_2"
2589 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2590 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2591 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2593 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2594 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2595 [(set_attr "type" "imov")
2596 (set_attr "modrm" "0,*")
2597 (set_attr "length_address" "8,0")
2598 (set_attr "length_immediate" "0")
2599 (set_attr "memory" "load")
2600 (set_attr "mode" "<MODE>")])
2602 (define_insn "*swap<mode>"
2603 [(set (match_operand:SWI48 0 "register_operand" "+r")
2604 (match_operand:SWI48 1 "register_operand" "+r"))
2608 "xchg{<imodesuffix>}\t%1, %0"
2609 [(set_attr "type" "imov")
2610 (set_attr "mode" "<MODE>")
2611 (set_attr "pent_pair" "np")
2612 (set_attr "athlon_decode" "vector")
2613 (set_attr "amdfam10_decode" "double")
2614 (set_attr "bdver1_decode" "double")])
2616 (define_insn "*swap<mode>_1"
2617 [(set (match_operand:SWI12 0 "register_operand" "+r")
2618 (match_operand:SWI12 1 "register_operand" "+r"))
2621 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2623 [(set_attr "type" "imov")
2624 (set_attr "mode" "SI")
2625 (set_attr "pent_pair" "np")
2626 (set_attr "athlon_decode" "vector")
2627 (set_attr "amdfam10_decode" "double")
2628 (set_attr "bdver1_decode" "double")])
2630 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2631 ;; is disabled for AMDFAM10
2632 (define_insn "*swap<mode>_2"
2633 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2634 (match_operand:SWI12 1 "register_operand" "+<r>"))
2637 "TARGET_PARTIAL_REG_STALL"
2638 "xchg{<imodesuffix>}\t%1, %0"
2639 [(set_attr "type" "imov")
2640 (set_attr "mode" "<MODE>")
2641 (set_attr "pent_pair" "np")
2642 (set_attr "athlon_decode" "vector")])
2644 (define_expand "movstrict<mode>"
2645 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2646 (match_operand:SWI12 1 "general_operand"))]
2649 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2651 if (GET_CODE (operands[0]) == SUBREG
2652 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2654 /* Don't generate memory->memory moves, go through a register */
2655 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2656 operands[1] = force_reg (<MODE>mode, operands[1]);
2659 (define_insn "*movstrict<mode>_1"
2660 [(set (strict_low_part
2661 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2662 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2663 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2665 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2666 [(set_attr "type" "imov")
2667 (set_attr "mode" "<MODE>")])
2669 (define_insn "*movstrict<mode>_xor"
2670 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2671 (match_operand:SWI12 1 "const0_operand"))
2672 (clobber (reg:CC FLAGS_REG))]
2674 "xor{<imodesuffix>}\t%0, %0"
2675 [(set_attr "type" "alu1")
2676 (set_attr "mode" "<MODE>")
2677 (set_attr "length_immediate" "0")])
2679 (define_insn "*mov<mode>_extv_1"
2680 [(set (match_operand:SWI24 0 "register_operand" "=R")
2681 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2685 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2686 [(set_attr "type" "imovx")
2687 (set_attr "mode" "SI")])
2689 (define_insn "*movqi_extv_1"
2690 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2691 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2696 switch (get_attr_type (insn))
2699 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2701 return "mov{b}\t{%h1, %0|%0, %h1}";
2704 [(set_attr "isa" "*,*,nox64")
2706 (if_then_else (and (match_operand:QI 0 "register_operand")
2707 (ior (not (match_operand:QI 0 "QIreg_operand"))
2708 (match_test "TARGET_MOVX")))
2709 (const_string "imovx")
2710 (const_string "imov")))
2712 (if_then_else (eq_attr "type" "imovx")
2714 (const_string "QI")))])
2716 (define_insn "*mov<mode>_extzv_1"
2717 [(set (match_operand:SWI48 0 "register_operand" "=R")
2718 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2722 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2723 [(set_attr "type" "imovx")
2724 (set_attr "mode" "SI")])
2726 (define_insn "*movqi_extzv_2"
2727 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2729 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2734 switch (get_attr_type (insn))
2737 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2739 return "mov{b}\t{%h1, %0|%0, %h1}";
2742 [(set_attr "isa" "*,*,nox64")
2744 (if_then_else (and (match_operand:QI 0 "register_operand")
2745 (ior (not (match_operand:QI 0 "QIreg_operand"))
2746 (match_test "TARGET_MOVX")))
2747 (const_string "imovx")
2748 (const_string "imov")))
2750 (if_then_else (eq_attr "type" "imovx")
2752 (const_string "QI")))])
2754 (define_insn "mov<mode>_insv_1"
2755 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2758 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2761 if (CONST_INT_P (operands[1]))
2762 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2763 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2765 [(set_attr "isa" "*,nox64")
2766 (set_attr "type" "imov")
2767 (set_attr "mode" "QI")])
2769 (define_insn "*movqi_insv_2"
2770 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2773 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2776 "mov{b}\t{%h1, %h0|%h0, %h1}"
2777 [(set_attr "type" "imov")
2778 (set_attr "mode" "QI")])
2780 ;; Floating point push instructions.
2782 (define_insn "*pushtf"
2783 [(set (match_operand:TF 0 "push_operand" "=<,<")
2784 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2785 "TARGET_64BIT || TARGET_SSE"
2787 /* This insn should be already split before reg-stack. */
2790 [(set_attr "isa" "*,x64")
2791 (set_attr "type" "multi")
2792 (set_attr "unit" "sse,*")
2793 (set_attr "mode" "TF,DI")])
2795 ;; %%% Kill this when call knows how to work this out.
2797 [(set (match_operand:TF 0 "push_operand")
2798 (match_operand:TF 1 "sse_reg_operand"))]
2799 "TARGET_SSE && reload_completed"
2800 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2801 (set (match_dup 0) (match_dup 1))]
2803 /* Preserve memory attributes. */
2804 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2807 (define_insn "*pushxf"
2808 [(set (match_operand:XF 0 "push_operand" "=<,<")
2809 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2812 /* This insn should be already split before reg-stack. */
2815 [(set_attr "type" "multi")
2816 (set_attr "unit" "i387,*")
2818 (cond [(eq_attr "alternative" "1")
2819 (if_then_else (match_test "TARGET_64BIT")
2821 (const_string "SI"))
2823 (const_string "XF")))])
2825 ;; %%% Kill this when call knows how to work this out.
2827 [(set (match_operand:XF 0 "push_operand")
2828 (match_operand:XF 1 "fp_register_operand"))]
2830 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2831 (set (match_dup 0) (match_dup 1))]
2833 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2834 /* Preserve memory attributes. */
2835 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2838 (define_insn "*pushdf"
2839 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2840 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2843 /* This insn should be already split before reg-stack. */
2846 [(set_attr "isa" "*,nox64,x64,sse2")
2847 (set_attr "type" "multi")
2848 (set_attr "unit" "i387,*,*,sse")
2849 (set_attr "mode" "DF,SI,DI,DF")])
2851 ;; %%% Kill this when call knows how to work this out.
2853 [(set (match_operand:DF 0 "push_operand")
2854 (match_operand:DF 1 "any_fp_register_operand"))]
2856 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2857 (set (match_dup 0) (match_dup 1))]
2859 /* Preserve memory attributes. */
2860 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2863 (define_insn "*pushsf_rex64"
2864 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2865 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2868 /* Anything else should be already split before reg-stack. */
2869 gcc_assert (which_alternative == 1);
2870 return "push{q}\t%q1";
2872 [(set_attr "type" "multi,push,multi")
2873 (set_attr "unit" "i387,*,*")
2874 (set_attr "mode" "SF,DI,SF")])
2876 (define_insn "*pushsf"
2877 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2878 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2881 /* Anything else should be already split before reg-stack. */
2882 gcc_assert (which_alternative == 1);
2883 return "push{l}\t%1";
2885 [(set_attr "type" "multi,push,multi")
2886 (set_attr "unit" "i387,*,*")
2887 (set_attr "mode" "SF,SI,SF")])
2889 ;; %%% Kill this when call knows how to work this out.
2891 [(set (match_operand:SF 0 "push_operand")
2892 (match_operand:SF 1 "any_fp_register_operand"))]
2894 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2895 (set (match_dup 0) (match_dup 1))]
2897 rtx op = XEXP (operands[0], 0);
2898 if (GET_CODE (op) == PRE_DEC)
2900 gcc_assert (!TARGET_64BIT);
2905 op = XEXP (XEXP (op, 1), 1);
2906 gcc_assert (CONST_INT_P (op));
2909 /* Preserve memory attributes. */
2910 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2914 [(set (match_operand:SF 0 "push_operand")
2915 (match_operand:SF 1 "memory_operand"))]
2917 && (operands[2] = find_constant_src (insn))"
2918 [(set (match_dup 0) (match_dup 2))])
2921 [(set (match_operand 0 "push_operand")
2922 (match_operand 1 "general_operand"))]
2924 && (GET_MODE (operands[0]) == TFmode
2925 || GET_MODE (operands[0]) == XFmode
2926 || GET_MODE (operands[0]) == DFmode)
2927 && !ANY_FP_REG_P (operands[1])"
2929 "ix86_split_long_move (operands); DONE;")
2931 ;; Floating point move instructions.
2933 (define_expand "movtf"
2934 [(set (match_operand:TF 0 "nonimmediate_operand")
2935 (match_operand:TF 1 "nonimmediate_operand"))]
2936 "TARGET_64BIT || TARGET_SSE"
2937 "ix86_expand_move (TFmode, operands); DONE;")
2939 (define_expand "mov<mode>"
2940 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2941 (match_operand:X87MODEF 1 "general_operand"))]
2943 "ix86_expand_move (<MODE>mode, operands); DONE;")
2945 (define_insn "*movtf_internal"
2946 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2947 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2948 "(TARGET_64BIT || TARGET_SSE)
2949 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2950 && (!can_create_pseudo_p ()
2951 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2952 || GET_CODE (operands[1]) != CONST_DOUBLE
2953 || (optimize_function_for_size_p (cfun)
2954 && standard_sse_constant_p (operands[1])
2955 && !memory_operand (operands[0], TFmode))
2956 || (!TARGET_MEMORY_MISMATCH_STALL
2957 && memory_operand (operands[0], TFmode)))"
2959 switch (get_attr_type (insn))
2962 return standard_sse_constant_opcode (insn, operands[1]);
2965 /* Handle misaligned load/store since we
2966 don't have movmisaligntf pattern. */
2967 if (misaligned_operand (operands[0], TFmode)
2968 || misaligned_operand (operands[1], TFmode))
2970 if (get_attr_mode (insn) == MODE_V4SF)
2971 return "%vmovups\t{%1, %0|%0, %1}";
2973 return "%vmovdqu\t{%1, %0|%0, %1}";
2977 if (get_attr_mode (insn) == MODE_V4SF)
2978 return "%vmovaps\t{%1, %0|%0, %1}";
2980 return "%vmovdqa\t{%1, %0|%0, %1}";
2990 [(set_attr "isa" "*,*,*,x64,x64")
2991 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2992 (set (attr "prefix")
2993 (if_then_else (eq_attr "type" "sselog1,ssemov")
2994 (const_string "maybe_vex")
2995 (const_string "orig")))
2997 (cond [(eq_attr "alternative" "3,4")
2999 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3000 (const_string "V4SF")
3001 (and (eq_attr "alternative" "2")
3002 (match_test "TARGET_SSE_TYPELESS_STORES"))
3003 (const_string "V4SF")
3004 (match_test "TARGET_AVX")
3006 (ior (not (match_test "TARGET_SSE2"))
3007 (match_test "optimize_function_for_size_p (cfun)"))
3008 (const_string "V4SF")
3010 (const_string "TI")))])
3012 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
3013 (define_insn "*movxf_internal"
3014 [(set (match_operand:XF 0 "nonimmediate_operand"
3015 "=f,m,f,?Yx*r ,!o ,!o")
3016 (match_operand:XF 1 "general_operand"
3017 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
3018 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3019 && (!can_create_pseudo_p ()
3020 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3021 || GET_CODE (operands[1]) != CONST_DOUBLE
3022 || (optimize_function_for_size_p (cfun)
3023 && standard_80387_constant_p (operands[1]) > 0
3024 && !memory_operand (operands[0], XFmode))
3025 || (!TARGET_MEMORY_MISMATCH_STALL
3026 && memory_operand (operands[0], XFmode)))"
3028 switch (get_attr_type (insn))
3031 if (which_alternative == 2)
3032 return standard_80387_constant_opcode (operands[1]);
3033 return output_387_reg_move (insn, operands);
3042 [(set_attr "isa" "*,*,*,*,nox64,x64")
3043 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3045 (cond [(eq_attr "alternative" "3,4,5")
3046 (if_then_else (match_test "TARGET_64BIT")
3048 (const_string "SI"))
3050 (const_string "XF")))])
3052 ;; Possible store forwarding (partial memory) stall in alternative 4.
3053 (define_insn "*movdf_internal"
3054 [(set (match_operand:DF 0 "nonimmediate_operand"
3055 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3056 (match_operand:DF 1 "general_operand"
3057 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3058 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3059 && (!can_create_pseudo_p ()
3060 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3061 || GET_CODE (operands[1]) != CONST_DOUBLE
3062 || (optimize_function_for_size_p (cfun)
3063 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3064 && standard_80387_constant_p (operands[1]) > 0)
3065 || (TARGET_SSE2 && TARGET_SSE_MATH
3066 && standard_sse_constant_p (operands[1])))
3067 && !memory_operand (operands[0], DFmode))
3068 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3069 && memory_operand (operands[0], DFmode)))"
3071 switch (get_attr_type (insn))
3074 if (which_alternative == 2)
3075 return standard_80387_constant_opcode (operands[1]);
3076 return output_387_reg_move (insn, operands);
3082 if (get_attr_mode (insn) == MODE_SI)
3083 return "mov{l}\t{%1, %k0|%k0, %1}";
3084 else if (which_alternative == 8)
3085 return "movabs{q}\t{%1, %0|%0, %1}";
3087 return "mov{q}\t{%1, %0|%0, %1}";
3090 return standard_sse_constant_opcode (insn, operands[1]);
3093 switch (get_attr_mode (insn))
3096 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3097 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3098 return "%vmovsd\t{%1, %0|%0, %1}";
3101 return "%vmovaps\t{%1, %0|%0, %1}";
3103 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3105 return "%vmovapd\t{%1, %0|%0, %1}";
3108 gcc_assert (!TARGET_AVX);
3109 return "movlps\t{%1, %0|%0, %1}";
3111 gcc_assert (!TARGET_AVX);
3112 return "movlpd\t{%1, %0|%0, %1}";
3115 /* Handle broken assemblers that require movd instead of movq. */
3116 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3117 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3118 return "%vmovd\t{%1, %0|%0, %1}";
3119 return "%vmovq\t{%1, %0|%0, %1}";
3130 (cond [(eq_attr "alternative" "3,4")
3131 (const_string "nox64")
3132 (eq_attr "alternative" "5,6,7,8,17,18")
3133 (const_string "x64")
3134 (eq_attr "alternative" "9,10,11,12")
3135 (const_string "sse2")
3137 (const_string "*")))
3139 (cond [(eq_attr "alternative" "0,1,2")
3140 (const_string "fmov")
3141 (eq_attr "alternative" "3,4")
3142 (const_string "multi")
3143 (eq_attr "alternative" "5,6,7,8")
3144 (const_string "imov")
3145 (eq_attr "alternative" "9,13")
3146 (const_string "sselog1")
3148 (const_string "ssemov")))
3150 (if_then_else (eq_attr "alternative" "8")
3152 (const_string "*")))
3153 (set (attr "length_immediate")
3154 (if_then_else (eq_attr "alternative" "8")
3156 (const_string "*")))
3157 (set (attr "prefix")
3158 (if_then_else (eq_attr "type" "sselog1,ssemov")
3159 (const_string "maybe_vex")
3160 (const_string "orig")))
3161 (set (attr "prefix_data16")
3163 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3164 (eq_attr "mode" "V1DF"))
3166 (const_string "*")))
3168 (cond [(eq_attr "alternative" "3,4,7")
3170 (eq_attr "alternative" "5,6,8,17,18")
3173 /* xorps is one byte shorter for non-AVX targets. */
3174 (eq_attr "alternative" "9,13")
3175 (cond [(not (match_test "TARGET_SSE2"))
3176 (const_string "V4SF")
3177 (match_test "TARGET_AVX512F")
3179 (match_test "TARGET_AVX")
3180 (const_string "V2DF")
3181 (match_test "optimize_function_for_size_p (cfun)")
3182 (const_string "V4SF")
3183 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3186 (const_string "V2DF"))
3188 /* For architectures resolving dependencies on
3189 whole SSE registers use movapd to break dependency
3190 chains, otherwise use short move to avoid extra work. */
3192 /* movaps is one byte shorter for non-AVX targets. */
3193 (eq_attr "alternative" "10,14")
3194 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3195 (match_operand 1 "ext_sse_reg_operand"))
3196 (const_string "V8DF")
3197 (ior (not (match_test "TARGET_SSE2"))
3198 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3199 (const_string "V4SF")
3200 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3201 (const_string "V2DF")
3202 (match_test "TARGET_AVX")
3204 (match_test "optimize_function_for_size_p (cfun)")
3205 (const_string "V4SF")
3207 (const_string "DF"))
3209 /* For architectures resolving dependencies on register
3210 parts we may avoid extra work to zero out upper part
3212 (eq_attr "alternative" "11,15")
3213 (cond [(not (match_test "TARGET_SSE2"))
3214 (const_string "V2SF")
3215 (match_test "TARGET_AVX")
3217 (match_test "TARGET_SSE_SPLIT_REGS")
3218 (const_string "V1DF")
3220 (const_string "DF"))
3222 (and (eq_attr "alternative" "12,16")
3223 (not (match_test "TARGET_SSE2")))
3224 (const_string "V2SF")
3226 (const_string "DF")))])
3228 (define_insn "*movsf_internal"
3229 [(set (match_operand:SF 0 "nonimmediate_operand"
3230 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3231 (match_operand:SF 1 "general_operand"
3232 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3233 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3234 && (!can_create_pseudo_p ()
3235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236 || GET_CODE (operands[1]) != CONST_DOUBLE
3237 || (optimize_function_for_size_p (cfun)
3238 && ((!TARGET_SSE_MATH
3239 && standard_80387_constant_p (operands[1]) > 0)
3241 && standard_sse_constant_p (operands[1]))))
3242 || memory_operand (operands[0], SFmode))"
3244 switch (get_attr_type (insn))
3247 if (which_alternative == 2)
3248 return standard_80387_constant_opcode (operands[1]);
3249 return output_387_reg_move (insn, operands);
3252 return "mov{l}\t{%1, %0|%0, %1}";
3255 return standard_sse_constant_opcode (insn, operands[1]);
3258 switch (get_attr_mode (insn))
3261 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3262 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3263 return "%vmovss\t{%1, %0|%0, %1}";
3266 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3268 return "%vmovaps\t{%1, %0|%0, %1}";
3271 return "%vmovd\t{%1, %0|%0, %1}";
3278 switch (get_attr_mode (insn))
3281 return "movq\t{%1, %0|%0, %1}";
3283 return "movd\t{%1, %0|%0, %1}";
3294 (cond [(eq_attr "alternative" "0,1,2")
3295 (const_string "fmov")
3296 (eq_attr "alternative" "3,4")
3297 (const_string "imov")
3298 (eq_attr "alternative" "5")
3299 (const_string "sselog1")
3300 (eq_attr "alternative" "11,12,13,14,15")
3301 (const_string "mmxmov")
3303 (const_string "ssemov")))
3304 (set (attr "prefix")
3305 (if_then_else (eq_attr "type" "sselog1,ssemov")
3306 (const_string "maybe_vex")
3307 (const_string "orig")))
3308 (set (attr "prefix_data16")
3309 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3311 (const_string "*")))
3313 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3315 (eq_attr "alternative" "11")
3317 (eq_attr "alternative" "5")
3318 (cond [(not (match_test "TARGET_SSE2"))
3319 (const_string "V4SF")
3320 (match_test "TARGET_AVX512F")
3321 (const_string "V16SF")
3322 (match_test "TARGET_AVX")
3323 (const_string "V4SF")
3324 (match_test "optimize_function_for_size_p (cfun)")
3325 (const_string "V4SF")
3326 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3329 (const_string "V4SF"))
3331 /* For architectures resolving dependencies on
3332 whole SSE registers use APS move to break dependency
3333 chains, otherwise use short move to avoid extra work.
3335 Do the same for architectures resolving dependencies on
3336 the parts. While in DF mode it is better to always handle
3337 just register parts, the SF mode is different due to lack
3338 of instructions to load just part of the register. It is
3339 better to maintain the whole registers in single format
3340 to avoid problems on using packed logical operations. */
3341 (eq_attr "alternative" "6")
3342 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3343 (match_operand 1 "ext_sse_reg_operand"))
3344 (const_string "V16SF")
3345 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3346 (match_test "TARGET_SSE_SPLIT_REGS"))
3347 (const_string "V4SF")
3349 (const_string "SF"))
3351 (const_string "SF")))])
3354 [(set (match_operand 0 "any_fp_register_operand")
3355 (match_operand 1 "memory_operand"))]
3357 && (GET_MODE (operands[0]) == TFmode
3358 || GET_MODE (operands[0]) == XFmode
3359 || GET_MODE (operands[0]) == DFmode
3360 || GET_MODE (operands[0]) == SFmode)
3361 && (operands[2] = find_constant_src (insn))"
3362 [(set (match_dup 0) (match_dup 2))]
3364 rtx c = operands[2];
3365 int r = REGNO (operands[0]);
3367 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3368 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3373 [(set (match_operand 0 "any_fp_register_operand")
3374 (float_extend (match_operand 1 "memory_operand")))]
3376 && (GET_MODE (operands[0]) == TFmode
3377 || GET_MODE (operands[0]) == XFmode
3378 || GET_MODE (operands[0]) == DFmode)
3379 && (operands[2] = find_constant_src (insn))"
3380 [(set (match_dup 0) (match_dup 2))]
3382 rtx c = operands[2];
3383 int r = REGNO (operands[0]);
3385 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3386 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3390 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3392 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3393 (match_operand:X87MODEF 1 "immediate_operand"))]
3395 && (standard_80387_constant_p (operands[1]) == 8
3396 || standard_80387_constant_p (operands[1]) == 9)"
3397 [(set (match_dup 0)(match_dup 1))
3399 (neg:X87MODEF (match_dup 0)))]
3403 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3404 if (real_isnegzero (&r))
3405 operands[1] = CONST0_RTX (<MODE>mode);
3407 operands[1] = CONST1_RTX (<MODE>mode);
3411 [(set (match_operand 0 "nonimmediate_operand")
3412 (match_operand 1 "general_operand"))]
3414 && (GET_MODE (operands[0]) == TFmode
3415 || GET_MODE (operands[0]) == XFmode
3416 || GET_MODE (operands[0]) == DFmode)
3417 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3419 "ix86_split_long_move (operands); DONE;")
3421 (define_insn "swapxf"
3422 [(set (match_operand:XF 0 "register_operand" "+f")
3423 (match_operand:XF 1 "register_operand" "+f"))
3428 if (STACK_TOP_P (operands[0]))
3433 [(set_attr "type" "fxch")
3434 (set_attr "mode" "XF")])
3436 (define_insn "*swap<mode>"
3437 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3438 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3441 "TARGET_80387 || reload_completed"
3443 if (STACK_TOP_P (operands[0]))
3448 [(set_attr "type" "fxch")
3449 (set_attr "mode" "<MODE>")])
3451 ;; Zero extension instructions
3453 (define_expand "zero_extendsidi2"
3454 [(set (match_operand:DI 0 "nonimmediate_operand")
3455 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3457 (define_insn "*zero_extendsidi2"
3458 [(set (match_operand:DI 0 "nonimmediate_operand"
3459 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3461 (match_operand:SI 1 "x86_64_zext_operand"
3462 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3465 switch (get_attr_type (insn))
3468 if (ix86_use_lea_for_mov (insn, operands))
3469 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3471 return "mov{l}\t{%1, %k0|%k0, %1}";
3477 return "movd\t{%1, %0|%0, %1}";
3480 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3483 if (GENERAL_REG_P (operands[0]))
3484 return "%vmovd\t{%1, %k0|%k0, %1}";
3486 return "%vmovd\t{%1, %0|%0, %1}";
3493 (cond [(eq_attr "alternative" "0,1,2")
3494 (const_string "nox64")
3495 (eq_attr "alternative" "3,7")
3496 (const_string "x64")
3497 (eq_attr "alternative" "8")
3498 (const_string "x64_sse4")
3499 (eq_attr "alternative" "10")
3500 (const_string "sse2")
3502 (const_string "*")))
3504 (cond [(eq_attr "alternative" "0,1,2,4")
3505 (const_string "multi")
3506 (eq_attr "alternative" "5,6")
3507 (const_string "mmxmov")
3508 (eq_attr "alternative" "7,9,10")
3509 (const_string "ssemov")
3510 (eq_attr "alternative" "8")
3511 (const_string "sselog1")
3513 (const_string "imovx")))
3514 (set (attr "prefix_extra")
3515 (if_then_else (eq_attr "alternative" "8")
3517 (const_string "*")))
3518 (set (attr "length_immediate")
3519 (if_then_else (eq_attr "alternative" "8")
3521 (const_string "*")))
3522 (set (attr "prefix")
3523 (if_then_else (eq_attr "type" "ssemov,sselog1")
3524 (const_string "maybe_vex")
3525 (const_string "orig")))
3526 (set (attr "prefix_0f")
3527 (if_then_else (eq_attr "type" "imovx")
3529 (const_string "*")))
3531 (cond [(eq_attr "alternative" "5,6")
3533 (eq_attr "alternative" "7,8,9")
3536 (const_string "SI")))])
3539 [(set (match_operand:DI 0 "memory_operand")
3540 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3542 [(set (match_dup 4) (const_int 0))]
3543 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3546 [(set (match_operand:DI 0 "register_operand")
3547 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3548 "!TARGET_64BIT && reload_completed
3549 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3550 && true_regnum (operands[0]) == true_regnum (operands[1])"
3551 [(set (match_dup 4) (const_int 0))]
3552 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3555 [(set (match_operand:DI 0 "nonimmediate_operand")
3556 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3557 "!TARGET_64BIT && reload_completed
3558 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3559 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3560 [(set (match_dup 3) (match_dup 1))
3561 (set (match_dup 4) (const_int 0))]
3562 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3564 (define_insn "zero_extend<mode>di2"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3567 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3569 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3573 (define_expand "zero_extend<mode>si2"
3574 [(set (match_operand:SI 0 "register_operand")
3575 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3578 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3580 operands[1] = force_reg (<MODE>mode, operands[1]);
3581 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3586 (define_insn_and_split "zero_extend<mode>si2_and"
3587 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3589 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3590 (clobber (reg:CC FLAGS_REG))]
3591 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3593 "&& reload_completed"
3594 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3595 (clobber (reg:CC FLAGS_REG))])]
3597 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3599 ix86_expand_clear (operands[0]);
3601 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3602 emit_insn (gen_movstrict<mode>
3603 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3607 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3609 [(set_attr "type" "alu1")
3610 (set_attr "mode" "SI")])
3612 (define_insn "*zero_extend<mode>si2"
3613 [(set (match_operand:SI 0 "register_operand" "=r")
3615 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3616 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3617 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3618 [(set_attr "type" "imovx")
3619 (set_attr "mode" "SI")])
3621 (define_expand "zero_extendqihi2"
3622 [(set (match_operand:HI 0 "register_operand")
3623 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3626 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3628 operands[1] = force_reg (QImode, operands[1]);
3629 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3634 (define_insn_and_split "zero_extendqihi2_and"
3635 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3636 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3637 (clobber (reg:CC FLAGS_REG))]
3638 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3640 "&& reload_completed"
3641 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3642 (clobber (reg:CC FLAGS_REG))])]
3644 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3646 ix86_expand_clear (operands[0]);
3648 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3649 emit_insn (gen_movstrictqi
3650 (gen_lowpart (QImode, operands[0]), operands[1]));
3654 operands[0] = gen_lowpart (SImode, operands[0]);
3656 [(set_attr "type" "alu1")
3657 (set_attr "mode" "SI")])
3659 ; zero extend to SImode to avoid partial register stalls
3660 (define_insn "*zero_extendqihi2"
3661 [(set (match_operand:HI 0 "register_operand" "=r")
3662 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3663 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3664 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3665 [(set_attr "type" "imovx")
3666 (set_attr "mode" "SI")])
3668 ;; Sign extension instructions
3670 (define_expand "extendsidi2"
3671 [(set (match_operand:DI 0 "register_operand")
3672 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3677 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3682 (define_insn "*extendsidi2_rex64"
3683 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3684 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3688 movs{lq|x}\t{%1, %0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")
3691 (set_attr "prefix_0f" "0")
3692 (set_attr "modrm" "0,1")])
3694 (define_insn "extendsidi2_1"
3695 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3696 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3697 (clobber (reg:CC FLAGS_REG))
3698 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3702 ;; Split the memory case. If the source register doesn't die, it will stay
3703 ;; this way, if it does die, following peephole2s take care of it.
3705 [(set (match_operand:DI 0 "memory_operand")
3706 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3707 (clobber (reg:CC FLAGS_REG))
3708 (clobber (match_operand:SI 2 "register_operand"))]
3712 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714 emit_move_insn (operands[3], operands[1]);
3716 /* Generate a cltd if possible and doing so it profitable. */
3717 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3718 && true_regnum (operands[1]) == AX_REG
3719 && true_regnum (operands[2]) == DX_REG)
3721 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3725 emit_move_insn (operands[2], operands[1]);
3726 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3728 emit_move_insn (operands[4], operands[2]);
3732 ;; Peepholes for the case where the source register does die, after
3733 ;; being split with the above splitter.
3735 [(set (match_operand:SI 0 "memory_operand")
3736 (match_operand:SI 1 "register_operand"))
3737 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3738 (parallel [(set (match_dup 2)
3739 (ashiftrt:SI (match_dup 2) (const_int 31)))
3740 (clobber (reg:CC FLAGS_REG))])
3741 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3742 "REGNO (operands[1]) != REGNO (operands[2])
3743 && peep2_reg_dead_p (2, operands[1])
3744 && peep2_reg_dead_p (4, operands[2])
3745 && !reg_mentioned_p (operands[2], operands[3])"
3746 [(set (match_dup 0) (match_dup 1))
3747 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3748 (clobber (reg:CC FLAGS_REG))])
3749 (set (match_dup 3) (match_dup 1))])
3752 [(set (match_operand:SI 0 "memory_operand")
3753 (match_operand:SI 1 "register_operand"))
3754 (parallel [(set (match_operand:SI 2 "register_operand")
3755 (ashiftrt:SI (match_dup 1) (const_int 31)))
3756 (clobber (reg:CC FLAGS_REG))])
3757 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3758 "/* cltd is shorter than sarl $31, %eax */
3759 !optimize_function_for_size_p (cfun)
3760 && true_regnum (operands[1]) == AX_REG
3761 && true_regnum (operands[2]) == DX_REG
3762 && peep2_reg_dead_p (2, operands[1])
3763 && peep2_reg_dead_p (3, operands[2])
3764 && !reg_mentioned_p (operands[2], operands[3])"
3765 [(set (match_dup 0) (match_dup 1))
3766 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3767 (clobber (reg:CC FLAGS_REG))])
3768 (set (match_dup 3) (match_dup 1))])
3770 ;; Extend to register case. Optimize case where source and destination
3771 ;; registers match and cases where we can use cltd.
3773 [(set (match_operand:DI 0 "register_operand")
3774 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3775 (clobber (reg:CC FLAGS_REG))
3776 (clobber (match_scratch:SI 2))]
3780 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3782 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3783 emit_move_insn (operands[3], operands[1]);
3785 /* Generate a cltd if possible and doing so it profitable. */
3786 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3787 && true_regnum (operands[3]) == AX_REG
3788 && true_regnum (operands[4]) == DX_REG)
3790 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3794 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3795 emit_move_insn (operands[4], operands[1]);
3797 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3801 (define_insn "extend<mode>di2"
3802 [(set (match_operand:DI 0 "register_operand" "=r")
3804 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3806 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3807 [(set_attr "type" "imovx")
3808 (set_attr "mode" "DI")])
3810 (define_insn "extendhisi2"
3811 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3812 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3815 switch (get_attr_prefix_0f (insn))
3818 return "{cwtl|cwde}";
3820 return "movs{wl|x}\t{%1, %0|%0, %1}";
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")
3825 (set (attr "prefix_0f")
3826 ;; movsx is short decodable while cwtl is vector decoded.
3827 (if_then_else (and (eq_attr "cpu" "!k6")
3828 (eq_attr "alternative" "0"))
3830 (const_string "1")))
3832 (if_then_else (eq_attr "prefix_0f" "0")
3834 (const_string "1")))])
3836 (define_insn "*extendhisi2_zext"
3837 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3840 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3843 switch (get_attr_prefix_0f (insn))
3846 return "{cwtl|cwde}";
3848 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3851 [(set_attr "type" "imovx")
3852 (set_attr "mode" "SI")
3853 (set (attr "prefix_0f")
3854 ;; movsx is short decodable while cwtl is vector decoded.
3855 (if_then_else (and (eq_attr "cpu" "!k6")
3856 (eq_attr "alternative" "0"))
3858 (const_string "1")))
3860 (if_then_else (eq_attr "prefix_0f" "0")
3862 (const_string "1")))])
3864 (define_insn "extendqisi2"
3865 [(set (match_operand:SI 0 "register_operand" "=r")
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3868 "movs{bl|x}\t{%1, %0|%0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3872 (define_insn "*extendqisi2_zext"
3873 [(set (match_operand:DI 0 "register_operand" "=r")
3875 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3877 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "SI")])
3881 (define_insn "extendqihi2"
3882 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3883 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3886 switch (get_attr_prefix_0f (insn))
3889 return "{cbtw|cbw}";
3891 return "movs{bw|x}\t{%1, %0|%0, %1}";
3894 [(set_attr "type" "imovx")
3895 (set_attr "mode" "HI")
3896 (set (attr "prefix_0f")
3897 ;; movsx is short decodable while cwtl is vector decoded.
3898 (if_then_else (and (eq_attr "cpu" "!k6")
3899 (eq_attr "alternative" "0"))
3901 (const_string "1")))
3903 (if_then_else (eq_attr "prefix_0f" "0")
3905 (const_string "1")))])
3907 ;; Conversions between float and double.
3909 ;; These are all no-ops in the model used for the 80387.
3910 ;; So just emit moves.
3912 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3914 [(set (match_operand:DF 0 "push_operand")
3915 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3917 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3918 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3921 [(set (match_operand:XF 0 "push_operand")
3922 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3924 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3925 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3926 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3928 (define_expand "extendsfdf2"
3929 [(set (match_operand:DF 0 "nonimmediate_operand")
3930 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3931 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3933 /* ??? Needed for compress_float_constant since all fp constants
3934 are TARGET_LEGITIMATE_CONSTANT_P. */
3935 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3937 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3938 && standard_80387_constant_p (operands[1]) > 0)
3940 operands[1] = simplify_const_unary_operation
3941 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3942 emit_move_insn_1 (operands[0], operands[1]);
3945 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3949 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3951 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3953 We do the conversion post reload to avoid producing of 128bit spills
3954 that might lead to ICE on 32bit target. The sequence unlikely combine
3957 [(set (match_operand:DF 0 "register_operand")
3959 (match_operand:SF 1 "nonimmediate_operand")))]
3960 "TARGET_USE_VECTOR_FP_CONVERTS
3961 && optimize_insn_for_speed_p ()
3962 && reload_completed && SSE_REG_P (operands[0])"
3967 (parallel [(const_int 0) (const_int 1)]))))]
3969 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972 Try to avoid move when unpacking can be done in source. */
3973 if (REG_P (operands[1]))
3975 /* If it is unsafe to overwrite upper half of source, we need
3976 to move to destination and unpack there. */
3977 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979 && true_regnum (operands[0]) != true_regnum (operands[1]))
3981 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982 emit_move_insn (tmp, operands[1]);
3985 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3990 emit_insn (gen_vec_setv4sf_0 (operands[3],
3991 CONST0_RTX (V4SFmode), operands[1]));
3994 ;; It's more profitable to split and then extend in the same register.
3996 [(set (match_operand:DF 0 "register_operand")
3998 (match_operand:SF 1 "memory_operand")))]
3999 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4000 && optimize_insn_for_speed_p ()
4001 && SSE_REG_P (operands[0])"
4002 [(set (match_dup 2) (match_dup 1))
4003 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4004 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4006 (define_insn "*extendsfdf2_mixed"
4007 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4009 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4010 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4012 switch (which_alternative)
4016 return output_387_reg_move (insn, operands);
4019 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4025 [(set_attr "type" "fmov,fmov,ssecvt")
4026 (set_attr "prefix" "orig,orig,maybe_vex")
4027 (set_attr "mode" "SF,XF,DF")])
4029 (define_insn "*extendsfdf2_sse"
4030 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4031 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4032 "TARGET_SSE2 && TARGET_SSE_MATH"
4033 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4034 [(set_attr "type" "ssecvt")
4035 (set_attr "prefix" "maybe_vex")
4036 (set_attr "mode" "DF")])
4038 (define_insn "*extendsfdf2_i387"
4039 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4040 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4042 "* return output_387_reg_move (insn, operands);"
4043 [(set_attr "type" "fmov")
4044 (set_attr "mode" "SF,XF")])
4046 (define_expand "extend<mode>xf2"
4047 [(set (match_operand:XF 0 "nonimmediate_operand")
4048 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4051 /* ??? Needed for compress_float_constant since all fp constants
4052 are TARGET_LEGITIMATE_CONSTANT_P. */
4053 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4055 if (standard_80387_constant_p (operands[1]) > 0)
4057 operands[1] = simplify_const_unary_operation
4058 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4059 emit_move_insn_1 (operands[0], operands[1]);
4062 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4066 (define_insn "*extend<mode>xf2_i387"
4067 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4069 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4071 "* return output_387_reg_move (insn, operands);"
4072 [(set_attr "type" "fmov")
4073 (set_attr "mode" "<MODE>,XF")])
4075 ;; %%% This seems bad bad news.
4076 ;; This cannot output into an f-reg because there is no way to be sure
4077 ;; of truncating in that case. Otherwise this is just like a simple move
4078 ;; insn. So we pretend we can output to a reg in order to get better
4079 ;; register preferencing, but we really use a stack slot.
4081 ;; Conversion from DFmode to SFmode.
4083 (define_expand "truncdfsf2"
4084 [(set (match_operand:SF 0 "nonimmediate_operand")
4086 (match_operand:DF 1 "nonimmediate_operand")))]
4087 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4089 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4091 else if (flag_unsafe_math_optimizations)
4095 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4096 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4101 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4103 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4105 We do the conversion post reload to avoid producing of 128bit spills
4106 that might lead to ICE on 32bit target. The sequence unlikely combine
4109 [(set (match_operand:SF 0 "register_operand")
4111 (match_operand:DF 1 "nonimmediate_operand")))]
4112 "TARGET_USE_VECTOR_FP_CONVERTS
4113 && optimize_insn_for_speed_p ()
4114 && reload_completed && SSE_REG_P (operands[0])"
4117 (float_truncate:V2SF
4121 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4122 operands[3] = CONST0_RTX (V2SFmode);
4123 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4124 /* Use movsd for loading from memory, unpcklpd for registers.
4125 Try to avoid move when unpacking can be done in source, or SSE3
4126 movddup is available. */
4127 if (REG_P (operands[1]))
4130 && true_regnum (operands[0]) != true_regnum (operands[1])
4131 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4132 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4134 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4135 emit_move_insn (tmp, operands[1]);
4138 else if (!TARGET_SSE3)
4139 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4140 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4143 emit_insn (gen_sse2_loadlpd (operands[4],
4144 CONST0_RTX (V2DFmode), operands[1]));
4147 ;; It's more profitable to split and then extend in the same register.
4149 [(set (match_operand:SF 0 "register_operand")
4151 (match_operand:DF 1 "memory_operand")))]
4152 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4153 && optimize_insn_for_speed_p ()
4154 && SSE_REG_P (operands[0])"
4155 [(set (match_dup 2) (match_dup 1))
4156 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4157 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4159 (define_expand "truncdfsf2_with_temp"
4160 [(parallel [(set (match_operand:SF 0)
4161 (float_truncate:SF (match_operand:DF 1)))
4162 (clobber (match_operand:SF 2))])])
4164 (define_insn "*truncdfsf_fast_mixed"
4165 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4167 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4168 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4170 switch (which_alternative)
4173 return output_387_reg_move (insn, operands);
4175 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4180 [(set_attr "type" "fmov,ssecvt")
4181 (set_attr "prefix" "orig,maybe_vex")
4182 (set_attr "mode" "SF")])
4184 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4185 ;; because nothing we do here is unsafe.
4186 (define_insn "*truncdfsf_fast_sse"
4187 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4189 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4190 "TARGET_SSE2 && TARGET_SSE_MATH"
4191 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4192 [(set_attr "type" "ssecvt")
4193 (set_attr "prefix" "maybe_vex")
4194 (set_attr "mode" "SF")])
4196 (define_insn "*truncdfsf_fast_i387"
4197 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4199 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4200 "TARGET_80387 && flag_unsafe_math_optimizations"
4201 "* return output_387_reg_move (insn, operands);"
4202 [(set_attr "type" "fmov")
4203 (set_attr "mode" "SF")])
4205 (define_insn "*truncdfsf_mixed"
4206 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4208 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4209 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4210 "TARGET_MIX_SSE_I387"
4212 switch (which_alternative)
4215 return output_387_reg_move (insn, operands);
4217 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4223 [(set_attr "isa" "*,sse2,*,*,*")
4224 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4225 (set_attr "unit" "*,*,i387,i387,i387")
4226 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4227 (set_attr "mode" "SF")])
4229 (define_insn "*truncdfsf_i387"
4230 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4232 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4233 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4236 switch (which_alternative)
4239 return output_387_reg_move (insn, operands);
4245 [(set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "SF")])
4249 (define_insn "*truncdfsf2_i387_1"
4250 [(set (match_operand:SF 0 "memory_operand" "=m")
4252 (match_operand:DF 1 "register_operand" "f")))]
4254 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4255 && !TARGET_MIX_SSE_I387"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "SF")])
4261 [(set (match_operand:SF 0 "register_operand")
4263 (match_operand:DF 1 "fp_register_operand")))
4264 (clobber (match_operand 2))]
4266 [(set (match_dup 2) (match_dup 1))
4267 (set (match_dup 0) (match_dup 2))]
4268 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4270 ;; Conversion from XFmode to {SF,DF}mode
4272 (define_expand "truncxf<mode>2"
4273 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4274 (float_truncate:MODEF
4275 (match_operand:XF 1 "register_operand")))
4276 (clobber (match_dup 2))])]
4279 if (flag_unsafe_math_optimizations)
4281 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4282 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4283 if (reg != operands[0])
4284 emit_move_insn (operands[0], reg);
4288 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4291 (define_insn "*truncxfsf2_mixed"
4292 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4294 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4295 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4298 gcc_assert (!which_alternative);
4299 return output_387_reg_move (insn, operands);
4301 [(set_attr "type" "fmov,multi,multi,multi")
4302 (set_attr "unit" "*,i387,i387,i387")
4303 (set_attr "mode" "SF")])
4305 (define_insn "*truncxfdf2_mixed"
4306 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4308 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4309 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4312 gcc_assert (!which_alternative);
4313 return output_387_reg_move (insn, operands);
4315 [(set_attr "isa" "*,*,sse2,*")
4316 (set_attr "type" "fmov,multi,multi,multi")
4317 (set_attr "unit" "*,i387,i387,i387")
4318 (set_attr "mode" "DF")])
4320 (define_insn "truncxf<mode>2_i387_noop"
4321 [(set (match_operand:MODEF 0 "register_operand" "=f")
4322 (float_truncate:MODEF
4323 (match_operand:XF 1 "register_operand" "f")))]
4324 "TARGET_80387 && flag_unsafe_math_optimizations"
4325 "* return output_387_reg_move (insn, operands);"
4326 [(set_attr "type" "fmov")
4327 (set_attr "mode" "<MODE>")])
4329 (define_insn "*truncxf<mode>2_i387"
4330 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4331 (float_truncate:MODEF
4332 (match_operand:XF 1 "register_operand" "f")))]
4334 "* return output_387_reg_move (insn, operands);"
4335 [(set_attr "type" "fmov")
4336 (set_attr "mode" "<MODE>")])
4339 [(set (match_operand:MODEF 0 "register_operand")
4340 (float_truncate:MODEF
4341 (match_operand:XF 1 "register_operand")))
4342 (clobber (match_operand:MODEF 2 "memory_operand"))]
4343 "TARGET_80387 && reload_completed"
4344 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4345 (set (match_dup 0) (match_dup 2))])
4348 [(set (match_operand:MODEF 0 "memory_operand")
4349 (float_truncate:MODEF
4350 (match_operand:XF 1 "register_operand")))
4351 (clobber (match_operand:MODEF 2 "memory_operand"))]
4353 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4355 ;; Signed conversion to DImode.
4357 (define_expand "fix_truncxfdi2"
4358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4359 (fix:DI (match_operand:XF 1 "register_operand")))
4360 (clobber (reg:CC FLAGS_REG))])]
4365 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4370 (define_expand "fix_trunc<mode>di2"
4371 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4372 (fix:DI (match_operand:MODEF 1 "register_operand")))
4373 (clobber (reg:CC FLAGS_REG))])]
4374 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4377 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4379 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4382 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4384 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4385 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4386 if (out != operands[0])
4387 emit_move_insn (operands[0], out);
4392 ;; Signed conversion to SImode.
4394 (define_expand "fix_truncxfsi2"
4395 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4396 (fix:SI (match_operand:XF 1 "register_operand")))
4397 (clobber (reg:CC FLAGS_REG))])]
4402 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4407 (define_expand "fix_trunc<mode>si2"
4408 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4409 (fix:SI (match_operand:MODEF 1 "register_operand")))
4410 (clobber (reg:CC FLAGS_REG))])]
4411 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4414 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4416 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4419 if (SSE_FLOAT_MODE_P (<MODE>mode))
4421 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4422 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4423 if (out != operands[0])
4424 emit_move_insn (operands[0], out);
4429 ;; Signed conversion to HImode.
4431 (define_expand "fix_trunc<mode>hi2"
4432 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4433 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4434 (clobber (reg:CC FLAGS_REG))])]
4436 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4440 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4445 ;; Unsigned conversion to SImode.
4447 (define_expand "fixuns_trunc<mode>si2"
4449 [(set (match_operand:SI 0 "register_operand")
4451 (match_operand:MODEF 1 "nonimmediate_operand")))
4453 (clobber (match_scratch:<ssevecmode> 3))
4454 (clobber (match_scratch:<ssevecmode> 4))])]
4455 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4457 machine_mode mode = <MODE>mode;
4458 machine_mode vecmode = <ssevecmode>mode;
4459 REAL_VALUE_TYPE TWO31r;
4462 if (optimize_insn_for_size_p ())
4465 real_ldexp (&TWO31r, &dconst1, 31);
4466 two31 = const_double_from_real_value (TWO31r, mode);
4467 two31 = ix86_build_const_vector (vecmode, true, two31);
4468 operands[2] = force_reg (vecmode, two31);
4471 (define_insn_and_split "*fixuns_trunc<mode>_1"
4472 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4474 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4475 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4476 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4477 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4478 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4479 && optimize_function_for_speed_p (cfun)"
4481 "&& reload_completed"
4484 ix86_split_convert_uns_si_sse (operands);
4488 ;; Unsigned conversion to HImode.
4489 ;; Without these patterns, we'll try the unsigned SI conversion which
4490 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4492 (define_expand "fixuns_trunc<mode>hi2"
4494 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4495 (set (match_operand:HI 0 "nonimmediate_operand")
4496 (subreg:HI (match_dup 2) 0))]
4497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4498 "operands[2] = gen_reg_rtx (SImode);")
4500 ;; When SSE is available, it is always faster to use it!
4501 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4502 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4503 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4504 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4505 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4506 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "prefix" "maybe_vex")
4509 (set (attr "prefix_rex")
4511 (match_test "<SWI48:MODE>mode == DImode")
4513 (const_string "*")))
4514 (set_attr "mode" "<MODEF:MODE>")
4515 (set_attr "athlon_decode" "double,vector")
4516 (set_attr "amdfam10_decode" "double,double")
4517 (set_attr "bdver1_decode" "double,double")])
4519 ;; Avoid vector decoded forms of the instruction.
4521 [(match_scratch:MODEF 2 "x")
4522 (set (match_operand:SWI48 0 "register_operand")
4523 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4524 "TARGET_AVOID_VECTOR_DECODE
4525 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4526 && optimize_insn_for_speed_p ()"
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4532 (fix:SWI248x (match_operand 1 "register_operand")))]
4533 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && (TARGET_64BIT || <MODE>mode != DImode))
4538 && can_create_pseudo_p ()"
4543 if (memory_operand (operands[0], VOIDmode))
4544 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4547 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4554 [(set_attr "type" "fisttp")
4555 (set_attr "mode" "<MODE>")])
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4559 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4560 (clobber (match_scratch:XF 2 "=&1f"))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && TARGET_SSE_MATH)"
4566 "* return output_fix_trunc (insn, operands, true);"
4567 [(set_attr "type" "fisttp")
4568 (set_attr "mode" "<MODE>")])
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4572 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4573 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4574 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && (TARGET_64BIT || <MODE>mode != DImode))
4579 && TARGET_SSE_MATH)"
4581 [(set_attr "type" "fisttp")
4582 (set_attr "mode" "<MODE>")])
4585 [(set (match_operand:SWI248x 0 "register_operand")
4586 (fix:SWI248x (match_operand 1 "register_operand")))
4587 (clobber (match_operand:SWI248x 2 "memory_operand"))
4588 (clobber (match_scratch 3))]
4590 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4591 (clobber (match_dup 3))])
4592 (set (match_dup 0) (match_dup 2))])
4595 [(set (match_operand:SWI248x 0 "memory_operand")
4596 (fix:SWI248x (match_operand 1 "register_operand")))
4597 (clobber (match_operand:SWI248x 2 "memory_operand"))
4598 (clobber (match_scratch 3))]
4600 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4601 (clobber (match_dup 3))])])
4603 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4604 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4605 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4606 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4607 ;; function in i386.c.
4608 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4609 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4610 (fix:SWI248x (match_operand 1 "register_operand")))
4611 (clobber (reg:CC FLAGS_REG))]
4612 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && (TARGET_64BIT || <MODE>mode != DImode))
4616 && can_create_pseudo_p ()"
4621 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4623 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4624 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4625 if (memory_operand (operands[0], VOIDmode))
4626 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4627 operands[2], operands[3]));
4630 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4631 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4632 operands[2], operands[3],
4637 [(set_attr "type" "fistp")
4638 (set_attr "i387_cw" "trunc")
4639 (set_attr "mode" "<MODE>")])
4641 (define_insn "fix_truncdi_i387"
4642 [(set (match_operand:DI 0 "memory_operand" "=m")
4643 (fix:DI (match_operand 1 "register_operand" "f")))
4644 (use (match_operand:HI 2 "memory_operand" "m"))
4645 (use (match_operand:HI 3 "memory_operand" "m"))
4646 (clobber (match_scratch:XF 4 "=&1f"))]
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4650 "* return output_fix_trunc (insn, operands, false);"
4651 [(set_attr "type" "fistp")
4652 (set_attr "i387_cw" "trunc")
4653 (set_attr "mode" "DI")])
4655 (define_insn "fix_truncdi_i387_with_temp"
4656 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4657 (fix:DI (match_operand 1 "register_operand" "f,f")))
4658 (use (match_operand:HI 2 "memory_operand" "m,m"))
4659 (use (match_operand:HI 3 "memory_operand" "m,m"))
4660 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4661 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4666 [(set_attr "type" "fistp")
4667 (set_attr "i387_cw" "trunc")
4668 (set_attr "mode" "DI")])
4671 [(set (match_operand:DI 0 "register_operand")
4672 (fix:DI (match_operand 1 "register_operand")))
4673 (use (match_operand:HI 2 "memory_operand"))
4674 (use (match_operand:HI 3 "memory_operand"))
4675 (clobber (match_operand:DI 4 "memory_operand"))
4676 (clobber (match_scratch 5))]
4678 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4681 (clobber (match_dup 5))])
4682 (set (match_dup 0) (match_dup 4))])
4685 [(set (match_operand:DI 0 "memory_operand")
4686 (fix:DI (match_operand 1 "register_operand")))
4687 (use (match_operand:HI 2 "memory_operand"))
4688 (use (match_operand:HI 3 "memory_operand"))
4689 (clobber (match_operand:DI 4 "memory_operand"))
4690 (clobber (match_scratch 5))]
4692 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4695 (clobber (match_dup 5))])])
4697 (define_insn "fix_trunc<mode>_i387"
4698 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4699 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4700 (use (match_operand:HI 2 "memory_operand" "m"))
4701 (use (match_operand:HI 3 "memory_operand" "m"))]
4702 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4705 "* return output_fix_trunc (insn, operands, false);"
4706 [(set_attr "type" "fistp")
4707 (set_attr "i387_cw" "trunc")
4708 (set_attr "mode" "<MODE>")])
4710 (define_insn "fix_trunc<mode>_i387_with_temp"
4711 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4712 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4713 (use (match_operand:HI 2 "memory_operand" "m,m"))
4714 (use (match_operand:HI 3 "memory_operand" "m,m"))
4715 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4720 [(set_attr "type" "fistp")
4721 (set_attr "i387_cw" "trunc")
4722 (set_attr "mode" "<MODE>")])
4725 [(set (match_operand:SWI24 0 "register_operand")
4726 (fix:SWI24 (match_operand 1 "register_operand")))
4727 (use (match_operand:HI 2 "memory_operand"))
4728 (use (match_operand:HI 3 "memory_operand"))
4729 (clobber (match_operand:SWI24 4 "memory_operand"))]
4731 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4733 (use (match_dup 3))])
4734 (set (match_dup 0) (match_dup 4))])
4737 [(set (match_operand:SWI24 0 "memory_operand")
4738 (fix:SWI24 (match_operand 1 "register_operand")))
4739 (use (match_operand:HI 2 "memory_operand"))
4740 (use (match_operand:HI 3 "memory_operand"))
4741 (clobber (match_operand:SWI24 4 "memory_operand"))]
4743 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4745 (use (match_dup 3))])])
4747 (define_insn "x86_fnstcw_1"
4748 [(set (match_operand:HI 0 "memory_operand" "=m")
4749 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4752 [(set (attr "length")
4753 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4754 (set_attr "mode" "HI")
4755 (set_attr "unit" "i387")
4756 (set_attr "bdver1_decode" "vector")])
4758 (define_insn "x86_fldcw_1"
4759 [(set (reg:HI FPCR_REG)
4760 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4763 [(set (attr "length")
4764 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4765 (set_attr "mode" "HI")
4766 (set_attr "unit" "i387")
4767 (set_attr "athlon_decode" "vector")
4768 (set_attr "amdfam10_decode" "vector")
4769 (set_attr "bdver1_decode" "vector")])
4771 ;; Conversion between fixed point and floating point.
4773 ;; Even though we only accept memory inputs, the backend _really_
4774 ;; wants to be able to do this between registers. Thankfully, LRA
4775 ;; will fix this up for us during register allocation.
4777 (define_insn "floathi<mode>2"
4778 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4779 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4781 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4782 || TARGET_MIX_SSE_I387)"
4784 [(set_attr "type" "fmov")
4785 (set_attr "mode" "<MODE>")
4786 (set_attr "fp_int_src" "true")])
4788 (define_insn "float<SWI48x:mode>xf2"
4789 [(set (match_operand:XF 0 "register_operand" "=f")
4790 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4793 [(set_attr "type" "fmov")
4794 (set_attr "mode" "XF")
4795 (set_attr "fp_int_src" "true")])
4797 (define_expand "float<SWI48:mode><MODEF:mode>2"
4798 [(set (match_operand:MODEF 0 "register_operand")
4799 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4800 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4802 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4803 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4805 rtx reg = gen_reg_rtx (XFmode);
4806 rtx (*insn)(rtx, rtx);
4808 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4810 if (<MODEF:MODE>mode == SFmode)
4811 insn = gen_truncxfsf2;
4812 else if (<MODEF:MODE>mode == DFmode)
4813 insn = gen_truncxfdf2;
4817 emit_insn (insn (operands[0], reg));
4822 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4825 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4826 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4829 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4830 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4831 [(set_attr "type" "fmov,sseicvt,sseicvt")
4832 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4833 (set_attr "mode" "<MODEF:MODE>")
4834 (set (attr "prefix_rex")
4836 (and (eq_attr "prefix" "maybe_vex")
4837 (match_test "<SWI48:MODE>mode == DImode"))
4839 (const_string "*")))
4840 (set_attr "unit" "i387,*,*")
4841 (set_attr "athlon_decode" "*,double,direct")
4842 (set_attr "amdfam10_decode" "*,vector,double")
4843 (set_attr "bdver1_decode" "*,double,direct")
4844 (set_attr "fp_int_src" "true")
4845 (set (attr "enabled")
4846 (cond [(eq_attr "alternative" "0")
4847 (symbol_ref "TARGET_MIX_SSE_I387
4848 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4851 (symbol_ref "true")))
4852 (set (attr "preferred_for_speed")
4853 (cond [(eq_attr "alternative" "1")
4854 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4855 (symbol_ref "true")))
4858 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f")
4860 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4861 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4863 [(set_attr "type" "fmov")
4864 (set_attr "mode" "<MODEF:MODE>")
4865 (set_attr "fp_int_src" "true")])
4867 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4868 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4869 ;; alternative in sse2_loadld.
4871 [(set (match_operand:MODEF 0 "register_operand")
4872 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4873 "TARGET_SSE2 && TARGET_SSE_MATH
4874 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4875 && reload_completed && SSE_REG_P (operands[0])
4876 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4879 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4881 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4883 emit_insn (gen_sse2_loadld (operands[4],
4884 CONST0_RTX (V4SImode), operands[1]));
4886 if (<ssevecmode>mode == V4SFmode)
4887 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4889 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4893 ;; Avoid partial SSE register dependency stalls
4895 [(set (match_operand:MODEF 0 "register_operand")
4896 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4897 "TARGET_SSE2 && TARGET_SSE_MATH
4898 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4899 && optimize_function_for_speed_p (cfun)
4900 && reload_completed && SSE_REG_P (operands[0])"
4903 const machine_mode vmode = <MODEF:ssevecmode>mode;
4904 const machine_mode mode = <MODEF:MODE>mode;
4905 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4907 emit_move_insn (op0, CONST0_RTX (vmode));
4909 t = gen_rtx_FLOAT (mode, operands[1]);
4910 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4911 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4912 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4916 ;; Break partial reg stall for cvtsd2ss.
4919 [(set (match_operand:SF 0 "register_operand")
4921 (match_operand:DF 1 "nonimmediate_operand")))]
4922 "TARGET_SSE2 && TARGET_SSE_MATH
4923 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4924 && optimize_function_for_speed_p (cfun)
4925 && SSE_REG_P (operands[0])
4926 && (!SSE_REG_P (operands[1])
4927 || REGNO (operands[0]) != REGNO (operands[1]))"
4931 (float_truncate:V2SF
4936 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4938 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4940 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4943 ;; Break partial reg stall for cvtss2sd.
4946 [(set (match_operand:DF 0 "register_operand")
4948 (match_operand:SF 1 "nonimmediate_operand")))]
4949 "TARGET_SSE2 && TARGET_SSE_MATH
4950 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4951 && optimize_function_for_speed_p (cfun)
4952 && SSE_REG_P (operands[0])
4953 && (!SSE_REG_P (operands[1])
4954 || REGNO (operands[0]) != REGNO (operands[1]))"
4960 (parallel [(const_int 0) (const_int 1)])))
4964 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4966 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4968 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4971 ;; Avoid store forwarding (partial memory) stall penalty
4972 ;; by passing DImode value through XMM registers. */
4974 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4975 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4977 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4978 (clobber (match_scratch:V4SI 3 "=X,x"))
4979 (clobber (match_scratch:V4SI 4 "=X,x"))
4980 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4981 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4982 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4983 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4985 [(set_attr "type" "multi")
4986 (set_attr "mode" "<X87MODEF:MODE>")
4987 (set_attr "unit" "i387")
4988 (set_attr "fp_int_src" "true")])
4991 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4992 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4993 (clobber (match_scratch:V4SI 3))
4994 (clobber (match_scratch:V4SI 4))
4995 (clobber (match_operand:DI 2 "memory_operand"))]
4996 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4997 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4998 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4999 && reload_completed"
5000 [(set (match_dup 2) (match_dup 3))
5001 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5003 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5004 Assemble the 64-bit DImode value in an xmm register. */
5005 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5006 gen_rtx_SUBREG (SImode, operands[1], 0)));
5007 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5008 gen_rtx_SUBREG (SImode, operands[1], 4)));
5009 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5012 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5016 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5017 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5018 (clobber (match_scratch:V4SI 3))
5019 (clobber (match_scratch:V4SI 4))
5020 (clobber (match_operand:DI 2 "memory_operand"))]
5021 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5022 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5023 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5024 && reload_completed"
5025 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5027 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5028 [(set (match_operand:MODEF 0 "register_operand")
5029 (unsigned_float:MODEF
5030 (match_operand:SWI12 1 "nonimmediate_operand")))]
5032 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5034 operands[1] = convert_to_mode (SImode, operands[1], 1);
5035 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5039 ;; Avoid store forwarding (partial memory) stall penalty by extending
5040 ;; SImode value to DImode through XMM register instead of pushing two
5041 ;; SImode values to stack. Also note that fild loads from memory only.
5043 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5044 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5045 (unsigned_float:X87MODEF
5046 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5047 (clobber (match_scratch:DI 3 "=x"))
5048 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5050 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5051 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5053 "&& reload_completed"
5054 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5055 (set (match_dup 2) (match_dup 3))
5057 (float:X87MODEF (match_dup 2)))]
5059 [(set_attr "type" "multi")
5060 (set_attr "mode" "<MODE>")])
5062 (define_expand "floatunssi<mode>2"
5064 [(set (match_operand:X87MODEF 0 "register_operand")
5065 (unsigned_float:X87MODEF
5066 (match_operand:SI 1 "nonimmediate_operand")))
5067 (clobber (match_scratch:DI 3))
5068 (clobber (match_dup 2))])]
5070 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5072 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5074 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5076 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5080 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5083 (define_expand "floatunsdisf2"
5084 [(use (match_operand:SF 0 "register_operand"))
5085 (use (match_operand:DI 1 "nonimmediate_operand"))]
5086 "TARGET_64BIT && TARGET_SSE_MATH"
5087 "x86_emit_floatuns (operands); DONE;")
5089 (define_expand "floatunsdidf2"
5090 [(use (match_operand:DF 0 "register_operand"))
5091 (use (match_operand:DI 1 "nonimmediate_operand"))]
5092 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5093 && TARGET_SSE2 && TARGET_SSE_MATH"
5096 x86_emit_floatuns (operands);
5098 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5102 ;; Load effective address instructions
5104 (define_insn_and_split "*lea<mode>"
5105 [(set (match_operand:SWI48 0 "register_operand" "=r")
5106 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5109 if (SImode_address_operand (operands[1], VOIDmode))
5111 gcc_assert (TARGET_64BIT);
5112 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5115 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5117 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5120 machine_mode mode = <MODE>mode;
5123 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5124 change operands[] array behind our back. */
5125 pat = PATTERN (curr_insn);
5127 operands[0] = SET_DEST (pat);
5128 operands[1] = SET_SRC (pat);
5130 /* Emit all operations in SImode for zero-extended addresses. */
5131 if (SImode_address_operand (operands[1], VOIDmode))
5134 ix86_split_lea_for_addr (curr_insn, operands, mode);
5136 /* Zero-extend return register to DImode for zero-extended addresses. */
5137 if (mode != <MODE>mode)
5138 emit_insn (gen_zero_extendsidi2
5139 (operands[0], gen_lowpart (mode, operands[0])));
5143 [(set_attr "type" "lea")
5146 (match_operand 1 "SImode_address_operand")
5148 (const_string "<MODE>")))])
5152 (define_expand "add<mode>3"
5153 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5154 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5155 (match_operand:SDWIM 2 "<general_operand>")))]
5157 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5159 (define_insn_and_split "*add<dwi>3_doubleword"
5160 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5162 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5163 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5164 (clobber (reg:CC FLAGS_REG))]
5165 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5168 [(parallel [(set (reg:CC FLAGS_REG)
5169 (unspec:CC [(match_dup 1) (match_dup 2)]
5172 (plus:DWIH (match_dup 1) (match_dup 2)))])
5173 (parallel [(set (match_dup 3)
5177 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5179 (clobber (reg:CC FLAGS_REG))])]
5180 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5182 (define_insn "*add<mode>3_cc"
5183 [(set (reg:CC FLAGS_REG)
5185 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5186 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5188 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5189 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5190 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5191 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5192 [(set_attr "type" "alu")
5193 (set_attr "mode" "<MODE>")])
5195 (define_insn "addqi3_cc"
5196 [(set (reg:CC FLAGS_REG)
5198 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5199 (match_operand:QI 2 "general_operand" "qn,qm")]
5201 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5202 (plus:QI (match_dup 1) (match_dup 2)))]
5203 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5204 "add{b}\t{%2, %0|%0, %2}"
5205 [(set_attr "type" "alu")
5206 (set_attr "mode" "QI")])
5208 (define_insn "*add<mode>_1"
5209 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5211 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5212 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5213 (clobber (reg:CC FLAGS_REG))]
5214 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5216 switch (get_attr_type (insn))
5222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223 if (operands[2] == const1_rtx)
5224 return "inc{<imodesuffix>}\t%0";
5227 gcc_assert (operands[2] == constm1_rtx);
5228 return "dec{<imodesuffix>}\t%0";
5232 /* For most processors, ADD is faster than LEA. This alternative
5233 was added to use ADD as much as possible. */
5234 if (which_alternative == 2)
5235 std::swap (operands[1], operands[2]);
5237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5239 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5241 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5245 (cond [(eq_attr "alternative" "3")
5246 (const_string "lea")
5247 (match_operand:SWI48 2 "incdec_operand")
5248 (const_string "incdec")
5250 (const_string "alu")))
5251 (set (attr "length_immediate")
5253 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5255 (const_string "*")))
5256 (set_attr "mode" "<MODE>")])
5258 ;; It may seem that nonimmediate operand is proper one for operand 1.
5259 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5260 ;; we take care in ix86_binary_operator_ok to not allow two memory
5261 ;; operands so proper swapping will be done in reload. This allow
5262 ;; patterns constructed from addsi_1 to match.
5264 (define_insn "addsi_1_zext"
5265 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5267 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5268 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5269 (clobber (reg:CC FLAGS_REG))]
5270 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5272 switch (get_attr_type (insn))
5278 if (operands[2] == const1_rtx)
5279 return "inc{l}\t%k0";
5282 gcc_assert (operands[2] == constm1_rtx);
5283 return "dec{l}\t%k0";
5287 /* For most processors, ADD is faster than LEA. This alternative
5288 was added to use ADD as much as possible. */
5289 if (which_alternative == 1)
5290 std::swap (operands[1], operands[2]);
5292 if (x86_maybe_negate_const_int (&operands[2], SImode))
5293 return "sub{l}\t{%2, %k0|%k0, %2}";
5295 return "add{l}\t{%2, %k0|%k0, %2}";
5299 (cond [(eq_attr "alternative" "2")
5300 (const_string "lea")
5301 (match_operand:SI 2 "incdec_operand")
5302 (const_string "incdec")
5304 (const_string "alu")))
5305 (set (attr "length_immediate")
5307 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5309 (const_string "*")))
5310 (set_attr "mode" "SI")])
5312 (define_insn "*addhi_1"
5313 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5314 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5315 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5316 (clobber (reg:CC FLAGS_REG))]
5317 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5319 switch (get_attr_type (insn))
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 if (operands[2] == const1_rtx)
5327 return "inc{w}\t%0";
5330 gcc_assert (operands[2] == constm1_rtx);
5331 return "dec{w}\t%0";
5335 /* For most processors, ADD is faster than LEA. This alternative
5336 was added to use ADD as much as possible. */
5337 if (which_alternative == 2)
5338 std::swap (operands[1], operands[2]);
5340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341 if (x86_maybe_negate_const_int (&operands[2], HImode))
5342 return "sub{w}\t{%2, %0|%0, %2}";
5344 return "add{w}\t{%2, %0|%0, %2}";
5348 (cond [(eq_attr "alternative" "3")
5349 (const_string "lea")
5350 (match_operand:HI 2 "incdec_operand")
5351 (const_string "incdec")
5353 (const_string "alu")))
5354 (set (attr "length_immediate")
5356 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5358 (const_string "*")))
5359 (set_attr "mode" "HI,HI,HI,SI")])
5361 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5362 (define_insn "*addqi_1"
5363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5364 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5365 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5366 (clobber (reg:CC FLAGS_REG))]
5367 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5369 bool widen = (which_alternative == 3 || which_alternative == 4);
5371 switch (get_attr_type (insn))
5377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 if (operands[2] == const1_rtx)
5379 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5387 /* For most processors, ADD is faster than LEA. These alternatives
5388 were added to use ADD as much as possible. */
5389 if (which_alternative == 2 || which_alternative == 4)
5390 std::swap (operands[1], operands[2]);
5392 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5393 if (x86_maybe_negate_const_int (&operands[2], QImode))
5396 return "sub{l}\t{%2, %k0|%k0, %2}";
5398 return "sub{b}\t{%2, %0|%0, %2}";
5401 return "add{l}\t{%k2, %k0|%k0, %k2}";
5403 return "add{b}\t{%2, %0|%0, %2}";
5407 (cond [(eq_attr "alternative" "5")
5408 (const_string "lea")
5409 (match_operand:QI 2 "incdec_operand")
5410 (const_string "incdec")
5412 (const_string "alu")))
5413 (set (attr "length_immediate")
5415 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5417 (const_string "*")))
5418 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5420 (define_insn "*addqi_1_slp"
5421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5422 (plus:QI (match_dup 0)
5423 (match_operand:QI 1 "general_operand" "qn,qm")))
5424 (clobber (reg:CC FLAGS_REG))]
5425 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5428 switch (get_attr_type (insn))
5431 if (operands[1] == const1_rtx)
5432 return "inc{b}\t%0";
5435 gcc_assert (operands[1] == constm1_rtx);
5436 return "dec{b}\t%0";
5440 if (x86_maybe_negate_const_int (&operands[1], QImode))
5441 return "sub{b}\t{%1, %0|%0, %1}";
5443 return "add{b}\t{%1, %0|%0, %1}";
5447 (if_then_else (match_operand:QI 1 "incdec_operand")
5448 (const_string "incdec")
5449 (const_string "alu1")))
5450 (set (attr "memory")
5451 (if_then_else (match_operand 1 "memory_operand")
5452 (const_string "load")
5453 (const_string "none")))
5454 (set_attr "mode" "QI")])
5456 ;; Split non destructive adds if we cannot use lea.
5458 [(set (match_operand:SWI48 0 "register_operand")
5459 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5460 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5461 (clobber (reg:CC FLAGS_REG))]
5462 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5463 [(set (match_dup 0) (match_dup 1))
5464 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5465 (clobber (reg:CC FLAGS_REG))])])
5467 ;; Convert add to the lea pattern to avoid flags dependency.
5469 [(set (match_operand:SWI 0 "register_operand")
5470 (plus:SWI (match_operand:SWI 1 "register_operand")
5471 (match_operand:SWI 2 "<nonmemory_operand>")))
5472 (clobber (reg:CC FLAGS_REG))]
5473 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5476 machine_mode mode = <MODE>mode;
5479 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5482 operands[0] = gen_lowpart (mode, operands[0]);
5483 operands[1] = gen_lowpart (mode, operands[1]);
5484 operands[2] = gen_lowpart (mode, operands[2]);
5487 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5489 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5493 ;; Split non destructive adds if we cannot use lea.
5495 [(set (match_operand:DI 0 "register_operand")
5497 (plus:SI (match_operand:SI 1 "register_operand")
5498 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5499 (clobber (reg:CC FLAGS_REG))]
5501 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5502 [(set (match_dup 3) (match_dup 1))
5503 (parallel [(set (match_dup 0)
5504 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5505 (clobber (reg:CC FLAGS_REG))])]
5506 "operands[3] = gen_lowpart (SImode, operands[0]);")
5508 ;; Convert add to the lea pattern to avoid flags dependency.
5510 [(set (match_operand:DI 0 "register_operand")
5512 (plus:SI (match_operand:SI 1 "register_operand")
5513 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5514 (clobber (reg:CC FLAGS_REG))]
5515 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5517 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5519 (define_insn "*add<mode>_2"
5520 [(set (reg FLAGS_REG)
5523 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5524 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5526 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5527 (plus:SWI (match_dup 1) (match_dup 2)))]
5528 "ix86_match_ccmode (insn, CCGOCmode)
5529 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5531 switch (get_attr_type (insn))
5534 if (operands[2] == const1_rtx)
5535 return "inc{<imodesuffix>}\t%0";
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{<imodesuffix>}\t%0";
5543 if (which_alternative == 2)
5544 std::swap (operands[1], operands[2]);
5546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5548 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5554 (if_then_else (match_operand:SWI 2 "incdec_operand")
5555 (const_string "incdec")
5556 (const_string "alu")))
5557 (set (attr "length_immediate")
5559 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5561 (const_string "*")))
5562 (set_attr "mode" "<MODE>")])
5564 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5565 (define_insn "*addsi_2_zext"
5566 [(set (reg FLAGS_REG)
5568 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5569 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5571 (set (match_operand:DI 0 "register_operand" "=r,r")
5572 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5574 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5576 switch (get_attr_type (insn))
5579 if (operands[2] == const1_rtx)
5580 return "inc{l}\t%k0";
5583 gcc_assert (operands[2] == constm1_rtx);
5584 return "dec{l}\t%k0";
5588 if (which_alternative == 1)
5589 std::swap (operands[1], operands[2]);
5591 if (x86_maybe_negate_const_int (&operands[2], SImode))
5592 return "sub{l}\t{%2, %k0|%k0, %2}";
5594 return "add{l}\t{%2, %k0|%k0, %2}";
5598 (if_then_else (match_operand:SI 2 "incdec_operand")
5599 (const_string "incdec")
5600 (const_string "alu")))
5601 (set (attr "length_immediate")
5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5605 (const_string "*")))
5606 (set_attr "mode" "SI")])
5608 (define_insn "*add<mode>_3"
5609 [(set (reg FLAGS_REG)
5611 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5612 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5613 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5614 "ix86_match_ccmode (insn, CCZmode)
5615 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5617 switch (get_attr_type (insn))
5620 if (operands[2] == const1_rtx)
5621 return "inc{<imodesuffix>}\t%0";
5624 gcc_assert (operands[2] == constm1_rtx);
5625 return "dec{<imodesuffix>}\t%0";
5629 if (which_alternative == 1)
5630 std::swap (operands[1], operands[2]);
5632 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5634 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5636 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5640 (if_then_else (match_operand:SWI 2 "incdec_operand")
5641 (const_string "incdec")
5642 (const_string "alu")))
5643 (set (attr "length_immediate")
5645 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5647 (const_string "*")))
5648 (set_attr "mode" "<MODE>")])
5650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5651 (define_insn "*addsi_3_zext"
5652 [(set (reg FLAGS_REG)
5654 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5655 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5656 (set (match_operand:DI 0 "register_operand" "=r,r")
5657 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5658 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5659 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5661 switch (get_attr_type (insn))
5664 if (operands[2] == const1_rtx)
5665 return "inc{l}\t%k0";
5668 gcc_assert (operands[2] == constm1_rtx);
5669 return "dec{l}\t%k0";
5673 if (which_alternative == 1)
5674 std::swap (operands[1], operands[2]);
5676 if (x86_maybe_negate_const_int (&operands[2], SImode))
5677 return "sub{l}\t{%2, %k0|%k0, %2}";
5679 return "add{l}\t{%2, %k0|%k0, %2}";
5683 (if_then_else (match_operand:SI 2 "incdec_operand")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set (attr "length_immediate")
5688 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5690 (const_string "*")))
5691 (set_attr "mode" "SI")])
5693 ; For comparisons against 1, -1 and 128, we may generate better code
5694 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5695 ; is matched then. We can't accept general immediate, because for
5696 ; case of overflows, the result is messed up.
5697 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5698 ; only for comparisons not depending on it.
5700 (define_insn "*adddi_4"
5701 [(set (reg FLAGS_REG)
5703 (match_operand:DI 1 "nonimmediate_operand" "0")
5704 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5705 (clobber (match_scratch:DI 0 "=rm"))]
5707 && ix86_match_ccmode (insn, CCGCmode)"
5709 switch (get_attr_type (insn))
5712 if (operands[2] == constm1_rtx)
5713 return "inc{q}\t%0";
5716 gcc_assert (operands[2] == const1_rtx);
5717 return "dec{q}\t%0";
5721 if (x86_maybe_negate_const_int (&operands[2], DImode))
5722 return "add{q}\t{%2, %0|%0, %2}";
5724 return "sub{q}\t{%2, %0|%0, %2}";
5728 (if_then_else (match_operand:DI 2 "incdec_operand")
5729 (const_string "incdec")
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5735 (const_string "*")))
5736 (set_attr "mode" "DI")])
5738 ; For comparisons against 1, -1 and 128, we may generate better code
5739 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5740 ; is matched then. We can't accept general immediate, because for
5741 ; case of overflows, the result is messed up.
5742 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5743 ; only for comparisons not depending on it.
5745 (define_insn "*add<mode>_4"
5746 [(set (reg FLAGS_REG)
5748 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5749 (match_operand:SWI124 2 "const_int_operand" "n")))
5750 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5751 "ix86_match_ccmode (insn, CCGCmode)"
5753 switch (get_attr_type (insn))
5756 if (operands[2] == constm1_rtx)
5757 return "inc{<imodesuffix>}\t%0";
5760 gcc_assert (operands[2] == const1_rtx);
5761 return "dec{<imodesuffix>}\t%0";
5765 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5766 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5768 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5772 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5773 (const_string "incdec")
5774 (const_string "alu")))
5775 (set (attr "length_immediate")
5777 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5779 (const_string "*")))
5780 (set_attr "mode" "<MODE>")])
5782 (define_insn "*add<mode>_5"
5783 [(set (reg FLAGS_REG)
5786 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5787 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5789 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5790 "ix86_match_ccmode (insn, CCGOCmode)
5791 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5793 switch (get_attr_type (insn))
5796 if (operands[2] == const1_rtx)
5797 return "inc{<imodesuffix>}\t%0";
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{<imodesuffix>}\t%0";
5805 if (which_alternative == 1)
5806 std::swap (operands[1], operands[2]);
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5816 (if_then_else (match_operand:SWI 2 "incdec_operand")
5817 (const_string "incdec")
5818 (const_string "alu")))
5819 (set (attr "length_immediate")
5821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5823 (const_string "*")))
5824 (set_attr "mode" "<MODE>")])
5826 (define_insn "addqi_ext_1"
5827 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5832 (match_operand 1 "ext_register_operand" "0,0")
5835 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5836 (clobber (reg:CC FLAGS_REG))]
5839 switch (get_attr_type (insn))
5842 if (operands[2] == const1_rtx)
5843 return "inc{b}\t%h0";
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{b}\t%h0";
5851 return "add{b}\t{%2, %h0|%h0, %2}";
5854 [(set_attr "isa" "*,nox64")
5856 (if_then_else (match_operand:QI 2 "incdec_operand")
5857 (const_string "incdec")
5858 (const_string "alu")))
5859 (set_attr "modrm" "1")
5860 (set_attr "mode" "QI")])
5862 (define_insn "*addqi_ext_2"
5863 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5868 (match_operand 1 "ext_register_operand" "%0")
5872 (match_operand 2 "ext_register_operand" "Q")
5875 (clobber (reg:CC FLAGS_REG))]
5877 "add{b}\t{%h2, %h0|%h0, %h2}"
5878 [(set_attr "type" "alu")
5879 (set_attr "mode" "QI")])
5881 ;; Add with jump on overflow.
5882 (define_expand "addv<mode>4"
5883 [(parallel [(set (reg:CCO FLAGS_REG)
5886 (match_operand:SWI 1 "nonimmediate_operand"))
5889 (plus:SWI (match_dup 1)
5890 (match_operand:SWI 2
5891 "<general_operand>")))))
5892 (set (match_operand:SWI 0 "register_operand")
5893 (plus:SWI (match_dup 1) (match_dup 2)))])
5894 (set (pc) (if_then_else
5895 (eq (reg:CCO FLAGS_REG) (const_int 0))
5896 (label_ref (match_operand 3))
5900 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5901 if (CONST_INT_P (operands[2]))
5902 operands[4] = operands[2];
5904 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5907 (define_insn "*addv<mode>4"
5908 [(set (reg:CCO FLAGS_REG)
5911 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5913 (match_operand:SWI 2 "<general_sext_operand>"
5916 (plus:SWI (match_dup 1) (match_dup 2)))))
5917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5918 (plus:SWI (match_dup 1) (match_dup 2)))]
5919 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5920 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5921 [(set_attr "type" "alu")
5922 (set_attr "mode" "<MODE>")])
5924 (define_insn "*addv<mode>4_1"
5925 [(set (reg:CCO FLAGS_REG)
5928 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5929 (match_operand:<DWI> 3 "const_int_operand" "i"))
5931 (plus:SWI (match_dup 1)
5932 (match_operand:SWI 2 "x86_64_immediate_operand"
5934 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5935 (plus:SWI (match_dup 1) (match_dup 2)))]
5936 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5937 && CONST_INT_P (operands[2])
5938 && INTVAL (operands[2]) == INTVAL (operands[3])"
5939 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5940 [(set_attr "type" "alu")
5941 (set_attr "mode" "<MODE>")
5942 (set (attr "length_immediate")
5943 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5945 (match_test "<MODE_SIZE> == 8")
5947 (const_string "<MODE_SIZE>")))])
5949 ;; The lea patterns for modes less than 32 bits need to be matched by
5950 ;; several insns converted to real lea by splitters.
5952 (define_insn_and_split "*lea_general_1"
5953 [(set (match_operand 0 "register_operand" "=r")
5954 (plus (plus (match_operand 1 "index_register_operand" "l")
5955 (match_operand 2 "register_operand" "r"))
5956 (match_operand 3 "immediate_operand" "i")))]
5957 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5958 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5959 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5960 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5961 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5962 || GET_MODE (operands[3]) == VOIDmode)"
5964 "&& reload_completed"
5967 machine_mode mode = SImode;
5970 operands[0] = gen_lowpart (mode, operands[0]);
5971 operands[1] = gen_lowpart (mode, operands[1]);
5972 operands[2] = gen_lowpart (mode, operands[2]);
5973 operands[3] = gen_lowpart (mode, operands[3]);
5975 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5981 [(set_attr "type" "lea")
5982 (set_attr "mode" "SI")])
5984 (define_insn_and_split "*lea_general_2"
5985 [(set (match_operand 0 "register_operand" "=r")
5986 (plus (mult (match_operand 1 "index_register_operand" "l")
5987 (match_operand 2 "const248_operand" "n"))
5988 (match_operand 3 "nonmemory_operand" "ri")))]
5989 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5993 || GET_MODE (operands[3]) == VOIDmode)"
5995 "&& reload_completed"
5998 machine_mode mode = SImode;
6001 operands[0] = gen_lowpart (mode, operands[0]);
6002 operands[1] = gen_lowpart (mode, operands[1]);
6003 operands[3] = gen_lowpart (mode, operands[3]);
6005 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6008 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6011 [(set_attr "type" "lea")
6012 (set_attr "mode" "SI")])
6014 (define_insn_and_split "*lea_general_3"
6015 [(set (match_operand 0 "register_operand" "=r")
6016 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6017 (match_operand 2 "const248_operand" "n"))
6018 (match_operand 3 "register_operand" "r"))
6019 (match_operand 4 "immediate_operand" "i")))]
6020 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6021 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6022 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6023 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6025 "&& reload_completed"
6028 machine_mode mode = SImode;
6031 operands[0] = gen_lowpart (mode, operands[0]);
6032 operands[1] = gen_lowpart (mode, operands[1]);
6033 operands[3] = gen_lowpart (mode, operands[3]);
6034 operands[4] = gen_lowpart (mode, operands[4]);
6036 pat = gen_rtx_PLUS (mode,
6038 gen_rtx_MULT (mode, operands[1],
6043 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6046 [(set_attr "type" "lea")
6047 (set_attr "mode" "SI")])
6049 (define_insn_and_split "*lea_general_4"
6050 [(set (match_operand 0 "register_operand" "=r")
6052 (match_operand 1 "index_register_operand" "l")
6053 (match_operand 2 "const_int_operand" "n"))
6054 (match_operand 3 "const_int_operand" "n")))]
6055 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6056 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6057 || GET_MODE (operands[0]) == SImode
6058 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6059 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6060 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6061 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6062 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6064 "&& reload_completed"
6067 machine_mode mode = GET_MODE (operands[0]);
6070 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6073 operands[0] = gen_lowpart (mode, operands[0]);
6074 operands[1] = gen_lowpart (mode, operands[1]);
6077 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6079 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6080 INTVAL (operands[3]));
6082 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6085 [(set_attr "type" "lea")
6087 (if_then_else (match_operand:DI 0)
6089 (const_string "SI")))])
6091 ;; Subtract instructions
6093 (define_expand "sub<mode>3"
6094 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6095 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6096 (match_operand:SDWIM 2 "<general_operand>")))]
6098 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6100 (define_insn_and_split "*sub<dwi>3_doubleword"
6101 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6103 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6104 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6105 (clobber (reg:CC FLAGS_REG))]
6106 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6109 [(parallel [(set (reg:CC FLAGS_REG)
6110 (compare:CC (match_dup 1) (match_dup 2)))
6112 (minus:DWIH (match_dup 1) (match_dup 2)))])
6113 (parallel [(set (match_dup 3)
6117 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6119 (clobber (reg:CC FLAGS_REG))])]
6120 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6122 (define_insn "*sub<mode>_1"
6123 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6125 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6126 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6127 (clobber (reg:CC FLAGS_REG))]
6128 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6129 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6130 [(set_attr "type" "alu")
6131 (set_attr "mode" "<MODE>")])
6133 (define_insn "*subsi_1_zext"
6134 [(set (match_operand:DI 0 "register_operand" "=r")
6136 (minus:SI (match_operand:SI 1 "register_operand" "0")
6137 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6138 (clobber (reg:CC FLAGS_REG))]
6139 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6140 "sub{l}\t{%2, %k0|%k0, %2}"
6141 [(set_attr "type" "alu")
6142 (set_attr "mode" "SI")])
6144 (define_insn "*subqi_1_slp"
6145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6146 (minus:QI (match_dup 0)
6147 (match_operand:QI 1 "general_operand" "qn,qm")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6150 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6151 "sub{b}\t{%1, %0|%0, %1}"
6152 [(set_attr "type" "alu1")
6153 (set_attr "mode" "QI")])
6155 (define_insn "*sub<mode>_2"
6156 [(set (reg FLAGS_REG)
6159 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6160 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6162 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6163 (minus:SWI (match_dup 1) (match_dup 2)))]
6164 "ix86_match_ccmode (insn, CCGOCmode)
6165 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6166 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6167 [(set_attr "type" "alu")
6168 (set_attr "mode" "<MODE>")])
6170 (define_insn "*subsi_2_zext"
6171 [(set (reg FLAGS_REG)
6173 (minus:SI (match_operand:SI 1 "register_operand" "0")
6174 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6176 (set (match_operand:DI 0 "register_operand" "=r")
6178 (minus:SI (match_dup 1)
6180 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6181 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6182 "sub{l}\t{%2, %k0|%k0, %2}"
6183 [(set_attr "type" "alu")
6184 (set_attr "mode" "SI")])
6186 ;; Subtract with jump on overflow.
6187 (define_expand "subv<mode>4"
6188 [(parallel [(set (reg:CCO FLAGS_REG)
6189 (eq:CCO (minus:<DWI>
6191 (match_operand:SWI 1 "nonimmediate_operand"))
6194 (minus:SWI (match_dup 1)
6195 (match_operand:SWI 2
6196 "<general_operand>")))))
6197 (set (match_operand:SWI 0 "register_operand")
6198 (minus:SWI (match_dup 1) (match_dup 2)))])
6199 (set (pc) (if_then_else
6200 (eq (reg:CCO FLAGS_REG) (const_int 0))
6201 (label_ref (match_operand 3))
6205 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6206 if (CONST_INT_P (operands[2]))
6207 operands[4] = operands[2];
6209 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6212 (define_insn "*subv<mode>4"
6213 [(set (reg:CCO FLAGS_REG)
6214 (eq:CCO (minus:<DWI>
6216 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6218 (match_operand:SWI 2 "<general_sext_operand>"
6221 (minus:SWI (match_dup 1) (match_dup 2)))))
6222 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6223 (minus:SWI (match_dup 1) (match_dup 2)))]
6224 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6225 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6226 [(set_attr "type" "alu")
6227 (set_attr "mode" "<MODE>")])
6229 (define_insn "*subv<mode>4_1"
6230 [(set (reg:CCO FLAGS_REG)
6231 (eq:CCO (minus:<DWI>
6233 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6234 (match_operand:<DWI> 3 "const_int_operand" "i"))
6236 (minus:SWI (match_dup 1)
6237 (match_operand:SWI 2 "x86_64_immediate_operand"
6239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6240 (minus:SWI (match_dup 1) (match_dup 2)))]
6241 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6242 && CONST_INT_P (operands[2])
6243 && INTVAL (operands[2]) == INTVAL (operands[3])"
6244 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6245 [(set_attr "type" "alu")
6246 (set_attr "mode" "<MODE>")
6247 (set (attr "length_immediate")
6248 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6250 (match_test "<MODE_SIZE> == 8")
6252 (const_string "<MODE_SIZE>")))])
6254 (define_insn "*sub<mode>_3"
6255 [(set (reg FLAGS_REG)
6256 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6257 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6258 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6259 (minus:SWI (match_dup 1) (match_dup 2)))]
6260 "ix86_match_ccmode (insn, CCmode)
6261 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6262 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6263 [(set_attr "type" "alu")
6264 (set_attr "mode" "<MODE>")])
6266 (define_insn "*subsi_3_zext"
6267 [(set (reg FLAGS_REG)
6268 (compare (match_operand:SI 1 "register_operand" "0")
6269 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6270 (set (match_operand:DI 0 "register_operand" "=r")
6272 (minus:SI (match_dup 1)
6274 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6275 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6276 "sub{l}\t{%2, %1|%1, %2}"
6277 [(set_attr "type" "alu")
6278 (set_attr "mode" "SI")])
6280 ;; Add with carry and subtract with borrow
6282 (define_expand "<plusminus_insn><mode>3_carry"
6284 [(set (match_operand:SWI 0 "nonimmediate_operand")
6286 (match_operand:SWI 1 "nonimmediate_operand")
6287 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6288 [(match_operand 3 "flags_reg_operand")
6290 (match_operand:SWI 2 "<general_operand>"))))
6291 (clobber (reg:CC FLAGS_REG))])]
6292 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6294 (define_insn "*<plusminus_insn><mode>3_carry"
6295 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6297 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6299 (match_operator 3 "ix86_carry_flag_operator"
6300 [(reg FLAGS_REG) (const_int 0)])
6301 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6304 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6305 [(set_attr "type" "alu")
6306 (set_attr "use_carry" "1")
6307 (set_attr "pent_pair" "pu")
6308 (set_attr "mode" "<MODE>")])
6310 (define_insn "*addsi3_carry_zext"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6313 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6314 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6315 [(reg FLAGS_REG) (const_int 0)])
6316 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6317 (clobber (reg:CC FLAGS_REG))]
6318 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6319 "adc{l}\t{%2, %k0|%k0, %2}"
6320 [(set_attr "type" "alu")
6321 (set_attr "use_carry" "1")
6322 (set_attr "pent_pair" "pu")
6323 (set_attr "mode" "SI")])
6325 (define_insn "*subsi3_carry_zext"
6326 [(set (match_operand:DI 0 "register_operand" "=r")
6328 (minus:SI (match_operand:SI 1 "register_operand" "0")
6329 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6330 [(reg FLAGS_REG) (const_int 0)])
6331 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6332 (clobber (reg:CC FLAGS_REG))]
6333 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6334 "sbb{l}\t{%2, %k0|%k0, %2}"
6335 [(set_attr "type" "alu")
6336 (set_attr "pent_pair" "pu")
6337 (set_attr "mode" "SI")])
6341 (define_insn "adcx<mode>3"
6342 [(set (reg:CCC FLAGS_REG)
6345 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6347 (match_operator 4 "ix86_carry_flag_operator"
6348 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6349 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6351 (set (match_operand:SWI48 0 "register_operand" "=r")
6352 (plus:SWI48 (match_dup 1)
6353 (plus:SWI48 (match_op_dup 4
6354 [(match_dup 3) (const_int 0)])
6356 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6357 "adcx\t{%2, %0|%0, %2}"
6358 [(set_attr "type" "alu")
6359 (set_attr "use_carry" "1")
6360 (set_attr "mode" "<MODE>")])
6362 ;; Overflow setting add instructions
6364 (define_insn "*add<mode>3_cconly_overflow"
6365 [(set (reg:CCC FLAGS_REG)
6368 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6369 (match_operand:SWI 2 "<general_operand>" "<g>"))
6371 (clobber (match_scratch:SWI 0 "=<r>"))]
6372 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6373 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6374 [(set_attr "type" "alu")
6375 (set_attr "mode" "<MODE>")])
6377 (define_insn "*add<mode>3_cc_overflow"
6378 [(set (reg:CCC FLAGS_REG)
6381 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6382 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6384 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6385 (plus:SWI (match_dup 1) (match_dup 2)))]
6386 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6387 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6388 [(set_attr "type" "alu")
6389 (set_attr "mode" "<MODE>")])
6391 (define_insn "*addsi3_zext_cc_overflow"
6392 [(set (reg:CCC FLAGS_REG)
6395 (match_operand:SI 1 "nonimmediate_operand" "%0")
6396 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6398 (set (match_operand:DI 0 "register_operand" "=r")
6399 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6400 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6401 "add{l}\t{%2, %k0|%k0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "SI")])
6405 ;; The patterns that match these are at the end of this file.
6407 (define_expand "<plusminus_insn>xf3"
6408 [(set (match_operand:XF 0 "register_operand")
6410 (match_operand:XF 1 "register_operand")
6411 (match_operand:XF 2 "register_operand")))]
6414 (define_expand "<plusminus_insn><mode>3"
6415 [(set (match_operand:MODEF 0 "register_operand")
6417 (match_operand:MODEF 1 "register_operand")
6418 (match_operand:MODEF 2 "nonimmediate_operand")))]
6419 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6420 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6422 ;; Multiply instructions
6424 (define_expand "mul<mode>3"
6425 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6427 (match_operand:SWIM248 1 "register_operand")
6428 (match_operand:SWIM248 2 "<general_operand>")))
6429 (clobber (reg:CC FLAGS_REG))])])
6431 (define_expand "mulqi3"
6432 [(parallel [(set (match_operand:QI 0 "register_operand")
6434 (match_operand:QI 1 "register_operand")
6435 (match_operand:QI 2 "nonimmediate_operand")))
6436 (clobber (reg:CC FLAGS_REG))])]
6437 "TARGET_QIMODE_MATH")
6440 ;; IMUL reg32/64, reg32/64, imm8 Direct
6441 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6442 ;; IMUL reg32/64, reg32/64, imm32 Direct
6443 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6444 ;; IMUL reg32/64, reg32/64 Direct
6445 ;; IMUL reg32/64, mem32/64 Direct
6447 ;; On BDVER1, all above IMULs use DirectPath
6449 (define_insn "*mul<mode>3_1"
6450 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6452 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6453 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6457 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6458 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6459 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "imul")
6461 (set_attr "prefix_0f" "0,0,1")
6462 (set (attr "athlon_decode")
6463 (cond [(eq_attr "cpu" "athlon")
6464 (const_string "vector")
6465 (eq_attr "alternative" "1")
6466 (const_string "vector")
6467 (and (eq_attr "alternative" "2")
6468 (match_operand 1 "memory_operand"))
6469 (const_string "vector")]
6470 (const_string "direct")))
6471 (set (attr "amdfam10_decode")
6472 (cond [(and (eq_attr "alternative" "0,1")
6473 (match_operand 1 "memory_operand"))
6474 (const_string "vector")]
6475 (const_string "direct")))
6476 (set_attr "bdver1_decode" "direct")
6477 (set_attr "mode" "<MODE>")])
6479 (define_insn "*mulsi3_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6482 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6483 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6484 (clobber (reg:CC FLAGS_REG))]
6486 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6488 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6489 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6490 imul{l}\t{%2, %k0|%k0, %2}"
6491 [(set_attr "type" "imul")
6492 (set_attr "prefix_0f" "0,0,1")
6493 (set (attr "athlon_decode")
6494 (cond [(eq_attr "cpu" "athlon")
6495 (const_string "vector")
6496 (eq_attr "alternative" "1")
6497 (const_string "vector")
6498 (and (eq_attr "alternative" "2")
6499 (match_operand 1 "memory_operand"))
6500 (const_string "vector")]
6501 (const_string "direct")))
6502 (set (attr "amdfam10_decode")
6503 (cond [(and (eq_attr "alternative" "0,1")
6504 (match_operand 1 "memory_operand"))
6505 (const_string "vector")]
6506 (const_string "direct")))
6507 (set_attr "bdver1_decode" "direct")
6508 (set_attr "mode" "SI")])
6511 ;; IMUL reg16, reg16, imm8 VectorPath
6512 ;; IMUL reg16, mem16, imm8 VectorPath
6513 ;; IMUL reg16, reg16, imm16 VectorPath
6514 ;; IMUL reg16, mem16, imm16 VectorPath
6515 ;; IMUL reg16, reg16 Direct
6516 ;; IMUL reg16, mem16 Direct
6518 ;; On BDVER1, all HI MULs use DoublePath
6520 (define_insn "*mulhi3_1"
6521 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6522 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6523 (match_operand:HI 2 "general_operand" "K,n,mr")))
6524 (clobber (reg:CC FLAGS_REG))]
6526 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6528 imul{w}\t{%2, %1, %0|%0, %1, %2}
6529 imul{w}\t{%2, %1, %0|%0, %1, %2}
6530 imul{w}\t{%2, %0|%0, %2}"
6531 [(set_attr "type" "imul")
6532 (set_attr "prefix_0f" "0,0,1")
6533 (set (attr "athlon_decode")
6534 (cond [(eq_attr "cpu" "athlon")
6535 (const_string "vector")
6536 (eq_attr "alternative" "1,2")
6537 (const_string "vector")]
6538 (const_string "direct")))
6539 (set (attr "amdfam10_decode")
6540 (cond [(eq_attr "alternative" "0,1")
6541 (const_string "vector")]
6542 (const_string "direct")))
6543 (set_attr "bdver1_decode" "double")
6544 (set_attr "mode" "HI")])
6546 ;;On AMDFAM10 and BDVER1
6550 (define_insn "*mulqi3_1"
6551 [(set (match_operand:QI 0 "register_operand" "=a")
6552 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6553 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6554 (clobber (reg:CC FLAGS_REG))]
6556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6558 [(set_attr "type" "imul")
6559 (set_attr "length_immediate" "0")
6560 (set (attr "athlon_decode")
6561 (if_then_else (eq_attr "cpu" "athlon")
6562 (const_string "vector")
6563 (const_string "direct")))
6564 (set_attr "amdfam10_decode" "direct")
6565 (set_attr "bdver1_decode" "direct")
6566 (set_attr "mode" "QI")])
6568 ;; Multiply with jump on overflow.
6569 (define_expand "mulv<mode>4"
6570 [(parallel [(set (reg:CCO FLAGS_REG)
6573 (match_operand:SWI48 1 "register_operand"))
6576 (mult:SWI48 (match_dup 1)
6577 (match_operand:SWI48 2
6578 "<general_operand>")))))
6579 (set (match_operand:SWI48 0 "register_operand")
6580 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6581 (set (pc) (if_then_else
6582 (eq (reg:CCO FLAGS_REG) (const_int 0))
6583 (label_ref (match_operand 3))
6587 if (CONST_INT_P (operands[2]))
6588 operands[4] = operands[2];
6590 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6593 (define_insn "*mulv<mode>4"
6594 [(set (reg:CCO FLAGS_REG)
6597 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6599 (match_operand:SWI48 2 "<general_sext_operand>"
6602 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6603 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6604 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6605 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6607 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6608 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "imul")
6610 (set_attr "prefix_0f" "0,1")
6611 (set (attr "athlon_decode")
6612 (cond [(eq_attr "cpu" "athlon")
6613 (const_string "vector")
6614 (eq_attr "alternative" "0")
6615 (const_string "vector")
6616 (and (eq_attr "alternative" "1")
6617 (match_operand 1 "memory_operand"))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set (attr "amdfam10_decode")
6621 (cond [(and (eq_attr "alternative" "1")
6622 (match_operand 1 "memory_operand"))
6623 (const_string "vector")]
6624 (const_string "direct")))
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "<MODE>")])
6628 (define_insn "*mulv<mode>4_1"
6629 [(set (reg:CCO FLAGS_REG)
6632 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6633 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6635 (mult:SWI48 (match_dup 1)
6636 (match_operand:SWI 2 "x86_64_immediate_operand"
6638 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6639 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6641 && CONST_INT_P (operands[2])
6642 && INTVAL (operands[2]) == INTVAL (operands[3])"
6644 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6645 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6646 [(set_attr "type" "imul")
6647 (set (attr "athlon_decode")
6648 (cond [(eq_attr "cpu" "athlon")
6649 (const_string "vector")
6650 (eq_attr "alternative" "1")
6651 (const_string "vector")]
6652 (const_string "direct")))
6653 (set (attr "amdfam10_decode")
6654 (cond [(match_operand 1 "memory_operand")
6655 (const_string "vector")]
6656 (const_string "direct")))
6657 (set_attr "bdver1_decode" "direct")
6658 (set_attr "mode" "<MODE>")
6659 (set (attr "length_immediate")
6660 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6662 (match_test "<MODE_SIZE> == 8")
6664 (const_string "<MODE_SIZE>")))])
6666 (define_expand "<u>mul<mode><dwi>3"
6667 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6670 (match_operand:DWIH 1 "nonimmediate_operand"))
6672 (match_operand:DWIH 2 "register_operand"))))
6673 (clobber (reg:CC FLAGS_REG))])])
6675 (define_expand "<u>mulqihi3"
6676 [(parallel [(set (match_operand:HI 0 "register_operand")
6679 (match_operand:QI 1 "nonimmediate_operand"))
6681 (match_operand:QI 2 "register_operand"))))
6682 (clobber (reg:CC FLAGS_REG))])]
6683 "TARGET_QIMODE_MATH")
6685 (define_insn "*bmi2_umulditi3_1"
6686 [(set (match_operand:DI 0 "register_operand" "=r")
6688 (match_operand:DI 2 "nonimmediate_operand" "%d")
6689 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6690 (set (match_operand:DI 1 "register_operand" "=r")
6693 (mult:TI (zero_extend:TI (match_dup 2))
6694 (zero_extend:TI (match_dup 3)))
6696 "TARGET_64BIT && TARGET_BMI2
6697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6698 "mulx\t{%3, %0, %1|%1, %0, %3}"
6699 [(set_attr "type" "imulx")
6700 (set_attr "prefix" "vex")
6701 (set_attr "mode" "DI")])
6703 (define_insn "*bmi2_umulsidi3_1"
6704 [(set (match_operand:SI 0 "register_operand" "=r")
6706 (match_operand:SI 2 "nonimmediate_operand" "%d")
6707 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6708 (set (match_operand:SI 1 "register_operand" "=r")
6711 (mult:DI (zero_extend:DI (match_dup 2))
6712 (zero_extend:DI (match_dup 3)))
6714 "!TARGET_64BIT && TARGET_BMI2
6715 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716 "mulx\t{%3, %0, %1|%1, %0, %3}"
6717 [(set_attr "type" "imulx")
6718 (set_attr "prefix" "vex")
6719 (set_attr "mode" "SI")])
6721 (define_insn "*umul<mode><dwi>3_1"
6722 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6725 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6727 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6728 (clobber (reg:CC FLAGS_REG))]
6729 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6732 mul{<imodesuffix>}\t%2"
6733 [(set_attr "isa" "bmi2,*")
6734 (set_attr "type" "imulx,imul")
6735 (set_attr "length_immediate" "*,0")
6736 (set (attr "athlon_decode")
6737 (cond [(eq_attr "alternative" "1")
6738 (if_then_else (eq_attr "cpu" "athlon")
6739 (const_string "vector")
6740 (const_string "double"))]
6741 (const_string "*")))
6742 (set_attr "amdfam10_decode" "*,double")
6743 (set_attr "bdver1_decode" "*,direct")
6744 (set_attr "prefix" "vex,orig")
6745 (set_attr "mode" "<MODE>")])
6747 ;; Convert mul to the mulx pattern to avoid flags dependency.
6749 [(set (match_operand:<DWI> 0 "register_operand")
6752 (match_operand:DWIH 1 "register_operand"))
6754 (match_operand:DWIH 2 "nonimmediate_operand"))))
6755 (clobber (reg:CC FLAGS_REG))]
6756 "TARGET_BMI2 && reload_completed
6757 && true_regnum (operands[1]) == DX_REG"
6758 [(parallel [(set (match_dup 3)
6759 (mult:DWIH (match_dup 1) (match_dup 2)))
6763 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6764 (zero_extend:<DWI> (match_dup 2)))
6767 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6769 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6772 (define_insn "*mul<mode><dwi>3_1"
6773 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6776 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6778 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6779 (clobber (reg:CC FLAGS_REG))]
6780 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781 "imul{<imodesuffix>}\t%2"
6782 [(set_attr "type" "imul")
6783 (set_attr "length_immediate" "0")
6784 (set (attr "athlon_decode")
6785 (if_then_else (eq_attr "cpu" "athlon")
6786 (const_string "vector")
6787 (const_string "double")))
6788 (set_attr "amdfam10_decode" "double")
6789 (set_attr "bdver1_decode" "direct")
6790 (set_attr "mode" "<MODE>")])
6792 (define_insn "*<u>mulqihi3_1"
6793 [(set (match_operand:HI 0 "register_operand" "=a")
6796 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6798 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6799 (clobber (reg:CC FLAGS_REG))]
6801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6802 "<sgnprefix>mul{b}\t%2"
6803 [(set_attr "type" "imul")
6804 (set_attr "length_immediate" "0")
6805 (set (attr "athlon_decode")
6806 (if_then_else (eq_attr "cpu" "athlon")
6807 (const_string "vector")
6808 (const_string "direct")))
6809 (set_attr "amdfam10_decode" "direct")
6810 (set_attr "bdver1_decode" "direct")
6811 (set_attr "mode" "QI")])
6813 (define_expand "<s>mul<mode>3_highpart"
6814 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6819 (match_operand:SWI48 1 "nonimmediate_operand"))
6821 (match_operand:SWI48 2 "register_operand")))
6823 (clobber (match_scratch:SWI48 3))
6824 (clobber (reg:CC FLAGS_REG))])]
6826 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6828 (define_insn "*<s>muldi3_highpart_1"
6829 [(set (match_operand:DI 0 "register_operand" "=d")
6834 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6836 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6838 (clobber (match_scratch:DI 3 "=1"))
6839 (clobber (reg:CC FLAGS_REG))]
6841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6842 "<sgnprefix>mul{q}\t%2"
6843 [(set_attr "type" "imul")
6844 (set_attr "length_immediate" "0")
6845 (set (attr "athlon_decode")
6846 (if_then_else (eq_attr "cpu" "athlon")
6847 (const_string "vector")
6848 (const_string "double")))
6849 (set_attr "amdfam10_decode" "double")
6850 (set_attr "bdver1_decode" "direct")
6851 (set_attr "mode" "DI")])
6853 (define_insn "*<s>mulsi3_highpart_1"
6854 [(set (match_operand:SI 0 "register_operand" "=d")
6859 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6861 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6863 (clobber (match_scratch:SI 3 "=1"))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866 "<sgnprefix>mul{l}\t%2"
6867 [(set_attr "type" "imul")
6868 (set_attr "length_immediate" "0")
6869 (set (attr "athlon_decode")
6870 (if_then_else (eq_attr "cpu" "athlon")
6871 (const_string "vector")
6872 (const_string "double")))
6873 (set_attr "amdfam10_decode" "double")
6874 (set_attr "bdver1_decode" "direct")
6875 (set_attr "mode" "SI")])
6877 (define_insn "*<s>mulsi3_highpart_zext"
6878 [(set (match_operand:DI 0 "register_operand" "=d")
6879 (zero_extend:DI (truncate:SI
6881 (mult:DI (any_extend:DI
6882 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6884 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6886 (clobber (match_scratch:SI 3 "=1"))
6887 (clobber (reg:CC FLAGS_REG))]
6889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 "<sgnprefix>mul{l}\t%2"
6891 [(set_attr "type" "imul")
6892 (set_attr "length_immediate" "0")
6893 (set (attr "athlon_decode")
6894 (if_then_else (eq_attr "cpu" "athlon")
6895 (const_string "vector")
6896 (const_string "double")))
6897 (set_attr "amdfam10_decode" "double")
6898 (set_attr "bdver1_decode" "direct")
6899 (set_attr "mode" "SI")])
6901 ;; The patterns that match these are at the end of this file.
6903 (define_expand "mulxf3"
6904 [(set (match_operand:XF 0 "register_operand")
6905 (mult:XF (match_operand:XF 1 "register_operand")
6906 (match_operand:XF 2 "register_operand")))]
6909 (define_expand "mul<mode>3"
6910 [(set (match_operand:MODEF 0 "register_operand")
6911 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6912 (match_operand:MODEF 2 "nonimmediate_operand")))]
6913 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6914 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6916 ;; Divide instructions
6918 ;; The patterns that match these are at the end of this file.
6920 (define_expand "divxf3"
6921 [(set (match_operand:XF 0 "register_operand")
6922 (div:XF (match_operand:XF 1 "register_operand")
6923 (match_operand:XF 2 "register_operand")))]
6926 (define_expand "divdf3"
6927 [(set (match_operand:DF 0 "register_operand")
6928 (div:DF (match_operand:DF 1 "register_operand")
6929 (match_operand:DF 2 "nonimmediate_operand")))]
6930 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6931 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6933 (define_expand "divsf3"
6934 [(set (match_operand:SF 0 "register_operand")
6935 (div:SF (match_operand:SF 1 "register_operand")
6936 (match_operand:SF 2 "nonimmediate_operand")))]
6937 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6942 && optimize_insn_for_speed_p ()
6943 && flag_finite_math_only && !flag_trapping_math
6944 && flag_unsafe_math_optimizations)
6946 ix86_emit_swdivsf (operands[0], operands[1],
6947 operands[2], SFmode);
6952 ;; Divmod instructions.
6954 (define_expand "divmod<mode>4"
6955 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6957 (match_operand:SWIM248 1 "register_operand")
6958 (match_operand:SWIM248 2 "nonimmediate_operand")))
6959 (set (match_operand:SWIM248 3 "register_operand")
6960 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6961 (clobber (reg:CC FLAGS_REG))])])
6963 ;; Split with 8bit unsigned divide:
6964 ;; if (dividend an divisor are in [0-255])
6965 ;; use 8bit unsigned integer divide
6967 ;; use original integer divide
6969 [(set (match_operand:SWI48 0 "register_operand")
6970 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6971 (match_operand:SWI48 3 "nonimmediate_operand")))
6972 (set (match_operand:SWI48 1 "register_operand")
6973 (mod:SWI48 (match_dup 2) (match_dup 3)))
6974 (clobber (reg:CC FLAGS_REG))]
6975 "TARGET_USE_8BIT_IDIV
6976 && TARGET_QIMODE_MATH
6977 && can_create_pseudo_p ()
6978 && !optimize_insn_for_size_p ()"
6980 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6982 (define_insn_and_split "divmod<mode>4_1"
6983 [(set (match_operand:SWI48 0 "register_operand" "=a")
6984 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6985 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6986 (set (match_operand:SWI48 1 "register_operand" "=&d")
6987 (mod:SWI48 (match_dup 2) (match_dup 3)))
6988 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6989 (clobber (reg:CC FLAGS_REG))]
6993 [(parallel [(set (match_dup 1)
6994 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6995 (clobber (reg:CC FLAGS_REG))])
6996 (parallel [(set (match_dup 0)
6997 (div:SWI48 (match_dup 2) (match_dup 3)))
6999 (mod:SWI48 (match_dup 2) (match_dup 3)))
7001 (clobber (reg:CC FLAGS_REG))])]
7003 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7005 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7006 operands[4] = operands[2];
7009 /* Avoid use of cltd in favor of a mov+shift. */
7010 emit_move_insn (operands[1], operands[2]);
7011 operands[4] = operands[1];
7014 [(set_attr "type" "multi")
7015 (set_attr "mode" "<MODE>")])
7017 (define_insn_and_split "*divmod<mode>4"
7018 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7019 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7020 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7021 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7022 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7023 (clobber (reg:CC FLAGS_REG))]
7027 [(parallel [(set (match_dup 1)
7028 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7029 (clobber (reg:CC FLAGS_REG))])
7030 (parallel [(set (match_dup 0)
7031 (div:SWIM248 (match_dup 2) (match_dup 3)))
7033 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7035 (clobber (reg:CC FLAGS_REG))])]
7037 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7039 if (<MODE>mode != HImode
7040 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7041 operands[4] = operands[2];
7044 /* Avoid use of cltd in favor of a mov+shift. */
7045 emit_move_insn (operands[1], operands[2]);
7046 operands[4] = operands[1];
7049 [(set_attr "type" "multi")
7050 (set_attr "mode" "<MODE>")])
7052 (define_insn "*divmod<mode>4_noext"
7053 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7054 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7055 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7056 (set (match_operand:SWIM248 1 "register_operand" "=d")
7057 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7058 (use (match_operand:SWIM248 4 "register_operand" "1"))
7059 (clobber (reg:CC FLAGS_REG))]
7061 "idiv{<imodesuffix>}\t%3"
7062 [(set_attr "type" "idiv")
7063 (set_attr "mode" "<MODE>")])
7065 (define_expand "divmodqi4"
7066 [(parallel [(set (match_operand:QI 0 "register_operand")
7068 (match_operand:QI 1 "register_operand")
7069 (match_operand:QI 2 "nonimmediate_operand")))
7070 (set (match_operand:QI 3 "register_operand")
7071 (mod:QI (match_dup 1) (match_dup 2)))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7078 tmp0 = gen_reg_rtx (HImode);
7079 tmp1 = gen_reg_rtx (HImode);
7081 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7083 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7084 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7086 /* Extract remainder from AH. */
7087 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7088 insn = emit_move_insn (operands[3], tmp1);
7090 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7091 set_unique_reg_note (insn, REG_EQUAL, mod);
7093 /* Extract quotient from AL. */
7094 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7096 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7097 set_unique_reg_note (insn, REG_EQUAL, div);
7102 ;; Divide AX by r/m8, with result stored in
7105 ;; Change div/mod to HImode and extend the second argument to HImode
7106 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7107 ;; combine may fail.
7108 (define_insn "divmodhiqi3"
7109 [(set (match_operand:HI 0 "register_operand" "=a")
7114 (mod:HI (match_operand:HI 1 "register_operand" "0")
7116 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7120 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7121 (clobber (reg:CC FLAGS_REG))]
7122 "TARGET_QIMODE_MATH"
7124 [(set_attr "type" "idiv")
7125 (set_attr "mode" "QI")])
7127 (define_expand "udivmod<mode>4"
7128 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7130 (match_operand:SWIM248 1 "register_operand")
7131 (match_operand:SWIM248 2 "nonimmediate_operand")))
7132 (set (match_operand:SWIM248 3 "register_operand")
7133 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7134 (clobber (reg:CC FLAGS_REG))])])
7136 ;; Split with 8bit unsigned divide:
7137 ;; if (dividend an divisor are in [0-255])
7138 ;; use 8bit unsigned integer divide
7140 ;; use original integer divide
7142 [(set (match_operand:SWI48 0 "register_operand")
7143 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7144 (match_operand:SWI48 3 "nonimmediate_operand")))
7145 (set (match_operand:SWI48 1 "register_operand")
7146 (umod:SWI48 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))]
7148 "TARGET_USE_8BIT_IDIV
7149 && TARGET_QIMODE_MATH
7150 && can_create_pseudo_p ()
7151 && !optimize_insn_for_size_p ()"
7153 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7155 (define_insn_and_split "udivmod<mode>4_1"
7156 [(set (match_operand:SWI48 0 "register_operand" "=a")
7157 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7158 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7159 (set (match_operand:SWI48 1 "register_operand" "=&d")
7160 (umod:SWI48 (match_dup 2) (match_dup 3)))
7161 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7162 (clobber (reg:CC FLAGS_REG))]
7166 [(set (match_dup 1) (const_int 0))
7167 (parallel [(set (match_dup 0)
7168 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7170 (umod:SWI48 (match_dup 2) (match_dup 3)))
7172 (clobber (reg:CC FLAGS_REG))])]
7174 [(set_attr "type" "multi")
7175 (set_attr "mode" "<MODE>")])
7177 (define_insn_and_split "*udivmod<mode>4"
7178 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7179 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7180 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7181 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7182 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7183 (clobber (reg:CC FLAGS_REG))]
7187 [(set (match_dup 1) (const_int 0))
7188 (parallel [(set (match_dup 0)
7189 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7191 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))])]
7195 [(set_attr "type" "multi")
7196 (set_attr "mode" "<MODE>")])
7198 (define_insn "*udivmod<mode>4_noext"
7199 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7200 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7201 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7202 (set (match_operand:SWIM248 1 "register_operand" "=d")
7203 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (use (match_operand:SWIM248 4 "register_operand" "1"))
7205 (clobber (reg:CC FLAGS_REG))]
7207 "div{<imodesuffix>}\t%3"
7208 [(set_attr "type" "idiv")
7209 (set_attr "mode" "<MODE>")])
7211 (define_expand "udivmodqi4"
7212 [(parallel [(set (match_operand:QI 0 "register_operand")
7214 (match_operand:QI 1 "register_operand")
7215 (match_operand:QI 2 "nonimmediate_operand")))
7216 (set (match_operand:QI 3 "register_operand")
7217 (umod:QI (match_dup 1) (match_dup 2)))
7218 (clobber (reg:CC FLAGS_REG))])]
7219 "TARGET_QIMODE_MATH"
7224 tmp0 = gen_reg_rtx (HImode);
7225 tmp1 = gen_reg_rtx (HImode);
7227 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7229 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7230 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7232 /* Extract remainder from AH. */
7233 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7234 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7235 insn = emit_move_insn (operands[3], tmp1);
7237 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7238 set_unique_reg_note (insn, REG_EQUAL, mod);
7240 /* Extract quotient from AL. */
7241 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7243 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7244 set_unique_reg_note (insn, REG_EQUAL, div);
7249 (define_insn "udivmodhiqi3"
7250 [(set (match_operand:HI 0 "register_operand" "=a")
7255 (mod:HI (match_operand:HI 1 "register_operand" "0")
7257 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7261 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7262 (clobber (reg:CC FLAGS_REG))]
7263 "TARGET_QIMODE_MATH"
7265 [(set_attr "type" "idiv")
7266 (set_attr "mode" "QI")])
7268 ;; We cannot use div/idiv for double division, because it causes
7269 ;; "division by zero" on the overflow and that's not what we expect
7270 ;; from truncate. Because true (non truncating) double division is
7271 ;; never generated, we can't create this insn anyway.
7274 ; [(set (match_operand:SI 0 "register_operand" "=a")
7276 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7278 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7279 ; (set (match_operand:SI 3 "register_operand" "=d")
7281 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7282 ; (clobber (reg:CC FLAGS_REG))]
7284 ; "div{l}\t{%2, %0|%0, %2}"
7285 ; [(set_attr "type" "idiv")])
7287 ;;- Logical AND instructions
7289 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7290 ;; Note that this excludes ah.
7292 (define_expand "testsi_ccno_1"
7293 [(set (reg:CCNO FLAGS_REG)
7295 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7296 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7299 (define_expand "testqi_ccz_1"
7300 [(set (reg:CCZ FLAGS_REG)
7301 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7302 (match_operand:QI 1 "nonmemory_operand"))
7305 (define_expand "testdi_ccno_1"
7306 [(set (reg:CCNO FLAGS_REG)
7308 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7309 (match_operand:DI 1 "x86_64_szext_general_operand"))
7311 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7313 (define_insn "*testdi_1"
7314 [(set (reg FLAGS_REG)
7317 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7318 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7320 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7321 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7323 test{l}\t{%k1, %k0|%k0, %k1}
7324 test{l}\t{%k1, %k0|%k0, %k1}
7325 test{q}\t{%1, %0|%0, %1}
7326 test{q}\t{%1, %0|%0, %1}
7327 test{q}\t{%1, %0|%0, %1}"
7328 [(set_attr "type" "test")
7329 (set_attr "modrm" "0,1,0,1,1")
7330 (set_attr "mode" "SI,SI,DI,DI,DI")])
7332 (define_insn "*testqi_1_maybe_si"
7333 [(set (reg FLAGS_REG)
7336 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7337 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7339 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7340 && ix86_match_ccmode (insn,
7341 CONST_INT_P (operands[1])
7342 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7344 if (which_alternative == 3)
7346 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7347 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7348 return "test{l}\t{%1, %k0|%k0, %1}";
7350 return "test{b}\t{%1, %0|%0, %1}";
7352 [(set_attr "type" "test")
7353 (set_attr "modrm" "0,1,1,1")
7354 (set_attr "mode" "QI,QI,QI,SI")
7355 (set_attr "pent_pair" "uv,np,uv,np")])
7357 (define_insn "*test<mode>_1"
7358 [(set (reg FLAGS_REG)
7361 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7362 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7364 "ix86_match_ccmode (insn, CCNOmode)
7365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7366 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7367 [(set_attr "type" "test")
7368 (set_attr "modrm" "0,1,1")
7369 (set_attr "mode" "<MODE>")
7370 (set_attr "pent_pair" "uv,np,uv")])
7372 (define_expand "testqi_ext_ccno_0"
7373 [(set (reg:CCNO FLAGS_REG)
7377 (match_operand 0 "ext_register_operand")
7380 (match_operand 1 "const_int_operand"))
7383 (define_insn "*testqi_ext_0"
7384 [(set (reg FLAGS_REG)
7388 (match_operand 0 "ext_register_operand" "Q")
7391 (match_operand 1 "const_int_operand" "n"))
7393 "ix86_match_ccmode (insn, CCNOmode)"
7394 "test{b}\t{%1, %h0|%h0, %1}"
7395 [(set_attr "type" "test")
7396 (set_attr "mode" "QI")
7397 (set_attr "length_immediate" "1")
7398 (set_attr "modrm" "1")
7399 (set_attr "pent_pair" "np")])
7401 (define_insn "*testqi_ext_1"
7402 [(set (reg FLAGS_REG)
7406 (match_operand 0 "ext_register_operand" "Q,Q")
7410 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7412 "ix86_match_ccmode (insn, CCNOmode)"
7413 "test{b}\t{%1, %h0|%h0, %1}"
7414 [(set_attr "isa" "*,nox64")
7415 (set_attr "type" "test")
7416 (set_attr "mode" "QI")])
7418 (define_insn "*testqi_ext_2"
7419 [(set (reg FLAGS_REG)
7423 (match_operand 0 "ext_register_operand" "Q")
7427 (match_operand 1 "ext_register_operand" "Q")
7431 "ix86_match_ccmode (insn, CCNOmode)"
7432 "test{b}\t{%h1, %h0|%h0, %h1}"
7433 [(set_attr "type" "test")
7434 (set_attr "mode" "QI")])
7436 ;; Combine likes to form bit extractions for some tests. Humor it.
7437 (define_insn "*testqi_ext_3"
7438 [(set (reg FLAGS_REG)
7439 (compare (zero_extract:SWI48
7440 (match_operand 0 "nonimmediate_operand" "rm")
7441 (match_operand:SWI48 1 "const_int_operand")
7442 (match_operand:SWI48 2 "const_int_operand"))
7444 "ix86_match_ccmode (insn, CCNOmode)
7445 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7446 || GET_MODE (operands[0]) == SImode
7447 || GET_MODE (operands[0]) == HImode
7448 || GET_MODE (operands[0]) == QImode)
7449 /* Ensure that resulting mask is zero or sign extended operand. */
7450 && INTVAL (operands[2]) >= 0
7451 && ((INTVAL (operands[1]) > 0
7452 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7453 || (<MODE>mode == DImode
7454 && INTVAL (operands[1]) > 32
7455 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7459 [(set (match_operand 0 "flags_reg_operand")
7460 (match_operator 1 "compare_operator"
7462 (match_operand 2 "nonimmediate_operand")
7463 (match_operand 3 "const_int_operand")
7464 (match_operand 4 "const_int_operand"))
7466 "ix86_match_ccmode (insn, CCNOmode)"
7467 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7469 rtx val = operands[2];
7470 HOST_WIDE_INT len = INTVAL (operands[3]);
7471 HOST_WIDE_INT pos = INTVAL (operands[4]);
7473 machine_mode mode, submode;
7475 mode = GET_MODE (val);
7478 /* ??? Combine likes to put non-volatile mem extractions in QImode
7479 no matter the size of the test. So find a mode that works. */
7480 if (! MEM_VOLATILE_P (val))
7482 mode = smallest_mode_for_size (pos + len, MODE_INT);
7483 val = adjust_address (val, mode, 0);
7486 else if (GET_CODE (val) == SUBREG
7487 && (submode = GET_MODE (SUBREG_REG (val)),
7488 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7489 && pos + len <= GET_MODE_BITSIZE (submode)
7490 && GET_MODE_CLASS (submode) == MODE_INT)
7492 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7494 val = SUBREG_REG (val);
7496 else if (mode == HImode && pos + len <= 8)
7498 /* Small HImode tests can be converted to QImode. */
7500 val = gen_lowpart (QImode, val);
7503 if (len == HOST_BITS_PER_WIDE_INT)
7506 mask = ((HOST_WIDE_INT)1 << len) - 1;
7509 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7512 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7513 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7514 ;; this is relatively important trick.
7515 ;; Do the conversion only post-reload to avoid limiting of the register class
7518 [(set (match_operand 0 "flags_reg_operand")
7519 (match_operator 1 "compare_operator"
7520 [(and (match_operand 2 "register_operand")
7521 (match_operand 3 "const_int_operand"))
7524 && QI_REG_P (operands[2])
7525 && GET_MODE (operands[2]) != QImode
7526 && ((ix86_match_ccmode (insn, CCZmode)
7527 && !(INTVAL (operands[3]) & ~(255 << 8)))
7528 || (ix86_match_ccmode (insn, CCNOmode)
7529 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7532 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7536 operands[2] = gen_lowpart (SImode, operands[2]);
7537 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7541 [(set (match_operand 0 "flags_reg_operand")
7542 (match_operator 1 "compare_operator"
7543 [(and (match_operand 2 "nonimmediate_operand")
7544 (match_operand 3 "const_int_operand"))
7547 && GET_MODE (operands[2]) != QImode
7548 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7549 && ((ix86_match_ccmode (insn, CCZmode)
7550 && !(INTVAL (operands[3]) & ~255))
7551 || (ix86_match_ccmode (insn, CCNOmode)
7552 && !(INTVAL (operands[3]) & ~127)))"
7554 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7557 operands[2] = gen_lowpart (QImode, operands[2]);
7558 operands[3] = gen_lowpart (QImode, operands[3]);
7562 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7563 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7564 (match_operand:SWI1248x 2 "mask_reg_operand")))
7565 (clobber (reg:CC FLAGS_REG))]
7566 "TARGET_AVX512F && reload_completed"
7568 (any_logic:SWI1248x (match_dup 1)
7571 (define_insn "*k<logic><mode>"
7572 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7573 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7574 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7577 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7578 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7580 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7582 [(set_attr "mode" "<MODE>")
7583 (set_attr "type" "msklog")
7584 (set_attr "prefix" "vex")])
7586 ;; %%% This used to optimize known byte-wide and operations to memory,
7587 ;; and sometimes to QImode registers. If this is considered useful,
7588 ;; it should be done with splitters.
7590 (define_expand "and<mode>3"
7591 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7592 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7593 (match_operand:SWIM 2 "<general_szext_operand>")))]
7596 machine_mode mode = <MODE>mode;
7597 rtx (*insn) (rtx, rtx);
7599 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7601 HOST_WIDE_INT ival = INTVAL (operands[2]);
7603 if (ival == (HOST_WIDE_INT) 0xffffffff)
7605 else if (ival == 0xffff)
7607 else if (ival == 0xff)
7611 if (mode == <MODE>mode)
7613 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7617 if (<MODE>mode == DImode)
7618 insn = (mode == SImode)
7619 ? gen_zero_extendsidi2
7621 ? gen_zero_extendhidi2
7622 : gen_zero_extendqidi2;
7623 else if (<MODE>mode == SImode)
7624 insn = (mode == HImode)
7625 ? gen_zero_extendhisi2
7626 : gen_zero_extendqisi2;
7627 else if (<MODE>mode == HImode)
7628 insn = gen_zero_extendqihi2;
7632 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7636 (define_insn "*anddi_1"
7637 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7639 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7640 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7641 (clobber (reg:CC FLAGS_REG))]
7642 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7644 switch (get_attr_type (insn))
7650 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7653 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7654 if (get_attr_mode (insn) == MODE_SI)
7655 return "and{l}\t{%k2, %k0|%k0, %k2}";
7657 return "and{q}\t{%2, %0|%0, %2}";
7660 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7661 (set_attr "length_immediate" "*,*,*,0,0")
7662 (set (attr "prefix_rex")
7664 (and (eq_attr "type" "imovx")
7665 (and (match_test "INTVAL (operands[2]) == 0xff")
7666 (match_operand 1 "ext_QIreg_operand")))
7668 (const_string "*")))
7669 (set_attr "mode" "SI,DI,DI,SI,DI")])
7671 (define_insn "*andsi_1"
7672 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7673 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7674 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7675 (clobber (reg:CC FLAGS_REG))]
7676 "ix86_binary_operator_ok (AND, SImode, operands)"
7678 switch (get_attr_type (insn))
7684 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7688 return "and{l}\t{%2, %0|%0, %2}";
7691 [(set_attr "type" "alu,alu,imovx,msklog")
7692 (set (attr "prefix_rex")
7694 (and (eq_attr "type" "imovx")
7695 (and (match_test "INTVAL (operands[2]) == 0xff")
7696 (match_operand 1 "ext_QIreg_operand")))
7698 (const_string "*")))
7699 (set_attr "length_immediate" "*,*,0,0")
7700 (set_attr "mode" "SI")])
7702 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7703 (define_insn "*andsi_1_zext"
7704 [(set (match_operand:DI 0 "register_operand" "=r")
7706 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7707 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7708 (clobber (reg:CC FLAGS_REG))]
7709 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7710 "and{l}\t{%2, %k0|%k0, %2}"
7711 [(set_attr "type" "alu")
7712 (set_attr "mode" "SI")])
7714 (define_insn "*andhi_1"
7715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7716 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7717 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7718 (clobber (reg:CC FLAGS_REG))]
7719 "ix86_binary_operator_ok (AND, HImode, operands)"
7721 switch (get_attr_type (insn))
7727 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7731 return "and{w}\t{%2, %0|%0, %2}";
7734 [(set_attr "type" "alu,alu,imovx,msklog")
7735 (set_attr "length_immediate" "*,*,0,*")
7736 (set (attr "prefix_rex")
7738 (and (eq_attr "type" "imovx")
7739 (match_operand 1 "ext_QIreg_operand"))
7741 (const_string "*")))
7742 (set_attr "mode" "HI,HI,SI,HI")])
7744 ;; %%% Potential partial reg stall on alternative 2. What to do?
7745 (define_insn "*andqi_1"
7746 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7747 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7748 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "ix86_binary_operator_ok (AND, QImode, operands)"
7752 switch (which_alternative)
7756 return "and{b}\t{%2, %0|%0, %2}";
7758 return "and{l}\t{%k2, %k0|%k0, %k2}";
7760 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7761 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7766 [(set_attr "type" "alu,alu,alu,msklog")
7767 (set_attr "mode" "QI,QI,SI,HI")])
7769 (define_insn "*andqi_1_slp"
7770 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7771 (and:QI (match_dup 0)
7772 (match_operand:QI 1 "general_operand" "qn,qmn")))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7776 "and{b}\t{%1, %0|%0, %1}"
7777 [(set_attr "type" "alu1")
7778 (set_attr "mode" "QI")])
7780 (define_insn "kandn<mode>"
7781 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7784 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7785 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7786 (clobber (reg:CC FLAGS_REG))]
7789 switch (which_alternative)
7792 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7796 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7797 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7799 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7804 [(set_attr "isa" "bmi,*,avx512f")
7805 (set_attr "type" "bitmanip,*,msklog")
7806 (set_attr "prefix" "*,*,vex")
7807 (set_attr "btver2_decode" "direct,*,*")
7808 (set_attr "mode" "<MODE>")])
7811 [(set (match_operand:SWI12 0 "general_reg_operand")
7815 (match_operand:SWI12 1 "general_reg_operand")))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7819 (not:HI (match_dup 0)))
7820 (parallel [(set (match_dup 0)
7821 (and:HI (match_dup 0)
7823 (clobber (reg:CC FLAGS_REG))])])
7825 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7827 [(set (match_operand:DI 0 "register_operand")
7828 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7829 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7830 (clobber (reg:CC FLAGS_REG))]
7832 [(parallel [(set (match_dup 0)
7833 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7834 (clobber (reg:CC FLAGS_REG))])]
7835 "operands[2] = gen_lowpart (SImode, operands[2]);")
7838 [(set (match_operand:SWI248 0 "register_operand")
7839 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7840 (match_operand:SWI248 2 "const_int_operand")))
7841 (clobber (reg:CC FLAGS_REG))]
7843 && true_regnum (operands[0]) != true_regnum (operands[1])"
7846 HOST_WIDE_INT ival = INTVAL (operands[2]);
7848 rtx (*insn) (rtx, rtx);
7850 if (ival == (HOST_WIDE_INT) 0xffffffff)
7852 else if (ival == 0xffff)
7856 gcc_assert (ival == 0xff);
7860 if (<MODE>mode == DImode)
7861 insn = (mode == SImode)
7862 ? gen_zero_extendsidi2
7864 ? gen_zero_extendhidi2
7865 : gen_zero_extendqidi2;
7868 if (<MODE>mode != SImode)
7869 /* Zero extend to SImode to avoid partial register stalls. */
7870 operands[0] = gen_lowpart (SImode, operands[0]);
7872 insn = (mode == HImode)
7873 ? gen_zero_extendhisi2
7874 : gen_zero_extendqisi2;
7876 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7881 [(set (match_operand 0 "register_operand")
7883 (const_int -65536)))
7884 (clobber (reg:CC FLAGS_REG))]
7885 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7886 || optimize_function_for_size_p (cfun)"
7887 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7888 "operands[1] = gen_lowpart (HImode, operands[0]);")
7891 [(set (match_operand 0 "ext_register_operand")
7894 (clobber (reg:CC FLAGS_REG))]
7895 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7896 && reload_completed"
7897 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7898 "operands[1] = gen_lowpart (QImode, operands[0]);")
7901 [(set (match_operand 0 "ext_register_operand")
7903 (const_int -65281)))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7906 && reload_completed"
7907 [(parallel [(set (zero_extract:SI (match_dup 0)
7911 (zero_extract:SI (match_dup 0)
7914 (zero_extract:SI (match_dup 0)
7917 (clobber (reg:CC FLAGS_REG))])]
7918 "operands[0] = gen_lowpart (SImode, operands[0]);")
7920 (define_insn "*anddi_2"
7921 [(set (reg FLAGS_REG)
7924 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7925 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7927 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7928 (and:DI (match_dup 1) (match_dup 2)))]
7930 && ix86_match_ccmode
7932 /* If we are going to emit andl instead of andq, and the operands[2]
7933 constant might have the SImode sign bit set, make sure the sign
7934 flag isn't tested, because the instruction will set the sign flag
7935 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7936 conservatively assume it might have bit 31 set. */
7937 (satisfies_constraint_Z (operands[2])
7938 && (!CONST_INT_P (operands[2])
7939 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7940 ? CCZmode : CCNOmode)
7941 && ix86_binary_operator_ok (AND, DImode, operands)"
7943 and{l}\t{%k2, %k0|%k0, %k2}
7944 and{q}\t{%2, %0|%0, %2}
7945 and{q}\t{%2, %0|%0, %2}"
7946 [(set_attr "type" "alu")
7947 (set_attr "mode" "SI,DI,DI")])
7949 (define_insn "*andqi_2_maybe_si"
7950 [(set (reg FLAGS_REG)
7952 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7953 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7955 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7956 (and:QI (match_dup 1) (match_dup 2)))]
7957 "ix86_binary_operator_ok (AND, QImode, operands)
7958 && ix86_match_ccmode (insn,
7959 CONST_INT_P (operands[2])
7960 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7962 if (which_alternative == 2)
7964 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7965 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7966 return "and{l}\t{%2, %k0|%k0, %2}";
7968 return "and{b}\t{%2, %0|%0, %2}";
7970 [(set_attr "type" "alu")
7971 (set_attr "mode" "QI,QI,SI")])
7973 (define_insn "*and<mode>_2"
7974 [(set (reg FLAGS_REG)
7975 (compare (and:SWI124
7976 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7977 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7979 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7980 (and:SWI124 (match_dup 1) (match_dup 2)))]
7981 "ix86_match_ccmode (insn, CCNOmode)
7982 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7983 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "mode" "<MODE>")])
7987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7988 (define_insn "*andsi_2_zext"
7989 [(set (reg FLAGS_REG)
7991 (match_operand:SI 1 "nonimmediate_operand" "%0")
7992 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7994 (set (match_operand:DI 0 "register_operand" "=r")
7995 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7997 && ix86_binary_operator_ok (AND, SImode, operands)"
7998 "and{l}\t{%2, %k0|%k0, %2}"
7999 [(set_attr "type" "alu")
8000 (set_attr "mode" "SI")])
8002 (define_insn "*andqi_2_slp"
8003 [(set (reg FLAGS_REG)
8005 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8006 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8008 (set (strict_low_part (match_dup 0))
8009 (and:QI (match_dup 0) (match_dup 1)))]
8010 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011 && ix86_match_ccmode (insn, CCNOmode)
8012 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8013 "and{b}\t{%1, %0|%0, %1}"
8014 [(set_attr "type" "alu1")
8015 (set_attr "mode" "QI")])
8017 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8018 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8019 ;; for a QImode operand, which of course failed.
8020 (define_insn "andqi_ext_0"
8021 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8026 (match_operand 1 "ext_register_operand" "0")
8029 (match_operand 2 "const_int_operand" "n")))
8030 (clobber (reg:CC FLAGS_REG))]
8032 "and{b}\t{%2, %h0|%h0, %2}"
8033 [(set_attr "type" "alu")
8034 (set_attr "length_immediate" "1")
8035 (set_attr "modrm" "1")
8036 (set_attr "mode" "QI")])
8038 ;; Generated by peephole translating test to and. This shows up
8039 ;; often in fp comparisons.
8040 (define_insn "*andqi_ext_0_cc"
8041 [(set (reg FLAGS_REG)
8045 (match_operand 1 "ext_register_operand" "0")
8048 (match_operand 2 "const_int_operand" "n"))
8050 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059 "ix86_match_ccmode (insn, CCNOmode)"
8060 "and{b}\t{%2, %h0|%h0, %2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "1")
8063 (set_attr "modrm" "1")
8064 (set_attr "mode" "QI")])
8066 (define_insn "*andqi_ext_1"
8067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8072 (match_operand 1 "ext_register_operand" "0,0")
8076 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8077 (clobber (reg:CC FLAGS_REG))]
8079 "and{b}\t{%2, %h0|%h0, %2}"
8080 [(set_attr "isa" "*,nox64")
8081 (set_attr "type" "alu")
8082 (set_attr "length_immediate" "0")
8083 (set_attr "mode" "QI")])
8085 (define_insn "*andqi_ext_2"
8086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8091 (match_operand 1 "ext_register_operand" "%0")
8095 (match_operand 2 "ext_register_operand" "Q")
8098 (clobber (reg:CC FLAGS_REG))]
8100 "and{b}\t{%h2, %h0|%h0, %h2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "length_immediate" "0")
8103 (set_attr "mode" "QI")])
8105 ;; Convert wide AND instructions with immediate operand to shorter QImode
8106 ;; equivalents when possible.
8107 ;; Don't do the splitting with memory operands, since it introduces risk
8108 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8109 ;; for size, but that can (should?) be handled by generic code instead.
8111 [(set (match_operand 0 "register_operand")
8112 (and (match_operand 1 "register_operand")
8113 (match_operand 2 "const_int_operand")))
8114 (clobber (reg:CC FLAGS_REG))]
8116 && QI_REG_P (operands[0])
8117 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && !(~INTVAL (operands[2]) & ~(255 << 8))
8119 && GET_MODE (operands[0]) != QImode"
8120 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8121 (and:SI (zero_extract:SI (match_dup 1)
8122 (const_int 8) (const_int 8))
8124 (clobber (reg:CC FLAGS_REG))])]
8126 operands[0] = gen_lowpart (SImode, operands[0]);
8127 operands[1] = gen_lowpart (SImode, operands[1]);
8128 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8131 ;; Since AND can be encoded with sign extended immediate, this is only
8132 ;; profitable when 7th bit is not set.
8134 [(set (match_operand 0 "register_operand")
8135 (and (match_operand 1 "general_operand")
8136 (match_operand 2 "const_int_operand")))
8137 (clobber (reg:CC FLAGS_REG))]
8139 && ANY_QI_REG_P (operands[0])
8140 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8141 && !(~INTVAL (operands[2]) & ~255)
8142 && !(INTVAL (operands[2]) & 128)
8143 && GET_MODE (operands[0]) != QImode"
8144 [(parallel [(set (strict_low_part (match_dup 0))
8145 (and:QI (match_dup 1)
8147 (clobber (reg:CC FLAGS_REG))])]
8149 operands[0] = gen_lowpart (QImode, operands[0]);
8150 operands[1] = gen_lowpart (QImode, operands[1]);
8151 operands[2] = gen_lowpart (QImode, operands[2]);
8154 ;; Logical inclusive and exclusive OR instructions
8156 ;; %%% This used to optimize known byte-wide and operations to memory.
8157 ;; If this is considered useful, it should be done with splitters.
8159 (define_expand "<code><mode>3"
8160 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8161 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8162 (match_operand:SWIM 2 "<general_operand>")))]
8164 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8166 (define_insn "*<code><mode>_1"
8167 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8169 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8170 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8171 (clobber (reg:CC FLAGS_REG))]
8172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8174 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8175 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8176 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8177 [(set_attr "type" "alu,alu,msklog")
8178 (set_attr "mode" "<MODE>")])
8180 (define_insn "*<code>hi_1"
8181 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8183 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8184 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8188 <logic>{w}\t{%2, %0|%0, %2}
8189 <logic>{w}\t{%2, %0|%0, %2}
8190 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8191 [(set_attr "type" "alu,alu,msklog")
8192 (set_attr "mode" "HI")])
8194 ;; %%% Potential partial reg stall on alternative 2. What to do?
8195 (define_insn "*<code>qi_1"
8196 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8197 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8198 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8202 <logic>{b}\t{%2, %0|%0, %2}
8203 <logic>{b}\t{%2, %0|%0, %2}
8204 <logic>{l}\t{%k2, %k0|%k0, %k2}
8205 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8206 [(set_attr "type" "alu,alu,alu,msklog")
8207 (set_attr "mode" "QI,QI,SI,HI")])
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*<code>si_1_zext"
8211 [(set (match_operand:DI 0 "register_operand" "=r")
8213 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8214 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8215 (clobber (reg:CC FLAGS_REG))]
8216 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8217 "<logic>{l}\t{%2, %k0|%k0, %2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "mode" "SI")])
8221 (define_insn "*<code>si_1_zext_imm"
8222 [(set (match_operand:DI 0 "register_operand" "=r")
8224 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8225 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228 "<logic>{l}\t{%2, %k0|%k0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "SI")])
8232 (define_insn "*<code>qi_1_slp"
8233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8234 (any_or:QI (match_dup 0)
8235 (match_operand:QI 1 "general_operand" "qmn,qn")))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8238 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8239 "<logic>{b}\t{%1, %0|%0, %1}"
8240 [(set_attr "type" "alu1")
8241 (set_attr "mode" "QI")])
8243 (define_insn "*<code><mode>_2"
8244 [(set (reg FLAGS_REG)
8245 (compare (any_or:SWI
8246 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8247 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8249 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8250 (any_or:SWI (match_dup 1) (match_dup 2)))]
8251 "ix86_match_ccmode (insn, CCNOmode)
8252 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8253 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "<MODE>")])
8257 (define_insn "kxnor<mode>"
8258 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8261 (match_operand:SWI12 1 "register_operand" "0,k")
8262 (match_operand:SWI12 2 "register_operand" "r,k"))))
8263 (clobber (reg:CC FLAGS_REG))]
8266 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8267 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8268 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8270 [(set_attr "type" "*,msklog")
8271 (set_attr "prefix" "*,vex")
8272 (set_attr "mode" "<MODE>")])
8274 (define_insn "kxnor<mode>"
8275 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8278 (match_operand:SWI48x 1 "register_operand" "0,k")
8279 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8280 (clobber (reg:CC FLAGS_REG))]
8284 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8285 [(set_attr "type" "*,msklog")
8286 (set_attr "prefix" "*,vex")
8287 (set_attr "mode" "<MODE>")])
8290 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8294 (match_operand:SWI1248x 1 "general_reg_operand"))))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "TARGET_AVX512F && reload_completed"
8297 [(parallel [(set (match_dup 0)
8298 (xor:HI (match_dup 0)
8300 (clobber (reg:CC FLAGS_REG))])
8302 (not:HI (match_dup 0)))])
8304 ;;There are kortrest[bdq] but no intrinsics for them.
8305 ;;We probably don't need to implement them.
8306 (define_insn "kortestzhi"
8307 [(set (reg:CCZ FLAGS_REG)
8310 (match_operand:HI 0 "register_operand" "k")
8311 (match_operand:HI 1 "register_operand" "k"))
8313 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8314 "kortestw\t{%1, %0|%0, %1}"
8315 [(set_attr "mode" "HI")
8316 (set_attr "type" "msklog")
8317 (set_attr "prefix" "vex")])
8319 (define_insn "kortestchi"
8320 [(set (reg:CCC FLAGS_REG)
8323 (match_operand:HI 0 "register_operand" "k")
8324 (match_operand:HI 1 "register_operand" "k"))
8326 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8327 "kortestw\t{%1, %0|%0, %1}"
8328 [(set_attr "mode" "HI")
8329 (set_attr "type" "msklog")
8330 (set_attr "prefix" "vex")])
8332 (define_insn "kunpckhi"
8333 [(set (match_operand:HI 0 "register_operand" "=k")
8336 (match_operand:HI 1 "register_operand" "k")
8338 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8340 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8341 [(set_attr "mode" "HI")
8342 (set_attr "type" "msklog")
8343 (set_attr "prefix" "vex")])
8345 (define_insn "kunpcksi"
8346 [(set (match_operand:SI 0 "register_operand" "=k")
8349 (match_operand:SI 1 "register_operand" "k")
8351 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8353 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8354 [(set_attr "mode" "SI")])
8356 (define_insn "kunpckdi"
8357 [(set (match_operand:DI 0 "register_operand" "=k")
8360 (match_operand:DI 1 "register_operand" "k")
8362 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8364 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8365 [(set_attr "mode" "DI")])
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 ;; ??? Special case for immediate operand is missing - it is tricky.
8369 (define_insn "*<code>si_2_zext"
8370 [(set (reg FLAGS_REG)
8371 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8374 (set (match_operand:DI 0 "register_operand" "=r")
8375 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8376 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8377 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378 "<logic>{l}\t{%2, %k0|%k0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "SI")])
8382 (define_insn "*<code>si_2_zext_imm"
8383 [(set (reg FLAGS_REG)
8385 (match_operand:SI 1 "nonimmediate_operand" "%0")
8386 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8388 (set (match_operand:DI 0 "register_operand" "=r")
8389 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8390 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392 "<logic>{l}\t{%2, %k0|%k0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "SI")])
8396 (define_insn "*<code>qi_2_slp"
8397 [(set (reg FLAGS_REG)
8398 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399 (match_operand:QI 1 "general_operand" "qmn,qn"))
8401 (set (strict_low_part (match_dup 0))
8402 (any_or:QI (match_dup 0) (match_dup 1)))]
8403 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404 && ix86_match_ccmode (insn, CCNOmode)
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "<logic>{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8410 (define_insn "*<code><mode>_3"
8411 [(set (reg FLAGS_REG)
8412 (compare (any_or:SWI
8413 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8414 (match_operand:SWI 2 "<general_operand>" "<g>"))
8416 (clobber (match_scratch:SWI 0 "=<r>"))]
8417 "ix86_match_ccmode (insn, CCNOmode)
8418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8419 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "<MODE>")])
8423 (define_insn "*<code>qi_ext_0"
8424 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429 (match_operand 1 "ext_register_operand" "0")
8432 (match_operand 2 "const_int_operand" "n")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435 "<logic>{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "length_immediate" "1")
8438 (set_attr "modrm" "1")
8439 (set_attr "mode" "QI")])
8441 (define_insn "*<code>qi_ext_1"
8442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8447 (match_operand 1 "ext_register_operand" "0,0")
8451 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454 "<logic>{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "isa" "*,nox64")
8456 (set_attr "type" "alu")
8457 (set_attr "length_immediate" "0")
8458 (set_attr "mode" "QI")])
8460 (define_insn "*<code>qi_ext_2"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8465 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8468 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8471 (clobber (reg:CC FLAGS_REG))]
8472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8473 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "QI")])
8479 [(set (match_operand 0 "register_operand")
8480 (any_or (match_operand 1 "register_operand")
8481 (match_operand 2 "const_int_operand")))
8482 (clobber (reg:CC FLAGS_REG))]
8484 && QI_REG_P (operands[0])
8485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486 && !(INTVAL (operands[2]) & ~(255 << 8))
8487 && GET_MODE (operands[0]) != QImode"
8488 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8489 (any_or:SI (zero_extract:SI (match_dup 1)
8490 (const_int 8) (const_int 8))
8492 (clobber (reg:CC FLAGS_REG))])]
8494 operands[0] = gen_lowpart (SImode, operands[0]);
8495 operands[1] = gen_lowpart (SImode, operands[1]);
8496 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8499 ;; Since OR can be encoded with sign extended immediate, this is only
8500 ;; profitable when 7th bit is set.
8502 [(set (match_operand 0 "register_operand")
8503 (any_or (match_operand 1 "general_operand")
8504 (match_operand 2 "const_int_operand")))
8505 (clobber (reg:CC FLAGS_REG))]
8507 && ANY_QI_REG_P (operands[0])
8508 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509 && !(INTVAL (operands[2]) & ~255)
8510 && (INTVAL (operands[2]) & 128)
8511 && GET_MODE (operands[0]) != QImode"
8512 [(parallel [(set (strict_low_part (match_dup 0))
8513 (any_or:QI (match_dup 1)
8515 (clobber (reg:CC FLAGS_REG))])]
8517 operands[0] = gen_lowpart (QImode, operands[0]);
8518 operands[1] = gen_lowpart (QImode, operands[1]);
8519 operands[2] = gen_lowpart (QImode, operands[2]);
8522 (define_expand "xorqi_cc_ext_1"
8524 (set (reg:CCNO FLAGS_REG)
8528 (match_operand 1 "ext_register_operand")
8531 (match_operand:QI 2 "const_int_operand"))
8533 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8543 (define_insn "*xorqi_cc_ext_1"
8544 [(set (reg FLAGS_REG)
8548 (match_operand 1 "ext_register_operand" "0,0")
8551 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8553 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8562 "ix86_match_ccmode (insn, CCNOmode)"
8563 "xor{b}\t{%2, %h0|%h0, %2}"
8564 [(set_attr "isa" "*,nox64")
8565 (set_attr "type" "alu")
8566 (set_attr "modrm" "1")
8567 (set_attr "mode" "QI")])
8569 ;; Negation instructions
8571 (define_expand "neg<mode>2"
8572 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8573 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8575 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8577 (define_insn_and_split "*neg<dwi>2_doubleword"
8578 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8579 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8585 [(set (reg:CCZ FLAGS_REG)
8586 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8587 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8590 (plus:DWIH (match_dup 3)
8591 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8593 (clobber (reg:CC FLAGS_REG))])
8596 (neg:DWIH (match_dup 2)))
8597 (clobber (reg:CC FLAGS_REG))])]
8598 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8600 (define_insn "*neg<mode>2_1"
8601 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8602 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8603 (clobber (reg:CC FLAGS_REG))]
8604 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8605 "neg{<imodesuffix>}\t%0"
8606 [(set_attr "type" "negnot")
8607 (set_attr "mode" "<MODE>")])
8609 ;; Combine is quite creative about this pattern.
8610 (define_insn "*negsi2_1_zext"
8611 [(set (match_operand:DI 0 "register_operand" "=r")
8613 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8616 (clobber (reg:CC FLAGS_REG))]
8617 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8619 [(set_attr "type" "negnot")
8620 (set_attr "mode" "SI")])
8622 ;; The problem with neg is that it does not perform (compare x 0),
8623 ;; it really performs (compare 0 x), which leaves us with the zero
8624 ;; flag being the only useful item.
8626 (define_insn "*neg<mode>2_cmpz"
8627 [(set (reg:CCZ FLAGS_REG)
8629 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8631 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8632 (neg:SWI (match_dup 1)))]
8633 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8634 "neg{<imodesuffix>}\t%0"
8635 [(set_attr "type" "negnot")
8636 (set_attr "mode" "<MODE>")])
8638 (define_insn "*negsi2_cmpz_zext"
8639 [(set (reg:CCZ FLAGS_REG)
8643 (match_operand:DI 1 "register_operand" "0")
8647 (set (match_operand:DI 0 "register_operand" "=r")
8648 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8651 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8653 [(set_attr "type" "negnot")
8654 (set_attr "mode" "SI")])
8656 ;; Negate with jump on overflow.
8657 (define_expand "negv<mode>3"
8658 [(parallel [(set (reg:CCO FLAGS_REG)
8659 (ne:CCO (match_operand:SWI 1 "register_operand")
8661 (set (match_operand:SWI 0 "register_operand")
8662 (neg:SWI (match_dup 1)))])
8663 (set (pc) (if_then_else
8664 (eq (reg:CCO FLAGS_REG) (const_int 0))
8665 (label_ref (match_operand 2))
8670 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8674 (define_insn "*negv<mode>3"
8675 [(set (reg:CCO FLAGS_REG)
8676 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8677 (match_operand:SWI 2 "const_int_operand")))
8678 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8679 (neg:SWI (match_dup 1)))]
8680 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8681 && mode_signbit_p (<MODE>mode, operands[2])"
8682 "neg{<imodesuffix>}\t%0"
8683 [(set_attr "type" "negnot")
8684 (set_attr "mode" "<MODE>")])
8686 ;; Changing of sign for FP values is doable using integer unit too.
8688 (define_expand "<code><mode>2"
8689 [(set (match_operand:X87MODEF 0 "register_operand")
8690 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8691 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8692 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8694 (define_insn "*absneg<mode>2_mixed"
8695 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8696 (match_operator:MODEF 3 "absneg_operator"
8697 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8698 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8699 (clobber (reg:CC FLAGS_REG))]
8700 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8703 (define_insn "*absneg<mode>2_sse"
8704 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8705 (match_operator:MODEF 3 "absneg_operator"
8706 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8707 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8712 (define_insn "*absneg<mode>2_i387"
8713 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8714 (match_operator:X87MODEF 3 "absneg_operator"
8715 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8716 (use (match_operand 2))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8721 (define_expand "<code>tf2"
8722 [(set (match_operand:TF 0 "register_operand")
8723 (absneg:TF (match_operand:TF 1 "register_operand")))]
8725 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8727 (define_insn "*absnegtf2_sse"
8728 [(set (match_operand:TF 0 "register_operand" "=x,x")
8729 (match_operator:TF 3 "absneg_operator"
8730 [(match_operand:TF 1 "register_operand" "0,x")]))
8731 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8732 (clobber (reg:CC FLAGS_REG))]
8736 ;; Splitters for fp abs and neg.
8739 [(set (match_operand 0 "fp_register_operand")
8740 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8741 (use (match_operand 2))
8742 (clobber (reg:CC FLAGS_REG))]
8744 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8747 [(set (match_operand 0 "register_operand")
8748 (match_operator 3 "absneg_operator"
8749 [(match_operand 1 "register_operand")]))
8750 (use (match_operand 2 "nonimmediate_operand"))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "reload_completed && SSE_REG_P (operands[0])"
8753 [(set (match_dup 0) (match_dup 3))]
8755 machine_mode mode = GET_MODE (operands[0]);
8756 machine_mode vmode = GET_MODE (operands[2]);
8759 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8760 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8761 if (operands_match_p (operands[0], operands[2]))
8762 std::swap (operands[1], operands[2]);
8763 if (GET_CODE (operands[3]) == ABS)
8764 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8766 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8771 [(set (match_operand:SF 0 "register_operand")
8772 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8773 (use (match_operand:V4SF 2))
8774 (clobber (reg:CC FLAGS_REG))]
8776 [(parallel [(set (match_dup 0) (match_dup 1))
8777 (clobber (reg:CC FLAGS_REG))])]
8780 operands[0] = gen_lowpart (SImode, operands[0]);
8781 if (GET_CODE (operands[1]) == ABS)
8783 tmp = gen_int_mode (0x7fffffff, SImode);
8784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8788 tmp = gen_int_mode (0x80000000, SImode);
8789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8795 [(set (match_operand:DF 0 "register_operand")
8796 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8797 (use (match_operand 2))
8798 (clobber (reg:CC FLAGS_REG))]
8800 [(parallel [(set (match_dup 0) (match_dup 1))
8801 (clobber (reg:CC FLAGS_REG))])]
8806 tmp = gen_lowpart (DImode, operands[0]);
8807 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8810 if (GET_CODE (operands[1]) == ABS)
8813 tmp = gen_rtx_NOT (DImode, tmp);
8817 operands[0] = gen_highpart (SImode, operands[0]);
8818 if (GET_CODE (operands[1]) == ABS)
8820 tmp = gen_int_mode (0x7fffffff, SImode);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8825 tmp = gen_int_mode (0x80000000, SImode);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8833 [(set (match_operand:XF 0 "register_operand")
8834 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8835 (use (match_operand 2))
8836 (clobber (reg:CC FLAGS_REG))]
8838 [(parallel [(set (match_dup 0) (match_dup 1))
8839 (clobber (reg:CC FLAGS_REG))])]
8842 operands[0] = gen_rtx_REG (SImode,
8843 true_regnum (operands[0])
8844 + (TARGET_64BIT ? 1 : 2));
8845 if (GET_CODE (operands[1]) == ABS)
8847 tmp = GEN_INT (0x7fff);
8848 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8852 tmp = GEN_INT (0x8000);
8853 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8858 ;; Conditionalize these after reload. If they match before reload, we
8859 ;; lose the clobber and ability to use integer instructions.
8861 (define_insn "*<code><mode>2_1"
8862 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8863 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8865 && (reload_completed
8866 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "<MODE>")])
8871 (define_insn "*<code>extendsfdf2"
8872 [(set (match_operand:DF 0 "register_operand" "=f")
8873 (absneg:DF (float_extend:DF
8874 (match_operand:SF 1 "register_operand" "0"))))]
8875 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8876 "f<absneg_mnemonic>"
8877 [(set_attr "type" "fsgn")
8878 (set_attr "mode" "DF")])
8880 (define_insn "*<code>extendsfxf2"
8881 [(set (match_operand:XF 0 "register_operand" "=f")
8882 (absneg:XF (float_extend:XF
8883 (match_operand:SF 1 "register_operand" "0"))))]
8885 "f<absneg_mnemonic>"
8886 [(set_attr "type" "fsgn")
8887 (set_attr "mode" "XF")])
8889 (define_insn "*<code>extenddfxf2"
8890 [(set (match_operand:XF 0 "register_operand" "=f")
8891 (absneg:XF (float_extend:XF
8892 (match_operand:DF 1 "register_operand" "0"))))]
8894 "f<absneg_mnemonic>"
8895 [(set_attr "type" "fsgn")
8896 (set_attr "mode" "XF")])
8898 ;; Copysign instructions
8900 (define_mode_iterator CSGNMODE [SF DF TF])
8901 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8903 (define_expand "copysign<mode>3"
8904 [(match_operand:CSGNMODE 0 "register_operand")
8905 (match_operand:CSGNMODE 1 "nonmemory_operand")
8906 (match_operand:CSGNMODE 2 "register_operand")]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE && (<MODE>mode == TFmode))"
8909 "ix86_expand_copysign (operands); DONE;")
8911 (define_insn_and_split "copysign<mode>3_const"
8912 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8914 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8915 (match_operand:CSGNMODE 2 "register_operand" "0")
8916 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8918 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8919 || (TARGET_SSE && (<MODE>mode == TFmode))"
8921 "&& reload_completed"
8923 "ix86_split_copysign_const (operands); DONE;")
8925 (define_insn "copysign<mode>3_var"
8926 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8928 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8929 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8930 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8931 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8933 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8934 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8935 || (TARGET_SSE && (<MODE>mode == TFmode))"
8939 [(set (match_operand:CSGNMODE 0 "register_operand")
8941 [(match_operand:CSGNMODE 2 "register_operand")
8942 (match_operand:CSGNMODE 3 "register_operand")
8943 (match_operand:<CSGNVMODE> 4)
8944 (match_operand:<CSGNVMODE> 5)]
8946 (clobber (match_scratch:<CSGNVMODE> 1))]
8947 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8948 || (TARGET_SSE && (<MODE>mode == TFmode)))
8949 && reload_completed"
8951 "ix86_split_copysign_var (operands); DONE;")
8953 ;; One complement instructions
8955 (define_expand "one_cmpl<mode>2"
8956 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8957 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8959 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8961 (define_insn "*one_cmpl<mode>2_1"
8962 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8963 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8964 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8966 not{<imodesuffix>}\t%0
8967 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8968 [(set_attr "isa" "*,avx512bw")
8969 (set_attr "type" "negnot,msklog")
8970 (set_attr "prefix" "*,vex")
8971 (set_attr "mode" "<MODE>")])
8973 (define_insn "*one_cmplhi2_1"
8974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8975 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8976 "ix86_unary_operator_ok (NOT, HImode, operands)"
8979 knotw\t{%1, %0|%0, %1}"
8980 [(set_attr "isa" "*,avx512f")
8981 (set_attr "type" "negnot,msklog")
8982 (set_attr "prefix" "*,vex")
8983 (set_attr "mode" "HI")])
8985 ;; %%% Potential partial reg stall on alternative 1. What to do?
8986 (define_insn "*one_cmplqi2_1"
8987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8988 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8989 "ix86_unary_operator_ok (NOT, QImode, operands)"
8991 switch (which_alternative)
8994 return "not{b}\t%0";
8996 return "not{l}\t%k0";
8998 if (TARGET_AVX512DQ)
8999 return "knotb\t{%1, %0|%0, %1}";
9000 return "knotw\t{%1, %0|%0, %1}";
9005 [(set_attr "isa" "*,*,avx512f")
9006 (set_attr "type" "negnot,negnot,msklog")
9007 (set_attr "prefix" "*,*,vex")
9008 (set_attr "mode" "QI,SI,QI")])
9010 ;; ??? Currently never generated - xor is used instead.
9011 (define_insn "*one_cmplsi2_1_zext"
9012 [(set (match_operand:DI 0 "register_operand" "=r")
9014 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9015 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9017 [(set_attr "type" "negnot")
9018 (set_attr "mode" "SI")])
9020 (define_insn "*one_cmpl<mode>2_2"
9021 [(set (reg FLAGS_REG)
9022 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9024 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9025 (not:SWI (match_dup 1)))]
9026 "ix86_match_ccmode (insn, CCNOmode)
9027 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9029 [(set_attr "type" "alu1")
9030 (set_attr "mode" "<MODE>")])
9033 [(set (match_operand 0 "flags_reg_operand")
9034 (match_operator 2 "compare_operator"
9035 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9037 (set (match_operand:SWI 1 "nonimmediate_operand")
9038 (not:SWI (match_dup 3)))]
9039 "ix86_match_ccmode (insn, CCNOmode)"
9040 [(parallel [(set (match_dup 0)
9041 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9044 (xor:SWI (match_dup 3) (const_int -1)))])])
9046 ;; ??? Currently never generated - xor is used instead.
9047 (define_insn "*one_cmplsi2_2_zext"
9048 [(set (reg FLAGS_REG)
9049 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9051 (set (match_operand:DI 0 "register_operand" "=r")
9052 (zero_extend:DI (not:SI (match_dup 1))))]
9053 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9054 && ix86_unary_operator_ok (NOT, SImode, operands)"
9056 [(set_attr "type" "alu1")
9057 (set_attr "mode" "SI")])
9060 [(set (match_operand 0 "flags_reg_operand")
9061 (match_operator 2 "compare_operator"
9062 [(not:SI (match_operand:SI 3 "register_operand"))
9064 (set (match_operand:DI 1 "register_operand")
9065 (zero_extend:DI (not:SI (match_dup 3))))]
9066 "ix86_match_ccmode (insn, CCNOmode)"
9067 [(parallel [(set (match_dup 0)
9068 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9071 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9073 ;; Shift instructions
9075 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9076 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9077 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9078 ;; from the assembler input.
9080 ;; This instruction shifts the target reg/mem as usual, but instead of
9081 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9082 ;; is a left shift double, bits are taken from the high order bits of
9083 ;; reg, else if the insn is a shift right double, bits are taken from the
9084 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9085 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9087 ;; Since sh[lr]d does not change the `reg' operand, that is done
9088 ;; separately, making all shifts emit pairs of shift double and normal
9089 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9090 ;; support a 63 bit shift, each shift where the count is in a reg expands
9091 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9093 ;; If the shift count is a constant, we need never emit more than one
9094 ;; shift pair, instead using moves and sign extension for counts greater
9097 (define_expand "ashl<mode>3"
9098 [(set (match_operand:SDWIM 0 "<shift_operand>")
9099 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9100 (match_operand:QI 2 "nonmemory_operand")))]
9102 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9104 (define_insn "*ashl<mode>3_doubleword"
9105 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9106 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9107 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9108 (clobber (reg:CC FLAGS_REG))]
9111 [(set_attr "type" "multi")])
9114 [(set (match_operand:DWI 0 "register_operand")
9115 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9116 (match_operand:QI 2 "nonmemory_operand")))
9117 (clobber (reg:CC FLAGS_REG))]
9118 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9120 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9122 ;; By default we don't ask for a scratch register, because when DWImode
9123 ;; values are manipulated, registers are already at a premium. But if
9124 ;; we have one handy, we won't turn it away.
9127 [(match_scratch:DWIH 3 "r")
9128 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9130 (match_operand:<DWI> 1 "nonmemory_operand")
9131 (match_operand:QI 2 "nonmemory_operand")))
9132 (clobber (reg:CC FLAGS_REG))])
9136 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9138 (define_insn "x86_64_shld"
9139 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9140 (ior:DI (ashift:DI (match_dup 0)
9141 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9142 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9143 (minus:QI (const_int 64) (match_dup 2)))))
9144 (clobber (reg:CC FLAGS_REG))]
9146 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9147 [(set_attr "type" "ishift")
9148 (set_attr "prefix_0f" "1")
9149 (set_attr "mode" "DI")
9150 (set_attr "athlon_decode" "vector")
9151 (set_attr "amdfam10_decode" "vector")
9152 (set_attr "bdver1_decode" "vector")])
9154 (define_insn "x86_shld"
9155 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9156 (ior:SI (ashift:SI (match_dup 0)
9157 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9158 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9159 (minus:QI (const_int 32) (match_dup 2)))))
9160 (clobber (reg:CC FLAGS_REG))]
9162 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9163 [(set_attr "type" "ishift")
9164 (set_attr "prefix_0f" "1")
9165 (set_attr "mode" "SI")
9166 (set_attr "pent_pair" "np")
9167 (set_attr "athlon_decode" "vector")
9168 (set_attr "amdfam10_decode" "vector")
9169 (set_attr "bdver1_decode" "vector")])
9171 (define_expand "x86_shift<mode>_adj_1"
9172 [(set (reg:CCZ FLAGS_REG)
9173 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9176 (set (match_operand:SWI48 0 "register_operand")
9177 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9178 (match_operand:SWI48 1 "register_operand")
9181 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9182 (match_operand:SWI48 3 "register_operand")
9185 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9187 (define_expand "x86_shift<mode>_adj_2"
9188 [(use (match_operand:SWI48 0 "register_operand"))
9189 (use (match_operand:SWI48 1 "register_operand"))
9190 (use (match_operand:QI 2 "register_operand"))]
9193 rtx_code_label *label = gen_label_rtx ();
9196 emit_insn (gen_testqi_ccz_1 (operands[2],
9197 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9199 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9200 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9201 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9202 gen_rtx_LABEL_REF (VOIDmode, label),
9204 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9205 JUMP_LABEL (tmp) = label;
9207 emit_move_insn (operands[0], operands[1]);
9208 ix86_expand_clear (operands[1]);
9211 LABEL_NUSES (label) = 1;
9216 ;; Avoid useless masking of count operand.
9217 (define_insn "*ashl<mode>3_mask"
9218 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9220 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9223 (match_operand:SI 2 "register_operand" "c")
9224 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9227 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9228 == GET_MODE_BITSIZE (<MODE>mode)-1"
9230 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9232 [(set_attr "type" "ishift")
9233 (set_attr "mode" "<MODE>")])
9235 (define_insn "*bmi2_ashl<mode>3_1"
9236 [(set (match_operand:SWI48 0 "register_operand" "=r")
9237 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9238 (match_operand:SWI48 2 "register_operand" "r")))]
9240 "shlx\t{%2, %1, %0|%0, %1, %2}"
9241 [(set_attr "type" "ishiftx")
9242 (set_attr "mode" "<MODE>")])
9244 (define_insn "*ashl<mode>3_1"
9245 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9246 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9247 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9251 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260 return "add{<imodesuffix>}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{<imodesuffix>}\t%0";
9267 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9270 [(set_attr "isa" "*,*,bmi2")
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (eq_attr "alternative" "2")
9275 (const_string "ishiftx")
9276 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9277 (match_operand 0 "register_operand"))
9278 (match_operand 2 "const1_operand"))
9279 (const_string "alu")
9281 (const_string "ishift")))
9282 (set (attr "length_immediate")
9284 (ior (eq_attr "type" "alu")
9285 (and (eq_attr "type" "ishift")
9286 (and (match_operand 2 "const1_operand")
9287 (ior (match_test "TARGET_SHIFT1")
9288 (match_test "optimize_function_for_size_p (cfun)")))))
9290 (const_string "*")))
9291 (set_attr "mode" "<MODE>")])
9293 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9295 [(set (match_operand:SWI48 0 "register_operand")
9296 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9297 (match_operand:QI 2 "register_operand")))
9298 (clobber (reg:CC FLAGS_REG))]
9299 "TARGET_BMI2 && reload_completed"
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9302 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9304 (define_insn "*bmi2_ashlsi3_1_zext"
9305 [(set (match_operand:DI 0 "register_operand" "=r")
9307 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9308 (match_operand:SI 2 "register_operand" "r"))))]
9309 "TARGET_64BIT && TARGET_BMI2"
9310 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9311 [(set_attr "type" "ishiftx")
9312 (set_attr "mode" "SI")])
9314 (define_insn "*ashlsi3_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9317 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9318 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9322 switch (get_attr_type (insn))
9329 gcc_assert (operands[2] == const1_rtx);
9330 return "add{l}\t%k0, %k0";
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335 return "sal{l}\t%k0";
9337 return "sal{l}\t{%2, %k0|%k0, %2}";
9340 [(set_attr "isa" "*,*,bmi2")
9342 (cond [(eq_attr "alternative" "1")
9343 (const_string "lea")
9344 (eq_attr "alternative" "2")
9345 (const_string "ishiftx")
9346 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347 (match_operand 2 "const1_operand"))
9348 (const_string "alu")
9350 (const_string "ishift")))
9351 (set (attr "length_immediate")
9353 (ior (eq_attr "type" "alu")
9354 (and (eq_attr "type" "ishift")
9355 (and (match_operand 2 "const1_operand")
9356 (ior (match_test "TARGET_SHIFT1")
9357 (match_test "optimize_function_for_size_p (cfun)")))))
9359 (const_string "*")))
9360 (set_attr "mode" "SI")])
9362 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9364 [(set (match_operand:DI 0 "register_operand")
9366 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9367 (match_operand:QI 2 "register_operand"))))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9371 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9372 "operands[2] = gen_lowpart (SImode, operands[2]);")
9374 (define_insn "*ashlhi3_1"
9375 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9376 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9377 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9381 switch (get_attr_type (insn))
9387 gcc_assert (operands[2] == const1_rtx);
9388 return "add{w}\t%0, %0";
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393 return "sal{w}\t%0";
9395 return "sal{w}\t{%2, %0|%0, %2}";
9399 (cond [(eq_attr "alternative" "1")
9400 (const_string "lea")
9401 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9402 (match_operand 0 "register_operand"))
9403 (match_operand 2 "const1_operand"))
9404 (const_string "alu")
9406 (const_string "ishift")))
9407 (set (attr "length_immediate")
9409 (ior (eq_attr "type" "alu")
9410 (and (eq_attr "type" "ishift")
9411 (and (match_operand 2 "const1_operand")
9412 (ior (match_test "TARGET_SHIFT1")
9413 (match_test "optimize_function_for_size_p (cfun)")))))
9415 (const_string "*")))
9416 (set_attr "mode" "HI,SI")])
9418 ;; %%% Potential partial reg stall on alternative 1. What to do?
9419 (define_insn "*ashlqi3_1"
9420 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9421 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9426 switch (get_attr_type (insn))
9432 gcc_assert (operands[2] == const1_rtx);
9433 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9434 return "add{l}\t%k0, %k0";
9436 return "add{b}\t%0, %0";
9439 if (operands[2] == const1_rtx
9440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9442 if (get_attr_mode (insn) == MODE_SI)
9443 return "sal{l}\t%k0";
9445 return "sal{b}\t%0";
9449 if (get_attr_mode (insn) == MODE_SI)
9450 return "sal{l}\t{%2, %k0|%k0, %2}";
9452 return "sal{b}\t{%2, %0|%0, %2}";
9457 (cond [(eq_attr "alternative" "2")
9458 (const_string "lea")
9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460 (match_operand 0 "register_operand"))
9461 (match_operand 2 "const1_operand"))
9462 (const_string "alu")
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9473 (const_string "*")))
9474 (set_attr "mode" "QI,SI,SI")])
9476 (define_insn "*ashlqi3_1_slp"
9477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9478 (ashift:QI (match_dup 0)
9479 (match_operand:QI 1 "nonmemory_operand" "cI")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(optimize_function_for_size_p (cfun)
9482 || !TARGET_PARTIAL_FLAG_REG_STALL
9483 || (operands[1] == const1_rtx
9485 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9487 switch (get_attr_type (insn))
9490 gcc_assert (operands[1] == const1_rtx);
9491 return "add{b}\t%0, %0";
9494 if (operands[1] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{b}\t%0";
9498 return "sal{b}\t{%1, %0|%0, %1}";
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand"))
9504 (match_operand 1 "const1_operand"))
9505 (const_string "alu")
9507 (const_string "ishift1")))
9508 (set (attr "length_immediate")
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift1")
9512 (and (match_operand 1 "const1_operand")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9516 (const_string "*")))
9517 (set_attr "mode" "QI")])
9519 ;; Convert ashift to the lea pattern to avoid flags dependency.
9521 [(set (match_operand 0 "register_operand")
9522 (ashift (match_operand 1 "index_register_operand")
9523 (match_operand:QI 2 "const_int_operand")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9530 machine_mode mode = GET_MODE (operands[0]);
9533 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9536 operands[0] = gen_lowpart (mode, operands[0]);
9537 operands[1] = gen_lowpart (mode, operands[1]);
9540 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9542 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9548 ;; Convert ashift to the lea pattern to avoid flags dependency.
9550 [(set (match_operand:DI 0 "register_operand")
9552 (ashift:SI (match_operand:SI 1 "index_register_operand")
9553 (match_operand:QI 2 "const_int_operand"))))
9554 (clobber (reg:CC FLAGS_REG))]
9555 "TARGET_64BIT && reload_completed
9556 && true_regnum (operands[0]) != true_regnum (operands[1])"
9558 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9560 operands[1] = gen_lowpart (SImode, operands[1]);
9561 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9564 ;; This pattern can't accept a variable shift count, since shifts by
9565 ;; zero don't affect the flags. We assume that shifts by constant
9566 ;; zero are optimized away.
9567 (define_insn "*ashl<mode>3_cmp"
9568 [(set (reg FLAGS_REG)
9570 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9571 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9573 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9574 (ashift:SWI (match_dup 1) (match_dup 2)))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9579 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9580 && ix86_match_ccmode (insn, CCGOCmode)
9581 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9583 switch (get_attr_type (insn))
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{<imodesuffix>}\t%0, %0";
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{<imodesuffix>}\t%0";
9594 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9598 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599 (match_operand 0 "register_operand"))
9600 (match_operand 2 "const1_operand"))
9601 (const_string "alu")
9603 (const_string "ishift")))
9604 (set (attr "length_immediate")
9606 (ior (eq_attr "type" "alu")
9607 (and (eq_attr "type" "ishift")
9608 (and (match_operand 2 "const1_operand")
9609 (ior (match_test "TARGET_SHIFT1")
9610 (match_test "optimize_function_for_size_p (cfun)")))))
9612 (const_string "*")))
9613 (set_attr "mode" "<MODE>")])
9615 (define_insn "*ashlsi3_cmp_zext"
9616 [(set (reg FLAGS_REG)
9618 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9621 (set (match_operand:DI 0 "register_operand" "=r")
9622 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9624 && (optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9628 || TARGET_DOUBLE_WITH_ADD)))
9629 && ix86_match_ccmode (insn, CCGOCmode)
9630 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9632 switch (get_attr_type (insn))
9635 gcc_assert (operands[2] == const1_rtx);
9636 return "add{l}\t%k0, %k0";
9639 if (operands[2] == const1_rtx
9640 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641 return "sal{l}\t%k0";
9643 return "sal{l}\t{%2, %k0|%k0, %2}";
9647 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9648 (match_operand 2 "const1_operand"))
9649 (const_string "alu")
9651 (const_string "ishift")))
9652 (set (attr "length_immediate")
9654 (ior (eq_attr "type" "alu")
9655 (and (eq_attr "type" "ishift")
9656 (and (match_operand 2 "const1_operand")
9657 (ior (match_test "TARGET_SHIFT1")
9658 (match_test "optimize_function_for_size_p (cfun)")))))
9660 (const_string "*")))
9661 (set_attr "mode" "SI")])
9663 (define_insn "*ashl<mode>3_cconly"
9664 [(set (reg FLAGS_REG)
9666 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9667 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9669 (clobber (match_scratch:SWI 0 "=<r>"))]
9670 "(optimize_function_for_size_p (cfun)
9671 || !TARGET_PARTIAL_FLAG_REG_STALL
9672 || (operands[2] == const1_rtx
9674 || TARGET_DOUBLE_WITH_ADD)))
9675 && ix86_match_ccmode (insn, CCGOCmode)"
9677 switch (get_attr_type (insn))
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{<imodesuffix>}\t%0, %0";
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{<imodesuffix>}\t%0";
9688 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9692 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 0 "register_operand"))
9694 (match_operand 2 "const1_operand"))
9695 (const_string "alu")
9697 (const_string "ishift")))
9698 (set (attr "length_immediate")
9700 (ior (eq_attr "type" "alu")
9701 (and (eq_attr "type" "ishift")
9702 (and (match_operand 2 "const1_operand")
9703 (ior (match_test "TARGET_SHIFT1")
9704 (match_test "optimize_function_for_size_p (cfun)")))))
9706 (const_string "*")))
9707 (set_attr "mode" "<MODE>")])
9709 ;; See comment above `ashl<mode>3' about how this works.
9711 (define_expand "<shift_insn><mode>3"
9712 [(set (match_operand:SDWIM 0 "<shift_operand>")
9713 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9714 (match_operand:QI 2 "nonmemory_operand")))]
9716 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9718 ;; Avoid useless masking of count operand.
9719 (define_insn "*<shift_insn><mode>3_mask"
9720 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9722 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9725 (match_operand:SI 2 "register_operand" "c")
9726 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730 == GET_MODE_BITSIZE (<MODE>mode)-1"
9732 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9734 [(set_attr "type" "ishift")
9735 (set_attr "mode" "<MODE>")])
9737 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9738 [(set (match_operand:DWI 0 "register_operand" "=r")
9739 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9740 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9741 (clobber (reg:CC FLAGS_REG))]
9744 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9746 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9747 [(set_attr "type" "multi")])
9749 ;; By default we don't ask for a scratch register, because when DWImode
9750 ;; values are manipulated, registers are already at a premium. But if
9751 ;; we have one handy, we won't turn it away.
9754 [(match_scratch:DWIH 3 "r")
9755 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9757 (match_operand:<DWI> 1 "register_operand")
9758 (match_operand:QI 2 "nonmemory_operand")))
9759 (clobber (reg:CC FLAGS_REG))])
9763 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9765 (define_insn "x86_64_shrd"
9766 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9767 (ior:DI (lshiftrt:DI (match_dup 0)
9768 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9769 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9770 (minus:QI (const_int 64) (match_dup 2)))))
9771 (clobber (reg:CC FLAGS_REG))]
9773 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9774 [(set_attr "type" "ishift")
9775 (set_attr "prefix_0f" "1")
9776 (set_attr "mode" "DI")
9777 (set_attr "athlon_decode" "vector")
9778 (set_attr "amdfam10_decode" "vector")
9779 (set_attr "bdver1_decode" "vector")])
9781 (define_insn "x86_shrd"
9782 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9783 (ior:SI (lshiftrt:SI (match_dup 0)
9784 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9785 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9786 (minus:QI (const_int 32) (match_dup 2)))))
9787 (clobber (reg:CC FLAGS_REG))]
9789 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9790 [(set_attr "type" "ishift")
9791 (set_attr "prefix_0f" "1")
9792 (set_attr "mode" "SI")
9793 (set_attr "pent_pair" "np")
9794 (set_attr "athlon_decode" "vector")
9795 (set_attr "amdfam10_decode" "vector")
9796 (set_attr "bdver1_decode" "vector")])
9798 (define_insn "ashrdi3_cvt"
9799 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9800 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9801 (match_operand:QI 2 "const_int_operand")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "TARGET_64BIT && INTVAL (operands[2]) == 63
9804 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9805 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9808 sar{q}\t{%2, %0|%0, %2}"
9809 [(set_attr "type" "imovx,ishift")
9810 (set_attr "prefix_0f" "0,*")
9811 (set_attr "length_immediate" "0,*")
9812 (set_attr "modrm" "0,1")
9813 (set_attr "mode" "DI")])
9815 (define_insn "ashrsi3_cvt"
9816 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9817 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9818 (match_operand:QI 2 "const_int_operand")))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "INTVAL (operands[2]) == 31
9821 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9822 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9825 sar{l}\t{%2, %0|%0, %2}"
9826 [(set_attr "type" "imovx,ishift")
9827 (set_attr "prefix_0f" "0,*")
9828 (set_attr "length_immediate" "0,*")
9829 (set_attr "modrm" "0,1")
9830 (set_attr "mode" "SI")])
9832 (define_insn "*ashrsi3_cvt_zext"
9833 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9835 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9836 (match_operand:QI 2 "const_int_operand"))))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_64BIT && INTVAL (operands[2]) == 31
9839 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9840 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9843 sar{l}\t{%2, %k0|%k0, %2}"
9844 [(set_attr "type" "imovx,ishift")
9845 (set_attr "prefix_0f" "0,*")
9846 (set_attr "length_immediate" "0,*")
9847 (set_attr "modrm" "0,1")
9848 (set_attr "mode" "SI")])
9850 (define_expand "x86_shift<mode>_adj_3"
9851 [(use (match_operand:SWI48 0 "register_operand"))
9852 (use (match_operand:SWI48 1 "register_operand"))
9853 (use (match_operand:QI 2 "register_operand"))]
9856 rtx_code_label *label = gen_label_rtx ();
9859 emit_insn (gen_testqi_ccz_1 (operands[2],
9860 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9862 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9863 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9864 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9865 gen_rtx_LABEL_REF (VOIDmode, label),
9867 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9868 JUMP_LABEL (tmp) = label;
9870 emit_move_insn (operands[0], operands[1]);
9871 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9872 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9874 LABEL_NUSES (label) = 1;
9879 (define_insn "*bmi2_<shift_insn><mode>3_1"
9880 [(set (match_operand:SWI48 0 "register_operand" "=r")
9881 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9882 (match_operand:SWI48 2 "register_operand" "r")))]
9884 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9885 [(set_attr "type" "ishiftx")
9886 (set_attr "mode" "<MODE>")])
9888 (define_insn "*<shift_insn><mode>3_1"
9889 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9891 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9892 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9896 switch (get_attr_type (insn))
9902 if (operands[2] == const1_rtx
9903 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904 return "<shift>{<imodesuffix>}\t%0";
9906 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9909 [(set_attr "isa" "*,bmi2")
9910 (set_attr "type" "ishift,ishiftx")
9911 (set (attr "length_immediate")
9913 (and (match_operand 2 "const1_operand")
9914 (ior (match_test "TARGET_SHIFT1")
9915 (match_test "optimize_function_for_size_p (cfun)")))
9917 (const_string "*")))
9918 (set_attr "mode" "<MODE>")])
9920 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9922 [(set (match_operand:SWI48 0 "register_operand")
9923 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9924 (match_operand:QI 2 "register_operand")))
9925 (clobber (reg:CC FLAGS_REG))]
9926 "TARGET_BMI2 && reload_completed"
9928 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9929 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9931 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9932 [(set (match_operand:DI 0 "register_operand" "=r")
9934 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9935 (match_operand:SI 2 "register_operand" "r"))))]
9936 "TARGET_64BIT && TARGET_BMI2"
9937 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9938 [(set_attr "type" "ishiftx")
9939 (set_attr "mode" "SI")])
9941 (define_insn "*<shift_insn>si3_1_zext"
9942 [(set (match_operand:DI 0 "register_operand" "=r,r")
9944 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9945 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9949 switch (get_attr_type (insn))
9955 if (operands[2] == const1_rtx
9956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957 return "<shift>{l}\t%k0";
9959 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9962 [(set_attr "isa" "*,bmi2")
9963 (set_attr "type" "ishift,ishiftx")
9964 (set (attr "length_immediate")
9966 (and (match_operand 2 "const1_operand")
9967 (ior (match_test "TARGET_SHIFT1")
9968 (match_test "optimize_function_for_size_p (cfun)")))
9970 (const_string "*")))
9971 (set_attr "mode" "SI")])
9973 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9975 [(set (match_operand:DI 0 "register_operand")
9977 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9978 (match_operand:QI 2 "register_operand"))))
9979 (clobber (reg:CC FLAGS_REG))]
9980 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9982 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9983 "operands[2] = gen_lowpart (SImode, operands[2]);")
9985 (define_insn "*<shift_insn><mode>3_1"
9986 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9988 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9989 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9990 (clobber (reg:CC FLAGS_REG))]
9991 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9993 if (operands[2] == const1_rtx
9994 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995 return "<shift>{<imodesuffix>}\t%0";
9997 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9999 [(set_attr "type" "ishift")
10000 (set (attr "length_immediate")
10002 (and (match_operand 2 "const1_operand")
10003 (ior (match_test "TARGET_SHIFT1")
10004 (match_test "optimize_function_for_size_p (cfun)")))
10006 (const_string "*")))
10007 (set_attr "mode" "<MODE>")])
10009 (define_insn "*<shift_insn>qi3_1_slp"
10010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10011 (any_shiftrt:QI (match_dup 0)
10012 (match_operand:QI 1 "nonmemory_operand" "cI")))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "(optimize_function_for_size_p (cfun)
10015 || !TARGET_PARTIAL_REG_STALL
10016 || (operands[1] == const1_rtx
10017 && TARGET_SHIFT1))"
10019 if (operands[1] == const1_rtx
10020 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10021 return "<shift>{b}\t%0";
10023 return "<shift>{b}\t{%1, %0|%0, %1}";
10025 [(set_attr "type" "ishift1")
10026 (set (attr "length_immediate")
10028 (and (match_operand 1 "const1_operand")
10029 (ior (match_test "TARGET_SHIFT1")
10030 (match_test "optimize_function_for_size_p (cfun)")))
10032 (const_string "*")))
10033 (set_attr "mode" "QI")])
10035 ;; This pattern can't accept a variable shift count, since shifts by
10036 ;; zero don't affect the flags. We assume that shifts by constant
10037 ;; zero are optimized away.
10038 (define_insn "*<shift_insn><mode>3_cmp"
10039 [(set (reg FLAGS_REG)
10042 (match_operand:SWI 1 "nonimmediate_operand" "0")
10043 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10045 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10046 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10047 "(optimize_function_for_size_p (cfun)
10048 || !TARGET_PARTIAL_FLAG_REG_STALL
10049 || (operands[2] == const1_rtx
10051 && ix86_match_ccmode (insn, CCGOCmode)
10052 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10054 if (operands[2] == const1_rtx
10055 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10056 return "<shift>{<imodesuffix>}\t%0";
10058 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10060 [(set_attr "type" "ishift")
10061 (set (attr "length_immediate")
10063 (and (match_operand 2 "const1_operand")
10064 (ior (match_test "TARGET_SHIFT1")
10065 (match_test "optimize_function_for_size_p (cfun)")))
10067 (const_string "*")))
10068 (set_attr "mode" "<MODE>")])
10070 (define_insn "*<shift_insn>si3_cmp_zext"
10071 [(set (reg FLAGS_REG)
10073 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10074 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10076 (set (match_operand:DI 0 "register_operand" "=r")
10077 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10079 && (optimize_function_for_size_p (cfun)
10080 || !TARGET_PARTIAL_FLAG_REG_STALL
10081 || (operands[2] == const1_rtx
10083 && ix86_match_ccmode (insn, CCGOCmode)
10084 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10086 if (operands[2] == const1_rtx
10087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10088 return "<shift>{l}\t%k0";
10090 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10092 [(set_attr "type" "ishift")
10093 (set (attr "length_immediate")
10095 (and (match_operand 2 "const1_operand")
10096 (ior (match_test "TARGET_SHIFT1")
10097 (match_test "optimize_function_for_size_p (cfun)")))
10099 (const_string "*")))
10100 (set_attr "mode" "SI")])
10102 (define_insn "*<shift_insn><mode>3_cconly"
10103 [(set (reg FLAGS_REG)
10106 (match_operand:SWI 1 "register_operand" "0")
10107 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10109 (clobber (match_scratch:SWI 0 "=<r>"))]
10110 "(optimize_function_for_size_p (cfun)
10111 || !TARGET_PARTIAL_FLAG_REG_STALL
10112 || (operands[2] == const1_rtx
10114 && ix86_match_ccmode (insn, CCGOCmode)"
10116 if (operands[2] == const1_rtx
10117 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10118 return "<shift>{<imodesuffix>}\t%0";
10120 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10122 [(set_attr "type" "ishift")
10123 (set (attr "length_immediate")
10125 (and (match_operand 2 "const1_operand")
10126 (ior (match_test "TARGET_SHIFT1")
10127 (match_test "optimize_function_for_size_p (cfun)")))
10129 (const_string "*")))
10130 (set_attr "mode" "<MODE>")])
10132 ;; Rotate instructions
10134 (define_expand "<rotate_insn>ti3"
10135 [(set (match_operand:TI 0 "register_operand")
10136 (any_rotate:TI (match_operand:TI 1 "register_operand")
10137 (match_operand:QI 2 "nonmemory_operand")))]
10140 if (const_1_to_63_operand (operands[2], VOIDmode))
10141 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10142 (operands[0], operands[1], operands[2]));
10149 (define_expand "<rotate_insn>di3"
10150 [(set (match_operand:DI 0 "shiftdi_operand")
10151 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10152 (match_operand:QI 2 "nonmemory_operand")))]
10156 ix86_expand_binary_operator (<CODE>, DImode, operands);
10157 else if (const_1_to_31_operand (operands[2], VOIDmode))
10158 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10159 (operands[0], operands[1], operands[2]));
10166 (define_expand "<rotate_insn><mode>3"
10167 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10168 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10169 (match_operand:QI 2 "nonmemory_operand")))]
10171 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10173 ;; Avoid useless masking of count operand.
10174 (define_insn "*<rotate_insn><mode>3_mask"
10175 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10177 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10180 (match_operand:SI 2 "register_operand" "c")
10181 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10184 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10185 == GET_MODE_BITSIZE (<MODE>mode)-1"
10187 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10189 [(set_attr "type" "rotate")
10190 (set_attr "mode" "<MODE>")])
10192 ;; Implement rotation using two double-precision
10193 ;; shift instructions and a scratch register.
10195 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10196 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10197 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10198 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10199 (clobber (reg:CC FLAGS_REG))
10200 (clobber (match_scratch:DWIH 3 "=&r"))]
10204 [(set (match_dup 3) (match_dup 4))
10206 [(set (match_dup 4)
10207 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10208 (lshiftrt:DWIH (match_dup 5)
10209 (minus:QI (match_dup 6) (match_dup 2)))))
10210 (clobber (reg:CC FLAGS_REG))])
10212 [(set (match_dup 5)
10213 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10214 (lshiftrt:DWIH (match_dup 3)
10215 (minus:QI (match_dup 6) (match_dup 2)))))
10216 (clobber (reg:CC FLAGS_REG))])]
10218 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10220 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10223 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10224 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10225 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10227 (clobber (reg:CC FLAGS_REG))
10228 (clobber (match_scratch:DWIH 3 "=&r"))]
10232 [(set (match_dup 3) (match_dup 4))
10234 [(set (match_dup 4)
10235 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10236 (ashift:DWIH (match_dup 5)
10237 (minus:QI (match_dup 6) (match_dup 2)))))
10238 (clobber (reg:CC FLAGS_REG))])
10240 [(set (match_dup 5)
10241 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10242 (ashift:DWIH (match_dup 3)
10243 (minus:QI (match_dup 6) (match_dup 2)))))
10244 (clobber (reg:CC FLAGS_REG))])]
10246 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10248 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10251 (define_insn "*bmi2_rorx<mode>3_1"
10252 [(set (match_operand:SWI48 0 "register_operand" "=r")
10253 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10254 (match_operand:QI 2 "immediate_operand" "<S>")))]
10256 "rorx\t{%2, %1, %0|%0, %1, %2}"
10257 [(set_attr "type" "rotatex")
10258 (set_attr "mode" "<MODE>")])
10260 (define_insn "*<rotate_insn><mode>3_1"
10261 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10263 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10264 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10268 switch (get_attr_type (insn))
10274 if (operands[2] == const1_rtx
10275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276 return "<rotate>{<imodesuffix>}\t%0";
10278 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10281 [(set_attr "isa" "*,bmi2")
10282 (set_attr "type" "rotate,rotatex")
10283 (set (attr "length_immediate")
10285 (and (eq_attr "type" "rotate")
10286 (and (match_operand 2 "const1_operand")
10287 (ior (match_test "TARGET_SHIFT1")
10288 (match_test "optimize_function_for_size_p (cfun)"))))
10290 (const_string "*")))
10291 (set_attr "mode" "<MODE>")])
10293 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10295 [(set (match_operand:SWI48 0 "register_operand")
10296 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10297 (match_operand:QI 2 "immediate_operand")))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_BMI2 && reload_completed"
10300 [(set (match_dup 0)
10301 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10304 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10308 [(set (match_operand:SWI48 0 "register_operand")
10309 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10310 (match_operand:QI 2 "immediate_operand")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "TARGET_BMI2 && reload_completed"
10313 [(set (match_dup 0)
10314 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10316 (define_insn "*bmi2_rorxsi3_1_zext"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10319 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10320 (match_operand:QI 2 "immediate_operand" "I"))))]
10321 "TARGET_64BIT && TARGET_BMI2"
10322 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10323 [(set_attr "type" "rotatex")
10324 (set_attr "mode" "SI")])
10326 (define_insn "*<rotate_insn>si3_1_zext"
10327 [(set (match_operand:DI 0 "register_operand" "=r,r")
10329 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10330 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10334 switch (get_attr_type (insn))
10340 if (operands[2] == const1_rtx
10341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342 return "<rotate>{l}\t%k0";
10344 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10347 [(set_attr "isa" "*,bmi2")
10348 (set_attr "type" "rotate,rotatex")
10349 (set (attr "length_immediate")
10351 (and (eq_attr "type" "rotate")
10352 (and (match_operand 2 "const1_operand")
10353 (ior (match_test "TARGET_SHIFT1")
10354 (match_test "optimize_function_for_size_p (cfun)"))))
10356 (const_string "*")))
10357 (set_attr "mode" "SI")])
10359 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10361 [(set (match_operand:DI 0 "register_operand")
10363 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10364 (match_operand:QI 2 "immediate_operand"))))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10367 [(set (match_dup 0)
10368 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10371 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10375 [(set (match_operand:DI 0 "register_operand")
10377 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10378 (match_operand:QI 2 "immediate_operand"))))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10381 [(set (match_dup 0)
10382 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10384 (define_insn "*<rotate_insn><mode>3_1"
10385 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10386 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10387 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10391 if (operands[2] == const1_rtx
10392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10393 return "<rotate>{<imodesuffix>}\t%0";
10395 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10397 [(set_attr "type" "rotate")
10398 (set (attr "length_immediate")
10400 (and (match_operand 2 "const1_operand")
10401 (ior (match_test "TARGET_SHIFT1")
10402 (match_test "optimize_function_for_size_p (cfun)")))
10404 (const_string "*")))
10405 (set_attr "mode" "<MODE>")])
10407 (define_insn "*<rotate_insn>qi3_1_slp"
10408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10409 (any_rotate:QI (match_dup 0)
10410 (match_operand:QI 1 "nonmemory_operand" "cI")))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "(optimize_function_for_size_p (cfun)
10413 || !TARGET_PARTIAL_REG_STALL
10414 || (operands[1] == const1_rtx
10415 && TARGET_SHIFT1))"
10417 if (operands[1] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "<rotate>{b}\t%0";
10421 return "<rotate>{b}\t{%1, %0|%0, %1}";
10423 [(set_attr "type" "rotate1")
10424 (set (attr "length_immediate")
10426 (and (match_operand 1 "const1_operand")
10427 (ior (match_test "TARGET_SHIFT1")
10428 (match_test "optimize_function_for_size_p (cfun)")))
10430 (const_string "*")))
10431 (set_attr "mode" "QI")])
10434 [(set (match_operand:HI 0 "register_operand")
10435 (any_rotate:HI (match_dup 0) (const_int 8)))
10436 (clobber (reg:CC FLAGS_REG))]
10438 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10439 [(parallel [(set (strict_low_part (match_dup 0))
10440 (bswap:HI (match_dup 0)))
10441 (clobber (reg:CC FLAGS_REG))])])
10443 ;; Bit set / bit test instructions
10445 (define_expand "extv"
10446 [(set (match_operand:SI 0 "register_operand")
10447 (sign_extract:SI (match_operand:SI 1 "register_operand")
10448 (match_operand:SI 2 "const8_operand")
10449 (match_operand:SI 3 "const8_operand")))]
10452 /* Handle extractions from %ah et al. */
10453 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10456 /* From mips.md: extract_bit_field doesn't verify that our source
10457 matches the predicate, so check it again here. */
10458 if (! ext_register_operand (operands[1], VOIDmode))
10462 (define_expand "extzv"
10463 [(set (match_operand:SI 0 "register_operand")
10464 (zero_extract:SI (match_operand 1 "ext_register_operand")
10465 (match_operand:SI 2 "const8_operand")
10466 (match_operand:SI 3 "const8_operand")))]
10469 /* Handle extractions from %ah et al. */
10470 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10473 /* From mips.md: extract_bit_field doesn't verify that our source
10474 matches the predicate, so check it again here. */
10475 if (! ext_register_operand (operands[1], VOIDmode))
10479 (define_expand "insv"
10480 [(set (zero_extract (match_operand 0 "register_operand")
10481 (match_operand 1 "const_int_operand")
10482 (match_operand 2 "const_int_operand"))
10483 (match_operand 3 "register_operand"))]
10486 rtx (*gen_mov_insv_1) (rtx, rtx);
10488 if (ix86_expand_pinsr (operands))
10491 /* Handle insertions to %ah et al. */
10492 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10495 /* From mips.md: insert_bit_field doesn't verify that our source
10496 matches the predicate, so check it again here. */
10497 if (! ext_register_operand (operands[0], VOIDmode))
10500 gen_mov_insv_1 = (TARGET_64BIT
10501 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10503 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10507 ;; %%% bts, btr, btc, bt.
10508 ;; In general these instructions are *slow* when applied to memory,
10509 ;; since they enforce atomic operation. When applied to registers,
10510 ;; it depends on the cpu implementation. They're never faster than
10511 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10512 ;; no point. But in 64-bit, we can't hold the relevant immediates
10513 ;; within the instruction itself, so operating on bits in the high
10514 ;; 32-bits of a register becomes easier.
10516 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10517 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10518 ;; negdf respectively, so they can never be disabled entirely.
10520 (define_insn "*btsq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "bts{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10532 (define_insn "*btrq"
10533 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10535 (match_operand:DI 1 "const_0_to_63_operand"))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539 "btr{q}\t{%1, %0|%0, %1}"
10540 [(set_attr "type" "alu1")
10541 (set_attr "prefix_0f" "1")
10542 (set_attr "mode" "DI")])
10544 (define_insn "*btcq"
10545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10547 (match_operand:DI 1 "const_0_to_63_operand"))
10548 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10551 "btc{q}\t{%1, %0|%0, %1}"
10552 [(set_attr "type" "alu1")
10553 (set_attr "prefix_0f" "1")
10554 (set_attr "mode" "DI")])
10556 ;; Allow Nocona to avoid these instructions if a register is available.
10559 [(match_scratch:DI 2 "r")
10560 (parallel [(set (zero_extract:DI
10561 (match_operand:DI 0 "register_operand")
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10565 (clobber (reg:CC FLAGS_REG))])]
10566 "TARGET_64BIT && !TARGET_USE_BT"
10569 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10572 if (HOST_BITS_PER_WIDE_INT >= 64)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574 else if (i < HOST_BITS_PER_WIDE_INT)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10577 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10579 op1 = immed_double_const (lo, hi, DImode);
10582 emit_move_insn (operands[2], op1);
10586 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10591 [(match_scratch:DI 2 "r")
10592 (parallel [(set (zero_extract:DI
10593 (match_operand:DI 0 "register_operand")
10595 (match_operand:DI 1 "const_0_to_63_operand"))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "TARGET_64BIT && !TARGET_USE_BT"
10601 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10604 if (HOST_BITS_PER_WIDE_INT >= 64)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606 else if (i < HOST_BITS_PER_WIDE_INT)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10609 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10611 op1 = immed_double_const (~lo, ~hi, DImode);
10614 emit_move_insn (operands[2], op1);
10618 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10623 [(match_scratch:DI 2 "r")
10624 (parallel [(set (zero_extract:DI
10625 (match_operand:DI 0 "register_operand")
10627 (match_operand:DI 1 "const_0_to_63_operand"))
10628 (not:DI (zero_extract:DI
10629 (match_dup 0) (const_int 1) (match_dup 1))))
10630 (clobber (reg:CC FLAGS_REG))])]
10631 "TARGET_64BIT && !TARGET_USE_BT"
10634 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10637 if (HOST_BITS_PER_WIDE_INT >= 64)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639 else if (i < HOST_BITS_PER_WIDE_INT)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10642 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10644 op1 = immed_double_const (lo, hi, DImode);
10647 emit_move_insn (operands[2], op1);
10651 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10655 (define_insn "*bt<mode>"
10656 [(set (reg:CCC FLAGS_REG)
10658 (zero_extract:SWI48
10659 (match_operand:SWI48 0 "register_operand" "r")
10661 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10663 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10664 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10665 [(set_attr "type" "alu1")
10666 (set_attr "prefix_0f" "1")
10667 (set_attr "mode" "<MODE>")])
10669 ;; Store-flag instructions.
10671 ;; For all sCOND expanders, also expand the compare or test insn that
10672 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10674 (define_insn_and_split "*setcc_di_1"
10675 [(set (match_operand:DI 0 "register_operand" "=q")
10676 (match_operator:DI 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)]))]
10678 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10680 "&& reload_completed"
10681 [(set (match_dup 2) (match_dup 1))
10682 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10684 PUT_MODE (operands[1], QImode);
10685 operands[2] = gen_lowpart (QImode, operands[0]);
10688 (define_insn_and_split "*setcc_si_1_and"
10689 [(set (match_operand:SI 0 "register_operand" "=q")
10690 (match_operator:SI 1 "ix86_comparison_operator"
10691 [(reg FLAGS_REG) (const_int 0)]))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "!TARGET_PARTIAL_REG_STALL
10694 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10699 (clobber (reg:CC FLAGS_REG))])]
10701 PUT_MODE (operands[1], QImode);
10702 operands[2] = gen_lowpart (QImode, operands[0]);
10705 (define_insn_and_split "*setcc_si_1_movzbl"
10706 [(set (match_operand:SI 0 "register_operand" "=q")
10707 (match_operator:SI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10716 PUT_MODE (operands[1], QImode);
10717 operands[2] = gen_lowpart (QImode, operands[0]);
10720 (define_insn "*setcc_qi"
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10722 (match_operator:QI 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)]))]
10726 [(set_attr "type" "setcc")
10727 (set_attr "mode" "QI")])
10729 (define_insn "*setcc_qi_slp"
10730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10731 (match_operator:QI 1 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)]))]
10735 [(set_attr "type" "setcc")
10736 (set_attr "mode" "QI")])
10738 ;; In general it is not safe to assume too much about CCmode registers,
10739 ;; so simplify-rtx stops when it sees a second one. Under certain
10740 ;; conditions this is safe on x86, so help combine not create
10747 [(set (match_operand:QI 0 "nonimmediate_operand")
10748 (ne:QI (match_operator 1 "ix86_comparison_operator"
10749 [(reg FLAGS_REG) (const_int 0)])
10752 [(set (match_dup 0) (match_dup 1))]
10753 "PUT_MODE (operands[1], QImode);")
10756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10757 (ne:QI (match_operator 1 "ix86_comparison_operator"
10758 [(reg FLAGS_REG) (const_int 0)])
10761 [(set (match_dup 0) (match_dup 1))]
10762 "PUT_MODE (operands[1], QImode);")
10765 [(set (match_operand:QI 0 "nonimmediate_operand")
10766 (eq:QI (match_operator 1 "ix86_comparison_operator"
10767 [(reg FLAGS_REG) (const_int 0)])
10770 [(set (match_dup 0) (match_dup 1))]
10772 rtx new_op1 = copy_rtx (operands[1]);
10773 operands[1] = new_op1;
10774 PUT_MODE (new_op1, QImode);
10775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10776 GET_MODE (XEXP (new_op1, 0))));
10778 /* Make sure that (a) the CCmode we have for the flags is strong
10779 enough for the reversed compare or (b) we have a valid FP compare. */
10780 if (! ix86_comparison_operator (new_op1, VOIDmode))
10785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10786 (eq:QI (match_operator 1 "ix86_comparison_operator"
10787 [(reg FLAGS_REG) (const_int 0)])
10790 [(set (match_dup 0) (match_dup 1))]
10792 rtx new_op1 = copy_rtx (operands[1]);
10793 operands[1] = new_op1;
10794 PUT_MODE (new_op1, QImode);
10795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10796 GET_MODE (XEXP (new_op1, 0))));
10798 /* Make sure that (a) the CCmode we have for the flags is strong
10799 enough for the reversed compare or (b) we have a valid FP compare. */
10800 if (! ix86_comparison_operator (new_op1, VOIDmode))
10804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10805 ;; subsequent logical operations are used to imitate conditional moves.
10806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10809 (define_insn "setcc_<mode>_sse"
10810 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10811 (match_operator:MODEF 3 "sse_comparison_operator"
10812 [(match_operand:MODEF 1 "register_operand" "0,x")
10813 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10814 "SSE_FLOAT_MODE_P (<MODE>mode)"
10816 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10817 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10818 [(set_attr "isa" "noavx,avx")
10819 (set_attr "type" "ssecmp")
10820 (set_attr "length_immediate" "1")
10821 (set_attr "prefix" "orig,vex")
10822 (set_attr "mode" "<MODE>")])
10824 ;; Basic conditional jump instructions.
10825 ;; We ignore the overflow flag for signed branch instructions.
10827 (define_insn "*jcc_1"
10829 (if_then_else (match_operator 1 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10831 (label_ref (match_operand 0))
10835 [(set_attr "type" "ibr")
10836 (set_attr "modrm" "0")
10837 (set (attr "length_nobnd")
10838 (if_then_else (and (ge (minus (match_dup 0) (pc))
10840 (lt (minus (match_dup 0) (pc))
10845 (define_insn "*jcc_2"
10847 (if_then_else (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10850 (label_ref (match_operand 0))))]
10853 [(set_attr "type" "ibr")
10854 (set_attr "modrm" "0")
10855 (set (attr "length_nobnd")
10856 (if_then_else (and (ge (minus (match_dup 0) (pc))
10858 (lt (minus (match_dup 0) (pc))
10863 ;; In general it is not safe to assume too much about CCmode registers,
10864 ;; so simplify-rtx stops when it sees a second one. Under certain
10865 ;; conditions this is safe on x86, so help combine not create
10873 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10874 [(reg FLAGS_REG) (const_int 0)])
10876 (label_ref (match_operand 1))
10880 (if_then_else (match_dup 0)
10881 (label_ref (match_dup 1))
10883 "PUT_MODE (operands[0], VOIDmode);")
10887 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10888 [(reg FLAGS_REG) (const_int 0)])
10890 (label_ref (match_operand 1))
10894 (if_then_else (match_dup 0)
10895 (label_ref (match_dup 1))
10898 rtx new_op0 = copy_rtx (operands[0]);
10899 operands[0] = new_op0;
10900 PUT_MODE (new_op0, VOIDmode);
10901 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10902 GET_MODE (XEXP (new_op0, 0))));
10904 /* Make sure that (a) the CCmode we have for the flags is strong
10905 enough for the reversed compare or (b) we have a valid FP compare. */
10906 if (! ix86_comparison_operator (new_op0, VOIDmode))
10910 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10911 ;; pass generates from shift insn with QImode operand. Actually, the mode
10912 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10913 ;; appropriate modulo of the bit offset value.
10915 (define_insn_and_split "*jcc_bt<mode>"
10917 (if_then_else (match_operator 0 "bt_comparison_operator"
10918 [(zero_extract:SWI48
10919 (match_operand:SWI48 1 "register_operand" "r")
10922 (match_operand:QI 2 "register_operand" "r")))
10924 (label_ref (match_operand 3))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10930 [(set (reg:CCC FLAGS_REG)
10932 (zero_extract:SWI48
10938 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939 (label_ref (match_dup 3))
10942 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10944 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10947 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10948 ;; zero extended to SImode.
10949 (define_insn_and_split "*jcc_bt<mode>_1"
10951 (if_then_else (match_operator 0 "bt_comparison_operator"
10952 [(zero_extract:SWI48
10953 (match_operand:SWI48 1 "register_operand" "r")
10955 (match_operand:SI 2 "register_operand" "r"))
10957 (label_ref (match_operand 3))
10959 (clobber (reg:CC FLAGS_REG))]
10960 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10963 [(set (reg:CCC FLAGS_REG)
10965 (zero_extract:SWI48
10971 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10972 (label_ref (match_dup 3))
10975 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10977 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10980 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10981 ;; also for DImode, this is what combine produces.
10982 (define_insn_and_split "*jcc_bt<mode>_mask"
10984 (if_then_else (match_operator 0 "bt_comparison_operator"
10985 [(zero_extract:SWI48
10986 (match_operand:SWI48 1 "register_operand" "r")
10989 (match_operand:SI 2 "register_operand" "r")
10990 (match_operand:SI 3 "const_int_operand" "n")))])
10991 (label_ref (match_operand 4))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10995 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10996 == GET_MODE_BITSIZE (<MODE>mode)-1"
10999 [(set (reg:CCC FLAGS_REG)
11001 (zero_extract:SWI48
11007 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11008 (label_ref (match_dup 4))
11011 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11013 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11016 (define_insn_and_split "*jcc_btsi_1"
11018 (if_then_else (match_operator 0 "bt_comparison_operator"
11021 (match_operand:SI 1 "register_operand" "r")
11022 (match_operand:QI 2 "register_operand" "r"))
11025 (label_ref (match_operand 3))
11027 (clobber (reg:CC FLAGS_REG))]
11028 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11031 [(set (reg:CCC FLAGS_REG)
11039 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11040 (label_ref (match_dup 3))
11043 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11045 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11048 ;; avoid useless masking of bit offset operand
11049 (define_insn_and_split "*jcc_btsi_mask_1"
11052 (match_operator 0 "bt_comparison_operator"
11055 (match_operand:SI 1 "register_operand" "r")
11058 (match_operand:SI 2 "register_operand" "r")
11059 (match_operand:SI 3 "const_int_operand" "n")) 0))
11062 (label_ref (match_operand 4))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11066 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11069 [(set (reg:CCC FLAGS_REG)
11077 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11078 (label_ref (match_dup 4))
11080 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11082 ;; Define combination compare-and-branch fp compare instructions to help
11085 (define_insn "*jcc<mode>_0_i387"
11087 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11088 [(match_operand:X87MODEF 1 "register_operand" "f")
11089 (match_operand:X87MODEF 2 "const0_operand")])
11090 (label_ref (match_operand 3))
11092 (clobber (reg:CCFP FPSR_REG))
11093 (clobber (reg:CCFP FLAGS_REG))
11094 (clobber (match_scratch:HI 4 "=a"))]
11095 "TARGET_80387 && !TARGET_CMOVE"
11098 (define_insn "*jcc<mode>_0_r_i387"
11100 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11101 [(match_operand:X87MODEF 1 "register_operand" "f")
11102 (match_operand:X87MODEF 2 "const0_operand")])
11104 (label_ref (match_operand 3))))
11105 (clobber (reg:CCFP FPSR_REG))
11106 (clobber (reg:CCFP FLAGS_REG))
11107 (clobber (match_scratch:HI 4 "=a"))]
11108 "TARGET_80387 && !TARGET_CMOVE"
11111 (define_insn "*jccxf_i387"
11113 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11114 [(match_operand:XF 1 "register_operand" "f")
11115 (match_operand:XF 2 "register_operand" "f")])
11116 (label_ref (match_operand 3))
11118 (clobber (reg:CCFP FPSR_REG))
11119 (clobber (reg:CCFP FLAGS_REG))
11120 (clobber (match_scratch:HI 4 "=a"))]
11121 "TARGET_80387 && !TARGET_CMOVE"
11124 (define_insn "*jccxf_r_i387"
11126 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11127 [(match_operand:XF 1 "register_operand" "f")
11128 (match_operand:XF 2 "register_operand" "f")])
11130 (label_ref (match_operand 3))))
11131 (clobber (reg:CCFP FPSR_REG))
11132 (clobber (reg:CCFP FLAGS_REG))
11133 (clobber (match_scratch:HI 4 "=a"))]
11134 "TARGET_80387 && !TARGET_CMOVE"
11137 (define_insn "*jcc<mode>_i387"
11139 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11140 [(match_operand:MODEF 1 "register_operand" "f")
11141 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11142 (label_ref (match_operand 3))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 4 "=a"))]
11147 "TARGET_80387 && !TARGET_CMOVE"
11150 (define_insn "*jcc<mode>_r_i387"
11152 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11153 [(match_operand:MODEF 1 "register_operand" "f")
11154 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11156 (label_ref (match_operand 3))))
11157 (clobber (reg:CCFP FPSR_REG))
11158 (clobber (reg:CCFP FLAGS_REG))
11159 (clobber (match_scratch:HI 4 "=a"))]
11160 "TARGET_80387 && !TARGET_CMOVE"
11163 (define_insn "*jccu<mode>_i387"
11165 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11166 [(match_operand:X87MODEF 1 "register_operand" "f")
11167 (match_operand:X87MODEF 2 "register_operand" "f")])
11168 (label_ref (match_operand 3))
11170 (clobber (reg:CCFP FPSR_REG))
11171 (clobber (reg:CCFP FLAGS_REG))
11172 (clobber (match_scratch:HI 4 "=a"))]
11173 "TARGET_80387 && !TARGET_CMOVE"
11176 (define_insn "*jccu<mode>_r_i387"
11178 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11179 [(match_operand:X87MODEF 1 "register_operand" "f")
11180 (match_operand:X87MODEF 2 "register_operand" "f")])
11182 (label_ref (match_operand 3))))
11183 (clobber (reg:CCFP FPSR_REG))
11184 (clobber (reg:CCFP FLAGS_REG))
11185 (clobber (match_scratch:HI 4 "=a"))]
11186 "TARGET_80387 && !TARGET_CMOVE"
11191 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11192 [(match_operand:X87MODEF 1 "register_operand")
11193 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11195 (match_operand 4)))
11196 (clobber (reg:CCFP FPSR_REG))
11197 (clobber (reg:CCFP FLAGS_REG))]
11198 "TARGET_80387 && !TARGET_CMOVE
11199 && reload_completed"
11202 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11203 operands[3], operands[4], NULL_RTX);
11209 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11210 [(match_operand:X87MODEF 1 "register_operand")
11211 (match_operand:X87MODEF 2 "general_operand")])
11213 (match_operand 4)))
11214 (clobber (reg:CCFP FPSR_REG))
11215 (clobber (reg:CCFP FLAGS_REG))
11216 (clobber (match_scratch:HI 5))]
11217 "TARGET_80387 && !TARGET_CMOVE
11218 && reload_completed"
11221 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11222 operands[3], operands[4], operands[5]);
11226 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11227 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11228 ;; with a precedence over other operators and is always put in the first
11229 ;; place. Swap condition and operands to match ficom instruction.
11231 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11234 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11235 [(match_operator:X87MODEF 1 "float_operator"
11236 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11237 (match_operand:X87MODEF 3 "register_operand" "f")])
11238 (label_ref (match_operand 4))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 5 "=a"))]
11243 "TARGET_80387 && !TARGET_CMOVE
11244 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11245 || optimize_function_for_size_p (cfun))"
11248 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11251 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11252 [(match_operator:X87MODEF 1 "float_operator"
11253 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11254 (match_operand:X87MODEF 3 "register_operand" "f")])
11256 (label_ref (match_operand 4))))
11257 (clobber (reg:CCFP FPSR_REG))
11258 (clobber (reg:CCFP FLAGS_REG))
11259 (clobber (match_scratch:HI 5 "=a"))]
11260 "TARGET_80387 && !TARGET_CMOVE
11261 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11262 || optimize_function_for_size_p (cfun))"
11268 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11269 [(match_operator:X87MODEF 1 "float_operator"
11270 [(match_operand:SWI24 2 "memory_operand")])
11271 (match_operand:X87MODEF 3 "register_operand")])
11273 (match_operand 5)))
11274 (clobber (reg:CCFP FPSR_REG))
11275 (clobber (reg:CCFP FLAGS_REG))
11276 (clobber (match_scratch:HI 6))]
11277 "TARGET_80387 && !TARGET_CMOVE
11278 && reload_completed"
11281 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11282 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11283 operands[4], operands[5], operands[6]);
11287 ;; Unconditional and other jump instructions
11289 (define_insn "jump"
11291 (label_ref (match_operand 0)))]
11294 [(set_attr "type" "ibr")
11295 (set (attr "length_nobnd")
11296 (if_then_else (and (ge (minus (match_dup 0) (pc))
11298 (lt (minus (match_dup 0) (pc))
11302 (set_attr "modrm" "0")])
11304 (define_expand "indirect_jump"
11305 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11309 operands[0] = convert_memory_address (word_mode, operands[0]);
11312 (define_insn "*indirect_jump"
11313 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11316 [(set_attr "type" "ibr")
11317 (set_attr "length_immediate" "0")])
11319 (define_expand "tablejump"
11320 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11321 (use (label_ref (match_operand 1)))])]
11324 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11325 relative. Convert the relative address to an absolute address. */
11329 enum rtx_code code;
11331 /* We can't use @GOTOFF for text labels on VxWorks;
11332 see gotoff_operand. */
11333 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11337 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11339 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11343 op1 = pic_offset_table_rtx;
11348 op0 = pic_offset_table_rtx;
11352 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11357 operands[0] = convert_memory_address (word_mode, operands[0]);
11360 (define_insn "*tablejump_1"
11361 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11362 (use (label_ref (match_operand 1)))]
11365 [(set_attr "type" "ibr")
11366 (set_attr "length_immediate" "0")])
11368 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11371 [(set (reg FLAGS_REG) (match_operand 0))
11372 (set (match_operand:QI 1 "register_operand")
11373 (match_operator:QI 2 "ix86_comparison_operator"
11374 [(reg FLAGS_REG) (const_int 0)]))
11375 (set (match_operand 3 "q_regs_operand")
11376 (zero_extend (match_dup 1)))]
11377 "(peep2_reg_dead_p (3, operands[1])
11378 || operands_match_p (operands[1], operands[3]))
11379 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11380 [(set (match_dup 4) (match_dup 0))
11381 (set (strict_low_part (match_dup 5))
11384 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11385 operands[5] = gen_lowpart (QImode, operands[3]);
11386 ix86_expand_clear (operands[3]);
11390 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11391 (match_operand 4)])
11392 (set (match_operand:QI 1 "register_operand")
11393 (match_operator:QI 2 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))
11395 (set (match_operand 3 "q_regs_operand")
11396 (zero_extend (match_dup 1)))]
11397 "(peep2_reg_dead_p (3, operands[1])
11398 || operands_match_p (operands[1], operands[3]))
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(parallel [(set (match_dup 5) (match_dup 0))
11402 (set (strict_low_part (match_dup 6))
11405 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11406 operands[6] = gen_lowpart (QImode, operands[3]);
11407 ix86_expand_clear (operands[3]);
11410 ;; Similar, but match zero extend with andsi3.
11413 [(set (reg FLAGS_REG) (match_operand 0))
11414 (set (match_operand:QI 1 "register_operand")
11415 (match_operator:QI 2 "ix86_comparison_operator"
11416 [(reg FLAGS_REG) (const_int 0)]))
11417 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11418 (and:SI (match_dup 3) (const_int 255)))
11419 (clobber (reg:CC FLAGS_REG))])]
11420 "REGNO (operands[1]) == REGNO (operands[3])
11421 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11422 [(set (match_dup 4) (match_dup 0))
11423 (set (strict_low_part (match_dup 5))
11426 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427 operands[5] = gen_lowpart (QImode, operands[3]);
11428 ix86_expand_clear (operands[3]);
11432 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11433 (match_operand 4)])
11434 (set (match_operand:QI 1 "register_operand")
11435 (match_operator:QI 2 "ix86_comparison_operator"
11436 [(reg FLAGS_REG) (const_int 0)]))
11437 (parallel [(set (match_operand 3 "q_regs_operand")
11438 (zero_extend (match_dup 1)))
11439 (clobber (reg:CC FLAGS_REG))])]
11440 "(peep2_reg_dead_p (3, operands[1])
11441 || operands_match_p (operands[1], operands[3]))
11442 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11443 [(parallel [(set (match_dup 5) (match_dup 0))
11445 (set (strict_low_part (match_dup 6))
11448 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11449 operands[6] = gen_lowpart (QImode, operands[3]);
11450 ix86_expand_clear (operands[3]);
11453 ;; Call instructions.
11455 ;; The predicates normally associated with named expanders are not properly
11456 ;; checked for calls. This is a bug in the generic code, but it isn't that
11457 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11459 ;; P6 processors will jump to the address after the decrement when %esp
11460 ;; is used as a call operand, so they will execute return address as a code.
11461 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11463 ;; Register constraint for call instruction.
11464 (define_mode_attr c [(SI "l") (DI "r")])
11466 ;; Call subroutine returning no value.
11468 (define_expand "call"
11469 [(call (match_operand:QI 0)
11471 (use (match_operand 2))]
11474 ix86_expand_call (NULL, operands[0], operands[1],
11475 operands[2], NULL, false);
11479 (define_expand "sibcall"
11480 [(call (match_operand:QI 0)
11482 (use (match_operand 2))]
11485 ix86_expand_call (NULL, operands[0], operands[1],
11486 operands[2], NULL, true);
11490 (define_insn "*call"
11491 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11492 (match_operand 1))]
11493 "!SIBLING_CALL_P (insn)"
11494 "* return ix86_output_call_insn (insn, operands[0]);"
11495 [(set_attr "type" "call")])
11497 (define_insn "*sibcall"
11498 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11499 (match_operand 1))]
11500 "SIBLING_CALL_P (insn)"
11501 "* return ix86_output_call_insn (insn, operands[0]);"
11502 [(set_attr "type" "call")])
11504 (define_insn "*sibcall_memory"
11505 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11507 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11509 "* return ix86_output_call_insn (insn, operands[0]);"
11510 [(set_attr "type" "call")])
11513 [(set (match_operand:W 0 "register_operand")
11514 (match_operand:W 1 "memory_operand"))
11515 (call (mem:QI (match_dup 0))
11516 (match_operand 3))]
11517 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11518 && peep2_reg_dead_p (2, operands[0])"
11519 [(parallel [(call (mem:QI (match_dup 1))
11521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11524 [(set (match_operand:W 0 "register_operand")
11525 (match_operand:W 1 "memory_operand"))
11526 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11527 (call (mem:QI (match_dup 0))
11528 (match_operand 3))]
11529 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11530 && peep2_reg_dead_p (3, operands[0])"
11531 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11532 (parallel [(call (mem:QI (match_dup 1))
11534 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11536 (define_expand "call_pop"
11537 [(parallel [(call (match_operand:QI 0)
11538 (match_operand:SI 1))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 3)))])]
11544 ix86_expand_call (NULL, operands[0], operands[1],
11545 operands[2], operands[3], false);
11549 (define_insn "*call_pop"
11550 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11552 (set (reg:SI SP_REG)
11553 (plus:SI (reg:SI SP_REG)
11554 (match_operand:SI 2 "immediate_operand" "i")))]
11555 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556 "* return ix86_output_call_insn (insn, operands[0]);"
11557 [(set_attr "type" "call")])
11559 (define_insn "*sibcall_pop"
11560 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11562 (set (reg:SI SP_REG)
11563 (plus:SI (reg:SI SP_REG)
11564 (match_operand:SI 2 "immediate_operand" "i")))]
11565 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11566 "* return ix86_output_call_insn (insn, operands[0]);"
11567 [(set_attr "type" "call")])
11569 (define_insn "*sibcall_pop_memory"
11570 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11572 (set (reg:SI SP_REG)
11573 (plus:SI (reg:SI SP_REG)
11574 (match_operand:SI 2 "immediate_operand" "i")))
11575 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11577 "* return ix86_output_call_insn (insn, operands[0]);"
11578 [(set_attr "type" "call")])
11581 [(set (match_operand:SI 0 "register_operand")
11582 (match_operand:SI 1 "memory_operand"))
11583 (parallel [(call (mem:QI (match_dup 0))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 4 "immediate_operand")))])]
11588 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11589 && peep2_reg_dead_p (2, operands[0])"
11590 [(parallel [(call (mem:QI (match_dup 1))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11595 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11598 [(set (match_operand:SI 0 "register_operand")
11599 (match_operand:SI 1 "memory_operand"))
11600 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11601 (parallel [(call (mem:QI (match_dup 0))
11603 (set (reg:SI SP_REG)
11604 (plus:SI (reg:SI SP_REG)
11605 (match_operand:SI 4 "immediate_operand")))])]
11606 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11607 && peep2_reg_dead_p (3, operands[0])"
11608 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11609 (parallel [(call (mem:QI (match_dup 1))
11611 (set (reg:SI SP_REG)
11612 (plus:SI (reg:SI SP_REG)
11614 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11616 ;; Combining simple memory jump instruction
11619 [(set (match_operand:W 0 "register_operand")
11620 (match_operand:W 1 "memory_operand"))
11621 (set (pc) (match_dup 0))]
11622 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11623 [(set (pc) (match_dup 1))])
11625 ;; Call subroutine, returning value in operand 0
11627 (define_expand "call_value"
11628 [(set (match_operand 0)
11629 (call (match_operand:QI 1)
11630 (match_operand 2)))
11631 (use (match_operand 3))]
11634 ix86_expand_call (operands[0], operands[1], operands[2],
11635 operands[3], NULL, false);
11639 (define_expand "sibcall_value"
11640 [(set (match_operand 0)
11641 (call (match_operand:QI 1)
11642 (match_operand 2)))
11643 (use (match_operand 3))]
11646 ix86_expand_call (operands[0], operands[1], operands[2],
11647 operands[3], NULL, true);
11651 (define_insn "*call_value"
11652 [(set (match_operand 0)
11653 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11654 (match_operand 2)))]
11655 "!SIBLING_CALL_P (insn)"
11656 "* return ix86_output_call_insn (insn, operands[1]);"
11657 [(set_attr "type" "callv")])
11659 (define_insn "*sibcall_value"
11660 [(set (match_operand 0)
11661 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11662 (match_operand 2)))]
11663 "SIBLING_CALL_P (insn)"
11664 "* return ix86_output_call_insn (insn, operands[1]);"
11665 [(set_attr "type" "callv")])
11667 (define_insn "*sibcall_value_memory"
11668 [(set (match_operand 0)
11669 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11670 (match_operand 2)))
11671 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11673 "* return ix86_output_call_insn (insn, operands[1]);"
11674 [(set_attr "type" "callv")])
11677 [(set (match_operand:W 0 "register_operand")
11678 (match_operand:W 1 "memory_operand"))
11679 (set (match_operand 2)
11680 (call (mem:QI (match_dup 0))
11681 (match_operand 3)))]
11682 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11683 && peep2_reg_dead_p (2, operands[0])"
11684 [(parallel [(set (match_dup 2)
11685 (call (mem:QI (match_dup 1))
11687 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11690 [(set (match_operand:W 0 "register_operand")
11691 (match_operand:W 1 "memory_operand"))
11692 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11693 (set (match_operand 2)
11694 (call (mem:QI (match_dup 0))
11695 (match_operand 3)))]
11696 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11697 && peep2_reg_dead_p (3, operands[0])"
11698 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11699 (parallel [(set (match_dup 2)
11700 (call (mem:QI (match_dup 1))
11702 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11704 (define_expand "call_value_pop"
11705 [(parallel [(set (match_operand 0)
11706 (call (match_operand:QI 1)
11707 (match_operand:SI 2)))
11708 (set (reg:SI SP_REG)
11709 (plus:SI (reg:SI SP_REG)
11710 (match_operand:SI 4)))])]
11713 ix86_expand_call (operands[0], operands[1], operands[2],
11714 operands[3], operands[4], false);
11718 (define_insn "*call_value_pop"
11719 [(set (match_operand 0)
11720 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11721 (match_operand 2)))
11722 (set (reg:SI SP_REG)
11723 (plus:SI (reg:SI SP_REG)
11724 (match_operand:SI 3 "immediate_operand" "i")))]
11725 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11726 "* return ix86_output_call_insn (insn, operands[1]);"
11727 [(set_attr "type" "callv")])
11729 (define_insn "*sibcall_value_pop"
11730 [(set (match_operand 0)
11731 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11732 (match_operand 2)))
11733 (set (reg:SI SP_REG)
11734 (plus:SI (reg:SI SP_REG)
11735 (match_operand:SI 3 "immediate_operand" "i")))]
11736 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11737 "* return ix86_output_call_insn (insn, operands[1]);"
11738 [(set_attr "type" "callv")])
11740 (define_insn "*sibcall_value_pop_memory"
11741 [(set (match_operand 0)
11742 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11743 (match_operand 2)))
11744 (set (reg:SI SP_REG)
11745 (plus:SI (reg:SI SP_REG)
11746 (match_operand:SI 3 "immediate_operand" "i")))
11747 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11749 "* return ix86_output_call_insn (insn, operands[1]);"
11750 [(set_attr "type" "callv")])
11753 [(set (match_operand:SI 0 "register_operand")
11754 (match_operand:SI 1 "memory_operand"))
11755 (parallel [(set (match_operand 2)
11756 (call (mem:QI (match_dup 0))
11757 (match_operand 3)))
11758 (set (reg:SI SP_REG)
11759 (plus:SI (reg:SI SP_REG)
11760 (match_operand:SI 4 "immediate_operand")))])]
11761 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11762 && peep2_reg_dead_p (2, operands[0])"
11763 [(parallel [(set (match_dup 2)
11764 (call (mem:QI (match_dup 1))
11766 (set (reg:SI SP_REG)
11767 (plus:SI (reg:SI SP_REG)
11769 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11772 [(set (match_operand:SI 0 "register_operand")
11773 (match_operand:SI 1 "memory_operand"))
11774 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11775 (parallel [(set (match_operand 2)
11776 (call (mem:QI (match_dup 0))
11777 (match_operand 3)))
11778 (set (reg:SI SP_REG)
11779 (plus:SI (reg:SI SP_REG)
11780 (match_operand:SI 4 "immediate_operand")))])]
11781 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11782 && peep2_reg_dead_p (3, operands[0])"
11783 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11784 (parallel [(set (match_dup 2)
11785 (call (mem:QI (match_dup 1))
11787 (set (reg:SI SP_REG)
11788 (plus:SI (reg:SI SP_REG)
11790 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11792 ;; Call subroutine returning any type.
11794 (define_expand "untyped_call"
11795 [(parallel [(call (match_operand 0)
11798 (match_operand 2)])]
11803 /* In order to give reg-stack an easier job in validating two
11804 coprocessor registers as containing a possible return value,
11805 simply pretend the untyped call returns a complex long double
11808 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11809 and should have the default ABI. */
11811 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11812 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11813 operands[0], const0_rtx,
11814 GEN_INT ((TARGET_64BIT
11815 ? (ix86_abi == SYSV_ABI
11816 ? X86_64_SSE_REGPARM_MAX
11817 : X86_64_MS_SSE_REGPARM_MAX)
11818 : X86_32_SSE_REGPARM_MAX)
11822 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11824 rtx set = XVECEXP (operands[2], 0, i);
11825 emit_move_insn (SET_DEST (set), SET_SRC (set));
11828 /* The optimizer does not know that the call sets the function value
11829 registers we stored in the result block. We avoid problems by
11830 claiming that all hard registers are used and clobbered at this
11832 emit_insn (gen_blockage ());
11837 ;; Prologue and epilogue instructions
11839 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11840 ;; all of memory. This blocks insns from being moved across this point.
11842 (define_insn "blockage"
11843 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11846 [(set_attr "length" "0")])
11848 ;; Do not schedule instructions accessing memory across this point.
11850 (define_expand "memory_blockage"
11851 [(set (match_dup 0)
11852 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11855 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11856 MEM_VOLATILE_P (operands[0]) = 1;
11859 (define_insn "*memory_blockage"
11860 [(set (match_operand:BLK 0)
11861 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11864 [(set_attr "length" "0")])
11866 ;; As USE insns aren't meaningful after reload, this is used instead
11867 ;; to prevent deleting instructions setting registers for PIC code
11868 (define_insn "prologue_use"
11869 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11872 [(set_attr "length" "0")])
11874 ;; Insn emitted into the body of a function to return from a function.
11875 ;; This is only done if the function's epilogue is known to be simple.
11876 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11878 (define_expand "return"
11880 "ix86_can_use_return_insn_p ()"
11882 if (crtl->args.pops_args)
11884 rtx popc = GEN_INT (crtl->args.pops_args);
11885 emit_jump_insn (gen_simple_return_pop_internal (popc));
11890 ;; We need to disable this for TARGET_SEH, as otherwise
11891 ;; shrink-wrapped prologue gets enabled too. This might exceed
11892 ;; the maximum size of prologue in unwind information.
11894 (define_expand "simple_return"
11898 if (crtl->args.pops_args)
11900 rtx popc = GEN_INT (crtl->args.pops_args);
11901 emit_jump_insn (gen_simple_return_pop_internal (popc));
11906 (define_insn "simple_return_internal"
11910 [(set_attr "length_nobnd" "1")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "0")
11913 (set_attr "modrm" "0")])
11915 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11916 ;; instruction Athlon and K8 have.
11918 (define_insn "simple_return_internal_long"
11920 (unspec [(const_int 0)] UNSPEC_REP)]
11923 if (ix86_bnd_prefixed_insn_p (insn))
11926 return "rep%; ret";
11928 [(set_attr "length" "2")
11929 (set_attr "atom_unit" "jeu")
11930 (set_attr "length_immediate" "0")
11931 (set_attr "prefix_rep" "1")
11932 (set_attr "modrm" "0")])
11934 (define_insn "simple_return_pop_internal"
11936 (use (match_operand:SI 0 "const_int_operand"))]
11939 [(set_attr "length_nobnd" "3")
11940 (set_attr "atom_unit" "jeu")
11941 (set_attr "length_immediate" "2")
11942 (set_attr "modrm" "0")])
11944 (define_insn "simple_return_indirect_internal"
11946 (use (match_operand:SI 0 "register_operand" "r"))]
11949 [(set_attr "type" "ibr")
11950 (set_attr "length_immediate" "0")])
11956 [(set_attr "length" "1")
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11960 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11961 (define_insn "nops"
11962 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11966 int num = INTVAL (operands[0]);
11968 gcc_assert (IN_RANGE (num, 1, 8));
11971 fputs ("\tnop\n", asm_out_file);
11975 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11976 (set_attr "length_immediate" "0")
11977 (set_attr "modrm" "0")])
11979 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11980 ;; branch prediction penalty for the third jump in a 16-byte
11984 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11987 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11988 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11990 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11991 The align insn is used to avoid 3 jump instructions in the row to improve
11992 branch prediction and the benefits hardly outweigh the cost of extra 8
11993 nops on the average inserted by full alignment pseudo operation. */
11997 [(set_attr "length" "16")])
11999 (define_expand "prologue"
12002 "ix86_expand_prologue (); DONE;")
12004 (define_insn "set_got"
12005 [(set (match_operand:SI 0 "register_operand" "=r")
12006 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12007 (clobber (reg:CC FLAGS_REG))]
12009 "* return output_set_got (operands[0], NULL_RTX);"
12010 [(set_attr "type" "multi")
12011 (set_attr "length" "12")])
12013 (define_insn "set_got_labelled"
12014 [(set (match_operand:SI 0 "register_operand" "=r")
12015 (unspec:SI [(label_ref (match_operand 1))]
12017 (clobber (reg:CC FLAGS_REG))]
12019 "* return output_set_got (operands[0], operands[1]);"
12020 [(set_attr "type" "multi")
12021 (set_attr "length" "12")])
12023 (define_insn "set_got_rex64"
12024 [(set (match_operand:DI 0 "register_operand" "=r")
12025 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12027 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12028 [(set_attr "type" "lea")
12029 (set_attr "length_address" "4")
12030 (set_attr "mode" "DI")])
12032 (define_insn "set_rip_rex64"
12033 [(set (match_operand:DI 0 "register_operand" "=r")
12034 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12036 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12037 [(set_attr "type" "lea")
12038 (set_attr "length_address" "4")
12039 (set_attr "mode" "DI")])
12041 (define_insn "set_got_offset_rex64"
12042 [(set (match_operand:DI 0 "register_operand" "=r")
12044 [(label_ref (match_operand 1))]
12045 UNSPEC_SET_GOT_OFFSET))]
12047 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12048 [(set_attr "type" "imov")
12049 (set_attr "length_immediate" "0")
12050 (set_attr "length_address" "8")
12051 (set_attr "mode" "DI")])
12053 (define_expand "epilogue"
12056 "ix86_expand_epilogue (1); DONE;")
12058 (define_expand "sibcall_epilogue"
12061 "ix86_expand_epilogue (0); DONE;")
12063 (define_expand "eh_return"
12064 [(use (match_operand 0 "register_operand"))]
12067 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12069 /* Tricky bit: we write the address of the handler to which we will
12070 be returning into someone else's stack frame, one word below the
12071 stack address we wish to restore. */
12072 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12073 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12074 tmp = gen_rtx_MEM (Pmode, tmp);
12075 emit_move_insn (tmp, ra);
12077 emit_jump_insn (gen_eh_return_internal ());
12082 (define_insn_and_split "eh_return_internal"
12086 "epilogue_completed"
12088 "ix86_expand_epilogue (2); DONE;")
12090 (define_insn "leave"
12091 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12092 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12093 (clobber (mem:BLK (scratch)))]
12096 [(set_attr "type" "leave")])
12098 (define_insn "leave_rex64"
12099 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12100 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12101 (clobber (mem:BLK (scratch)))]
12104 [(set_attr "type" "leave")])
12106 ;; Handle -fsplit-stack.
12108 (define_expand "split_stack_prologue"
12112 ix86_expand_split_stack_prologue ();
12116 ;; In order to support the call/return predictor, we use a return
12117 ;; instruction which the middle-end doesn't see.
12118 (define_insn "split_stack_return"
12119 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12120 UNSPECV_SPLIT_STACK_RETURN)]
12123 if (operands[0] == const0_rtx)
12128 [(set_attr "atom_unit" "jeu")
12129 (set_attr "modrm" "0")
12130 (set (attr "length")
12131 (if_then_else (match_operand:SI 0 "const0_operand")
12134 (set (attr "length_immediate")
12135 (if_then_else (match_operand:SI 0 "const0_operand")
12139 ;; If there are operand 0 bytes available on the stack, jump to
12142 (define_expand "split_stack_space_check"
12143 [(set (pc) (if_then_else
12144 (ltu (minus (reg SP_REG)
12145 (match_operand 0 "register_operand"))
12146 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12147 (label_ref (match_operand 1))
12151 rtx reg, size, limit;
12153 reg = gen_reg_rtx (Pmode);
12154 size = force_reg (Pmode, operands[0]);
12155 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12156 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12157 UNSPEC_STACK_CHECK);
12158 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12159 ix86_expand_branch (GEU, reg, limit, operands[1]);
12164 ;; Bit manipulation instructions.
12166 (define_expand "ffs<mode>2"
12167 [(set (match_dup 2) (const_int -1))
12168 (parallel [(set (match_dup 3) (match_dup 4))
12169 (set (match_operand:SWI48 0 "register_operand")
12171 (match_operand:SWI48 1 "nonimmediate_operand")))])
12172 (set (match_dup 0) (if_then_else:SWI48
12173 (eq (match_dup 3) (const_int 0))
12176 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12177 (clobber (reg:CC FLAGS_REG))])]
12180 machine_mode flags_mode;
12182 if (<MODE>mode == SImode && !TARGET_CMOVE)
12184 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12189 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12191 operands[2] = gen_reg_rtx (<MODE>mode);
12192 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12193 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12196 (define_insn_and_split "ffssi2_no_cmove"
12197 [(set (match_operand:SI 0 "register_operand" "=r")
12198 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12199 (clobber (match_scratch:SI 2 "=&q"))
12200 (clobber (reg:CC FLAGS_REG))]
12203 "&& reload_completed"
12204 [(parallel [(set (match_dup 4) (match_dup 5))
12205 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12206 (set (strict_low_part (match_dup 3))
12207 (eq:QI (match_dup 4) (const_int 0)))
12208 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12209 (clobber (reg:CC FLAGS_REG))])
12210 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12211 (clobber (reg:CC FLAGS_REG))])
12212 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12213 (clobber (reg:CC FLAGS_REG))])]
12215 machine_mode flags_mode
12216 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12218 operands[3] = gen_lowpart (QImode, operands[2]);
12219 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12220 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12222 ix86_expand_clear (operands[2]);
12225 (define_insn "*tzcnt<mode>_1"
12226 [(set (reg:CCC FLAGS_REG)
12227 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229 (set (match_operand:SWI48 0 "register_operand" "=r")
12230 (ctz:SWI48 (match_dup 1)))]
12231 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12232 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "alu1")
12234 (set_attr "prefix_0f" "1")
12235 (set_attr "prefix_rep" "1")
12236 (set_attr "btver2_decode" "double")
12237 (set_attr "mode" "<MODE>")])
12239 (define_insn "*bsf<mode>_1"
12240 [(set (reg:CCZ FLAGS_REG)
12241 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12243 (set (match_operand:SWI48 0 "register_operand" "=r")
12244 (ctz:SWI48 (match_dup 1)))]
12246 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "alu1")
12248 (set_attr "prefix_0f" "1")
12249 (set_attr "btver2_decode" "double")
12250 (set_attr "mode" "<MODE>")])
12252 (define_expand "ctz<mode>2"
12254 [(set (match_operand:SWI248 0 "register_operand")
12256 (match_operand:SWI248 1 "nonimmediate_operand")))
12257 (clobber (reg:CC FLAGS_REG))])])
12259 ; False dependency happens when destination is only updated by tzcnt,
12260 ; lzcnt or popcnt. There is no false dependency when destination is
12261 ; also used in source.
12262 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12263 [(set (match_operand:SWI48 0 "register_operand" "=r")
12265 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "(TARGET_BMI || TARGET_GENERIC)
12268 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12270 "&& reload_completed"
12272 [(set (match_dup 0)
12273 (ctz:SWI48 (match_dup 1)))
12274 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12275 (clobber (reg:CC FLAGS_REG))])]
12277 if (!reg_mentioned_p (operands[0], operands[1]))
12278 ix86_expand_clear (operands[0]);
12281 (define_insn "*ctz<mode>2_falsedep"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12285 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12286 UNSPEC_INSN_FALSE_DEP)
12287 (clobber (reg:CC FLAGS_REG))]
12291 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12292 else if (TARGET_GENERIC)
12293 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12294 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12296 gcc_unreachable ();
12298 [(set_attr "type" "alu1")
12299 (set_attr "prefix_0f" "1")
12300 (set_attr "prefix_rep" "1")
12301 (set_attr "mode" "<MODE>")])
12303 (define_insn "*ctz<mode>2"
12304 [(set (match_operand:SWI248 0 "register_operand" "=r")
12305 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12306 (clobber (reg:CC FLAGS_REG))]
12310 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12311 else if (optimize_function_for_size_p (cfun))
12313 else if (TARGET_GENERIC)
12314 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12315 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12317 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12319 [(set_attr "type" "alu1")
12320 (set_attr "prefix_0f" "1")
12321 (set (attr "prefix_rep")
12323 (ior (match_test "TARGET_BMI")
12324 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12325 (match_test "TARGET_GENERIC")))
12327 (const_string "0")))
12328 (set_attr "mode" "<MODE>")])
12330 (define_expand "clz<mode>2"
12332 [(set (match_operand:SWI248 0 "register_operand")
12335 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12336 (clobber (reg:CC FLAGS_REG))])
12338 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12339 (clobber (reg:CC FLAGS_REG))])]
12344 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12347 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12350 (define_expand "clz<mode>2_lzcnt"
12352 [(set (match_operand:SWI248 0 "register_operand")
12354 (match_operand:SWI248 1 "nonimmediate_operand")))
12355 (clobber (reg:CC FLAGS_REG))])]
12358 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12361 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12362 (clobber (reg:CC FLAGS_REG))]
12364 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12366 "&& reload_completed"
12368 [(set (match_dup 0)
12369 (clz:SWI48 (match_dup 1)))
12370 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12371 (clobber (reg:CC FLAGS_REG))])]
12373 if (!reg_mentioned_p (operands[0], operands[1]))
12374 ix86_expand_clear (operands[0]);
12377 (define_insn "*clz<mode>2_lzcnt_falsedep"
12378 [(set (match_operand:SWI48 0 "register_operand" "=r")
12380 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12381 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12382 UNSPEC_INSN_FALSE_DEP)
12383 (clobber (reg:CC FLAGS_REG))]
12385 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12386 [(set_attr "prefix_rep" "1")
12387 (set_attr "type" "bitmanip")
12388 (set_attr "mode" "<MODE>")])
12390 (define_insn "*clz<mode>2_lzcnt"
12391 [(set (match_operand:SWI248 0 "register_operand" "=r")
12392 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12393 (clobber (reg:CC FLAGS_REG))]
12395 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12396 [(set_attr "prefix_rep" "1")
12397 (set_attr "type" "bitmanip")
12398 (set_attr "mode" "<MODE>")])
12400 ;; BMI instructions.
12401 (define_insn "*bmi_andn_<mode>"
12402 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12405 (match_operand:SWI48 1 "register_operand" "r,r"))
12406 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12407 (clobber (reg:CC FLAGS_REG))]
12409 "andn\t{%2, %1, %0|%0, %1, %2}"
12410 [(set_attr "type" "bitmanip")
12411 (set_attr "btver2_decode" "direct, double")
12412 (set_attr "mode" "<MODE>")])
12414 (define_insn "bmi_bextr_<mode>"
12415 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12416 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12417 (match_operand:SWI48 2 "register_operand" "r,r")]
12419 (clobber (reg:CC FLAGS_REG))]
12421 "bextr\t{%2, %1, %0|%0, %1, %2}"
12422 [(set_attr "type" "bitmanip")
12423 (set_attr "btver2_decode" "direct, double")
12424 (set_attr "mode" "<MODE>")])
12426 (define_insn "*bmi_blsi_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12430 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12432 (clobber (reg:CC FLAGS_REG))]
12434 "blsi\t{%1, %0|%0, %1}"
12435 [(set_attr "type" "bitmanip")
12436 (set_attr "btver2_decode" "double")
12437 (set_attr "mode" "<MODE>")])
12439 (define_insn "*bmi_blsmsk_<mode>"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12443 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12446 (clobber (reg:CC FLAGS_REG))]
12448 "blsmsk\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "bitmanip")
12450 (set_attr "btver2_decode" "double")
12451 (set_attr "mode" "<MODE>")])
12453 (define_insn "*bmi_blsr_<mode>"
12454 [(set (match_operand:SWI48 0 "register_operand" "=r")
12457 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12460 (clobber (reg:CC FLAGS_REG))]
12462 "blsr\t{%1, %0|%0, %1}"
12463 [(set_attr "type" "bitmanip")
12464 (set_attr "btver2_decode" "double")
12465 (set_attr "mode" "<MODE>")])
12467 ;; BMI2 instructions.
12468 (define_insn "bmi2_bzhi_<mode>3"
12469 [(set (match_operand:SWI48 0 "register_operand" "=r")
12470 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12471 (match_operand:SWI48 2 "register_operand" "r"))
12472 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12473 (clobber (reg:CC FLAGS_REG))]
12475 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12476 [(set_attr "type" "bitmanip")
12477 (set_attr "prefix" "vex")
12478 (set_attr "mode" "<MODE>")])
12480 (define_insn "bmi2_pdep_<mode>3"
12481 [(set (match_operand:SWI48 0 "register_operand" "=r")
12482 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12483 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12486 "pdep\t{%2, %1, %0|%0, %1, %2}"
12487 [(set_attr "type" "bitmanip")
12488 (set_attr "prefix" "vex")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "bmi2_pext_<mode>3"
12492 [(set (match_operand:SWI48 0 "register_operand" "=r")
12493 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12494 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12497 "pext\t{%2, %1, %0|%0, %1, %2}"
12498 [(set_attr "type" "bitmanip")
12499 (set_attr "prefix" "vex")
12500 (set_attr "mode" "<MODE>")])
12502 ;; TBM instructions.
12503 (define_insn "tbm_bextri_<mode>"
12504 [(set (match_operand:SWI48 0 "register_operand" "=r")
12505 (zero_extract:SWI48
12506 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12507 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12508 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12509 (clobber (reg:CC FLAGS_REG))]
12512 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12513 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12515 [(set_attr "type" "bitmanip")
12516 (set_attr "mode" "<MODE>")])
12518 (define_insn "*tbm_blcfill_<mode>"
12519 [(set (match_operand:SWI48 0 "register_operand" "=r")
12522 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12525 (clobber (reg:CC FLAGS_REG))]
12527 "blcfill\t{%1, %0|%0, %1}"
12528 [(set_attr "type" "bitmanip")
12529 (set_attr "mode" "<MODE>")])
12531 (define_insn "*tbm_blci_<mode>"
12532 [(set (match_operand:SWI48 0 "register_operand" "=r")
12536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12539 (clobber (reg:CC FLAGS_REG))]
12541 "blci\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "bitmanip")
12543 (set_attr "mode" "<MODE>")])
12545 (define_insn "*tbm_blcic_<mode>"
12546 [(set (match_operand:SWI48 0 "register_operand" "=r")
12549 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12553 (clobber (reg:CC FLAGS_REG))]
12555 "blcic\t{%1, %0|%0, %1}"
12556 [(set_attr "type" "bitmanip")
12557 (set_attr "mode" "<MODE>")])
12559 (define_insn "*tbm_blcmsk_<mode>"
12560 [(set (match_operand:SWI48 0 "register_operand" "=r")
12563 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12566 (clobber (reg:CC FLAGS_REG))]
12568 "blcmsk\t{%1, %0|%0, %1}"
12569 [(set_attr "type" "bitmanip")
12570 (set_attr "mode" "<MODE>")])
12572 (define_insn "*tbm_blcs_<mode>"
12573 [(set (match_operand:SWI48 0 "register_operand" "=r")
12576 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12579 (clobber (reg:CC FLAGS_REG))]
12581 "blcs\t{%1, %0|%0, %1}"
12582 [(set_attr "type" "bitmanip")
12583 (set_attr "mode" "<MODE>")])
12585 (define_insn "*tbm_blsfill_<mode>"
12586 [(set (match_operand:SWI48 0 "register_operand" "=r")
12589 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12592 (clobber (reg:CC FLAGS_REG))]
12594 "blsfill\t{%1, %0|%0, %1}"
12595 [(set_attr "type" "bitmanip")
12596 (set_attr "mode" "<MODE>")])
12598 (define_insn "*tbm_blsic_<mode>"
12599 [(set (match_operand:SWI48 0 "register_operand" "=r")
12602 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12606 (clobber (reg:CC FLAGS_REG))]
12608 "blsic\t{%1, %0|%0, %1}"
12609 [(set_attr "type" "bitmanip")
12610 (set_attr "mode" "<MODE>")])
12612 (define_insn "*tbm_t1mskc_<mode>"
12613 [(set (match_operand:SWI48 0 "register_operand" "=r")
12616 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12620 (clobber (reg:CC FLAGS_REG))]
12622 "t1mskc\t{%1, %0|%0, %1}"
12623 [(set_attr "type" "bitmanip")
12624 (set_attr "mode" "<MODE>")])
12626 (define_insn "*tbm_tzmsk_<mode>"
12627 [(set (match_operand:SWI48 0 "register_operand" "=r")
12630 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12634 (clobber (reg:CC FLAGS_REG))]
12636 "tzmsk\t{%1, %0|%0, %1}"
12637 [(set_attr "type" "bitmanip")
12638 (set_attr "mode" "<MODE>")])
12640 (define_insn "bsr_rex64"
12641 [(set (match_operand:DI 0 "register_operand" "=r")
12642 (minus:DI (const_int 63)
12643 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12644 (clobber (reg:CC FLAGS_REG))]
12646 "bsr{q}\t{%1, %0|%0, %1}"
12647 [(set_attr "type" "alu1")
12648 (set_attr "prefix_0f" "1")
12649 (set_attr "mode" "DI")])
12652 [(set (match_operand:SI 0 "register_operand" "=r")
12653 (minus:SI (const_int 31)
12654 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12655 (clobber (reg:CC FLAGS_REG))]
12657 "bsr{l}\t{%1, %0|%0, %1}"
12658 [(set_attr "type" "alu1")
12659 (set_attr "prefix_0f" "1")
12660 (set_attr "mode" "SI")])
12662 (define_insn "*bsrhi"
12663 [(set (match_operand:HI 0 "register_operand" "=r")
12664 (minus:HI (const_int 15)
12665 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12666 (clobber (reg:CC FLAGS_REG))]
12668 "bsr{w}\t{%1, %0|%0, %1}"
12669 [(set_attr "type" "alu1")
12670 (set_attr "prefix_0f" "1")
12671 (set_attr "mode" "HI")])
12673 (define_expand "popcount<mode>2"
12675 [(set (match_operand:SWI248 0 "register_operand")
12677 (match_operand:SWI248 1 "nonimmediate_operand")))
12678 (clobber (reg:CC FLAGS_REG))])]
12681 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12682 [(set (match_operand:SWI48 0 "register_operand" "=r")
12684 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12685 (clobber (reg:CC FLAGS_REG))]
12687 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12689 "&& reload_completed"
12691 [(set (match_dup 0)
12692 (popcount:SWI48 (match_dup 1)))
12693 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12694 (clobber (reg:CC FLAGS_REG))])]
12696 if (!reg_mentioned_p (operands[0], operands[1]))
12697 ix86_expand_clear (operands[0]);
12700 (define_insn "*popcount<mode>2_falsedep"
12701 [(set (match_operand:SWI48 0 "register_operand" "=r")
12703 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12704 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12705 UNSPEC_INSN_FALSE_DEP)
12706 (clobber (reg:CC FLAGS_REG))]
12710 return "popcnt\t{%1, %0|%0, %1}";
12712 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12715 [(set_attr "prefix_rep" "1")
12716 (set_attr "type" "bitmanip")
12717 (set_attr "mode" "<MODE>")])
12719 (define_insn "*popcount<mode>2"
12720 [(set (match_operand:SWI248 0 "register_operand" "=r")
12722 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12723 (clobber (reg:CC FLAGS_REG))]
12727 return "popcnt\t{%1, %0|%0, %1}";
12729 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12732 [(set_attr "prefix_rep" "1")
12733 (set_attr "type" "bitmanip")
12734 (set_attr "mode" "<MODE>")])
12736 (define_expand "bswapdi2"
12737 [(set (match_operand:DI 0 "register_operand")
12738 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12742 operands[1] = force_reg (DImode, operands[1]);
12745 (define_expand "bswapsi2"
12746 [(set (match_operand:SI 0 "register_operand")
12747 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12752 else if (TARGET_BSWAP)
12753 operands[1] = force_reg (SImode, operands[1]);
12756 rtx x = operands[0];
12758 emit_move_insn (x, operands[1]);
12759 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12760 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12761 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12766 (define_insn "*bswap<mode>2_movbe"
12767 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12768 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12773 movbe\t{%1, %0|%0, %1}
12774 movbe\t{%1, %0|%0, %1}"
12775 [(set_attr "type" "bitmanip,imov,imov")
12776 (set_attr "modrm" "0,1,1")
12777 (set_attr "prefix_0f" "*,1,1")
12778 (set_attr "prefix_extra" "*,1,1")
12779 (set_attr "mode" "<MODE>")])
12781 (define_insn "*bswap<mode>2"
12782 [(set (match_operand:SWI48 0 "register_operand" "=r")
12783 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12786 [(set_attr "type" "bitmanip")
12787 (set_attr "modrm" "0")
12788 (set_attr "mode" "<MODE>")])
12790 (define_insn "*bswaphi_lowpart_1"
12791 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12792 (bswap:HI (match_dup 0)))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12796 xchg{b}\t{%h0, %b0|%b0, %h0}
12797 rol{w}\t{$8, %0|%0, 8}"
12798 [(set_attr "length" "2,4")
12799 (set_attr "mode" "QI,HI")])
12801 (define_insn "bswaphi_lowpart"
12802 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12803 (bswap:HI (match_dup 0)))
12804 (clobber (reg:CC FLAGS_REG))]
12806 "rol{w}\t{$8, %0|%0, 8}"
12807 [(set_attr "length" "4")
12808 (set_attr "mode" "HI")])
12810 (define_expand "paritydi2"
12811 [(set (match_operand:DI 0 "register_operand")
12812 (parity:DI (match_operand:DI 1 "register_operand")))]
12815 rtx scratch = gen_reg_rtx (QImode);
12818 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12819 NULL_RTX, operands[1]));
12821 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12822 gen_rtx_REG (CCmode, FLAGS_REG),
12824 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12827 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12830 rtx tmp = gen_reg_rtx (SImode);
12832 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12833 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12838 (define_expand "paritysi2"
12839 [(set (match_operand:SI 0 "register_operand")
12840 (parity:SI (match_operand:SI 1 "register_operand")))]
12843 rtx scratch = gen_reg_rtx (QImode);
12846 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12848 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12849 gen_rtx_REG (CCmode, FLAGS_REG),
12851 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12853 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12857 (define_insn_and_split "paritydi2_cmp"
12858 [(set (reg:CC FLAGS_REG)
12859 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12861 (clobber (match_scratch:DI 0 "=r"))
12862 (clobber (match_scratch:SI 1 "=&r"))
12863 (clobber (match_scratch:HI 2 "=Q"))]
12866 "&& reload_completed"
12868 [(set (match_dup 1)
12869 (xor:SI (match_dup 1) (match_dup 4)))
12870 (clobber (reg:CC FLAGS_REG))])
12872 [(set (reg:CC FLAGS_REG)
12873 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12874 (clobber (match_dup 1))
12875 (clobber (match_dup 2))])]
12877 operands[4] = gen_lowpart (SImode, operands[3]);
12881 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12882 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12885 operands[1] = gen_highpart (SImode, operands[3]);
12888 (define_insn_and_split "paritysi2_cmp"
12889 [(set (reg:CC FLAGS_REG)
12890 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12892 (clobber (match_scratch:SI 0 "=r"))
12893 (clobber (match_scratch:HI 1 "=&Q"))]
12896 "&& reload_completed"
12898 [(set (match_dup 1)
12899 (xor:HI (match_dup 1) (match_dup 3)))
12900 (clobber (reg:CC FLAGS_REG))])
12902 [(set (reg:CC FLAGS_REG)
12903 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12904 (clobber (match_dup 1))])]
12906 operands[3] = gen_lowpart (HImode, operands[2]);
12908 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12909 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12912 (define_insn "*parityhi2_cmp"
12913 [(set (reg:CC FLAGS_REG)
12914 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12916 (clobber (match_scratch:HI 0 "=Q"))]
12918 "xor{b}\t{%h0, %b0|%b0, %h0}"
12919 [(set_attr "length" "2")
12920 (set_attr "mode" "HI")])
12923 ;; Thread-local storage patterns for ELF.
12925 ;; Note that these code sequences must appear exactly as shown
12926 ;; in order to allow linker relaxation.
12928 (define_insn "*tls_global_dynamic_32_gnu"
12929 [(set (match_operand:SI 0 "register_operand" "=a")
12931 [(match_operand:SI 1 "register_operand" "b")
12932 (match_operand 2 "tls_symbolic_operand")
12933 (match_operand 3 "constant_call_address_operand" "Bz")
12936 (clobber (match_scratch:SI 4 "=d"))
12937 (clobber (match_scratch:SI 5 "=c"))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "!TARGET_64BIT && TARGET_GNU_TLS"
12942 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12943 if (TARGET_SUN_TLS)
12944 #ifdef HAVE_AS_IX86_TLSGDPLT
12945 return "call\t%a2@tlsgdplt";
12947 return "call\t%p3@plt";
12949 return "call\t%P3";
12951 [(set_attr "type" "multi")
12952 (set_attr "length" "12")])
12954 (define_expand "tls_global_dynamic_32"
12956 [(set (match_operand:SI 0 "register_operand")
12957 (unspec:SI [(match_operand:SI 2 "register_operand")
12958 (match_operand 1 "tls_symbolic_operand")
12959 (match_operand 3 "constant_call_address_operand")
12962 (clobber (match_scratch:SI 4))
12963 (clobber (match_scratch:SI 5))
12964 (clobber (reg:CC FLAGS_REG))])]
12966 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12968 (define_insn "*tls_global_dynamic_64_<mode>"
12969 [(set (match_operand:P 0 "register_operand" "=a")
12971 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12972 (match_operand 3)))
12973 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12978 fputs (ASM_BYTE "0x66\n", asm_out_file);
12980 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12981 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12982 fputs ("\trex64\n", asm_out_file);
12983 if (TARGET_SUN_TLS)
12984 return "call\t%p2@plt";
12985 return "call\t%P2";
12987 [(set_attr "type" "multi")
12988 (set (attr "length")
12989 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12991 (define_insn "*tls_global_dynamic_64_largepic"
12992 [(set (match_operand:DI 0 "register_operand" "=a")
12994 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12995 (match_operand:DI 3 "immediate_operand" "i")))
12996 (match_operand 4)))
12997 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12999 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13000 && GET_CODE (operands[3]) == CONST
13001 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13002 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13005 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13006 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13007 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13008 return "call\t{*%%rax|rax}";
13010 [(set_attr "type" "multi")
13011 (set_attr "length" "22")])
13013 (define_expand "tls_global_dynamic_64_<mode>"
13015 [(set (match_operand:P 0 "register_operand")
13017 (mem:QI (match_operand 2))
13019 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13022 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13024 (define_insn "*tls_local_dynamic_base_32_gnu"
13025 [(set (match_operand:SI 0 "register_operand" "=a")
13027 [(match_operand:SI 1 "register_operand" "b")
13028 (match_operand 2 "constant_call_address_operand" "Bz")
13030 UNSPEC_TLS_LD_BASE))
13031 (clobber (match_scratch:SI 3 "=d"))
13032 (clobber (match_scratch:SI 4 "=c"))
13033 (clobber (reg:CC FLAGS_REG))]
13034 "!TARGET_64BIT && TARGET_GNU_TLS"
13037 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13038 if (TARGET_SUN_TLS)
13040 if (HAVE_AS_IX86_TLSLDMPLT)
13041 return "call\t%&@tlsldmplt";
13043 return "call\t%p2@plt";
13045 return "call\t%P2";
13047 [(set_attr "type" "multi")
13048 (set_attr "length" "11")])
13050 (define_expand "tls_local_dynamic_base_32"
13052 [(set (match_operand:SI 0 "register_operand")
13054 [(match_operand:SI 1 "register_operand")
13055 (match_operand 2 "constant_call_address_operand")
13057 UNSPEC_TLS_LD_BASE))
13058 (clobber (match_scratch:SI 3))
13059 (clobber (match_scratch:SI 4))
13060 (clobber (reg:CC FLAGS_REG))])]
13062 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13064 (define_insn "*tls_local_dynamic_base_64_<mode>"
13065 [(set (match_operand:P 0 "register_operand" "=a")
13067 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13068 (match_operand 2)))
13069 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13073 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13074 if (TARGET_SUN_TLS)
13075 return "call\t%p1@plt";
13076 return "call\t%P1";
13078 [(set_attr "type" "multi")
13079 (set_attr "length" "12")])
13081 (define_insn "*tls_local_dynamic_base_64_largepic"
13082 [(set (match_operand:DI 0 "register_operand" "=a")
13084 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13085 (match_operand:DI 2 "immediate_operand" "i")))
13086 (match_operand 3)))
13087 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13088 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13089 && GET_CODE (operands[2]) == CONST
13090 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13091 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13094 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13095 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13096 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13097 return "call\t{*%%rax|rax}";
13099 [(set_attr "type" "multi")
13100 (set_attr "length" "22")])
13102 (define_expand "tls_local_dynamic_base_64_<mode>"
13104 [(set (match_operand:P 0 "register_operand")
13106 (mem:QI (match_operand 1))
13108 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13110 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13112 ;; Local dynamic of a single variable is a lose. Show combine how
13113 ;; to convert that back to global dynamic.
13115 (define_insn_and_split "*tls_local_dynamic_32_once"
13116 [(set (match_operand:SI 0 "register_operand" "=a")
13118 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13119 (match_operand 2 "constant_call_address_operand" "Bz")
13121 UNSPEC_TLS_LD_BASE)
13122 (const:SI (unspec:SI
13123 [(match_operand 3 "tls_symbolic_operand")]
13125 (clobber (match_scratch:SI 4 "=d"))
13126 (clobber (match_scratch:SI 5 "=c"))
13127 (clobber (reg:CC FLAGS_REG))]
13132 [(set (match_dup 0)
13133 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13136 (clobber (match_dup 4))
13137 (clobber (match_dup 5))
13138 (clobber (reg:CC FLAGS_REG))])])
13140 ;; Segment register for the thread base ptr load
13141 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13143 ;; Load and add the thread base pointer from %<tp_seg>:0.
13144 (define_insn "*load_tp_x32"
13145 [(set (match_operand:SI 0 "register_operand" "=r")
13146 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13148 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13149 [(set_attr "type" "imov")
13150 (set_attr "modrm" "0")
13151 (set_attr "length" "7")
13152 (set_attr "memory" "load")
13153 (set_attr "imm_disp" "false")])
13155 (define_insn "*load_tp_x32_zext"
13156 [(set (match_operand:DI 0 "register_operand" "=r")
13157 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13159 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13160 [(set_attr "type" "imov")
13161 (set_attr "modrm" "0")
13162 (set_attr "length" "7")
13163 (set_attr "memory" "load")
13164 (set_attr "imm_disp" "false")])
13166 (define_insn "*load_tp_<mode>"
13167 [(set (match_operand:P 0 "register_operand" "=r")
13168 (unspec:P [(const_int 0)] UNSPEC_TP))]
13170 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13171 [(set_attr "type" "imov")
13172 (set_attr "modrm" "0")
13173 (set_attr "length" "7")
13174 (set_attr "memory" "load")
13175 (set_attr "imm_disp" "false")])
13177 (define_insn "*add_tp_x32"
13178 [(set (match_operand:SI 0 "register_operand" "=r")
13179 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13180 (match_operand:SI 1 "register_operand" "0")))
13181 (clobber (reg:CC FLAGS_REG))]
13183 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13184 [(set_attr "type" "alu")
13185 (set_attr "modrm" "0")
13186 (set_attr "length" "7")
13187 (set_attr "memory" "load")
13188 (set_attr "imm_disp" "false")])
13190 (define_insn "*add_tp_x32_zext"
13191 [(set (match_operand:DI 0 "register_operand" "=r")
13193 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13194 (match_operand:SI 1 "register_operand" "0"))))
13195 (clobber (reg:CC FLAGS_REG))]
13197 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13198 [(set_attr "type" "alu")
13199 (set_attr "modrm" "0")
13200 (set_attr "length" "7")
13201 (set_attr "memory" "load")
13202 (set_attr "imm_disp" "false")])
13204 (define_insn "*add_tp_<mode>"
13205 [(set (match_operand:P 0 "register_operand" "=r")
13206 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13207 (match_operand:P 1 "register_operand" "0")))
13208 (clobber (reg:CC FLAGS_REG))]
13210 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13211 [(set_attr "type" "alu")
13212 (set_attr "modrm" "0")
13213 (set_attr "length" "7")
13214 (set_attr "memory" "load")
13215 (set_attr "imm_disp" "false")])
13217 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13218 ;; %rax as destination of the initial executable code sequence.
13219 (define_insn "tls_initial_exec_64_sun"
13220 [(set (match_operand:DI 0 "register_operand" "=a")
13222 [(match_operand 1 "tls_symbolic_operand")]
13223 UNSPEC_TLS_IE_SUN))
13224 (clobber (reg:CC FLAGS_REG))]
13225 "TARGET_64BIT && TARGET_SUN_TLS"
13228 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13229 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13231 [(set_attr "type" "multi")])
13233 ;; GNU2 TLS patterns can be split.
13235 (define_expand "tls_dynamic_gnu2_32"
13236 [(set (match_dup 3)
13237 (plus:SI (match_operand:SI 2 "register_operand")
13239 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13242 [(set (match_operand:SI 0 "register_operand")
13243 (unspec:SI [(match_dup 1) (match_dup 3)
13244 (match_dup 2) (reg:SI SP_REG)]
13246 (clobber (reg:CC FLAGS_REG))])]
13247 "!TARGET_64BIT && TARGET_GNU2_TLS"
13249 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13250 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13253 (define_insn "*tls_dynamic_gnu2_lea_32"
13254 [(set (match_operand:SI 0 "register_operand" "=r")
13255 (plus:SI (match_operand:SI 1 "register_operand" "b")
13257 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13258 UNSPEC_TLSDESC))))]
13259 "!TARGET_64BIT && TARGET_GNU2_TLS"
13260 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13261 [(set_attr "type" "lea")
13262 (set_attr "mode" "SI")
13263 (set_attr "length" "6")
13264 (set_attr "length_address" "4")])
13266 (define_insn "*tls_dynamic_gnu2_call_32"
13267 [(set (match_operand:SI 0 "register_operand" "=a")
13268 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13269 (match_operand:SI 2 "register_operand" "0")
13270 ;; we have to make sure %ebx still points to the GOT
13271 (match_operand:SI 3 "register_operand" "b")
13274 (clobber (reg:CC FLAGS_REG))]
13275 "!TARGET_64BIT && TARGET_GNU2_TLS"
13276 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13277 [(set_attr "type" "call")
13278 (set_attr "length" "2")
13279 (set_attr "length_address" "0")])
13281 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13282 [(set (match_operand:SI 0 "register_operand" "=&a")
13284 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13285 (match_operand:SI 4)
13286 (match_operand:SI 2 "register_operand" "b")
13289 (const:SI (unspec:SI
13290 [(match_operand 1 "tls_symbolic_operand")]
13292 (clobber (reg:CC FLAGS_REG))]
13293 "!TARGET_64BIT && TARGET_GNU2_TLS"
13296 [(set (match_dup 0) (match_dup 5))]
13298 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13299 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13302 (define_expand "tls_dynamic_gnu2_64"
13303 [(set (match_dup 2)
13304 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13307 [(set (match_operand:DI 0 "register_operand")
13308 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13310 (clobber (reg:CC FLAGS_REG))])]
13311 "TARGET_64BIT && TARGET_GNU2_TLS"
13313 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13314 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13317 (define_insn "*tls_dynamic_gnu2_lea_64"
13318 [(set (match_operand:DI 0 "register_operand" "=r")
13319 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13321 "TARGET_64BIT && TARGET_GNU2_TLS"
13322 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13323 [(set_attr "type" "lea")
13324 (set_attr "mode" "DI")
13325 (set_attr "length" "7")
13326 (set_attr "length_address" "4")])
13328 (define_insn "*tls_dynamic_gnu2_call_64"
13329 [(set (match_operand:DI 0 "register_operand" "=a")
13330 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13331 (match_operand:DI 2 "register_operand" "0")
13334 (clobber (reg:CC FLAGS_REG))]
13335 "TARGET_64BIT && TARGET_GNU2_TLS"
13336 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13337 [(set_attr "type" "call")
13338 (set_attr "length" "2")
13339 (set_attr "length_address" "0")])
13341 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13342 [(set (match_operand:DI 0 "register_operand" "=&a")
13344 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13345 (match_operand:DI 3)
13348 (const:DI (unspec:DI
13349 [(match_operand 1 "tls_symbolic_operand")]
13351 (clobber (reg:CC FLAGS_REG))]
13352 "TARGET_64BIT && TARGET_GNU2_TLS"
13355 [(set (match_dup 0) (match_dup 4))]
13357 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13358 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13361 ;; These patterns match the binary 387 instructions for addM3, subM3,
13362 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13363 ;; SFmode. The first is the normal insn, the second the same insn but
13364 ;; with one operand a conversion, and the third the same insn but with
13365 ;; the other operand a conversion. The conversion may be SFmode or
13366 ;; SImode if the target mode DFmode, but only SImode if the target mode
13369 ;; Gcc is slightly more smart about handling normal two address instructions
13370 ;; so use special patterns for add and mull.
13372 (define_insn "*fop_<mode>_comm_mixed"
13373 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13374 (match_operator:MODEF 3 "binary_fp_operator"
13375 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13376 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13378 && COMMUTATIVE_ARITH_P (operands[3])
13379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13380 "* return output_387_binary_op (insn, operands);"
13381 [(set (attr "type")
13382 (if_then_else (eq_attr "alternative" "1,2")
13383 (if_then_else (match_operand:MODEF 3 "mult_operator")
13384 (const_string "ssemul")
13385 (const_string "sseadd"))
13386 (if_then_else (match_operand:MODEF 3 "mult_operator")
13387 (const_string "fmul")
13388 (const_string "fop"))))
13389 (set_attr "isa" "*,noavx,avx")
13390 (set_attr "prefix" "orig,orig,vex")
13391 (set_attr "mode" "<MODE>")])
13393 (define_insn "*fop_<mode>_comm_sse"
13394 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13395 (match_operator:MODEF 3 "binary_fp_operator"
13396 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13397 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13398 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13399 && COMMUTATIVE_ARITH_P (operands[3])
13400 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13401 "* return output_387_binary_op (insn, operands);"
13402 [(set (attr "type")
13403 (if_then_else (match_operand:MODEF 3 "mult_operator")
13404 (const_string "ssemul")
13405 (const_string "sseadd")))
13406 (set_attr "isa" "noavx,avx")
13407 (set_attr "prefix" "orig,vex")
13408 (set_attr "mode" "<MODE>")])
13410 (define_insn "*fop_<mode>_comm_i387"
13411 [(set (match_operand:MODEF 0 "register_operand" "=f")
13412 (match_operator:MODEF 3 "binary_fp_operator"
13413 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13414 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13415 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13416 && COMMUTATIVE_ARITH_P (operands[3])
13417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13418 "* return output_387_binary_op (insn, operands);"
13419 [(set (attr "type")
13420 (if_then_else (match_operand:MODEF 3 "mult_operator")
13421 (const_string "fmul")
13422 (const_string "fop")))
13423 (set_attr "mode" "<MODE>")])
13425 (define_insn "*fop_<mode>_1_mixed"
13426 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13427 (match_operator:MODEF 3 "binary_fp_operator"
13428 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13429 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13430 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13431 && !COMMUTATIVE_ARITH_P (operands[3])
13432 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13433 "* return output_387_binary_op (insn, operands);"
13434 [(set (attr "type")
13435 (cond [(and (eq_attr "alternative" "2,3")
13436 (match_operand:MODEF 3 "mult_operator"))
13437 (const_string "ssemul")
13438 (and (eq_attr "alternative" "2,3")
13439 (match_operand:MODEF 3 "div_operator"))
13440 (const_string "ssediv")
13441 (eq_attr "alternative" "2,3")
13442 (const_string "sseadd")
13443 (match_operand:MODEF 3 "mult_operator")
13444 (const_string "fmul")
13445 (match_operand:MODEF 3 "div_operator")
13446 (const_string "fdiv")
13448 (const_string "fop")))
13449 (set_attr "isa" "*,*,noavx,avx")
13450 (set_attr "prefix" "orig,orig,orig,vex")
13451 (set_attr "mode" "<MODE>")])
13453 (define_insn "*rcpsf2_sse"
13454 [(set (match_operand:SF 0 "register_operand" "=x")
13455 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13458 "%vrcpss\t{%1, %d0|%d0, %1}"
13459 [(set_attr "type" "sse")
13460 (set_attr "atom_sse_attr" "rcp")
13461 (set_attr "btver2_sse_attr" "rcp")
13462 (set_attr "prefix" "maybe_vex")
13463 (set_attr "mode" "SF")])
13465 (define_insn "*fop_<mode>_1_sse"
13466 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13467 (match_operator:MODEF 3 "binary_fp_operator"
13468 [(match_operand:MODEF 1 "register_operand" "0,x")
13469 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13470 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13471 && !COMMUTATIVE_ARITH_P (operands[3])"
13472 "* return output_387_binary_op (insn, operands);"
13473 [(set (attr "type")
13474 (cond [(match_operand:MODEF 3 "mult_operator")
13475 (const_string "ssemul")
13476 (match_operand:MODEF 3 "div_operator")
13477 (const_string "ssediv")
13479 (const_string "sseadd")))
13480 (set_attr "isa" "noavx,avx")
13481 (set_attr "prefix" "orig,vex")
13482 (set_attr "mode" "<MODE>")])
13484 ;; This pattern is not fully shadowed by the pattern above.
13485 (define_insn "*fop_<mode>_1_i387"
13486 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13487 (match_operator:MODEF 3 "binary_fp_operator"
13488 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13489 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13490 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13491 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13492 && !COMMUTATIVE_ARITH_P (operands[3])
13493 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13494 "* return output_387_binary_op (insn, operands);"
13495 [(set (attr "type")
13496 (cond [(match_operand:MODEF 3 "mult_operator")
13497 (const_string "fmul")
13498 (match_operand:MODEF 3 "div_operator")
13499 (const_string "fdiv")
13501 (const_string "fop")))
13502 (set_attr "mode" "<MODE>")])
13504 ;; ??? Add SSE splitters for these!
13505 (define_insn "*fop_<MODEF:mode>_2_i387"
13506 [(set (match_operand:MODEF 0 "register_operand" "=f")
13507 (match_operator:MODEF 3 "binary_fp_operator"
13509 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13510 (match_operand:MODEF 2 "register_operand" "0")]))]
13511 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13512 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13513 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13514 || optimize_function_for_size_p (cfun))"
13515 { return output_387_binary_op (insn, operands); }
13516 [(set (attr "type")
13517 (cond [(match_operand:MODEF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:MODEF 3 "div_operator")
13520 (const_string "fdiv")
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<SWI24:MODE>")])
13526 (define_insn "*fop_<MODEF:mode>_3_i387"
13527 [(set (match_operand:MODEF 0 "register_operand" "=f")
13528 (match_operator:MODEF 3 "binary_fp_operator"
13529 [(match_operand:MODEF 1 "register_operand" "0")
13531 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13532 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13533 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13534 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13535 || optimize_function_for_size_p (cfun))"
13536 { return output_387_binary_op (insn, operands); }
13537 [(set (attr "type")
13538 (cond [(match_operand:MODEF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:MODEF 3 "div_operator")
13541 (const_string "fdiv")
13543 (const_string "fop")))
13544 (set_attr "fp_int_src" "true")
13545 (set_attr "mode" "<MODE>")])
13547 (define_insn "*fop_df_4_i387"
13548 [(set (match_operand:DF 0 "register_operand" "=f,f")
13549 (match_operator:DF 3 "binary_fp_operator"
13551 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13552 (match_operand:DF 2 "register_operand" "0,f")]))]
13553 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13554 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13556 "* return output_387_binary_op (insn, operands);"
13557 [(set (attr "type")
13558 (cond [(match_operand:DF 3 "mult_operator")
13559 (const_string "fmul")
13560 (match_operand:DF 3 "div_operator")
13561 (const_string "fdiv")
13563 (const_string "fop")))
13564 (set_attr "mode" "SF")])
13566 (define_insn "*fop_df_5_i387"
13567 [(set (match_operand:DF 0 "register_operand" "=f,f")
13568 (match_operator:DF 3 "binary_fp_operator"
13569 [(match_operand:DF 1 "register_operand" "0,f")
13571 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13572 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13573 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13574 "* return output_387_binary_op (insn, operands);"
13575 [(set (attr "type")
13576 (cond [(match_operand:DF 3 "mult_operator")
13577 (const_string "fmul")
13578 (match_operand:DF 3 "div_operator")
13579 (const_string "fdiv")
13581 (const_string "fop")))
13582 (set_attr "mode" "SF")])
13584 (define_insn "*fop_df_6_i387"
13585 [(set (match_operand:DF 0 "register_operand" "=f,f")
13586 (match_operator:DF 3 "binary_fp_operator"
13588 (match_operand:SF 1 "register_operand" "0,f"))
13590 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13591 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13592 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13593 "* return output_387_binary_op (insn, operands);"
13594 [(set (attr "type")
13595 (cond [(match_operand:DF 3 "mult_operator")
13596 (const_string "fmul")
13597 (match_operand:DF 3 "div_operator")
13598 (const_string "fdiv")
13600 (const_string "fop")))
13601 (set_attr "mode" "SF")])
13603 (define_insn "*fop_xf_comm_i387"
13604 [(set (match_operand:XF 0 "register_operand" "=f")
13605 (match_operator:XF 3 "binary_fp_operator"
13606 [(match_operand:XF 1 "register_operand" "%0")
13607 (match_operand:XF 2 "register_operand" "f")]))]
13609 && COMMUTATIVE_ARITH_P (operands[3])"
13610 "* return output_387_binary_op (insn, operands);"
13611 [(set (attr "type")
13612 (if_then_else (match_operand:XF 3 "mult_operator")
13613 (const_string "fmul")
13614 (const_string "fop")))
13615 (set_attr "mode" "XF")])
13617 (define_insn "*fop_xf_1_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f,f")
13619 (match_operator:XF 3 "binary_fp_operator"
13620 [(match_operand:XF 1 "register_operand" "0,f")
13621 (match_operand:XF 2 "register_operand" "f,0")]))]
13623 && !COMMUTATIVE_ARITH_P (operands[3])"
13624 "* return output_387_binary_op (insn, operands);"
13625 [(set (attr "type")
13626 (cond [(match_operand:XF 3 "mult_operator")
13627 (const_string "fmul")
13628 (match_operand:XF 3 "div_operator")
13629 (const_string "fdiv")
13631 (const_string "fop")))
13632 (set_attr "mode" "XF")])
13634 (define_insn "*fop_xf_2_i387"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (match_operator:XF 3 "binary_fp_operator"
13638 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13639 (match_operand:XF 2 "register_operand" "0")]))]
13641 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13642 { return output_387_binary_op (insn, operands); }
13643 [(set (attr "type")
13644 (cond [(match_operand:XF 3 "mult_operator")
13645 (const_string "fmul")
13646 (match_operand:XF 3 "div_operator")
13647 (const_string "fdiv")
13649 (const_string "fop")))
13650 (set_attr "fp_int_src" "true")
13651 (set_attr "mode" "<MODE>")])
13653 (define_insn "*fop_xf_3_i387"
13654 [(set (match_operand:XF 0 "register_operand" "=f")
13655 (match_operator:XF 3 "binary_fp_operator"
13656 [(match_operand:XF 1 "register_operand" "0")
13658 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13660 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13661 { return output_387_binary_op (insn, operands); }
13662 [(set (attr "type")
13663 (cond [(match_operand:XF 3 "mult_operator")
13664 (const_string "fmul")
13665 (match_operand:XF 3 "div_operator")
13666 (const_string "fdiv")
13668 (const_string "fop")))
13669 (set_attr "fp_int_src" "true")
13670 (set_attr "mode" "<MODE>")])
13672 (define_insn "*fop_xf_4_i387"
13673 [(set (match_operand:XF 0 "register_operand" "=f,f")
13674 (match_operator:XF 3 "binary_fp_operator"
13676 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13677 (match_operand:XF 2 "register_operand" "0,f")]))]
13679 "* return output_387_binary_op (insn, operands);"
13680 [(set (attr "type")
13681 (cond [(match_operand:XF 3 "mult_operator")
13682 (const_string "fmul")
13683 (match_operand:XF 3 "div_operator")
13684 (const_string "fdiv")
13686 (const_string "fop")))
13687 (set_attr "mode" "<MODE>")])
13689 (define_insn "*fop_xf_5_i387"
13690 [(set (match_operand:XF 0 "register_operand" "=f,f")
13691 (match_operator:XF 3 "binary_fp_operator"
13692 [(match_operand:XF 1 "register_operand" "0,f")
13694 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13696 "* return output_387_binary_op (insn, operands);"
13697 [(set (attr "type")
13698 (cond [(match_operand:XF 3 "mult_operator")
13699 (const_string "fmul")
13700 (match_operand:XF 3 "div_operator")
13701 (const_string "fdiv")
13703 (const_string "fop")))
13704 (set_attr "mode" "<MODE>")])
13706 (define_insn "*fop_xf_6_i387"
13707 [(set (match_operand:XF 0 "register_operand" "=f,f")
13708 (match_operator:XF 3 "binary_fp_operator"
13710 (match_operand:MODEF 1 "register_operand" "0,f"))
13712 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13714 "* return output_387_binary_op (insn, operands);"
13715 [(set (attr "type")
13716 (cond [(match_operand:XF 3 "mult_operator")
13717 (const_string "fmul")
13718 (match_operand:XF 3 "div_operator")
13719 (const_string "fdiv")
13721 (const_string "fop")))
13722 (set_attr "mode" "<MODE>")])
13724 ;; FPU special functions.
13726 ;; This pattern implements a no-op XFmode truncation for
13727 ;; all fancy i386 XFmode math functions.
13729 (define_insn "truncxf<mode>2_i387_noop_unspec"
13730 [(set (match_operand:MODEF 0 "register_operand" "=f")
13731 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13732 UNSPEC_TRUNC_NOOP))]
13733 "TARGET_USE_FANCY_MATH_387"
13734 "* return output_387_reg_move (insn, operands);"
13735 [(set_attr "type" "fmov")
13736 (set_attr "mode" "<MODE>")])
13738 (define_insn "sqrtxf2"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13741 "TARGET_USE_FANCY_MATH_387"
13743 [(set_attr "type" "fpspc")
13744 (set_attr "mode" "XF")
13745 (set_attr "athlon_decode" "direct")
13746 (set_attr "amdfam10_decode" "direct")
13747 (set_attr "bdver1_decode" "direct")])
13749 (define_insn "sqrt_extend<mode>xf2_i387"
13750 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (match_operand:MODEF 1 "register_operand" "0"))))]
13754 "TARGET_USE_FANCY_MATH_387"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")
13758 (set_attr "athlon_decode" "direct")
13759 (set_attr "amdfam10_decode" "direct")
13760 (set_attr "bdver1_decode" "direct")])
13762 (define_insn "*rsqrtsf2_sse"
13763 [(set (match_operand:SF 0 "register_operand" "=x")
13764 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13767 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13768 [(set_attr "type" "sse")
13769 (set_attr "atom_sse_attr" "rcp")
13770 (set_attr "btver2_sse_attr" "rcp")
13771 (set_attr "prefix" "maybe_vex")
13772 (set_attr "mode" "SF")])
13774 (define_expand "rsqrtsf2"
13775 [(set (match_operand:SF 0 "register_operand")
13776 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13780 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13784 (define_insn "*sqrt<mode>2_sse"
13785 [(set (match_operand:MODEF 0 "register_operand" "=x")
13787 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13789 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13790 [(set_attr "type" "sse")
13791 (set_attr "atom_sse_attr" "sqrt")
13792 (set_attr "btver2_sse_attr" "sqrt")
13793 (set_attr "prefix" "maybe_vex")
13794 (set_attr "mode" "<MODE>")
13795 (set_attr "athlon_decode" "*")
13796 (set_attr "amdfam10_decode" "*")
13797 (set_attr "bdver1_decode" "*")])
13799 (define_expand "sqrt<mode>2"
13800 [(set (match_operand:MODEF 0 "register_operand")
13802 (match_operand:MODEF 1 "nonimmediate_operand")))]
13803 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13804 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13806 if (<MODE>mode == SFmode
13808 && TARGET_RECIP_SQRT
13809 && !optimize_function_for_size_p (cfun)
13810 && flag_finite_math_only && !flag_trapping_math
13811 && flag_unsafe_math_optimizations)
13813 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13817 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13819 rtx op0 = gen_reg_rtx (XFmode);
13820 rtx op1 = force_reg (<MODE>mode, operands[1]);
13822 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13823 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13828 (define_insn "fpremxf4_i387"
13829 [(set (match_operand:XF 0 "register_operand" "=f")
13830 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13831 (match_operand:XF 3 "register_operand" "1")]
13833 (set (match_operand:XF 1 "register_operand" "=u")
13834 (unspec:XF [(match_dup 2) (match_dup 3)]
13836 (set (reg:CCFP FPSR_REG)
13837 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13839 "TARGET_USE_FANCY_MATH_387
13840 && flag_finite_math_only"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")])
13845 (define_expand "fmodxf3"
13846 [(use (match_operand:XF 0 "register_operand"))
13847 (use (match_operand:XF 1 "general_operand"))
13848 (use (match_operand:XF 2 "general_operand"))]
13849 "TARGET_USE_FANCY_MATH_387
13850 && flag_finite_math_only"
13852 rtx_code_label *label = gen_label_rtx ();
13854 rtx op1 = gen_reg_rtx (XFmode);
13855 rtx op2 = gen_reg_rtx (XFmode);
13857 emit_move_insn (op2, operands[2]);
13858 emit_move_insn (op1, operands[1]);
13860 emit_label (label);
13861 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13862 ix86_emit_fp_unordered_jump (label);
13863 LABEL_NUSES (label) = 1;
13865 emit_move_insn (operands[0], op1);
13869 (define_expand "fmod<mode>3"
13870 [(use (match_operand:MODEF 0 "register_operand"))
13871 (use (match_operand:MODEF 1 "general_operand"))
13872 (use (match_operand:MODEF 2 "general_operand"))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && flag_finite_math_only"
13876 rtx (*gen_truncxf) (rtx, rtx);
13878 rtx_code_label *label = gen_label_rtx ();
13880 rtx op1 = gen_reg_rtx (XFmode);
13881 rtx op2 = gen_reg_rtx (XFmode);
13883 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13886 emit_label (label);
13887 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13888 ix86_emit_fp_unordered_jump (label);
13889 LABEL_NUSES (label) = 1;
13891 /* Truncate the result properly for strict SSE math. */
13892 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13893 && !TARGET_MIX_SSE_I387)
13894 gen_truncxf = gen_truncxf<mode>2;
13896 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13898 emit_insn (gen_truncxf (operands[0], op1));
13902 (define_insn "fprem1xf4_i387"
13903 [(set (match_operand:XF 0 "register_operand" "=f")
13904 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13905 (match_operand:XF 3 "register_operand" "1")]
13907 (set (match_operand:XF 1 "register_operand" "=u")
13908 (unspec:XF [(match_dup 2) (match_dup 3)]
13910 (set (reg:CCFP FPSR_REG)
13911 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13913 "TARGET_USE_FANCY_MATH_387
13914 && flag_finite_math_only"
13916 [(set_attr "type" "fpspc")
13917 (set_attr "mode" "XF")])
13919 (define_expand "remainderxf3"
13920 [(use (match_operand:XF 0 "register_operand"))
13921 (use (match_operand:XF 1 "general_operand"))
13922 (use (match_operand:XF 2 "general_operand"))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && flag_finite_math_only"
13926 rtx_code_label *label = gen_label_rtx ();
13928 rtx op1 = gen_reg_rtx (XFmode);
13929 rtx op2 = gen_reg_rtx (XFmode);
13931 emit_move_insn (op2, operands[2]);
13932 emit_move_insn (op1, operands[1]);
13934 emit_label (label);
13935 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13936 ix86_emit_fp_unordered_jump (label);
13937 LABEL_NUSES (label) = 1;
13939 emit_move_insn (operands[0], op1);
13943 (define_expand "remainder<mode>3"
13944 [(use (match_operand:MODEF 0 "register_operand"))
13945 (use (match_operand:MODEF 1 "general_operand"))
13946 (use (match_operand:MODEF 2 "general_operand"))]
13947 "TARGET_USE_FANCY_MATH_387
13948 && flag_finite_math_only"
13950 rtx (*gen_truncxf) (rtx, rtx);
13952 rtx_code_label *label = gen_label_rtx ();
13954 rtx op1 = gen_reg_rtx (XFmode);
13955 rtx op2 = gen_reg_rtx (XFmode);
13957 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13958 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13960 emit_label (label);
13962 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13963 ix86_emit_fp_unordered_jump (label);
13964 LABEL_NUSES (label) = 1;
13966 /* Truncate the result properly for strict SSE math. */
13967 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13968 && !TARGET_MIX_SSE_I387)
13969 gen_truncxf = gen_truncxf<mode>2;
13971 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13973 emit_insn (gen_truncxf (operands[0], op1));
13977 (define_int_iterator SINCOS
13981 (define_int_attr sincos
13982 [(UNSPEC_SIN "sin")
13983 (UNSPEC_COS "cos")])
13985 (define_insn "*<sincos>xf2_i387"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13989 "TARGET_USE_FANCY_MATH_387
13990 && flag_unsafe_math_optimizations"
13992 [(set_attr "type" "fpspc")
13993 (set_attr "mode" "XF")])
13995 (define_insn "*<sincos>_extend<mode>xf2_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (unspec:XF [(float_extend:XF
13998 (match_operand:MODEF 1 "register_operand" "0"))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14008 ;; When sincos pattern is defined, sin and cos builtin functions will be
14009 ;; expanded to sincos pattern with one of its outputs left unused.
14010 ;; CSE pass will figure out if two sincos patterns can be combined,
14011 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14012 ;; depending on the unused output.
14014 (define_insn "sincosxf3"
14015 [(set (match_operand:XF 0 "register_operand" "=f")
14016 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14017 UNSPEC_SINCOS_COS))
14018 (set (match_operand:XF 1 "register_operand" "=u")
14019 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && flag_unsafe_math_optimizations"
14023 [(set_attr "type" "fpspc")
14024 (set_attr "mode" "XF")])
14027 [(set (match_operand:XF 0 "register_operand")
14028 (unspec:XF [(match_operand:XF 2 "register_operand")]
14029 UNSPEC_SINCOS_COS))
14030 (set (match_operand:XF 1 "register_operand")
14031 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14032 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14033 && can_create_pseudo_p ()"
14034 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14037 [(set (match_operand:XF 0 "register_operand")
14038 (unspec:XF [(match_operand:XF 2 "register_operand")]
14039 UNSPEC_SINCOS_COS))
14040 (set (match_operand:XF 1 "register_operand")
14041 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14042 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14043 && can_create_pseudo_p ()"
14044 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14046 (define_insn "sincos_extend<mode>xf3_i387"
14047 [(set (match_operand:XF 0 "register_operand" "=f")
14048 (unspec:XF [(float_extend:XF
14049 (match_operand:MODEF 2 "register_operand" "0"))]
14050 UNSPEC_SINCOS_COS))
14051 (set (match_operand:XF 1 "register_operand" "=u")
14052 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055 || TARGET_MIX_SSE_I387)
14056 && flag_unsafe_math_optimizations"
14058 [(set_attr "type" "fpspc")
14059 (set_attr "mode" "XF")])
14062 [(set (match_operand:XF 0 "register_operand")
14063 (unspec:XF [(float_extend:XF
14064 (match_operand:MODEF 2 "register_operand"))]
14065 UNSPEC_SINCOS_COS))
14066 (set (match_operand:XF 1 "register_operand")
14067 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14068 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14069 && can_create_pseudo_p ()"
14070 [(set (match_dup 1)
14071 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14074 [(set (match_operand:XF 0 "register_operand")
14075 (unspec:XF [(float_extend:XF
14076 (match_operand:MODEF 2 "register_operand"))]
14077 UNSPEC_SINCOS_COS))
14078 (set (match_operand:XF 1 "register_operand")
14079 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14080 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14081 && can_create_pseudo_p ()"
14082 [(set (match_dup 0)
14083 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14085 (define_expand "sincos<mode>3"
14086 [(use (match_operand:MODEF 0 "register_operand"))
14087 (use (match_operand:MODEF 1 "register_operand"))
14088 (use (match_operand:MODEF 2 "register_operand"))]
14089 "TARGET_USE_FANCY_MATH_387
14090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091 || TARGET_MIX_SSE_I387)
14092 && flag_unsafe_math_optimizations"
14094 rtx op0 = gen_reg_rtx (XFmode);
14095 rtx op1 = gen_reg_rtx (XFmode);
14097 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14103 (define_insn "fptanxf4_i387"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (match_operand:XF 3 "const_double_operand" "F"))
14106 (set (match_operand:XF 1 "register_operand" "=u")
14107 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations
14111 && standard_80387_constant_p (operands[3]) == 2"
14113 [(set_attr "type" "fpspc")
14114 (set_attr "mode" "XF")])
14116 (define_insn "fptan_extend<mode>xf4_i387"
14117 [(set (match_operand:MODEF 0 "register_operand" "=f")
14118 (match_operand:MODEF 3 "const_double_operand" "F"))
14119 (set (match_operand:XF 1 "register_operand" "=u")
14120 (unspec:XF [(float_extend:XF
14121 (match_operand:MODEF 2 "register_operand" "0"))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations
14127 && standard_80387_constant_p (operands[3]) == 2"
14129 [(set_attr "type" "fpspc")
14130 (set_attr "mode" "XF")])
14132 (define_expand "tanxf2"
14133 [(use (match_operand:XF 0 "register_operand"))
14134 (use (match_operand:XF 1 "register_operand"))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && flag_unsafe_math_optimizations"
14138 rtx one = gen_reg_rtx (XFmode);
14139 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14141 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14145 (define_expand "tan<mode>2"
14146 [(use (match_operand:MODEF 0 "register_operand"))
14147 (use (match_operand:MODEF 1 "register_operand"))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations"
14153 rtx op0 = gen_reg_rtx (XFmode);
14155 rtx one = gen_reg_rtx (<MODE>mode);
14156 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14158 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14159 operands[1], op2));
14160 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14164 (define_insn "*fpatanxf3_i387"
14165 [(set (match_operand:XF 0 "register_operand" "=f")
14166 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14167 (match_operand:XF 2 "register_operand" "u")]
14169 (clobber (match_scratch:XF 3 "=2"))]
14170 "TARGET_USE_FANCY_MATH_387
14171 && flag_unsafe_math_optimizations"
14173 [(set_attr "type" "fpspc")
14174 (set_attr "mode" "XF")])
14176 (define_insn "fpatan_extend<mode>xf3_i387"
14177 [(set (match_operand:XF 0 "register_operand" "=f")
14178 (unspec:XF [(float_extend:XF
14179 (match_operand:MODEF 1 "register_operand" "0"))
14181 (match_operand:MODEF 2 "register_operand" "u"))]
14183 (clobber (match_scratch:XF 3 "=2"))]
14184 "TARGET_USE_FANCY_MATH_387
14185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14186 || TARGET_MIX_SSE_I387)
14187 && flag_unsafe_math_optimizations"
14189 [(set_attr "type" "fpspc")
14190 (set_attr "mode" "XF")])
14192 (define_expand "atan2xf3"
14193 [(parallel [(set (match_operand:XF 0 "register_operand")
14194 (unspec:XF [(match_operand:XF 2 "register_operand")
14195 (match_operand:XF 1 "register_operand")]
14197 (clobber (match_scratch:XF 3))])]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations")
14201 (define_expand "atan2<mode>3"
14202 [(use (match_operand:MODEF 0 "register_operand"))
14203 (use (match_operand:MODEF 1 "register_operand"))
14204 (use (match_operand:MODEF 2 "register_operand"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207 || TARGET_MIX_SSE_I387)
14208 && flag_unsafe_math_optimizations"
14210 rtx op0 = gen_reg_rtx (XFmode);
14212 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14213 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14217 (define_expand "atanxf2"
14218 [(parallel [(set (match_operand:XF 0 "register_operand")
14219 (unspec:XF [(match_dup 2)
14220 (match_operand:XF 1 "register_operand")]
14222 (clobber (match_scratch:XF 3))])]
14223 "TARGET_USE_FANCY_MATH_387
14224 && flag_unsafe_math_optimizations"
14226 operands[2] = gen_reg_rtx (XFmode);
14227 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14230 (define_expand "atan<mode>2"
14231 [(use (match_operand:MODEF 0 "register_operand"))
14232 (use (match_operand:MODEF 1 "register_operand"))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235 || TARGET_MIX_SSE_I387)
14236 && flag_unsafe_math_optimizations"
14238 rtx op0 = gen_reg_rtx (XFmode);
14240 rtx op2 = gen_reg_rtx (<MODE>mode);
14241 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14243 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14244 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14248 (define_expand "asinxf2"
14249 [(set (match_dup 2)
14250 (mult:XF (match_operand:XF 1 "register_operand")
14252 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14253 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14254 (parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_dup 5) (match_dup 1)]
14257 (clobber (match_scratch:XF 6))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14263 if (optimize_insn_for_size_p ())
14266 for (i = 2; i < 6; i++)
14267 operands[i] = gen_reg_rtx (XFmode);
14269 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14272 (define_expand "asin<mode>2"
14273 [(use (match_operand:MODEF 0 "register_operand"))
14274 (use (match_operand:MODEF 1 "general_operand"))]
14275 "TARGET_USE_FANCY_MATH_387
14276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277 || TARGET_MIX_SSE_I387)
14278 && flag_unsafe_math_optimizations"
14280 rtx op0 = gen_reg_rtx (XFmode);
14281 rtx op1 = gen_reg_rtx (XFmode);
14283 if (optimize_insn_for_size_p ())
14286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287 emit_insn (gen_asinxf2 (op0, op1));
14288 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292 (define_expand "acosxf2"
14293 [(set (match_dup 2)
14294 (mult:XF (match_operand:XF 1 "register_operand")
14296 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14297 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14298 (parallel [(set (match_operand:XF 0 "register_operand")
14299 (unspec:XF [(match_dup 1) (match_dup 5)]
14301 (clobber (match_scratch:XF 6))])]
14302 "TARGET_USE_FANCY_MATH_387
14303 && flag_unsafe_math_optimizations"
14307 if (optimize_insn_for_size_p ())
14310 for (i = 2; i < 6; i++)
14311 operands[i] = gen_reg_rtx (XFmode);
14313 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14316 (define_expand "acos<mode>2"
14317 [(use (match_operand:MODEF 0 "register_operand"))
14318 (use (match_operand:MODEF 1 "general_operand"))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321 || TARGET_MIX_SSE_I387)
14322 && flag_unsafe_math_optimizations"
14324 rtx op0 = gen_reg_rtx (XFmode);
14325 rtx op1 = gen_reg_rtx (XFmode);
14327 if (optimize_insn_for_size_p ())
14330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14331 emit_insn (gen_acosxf2 (op0, op1));
14332 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14336 (define_insn "fyl2xxf3_i387"
14337 [(set (match_operand:XF 0 "register_operand" "=f")
14338 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14339 (match_operand:XF 2 "register_operand" "u")]
14341 (clobber (match_scratch:XF 3 "=2"))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && flag_unsafe_math_optimizations"
14345 [(set_attr "type" "fpspc")
14346 (set_attr "mode" "XF")])
14348 (define_insn "fyl2x_extend<mode>xf3_i387"
14349 [(set (match_operand:XF 0 "register_operand" "=f")
14350 (unspec:XF [(float_extend:XF
14351 (match_operand:MODEF 1 "register_operand" "0"))
14352 (match_operand:XF 2 "register_operand" "u")]
14354 (clobber (match_scratch:XF 3 "=2"))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357 || TARGET_MIX_SSE_I387)
14358 && flag_unsafe_math_optimizations"
14360 [(set_attr "type" "fpspc")
14361 (set_attr "mode" "XF")])
14363 (define_expand "logxf2"
14364 [(parallel [(set (match_operand:XF 0 "register_operand")
14365 (unspec:XF [(match_operand:XF 1 "register_operand")
14366 (match_dup 2)] UNSPEC_FYL2X))
14367 (clobber (match_scratch:XF 3))])]
14368 "TARGET_USE_FANCY_MATH_387
14369 && flag_unsafe_math_optimizations"
14371 operands[2] = gen_reg_rtx (XFmode);
14372 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14375 (define_expand "log<mode>2"
14376 [(use (match_operand:MODEF 0 "register_operand"))
14377 (use (match_operand:MODEF 1 "register_operand"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14383 rtx op0 = gen_reg_rtx (XFmode);
14385 rtx op2 = gen_reg_rtx (XFmode);
14386 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14388 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14393 (define_expand "log10xf2"
14394 [(parallel [(set (match_operand:XF 0 "register_operand")
14395 (unspec:XF [(match_operand:XF 1 "register_operand")
14396 (match_dup 2)] UNSPEC_FYL2X))
14397 (clobber (match_scratch:XF 3))])]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations"
14401 operands[2] = gen_reg_rtx (XFmode);
14402 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14405 (define_expand "log10<mode>2"
14406 [(use (match_operand:MODEF 0 "register_operand"))
14407 (use (match_operand:MODEF 1 "register_operand"))]
14408 "TARGET_USE_FANCY_MATH_387
14409 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410 || TARGET_MIX_SSE_I387)
14411 && flag_unsafe_math_optimizations"
14413 rtx op0 = gen_reg_rtx (XFmode);
14415 rtx op2 = gen_reg_rtx (XFmode);
14416 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14418 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423 (define_expand "log2xf2"
14424 [(parallel [(set (match_operand:XF 0 "register_operand")
14425 (unspec:XF [(match_operand:XF 1 "register_operand")
14426 (match_dup 2)] UNSPEC_FYL2X))
14427 (clobber (match_scratch:XF 3))])]
14428 "TARGET_USE_FANCY_MATH_387
14429 && flag_unsafe_math_optimizations"
14431 operands[2] = gen_reg_rtx (XFmode);
14432 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14435 (define_expand "log2<mode>2"
14436 [(use (match_operand:MODEF 0 "register_operand"))
14437 (use (match_operand:MODEF 1 "register_operand"))]
14438 "TARGET_USE_FANCY_MATH_387
14439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14440 || TARGET_MIX_SSE_I387)
14441 && flag_unsafe_math_optimizations"
14443 rtx op0 = gen_reg_rtx (XFmode);
14445 rtx op2 = gen_reg_rtx (XFmode);
14446 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14448 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14449 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14453 (define_insn "fyl2xp1xf3_i387"
14454 [(set (match_operand:XF 0 "register_operand" "=f")
14455 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14456 (match_operand:XF 2 "register_operand" "u")]
14458 (clobber (match_scratch:XF 3 "=2"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && flag_unsafe_math_optimizations"
14462 [(set_attr "type" "fpspc")
14463 (set_attr "mode" "XF")])
14465 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14466 [(set (match_operand:XF 0 "register_operand" "=f")
14467 (unspec:XF [(float_extend:XF
14468 (match_operand:MODEF 1 "register_operand" "0"))
14469 (match_operand:XF 2 "register_operand" "u")]
14471 (clobber (match_scratch:XF 3 "=2"))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations"
14477 [(set_attr "type" "fpspc")
14478 (set_attr "mode" "XF")])
14480 (define_expand "log1pxf2"
14481 [(use (match_operand:XF 0 "register_operand"))
14482 (use (match_operand:XF 1 "register_operand"))]
14483 "TARGET_USE_FANCY_MATH_387
14484 && flag_unsafe_math_optimizations"
14486 if (optimize_insn_for_size_p ())
14489 ix86_emit_i387_log1p (operands[0], operands[1]);
14493 (define_expand "log1p<mode>2"
14494 [(use (match_operand:MODEF 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14503 if (optimize_insn_for_size_p ())
14506 op0 = gen_reg_rtx (XFmode);
14508 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14510 ix86_emit_i387_log1p (op0, operands[1]);
14511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515 (define_insn "fxtractxf3_i387"
14516 [(set (match_operand:XF 0 "register_operand" "=f")
14517 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14518 UNSPEC_XTRACT_FRACT))
14519 (set (match_operand:XF 1 "register_operand" "=u")
14520 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && flag_unsafe_math_optimizations"
14524 [(set_attr "type" "fpspc")
14525 (set_attr "mode" "XF")])
14527 (define_insn "fxtract_extend<mode>xf3_i387"
14528 [(set (match_operand:XF 0 "register_operand" "=f")
14529 (unspec:XF [(float_extend:XF
14530 (match_operand:MODEF 2 "register_operand" "0"))]
14531 UNSPEC_XTRACT_FRACT))
14532 (set (match_operand:XF 1 "register_operand" "=u")
14533 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14534 "TARGET_USE_FANCY_MATH_387
14535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14536 || TARGET_MIX_SSE_I387)
14537 && flag_unsafe_math_optimizations"
14539 [(set_attr "type" "fpspc")
14540 (set_attr "mode" "XF")])
14542 (define_expand "logbxf2"
14543 [(parallel [(set (match_dup 2)
14544 (unspec:XF [(match_operand:XF 1 "register_operand")]
14545 UNSPEC_XTRACT_FRACT))
14546 (set (match_operand:XF 0 "register_operand")
14547 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14548 "TARGET_USE_FANCY_MATH_387
14549 && flag_unsafe_math_optimizations"
14550 "operands[2] = gen_reg_rtx (XFmode);")
14552 (define_expand "logb<mode>2"
14553 [(use (match_operand:MODEF 0 "register_operand"))
14554 (use (match_operand:MODEF 1 "register_operand"))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14557 || TARGET_MIX_SSE_I387)
14558 && flag_unsafe_math_optimizations"
14560 rtx op0 = gen_reg_rtx (XFmode);
14561 rtx op1 = gen_reg_rtx (XFmode);
14563 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14568 (define_expand "ilogbxf2"
14569 [(use (match_operand:SI 0 "register_operand"))
14570 (use (match_operand:XF 1 "register_operand"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations"
14576 if (optimize_insn_for_size_p ())
14579 op0 = gen_reg_rtx (XFmode);
14580 op1 = gen_reg_rtx (XFmode);
14582 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14583 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14587 (define_expand "ilogb<mode>2"
14588 [(use (match_operand:SI 0 "register_operand"))
14589 (use (match_operand:MODEF 1 "register_operand"))]
14590 "TARGET_USE_FANCY_MATH_387
14591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592 || TARGET_MIX_SSE_I387)
14593 && flag_unsafe_math_optimizations"
14597 if (optimize_insn_for_size_p ())
14600 op0 = gen_reg_rtx (XFmode);
14601 op1 = gen_reg_rtx (XFmode);
14603 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14604 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14608 (define_insn "*f2xm1xf2_i387"
14609 [(set (match_operand:XF 0 "register_operand" "=f")
14610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14612 "TARGET_USE_FANCY_MATH_387
14613 && flag_unsafe_math_optimizations"
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "XF")])
14618 (define_insn "fscalexf4_i387"
14619 [(set (match_operand:XF 0 "register_operand" "=f")
14620 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14621 (match_operand:XF 3 "register_operand" "1")]
14622 UNSPEC_FSCALE_FRACT))
14623 (set (match_operand:XF 1 "register_operand" "=u")
14624 (unspec:XF [(match_dup 2) (match_dup 3)]
14625 UNSPEC_FSCALE_EXP))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && flag_unsafe_math_optimizations"
14629 [(set_attr "type" "fpspc")
14630 (set_attr "mode" "XF")])
14632 (define_expand "expNcorexf3"
14633 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14634 (match_operand:XF 2 "register_operand")))
14635 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14636 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14637 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14638 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14639 (parallel [(set (match_operand:XF 0 "register_operand")
14640 (unspec:XF [(match_dup 8) (match_dup 4)]
14641 UNSPEC_FSCALE_FRACT))
14643 (unspec:XF [(match_dup 8) (match_dup 4)]
14644 UNSPEC_FSCALE_EXP))])]
14645 "TARGET_USE_FANCY_MATH_387
14646 && flag_unsafe_math_optimizations"
14650 if (optimize_insn_for_size_p ())
14653 for (i = 3; i < 10; i++)
14654 operands[i] = gen_reg_rtx (XFmode);
14656 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14659 (define_expand "expxf2"
14660 [(use (match_operand:XF 0 "register_operand"))
14661 (use (match_operand:XF 1 "register_operand"))]
14662 "TARGET_USE_FANCY_MATH_387
14663 && flag_unsafe_math_optimizations"
14667 if (optimize_insn_for_size_p ())
14670 op2 = gen_reg_rtx (XFmode);
14671 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14673 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14677 (define_expand "exp<mode>2"
14678 [(use (match_operand:MODEF 0 "register_operand"))
14679 (use (match_operand:MODEF 1 "general_operand"))]
14680 "TARGET_USE_FANCY_MATH_387
14681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14682 || TARGET_MIX_SSE_I387)
14683 && flag_unsafe_math_optimizations"
14687 if (optimize_insn_for_size_p ())
14690 op0 = gen_reg_rtx (XFmode);
14691 op1 = gen_reg_rtx (XFmode);
14693 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14694 emit_insn (gen_expxf2 (op0, op1));
14695 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14699 (define_expand "exp10xf2"
14700 [(use (match_operand:XF 0 "register_operand"))
14701 (use (match_operand:XF 1 "register_operand"))]
14702 "TARGET_USE_FANCY_MATH_387
14703 && flag_unsafe_math_optimizations"
14707 if (optimize_insn_for_size_p ())
14710 op2 = gen_reg_rtx (XFmode);
14711 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14713 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14717 (define_expand "exp10<mode>2"
14718 [(use (match_operand:MODEF 0 "register_operand"))
14719 (use (match_operand:MODEF 1 "general_operand"))]
14720 "TARGET_USE_FANCY_MATH_387
14721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14722 || TARGET_MIX_SSE_I387)
14723 && flag_unsafe_math_optimizations"
14727 if (optimize_insn_for_size_p ())
14730 op0 = gen_reg_rtx (XFmode);
14731 op1 = gen_reg_rtx (XFmode);
14733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14734 emit_insn (gen_exp10xf2 (op0, op1));
14735 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14739 (define_expand "exp2xf2"
14740 [(use (match_operand:XF 0 "register_operand"))
14741 (use (match_operand:XF 1 "register_operand"))]
14742 "TARGET_USE_FANCY_MATH_387
14743 && flag_unsafe_math_optimizations"
14747 if (optimize_insn_for_size_p ())
14750 op2 = gen_reg_rtx (XFmode);
14751 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14753 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14757 (define_expand "exp2<mode>2"
14758 [(use (match_operand:MODEF 0 "register_operand"))
14759 (use (match_operand:MODEF 1 "general_operand"))]
14760 "TARGET_USE_FANCY_MATH_387
14761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14762 || TARGET_MIX_SSE_I387)
14763 && flag_unsafe_math_optimizations"
14767 if (optimize_insn_for_size_p ())
14770 op0 = gen_reg_rtx (XFmode);
14771 op1 = gen_reg_rtx (XFmode);
14773 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14774 emit_insn (gen_exp2xf2 (op0, op1));
14775 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14779 (define_expand "expm1xf2"
14780 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14782 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14783 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14784 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14785 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14786 (parallel [(set (match_dup 7)
14787 (unspec:XF [(match_dup 6) (match_dup 4)]
14788 UNSPEC_FSCALE_FRACT))
14790 (unspec:XF [(match_dup 6) (match_dup 4)]
14791 UNSPEC_FSCALE_EXP))])
14792 (parallel [(set (match_dup 10)
14793 (unspec:XF [(match_dup 9) (match_dup 8)]
14794 UNSPEC_FSCALE_FRACT))
14795 (set (match_dup 11)
14796 (unspec:XF [(match_dup 9) (match_dup 8)]
14797 UNSPEC_FSCALE_EXP))])
14798 (set (match_dup 12) (minus:XF (match_dup 10)
14799 (float_extend:XF (match_dup 13))))
14800 (set (match_operand:XF 0 "register_operand")
14801 (plus:XF (match_dup 12) (match_dup 7)))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations"
14807 if (optimize_insn_for_size_p ())
14810 for (i = 2; i < 13; i++)
14811 operands[i] = gen_reg_rtx (XFmode);
14814 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14816 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14819 (define_expand "expm1<mode>2"
14820 [(use (match_operand:MODEF 0 "register_operand"))
14821 (use (match_operand:MODEF 1 "general_operand"))]
14822 "TARGET_USE_FANCY_MATH_387
14823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824 || TARGET_MIX_SSE_I387)
14825 && flag_unsafe_math_optimizations"
14829 if (optimize_insn_for_size_p ())
14832 op0 = gen_reg_rtx (XFmode);
14833 op1 = gen_reg_rtx (XFmode);
14835 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14836 emit_insn (gen_expm1xf2 (op0, op1));
14837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14841 (define_expand "ldexpxf3"
14842 [(match_operand:XF 0 "register_operand")
14843 (match_operand:XF 1 "register_operand")
14844 (match_operand:SI 2 "register_operand")]
14845 "TARGET_USE_FANCY_MATH_387
14846 && flag_unsafe_math_optimizations"
14849 if (optimize_insn_for_size_p ())
14852 tmp1 = gen_reg_rtx (XFmode);
14853 tmp2 = gen_reg_rtx (XFmode);
14855 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14856 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14857 operands[1], tmp1));
14861 (define_expand "ldexp<mode>3"
14862 [(use (match_operand:MODEF 0 "register_operand"))
14863 (use (match_operand:MODEF 1 "general_operand"))
14864 (use (match_operand:SI 2 "register_operand"))]
14865 "TARGET_USE_FANCY_MATH_387
14866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14867 || TARGET_MIX_SSE_I387)
14868 && flag_unsafe_math_optimizations"
14872 if (optimize_insn_for_size_p ())
14875 op0 = gen_reg_rtx (XFmode);
14876 op1 = gen_reg_rtx (XFmode);
14878 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14879 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14884 (define_expand "scalbxf3"
14885 [(parallel [(set (match_operand:XF 0 " register_operand")
14886 (unspec:XF [(match_operand:XF 1 "register_operand")
14887 (match_operand:XF 2 "register_operand")]
14888 UNSPEC_FSCALE_FRACT))
14890 (unspec:XF [(match_dup 1) (match_dup 2)]
14891 UNSPEC_FSCALE_EXP))])]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14895 if (optimize_insn_for_size_p ())
14898 operands[3] = gen_reg_rtx (XFmode);
14901 (define_expand "scalb<mode>3"
14902 [(use (match_operand:MODEF 0 "register_operand"))
14903 (use (match_operand:MODEF 1 "general_operand"))
14904 (use (match_operand:MODEF 2 "general_operand"))]
14905 "TARGET_USE_FANCY_MATH_387
14906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14907 || TARGET_MIX_SSE_I387)
14908 && flag_unsafe_math_optimizations"
14912 if (optimize_insn_for_size_p ())
14915 op0 = gen_reg_rtx (XFmode);
14916 op1 = gen_reg_rtx (XFmode);
14917 op2 = gen_reg_rtx (XFmode);
14919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14921 emit_insn (gen_scalbxf3 (op0, op1, op2));
14922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14926 (define_expand "significandxf2"
14927 [(parallel [(set (match_operand:XF 0 "register_operand")
14928 (unspec:XF [(match_operand:XF 1 "register_operand")]
14929 UNSPEC_XTRACT_FRACT))
14931 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "operands[2] = gen_reg_rtx (XFmode);")
14936 (define_expand "significand<mode>2"
14937 [(use (match_operand:MODEF 0 "register_operand"))
14938 (use (match_operand:MODEF 1 "register_operand"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14941 || TARGET_MIX_SSE_I387)
14942 && flag_unsafe_math_optimizations"
14944 rtx op0 = gen_reg_rtx (XFmode);
14945 rtx op1 = gen_reg_rtx (XFmode);
14947 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14948 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14953 (define_insn "sse4_1_round<mode>2"
14954 [(set (match_operand:MODEF 0 "register_operand" "=x")
14955 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14956 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14959 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14960 [(set_attr "type" "ssecvt")
14961 (set_attr "prefix_extra" "1")
14962 (set_attr "prefix" "maybe_vex")
14963 (set_attr "mode" "<MODE>")])
14965 (define_insn "rintxf2"
14966 [(set (match_operand:XF 0 "register_operand" "=f")
14967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14969 "TARGET_USE_FANCY_MATH_387
14970 && flag_unsafe_math_optimizations"
14972 [(set_attr "type" "fpspc")
14973 (set_attr "mode" "XF")])
14975 (define_expand "rint<mode>2"
14976 [(use (match_operand:MODEF 0 "register_operand"))
14977 (use (match_operand:MODEF 1 "register_operand"))]
14978 "(TARGET_USE_FANCY_MATH_387
14979 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14980 || TARGET_MIX_SSE_I387)
14981 && flag_unsafe_math_optimizations)
14982 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14983 && !flag_trapping_math)"
14985 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14986 && !flag_trapping_math)
14989 emit_insn (gen_sse4_1_round<mode>2
14990 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14991 else if (optimize_insn_for_size_p ())
14994 ix86_expand_rint (operands[0], operands[1]);
14998 rtx op0 = gen_reg_rtx (XFmode);
14999 rtx op1 = gen_reg_rtx (XFmode);
15001 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15002 emit_insn (gen_rintxf2 (op0, op1));
15004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15009 (define_expand "round<mode>2"
15010 [(match_operand:X87MODEF 0 "register_operand")
15011 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15012 "(TARGET_USE_FANCY_MATH_387
15013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15014 || TARGET_MIX_SSE_I387)
15015 && flag_unsafe_math_optimizations)
15016 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15017 && !flag_trapping_math && !flag_rounding_math)"
15019 if (optimize_insn_for_size_p ())
15022 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15023 && !flag_trapping_math && !flag_rounding_math)
15027 operands[1] = force_reg (<MODE>mode, operands[1]);
15028 ix86_expand_round_sse4 (operands[0], operands[1]);
15030 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15031 ix86_expand_round (operands[0], operands[1]);
15033 ix86_expand_rounddf_32 (operands[0], operands[1]);
15037 operands[1] = force_reg (<MODE>mode, operands[1]);
15038 ix86_emit_i387_round (operands[0], operands[1]);
15043 (define_insn_and_split "*fistdi2_1"
15044 [(set (match_operand:DI 0 "nonimmediate_operand")
15045 (unspec:DI [(match_operand:XF 1 "register_operand")]
15047 "TARGET_USE_FANCY_MATH_387
15048 && can_create_pseudo_p ()"
15053 if (memory_operand (operands[0], VOIDmode))
15054 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15057 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15058 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15063 [(set_attr "type" "fpspc")
15064 (set_attr "mode" "DI")])
15066 (define_insn "fistdi2"
15067 [(set (match_operand:DI 0 "memory_operand" "=m")
15068 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15070 (clobber (match_scratch:XF 2 "=&1f"))]
15071 "TARGET_USE_FANCY_MATH_387"
15072 "* return output_fix_trunc (insn, operands, false);"
15073 [(set_attr "type" "fpspc")
15074 (set_attr "mode" "DI")])
15076 (define_insn "fistdi2_with_temp"
15077 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15078 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15080 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15081 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15082 "TARGET_USE_FANCY_MATH_387"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DI")])
15088 [(set (match_operand:DI 0 "register_operand")
15089 (unspec:DI [(match_operand:XF 1 "register_operand")]
15091 (clobber (match_operand:DI 2 "memory_operand"))
15092 (clobber (match_scratch 3))]
15094 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15095 (clobber (match_dup 3))])
15096 (set (match_dup 0) (match_dup 2))])
15099 [(set (match_operand:DI 0 "memory_operand")
15100 (unspec:DI [(match_operand:XF 1 "register_operand")]
15102 (clobber (match_operand:DI 2 "memory_operand"))
15103 (clobber (match_scratch 3))]
15105 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15106 (clobber (match_dup 3))])])
15108 (define_insn_and_split "*fist<mode>2_1"
15109 [(set (match_operand:SWI24 0 "register_operand")
15110 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15112 "TARGET_USE_FANCY_MATH_387
15113 && can_create_pseudo_p ()"
15118 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15119 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15123 [(set_attr "type" "fpspc")
15124 (set_attr "mode" "<MODE>")])
15126 (define_insn "fist<mode>2"
15127 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15128 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15130 "TARGET_USE_FANCY_MATH_387"
15131 "* return output_fix_trunc (insn, operands, false);"
15132 [(set_attr "type" "fpspc")
15133 (set_attr "mode" "<MODE>")])
15135 (define_insn "fist<mode>2_with_temp"
15136 [(set (match_operand:SWI24 0 "register_operand" "=r")
15137 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15139 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15140 "TARGET_USE_FANCY_MATH_387"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "<MODE>")])
15146 [(set (match_operand:SWI24 0 "register_operand")
15147 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15149 (clobber (match_operand:SWI24 2 "memory_operand"))]
15151 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15152 (set (match_dup 0) (match_dup 2))])
15155 [(set (match_operand:SWI24 0 "memory_operand")
15156 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15158 (clobber (match_operand:SWI24 2 "memory_operand"))]
15160 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15162 (define_expand "lrintxf<mode>2"
15163 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15164 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15166 "TARGET_USE_FANCY_MATH_387")
15168 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15169 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15170 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15171 UNSPEC_FIX_NOTRUNC))]
15172 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15174 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15175 [(match_operand:SWI248x 0 "nonimmediate_operand")
15176 (match_operand:X87MODEF 1 "register_operand")]
15177 "(TARGET_USE_FANCY_MATH_387
15178 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15179 || TARGET_MIX_SSE_I387)
15180 && flag_unsafe_math_optimizations)
15181 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15182 && <SWI248x:MODE>mode != HImode
15183 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15184 && !flag_trapping_math && !flag_rounding_math)"
15186 if (optimize_insn_for_size_p ())
15189 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15190 && <SWI248x:MODE>mode != HImode
15191 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15192 && !flag_trapping_math && !flag_rounding_math)
15193 ix86_expand_lround (operands[0], operands[1]);
15195 ix86_emit_i387_round (operands[0], operands[1]);
15199 (define_int_iterator FRNDINT_ROUNDING
15200 [UNSPEC_FRNDINT_FLOOR
15201 UNSPEC_FRNDINT_CEIL
15202 UNSPEC_FRNDINT_TRUNC])
15204 (define_int_iterator FIST_ROUNDING
15208 ;; Base name for define_insn
15209 (define_int_attr rounding_insn
15210 [(UNSPEC_FRNDINT_FLOOR "floor")
15211 (UNSPEC_FRNDINT_CEIL "ceil")
15212 (UNSPEC_FRNDINT_TRUNC "btrunc")
15213 (UNSPEC_FIST_FLOOR "floor")
15214 (UNSPEC_FIST_CEIL "ceil")])
15216 (define_int_attr rounding
15217 [(UNSPEC_FRNDINT_FLOOR "floor")
15218 (UNSPEC_FRNDINT_CEIL "ceil")
15219 (UNSPEC_FRNDINT_TRUNC "trunc")
15220 (UNSPEC_FIST_FLOOR "floor")
15221 (UNSPEC_FIST_CEIL "ceil")])
15223 (define_int_attr ROUNDING
15224 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15225 (UNSPEC_FRNDINT_CEIL "CEIL")
15226 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15227 (UNSPEC_FIST_FLOOR "FLOOR")
15228 (UNSPEC_FIST_CEIL "CEIL")])
15230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15231 (define_insn_and_split "frndintxf2_<rounding>"
15232 [(set (match_operand:XF 0 "register_operand")
15233 (unspec:XF [(match_operand:XF 1 "register_operand")]
15235 (clobber (reg:CC FLAGS_REG))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations
15238 && can_create_pseudo_p ()"
15243 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15248 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15249 operands[2], operands[3]));
15252 [(set_attr "type" "frndint")
15253 (set_attr "i387_cw" "<rounding>")
15254 (set_attr "mode" "XF")])
15256 (define_insn "frndintxf2_<rounding>_i387"
15257 [(set (match_operand:XF 0 "register_operand" "=f")
15258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 (use (match_operand:HI 2 "memory_operand" "m"))
15261 (use (match_operand:HI 3 "memory_operand" "m"))]
15262 "TARGET_USE_FANCY_MATH_387
15263 && flag_unsafe_math_optimizations"
15264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15265 [(set_attr "type" "frndint")
15266 (set_attr "i387_cw" "<rounding>")
15267 (set_attr "mode" "XF")])
15269 (define_expand "<rounding_insn>xf2"
15270 [(parallel [(set (match_operand:XF 0 "register_operand")
15271 (unspec:XF [(match_operand:XF 1 "register_operand")]
15273 (clobber (reg:CC FLAGS_REG))])]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations
15276 && !optimize_insn_for_size_p ()")
15278 (define_expand "<rounding_insn><mode>2"
15279 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15280 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15282 (clobber (reg:CC FLAGS_REG))])]
15283 "(TARGET_USE_FANCY_MATH_387
15284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15285 || TARGET_MIX_SSE_I387)
15286 && flag_unsafe_math_optimizations)
15287 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15288 && !flag_trapping_math)"
15290 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15291 && !flag_trapping_math)
15294 emit_insn (gen_sse4_1_round<mode>2
15295 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15296 else if (optimize_insn_for_size_p ())
15298 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15300 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15301 ix86_expand_floorceil (operands[0], operands[1], true);
15302 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15303 ix86_expand_floorceil (operands[0], operands[1], false);
15304 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15305 ix86_expand_trunc (operands[0], operands[1]);
15307 gcc_unreachable ();
15311 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15312 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15313 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15314 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15315 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15316 ix86_expand_truncdf_32 (operands[0], operands[1]);
15318 gcc_unreachable ();
15325 if (optimize_insn_for_size_p ())
15328 op0 = gen_reg_rtx (XFmode);
15329 op1 = gen_reg_rtx (XFmode);
15330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15331 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15338 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15339 (define_insn_and_split "frndintxf2_mask_pm"
15340 [(set (match_operand:XF 0 "register_operand")
15341 (unspec:XF [(match_operand:XF 1 "register_operand")]
15342 UNSPEC_FRNDINT_MASK_PM))
15343 (clobber (reg:CC FLAGS_REG))]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations
15346 && can_create_pseudo_p ()"
15351 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15353 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15354 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15356 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15357 operands[2], operands[3]));
15360 [(set_attr "type" "frndint")
15361 (set_attr "i387_cw" "mask_pm")
15362 (set_attr "mode" "XF")])
15364 (define_insn "frndintxf2_mask_pm_i387"
15365 [(set (match_operand:XF 0 "register_operand" "=f")
15366 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15367 UNSPEC_FRNDINT_MASK_PM))
15368 (use (match_operand:HI 2 "memory_operand" "m"))
15369 (use (match_operand:HI 3 "memory_operand" "m"))]
15370 "TARGET_USE_FANCY_MATH_387
15371 && flag_unsafe_math_optimizations"
15372 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15373 [(set_attr "type" "frndint")
15374 (set_attr "i387_cw" "mask_pm")
15375 (set_attr "mode" "XF")])
15377 (define_expand "nearbyintxf2"
15378 [(parallel [(set (match_operand:XF 0 "register_operand")
15379 (unspec:XF [(match_operand:XF 1 "register_operand")]
15380 UNSPEC_FRNDINT_MASK_PM))
15381 (clobber (reg:CC FLAGS_REG))])]
15382 "TARGET_USE_FANCY_MATH_387
15383 && flag_unsafe_math_optimizations")
15385 (define_expand "nearbyint<mode>2"
15386 [(use (match_operand:MODEF 0 "register_operand"))
15387 (use (match_operand:MODEF 1 "register_operand"))]
15388 "TARGET_USE_FANCY_MATH_387
15389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15390 || TARGET_MIX_SSE_I387)
15391 && flag_unsafe_math_optimizations"
15393 rtx op0 = gen_reg_rtx (XFmode);
15394 rtx op1 = gen_reg_rtx (XFmode);
15396 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15397 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15403 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15404 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15405 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15406 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15408 (clobber (reg:CC FLAGS_REG))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations
15411 && can_create_pseudo_p ()"
15416 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15418 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15419 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15420 if (memory_operand (operands[0], VOIDmode))
15421 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15422 operands[2], operands[3]));
15425 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15426 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15427 (operands[0], operands[1], operands[2],
15428 operands[3], operands[4]));
15432 [(set_attr "type" "fistp")
15433 (set_attr "i387_cw" "<rounding>")
15434 (set_attr "mode" "<MODE>")])
15436 (define_insn "fistdi2_<rounding>"
15437 [(set (match_operand:DI 0 "memory_operand" "=m")
15438 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15440 (use (match_operand:HI 2 "memory_operand" "m"))
15441 (use (match_operand:HI 3 "memory_operand" "m"))
15442 (clobber (match_scratch:XF 4 "=&1f"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_unsafe_math_optimizations"
15445 "* return output_fix_trunc (insn, operands, false);"
15446 [(set_attr "type" "fistp")
15447 (set_attr "i387_cw" "<rounding>")
15448 (set_attr "mode" "DI")])
15450 (define_insn "fistdi2_<rounding>_with_temp"
15451 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15452 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15454 (use (match_operand:HI 2 "memory_operand" "m,m"))
15455 (use (match_operand:HI 3 "memory_operand" "m,m"))
15456 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15457 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && flag_unsafe_math_optimizations"
15461 [(set_attr "type" "fistp")
15462 (set_attr "i387_cw" "<rounding>")
15463 (set_attr "mode" "DI")])
15466 [(set (match_operand:DI 0 "register_operand")
15467 (unspec:DI [(match_operand:XF 1 "register_operand")]
15469 (use (match_operand:HI 2 "memory_operand"))
15470 (use (match_operand:HI 3 "memory_operand"))
15471 (clobber (match_operand:DI 4 "memory_operand"))
15472 (clobber (match_scratch 5))]
15474 [(parallel [(set (match_dup 4)
15475 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15476 (use (match_dup 2))
15477 (use (match_dup 3))
15478 (clobber (match_dup 5))])
15479 (set (match_dup 0) (match_dup 4))])
15482 [(set (match_operand:DI 0 "memory_operand")
15483 (unspec:DI [(match_operand:XF 1 "register_operand")]
15485 (use (match_operand:HI 2 "memory_operand"))
15486 (use (match_operand:HI 3 "memory_operand"))
15487 (clobber (match_operand:DI 4 "memory_operand"))
15488 (clobber (match_scratch 5))]
15490 [(parallel [(set (match_dup 0)
15491 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15492 (use (match_dup 2))
15493 (use (match_dup 3))
15494 (clobber (match_dup 5))])])
15496 (define_insn "fist<mode>2_<rounding>"
15497 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15498 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15500 (use (match_operand:HI 2 "memory_operand" "m"))
15501 (use (match_operand:HI 3 "memory_operand" "m"))]
15502 "TARGET_USE_FANCY_MATH_387
15503 && flag_unsafe_math_optimizations"
15504 "* return output_fix_trunc (insn, operands, false);"
15505 [(set_attr "type" "fistp")
15506 (set_attr "i387_cw" "<rounding>")
15507 (set_attr "mode" "<MODE>")])
15509 (define_insn "fist<mode>2_<rounding>_with_temp"
15510 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15511 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15513 (use (match_operand:HI 2 "memory_operand" "m,m"))
15514 (use (match_operand:HI 3 "memory_operand" "m,m"))
15515 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15516 "TARGET_USE_FANCY_MATH_387
15517 && flag_unsafe_math_optimizations"
15519 [(set_attr "type" "fistp")
15520 (set_attr "i387_cw" "<rounding>")
15521 (set_attr "mode" "<MODE>")])
15524 [(set (match_operand:SWI24 0 "register_operand")
15525 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15527 (use (match_operand:HI 2 "memory_operand"))
15528 (use (match_operand:HI 3 "memory_operand"))
15529 (clobber (match_operand:SWI24 4 "memory_operand"))]
15531 [(parallel [(set (match_dup 4)
15532 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15533 (use (match_dup 2))
15534 (use (match_dup 3))])
15535 (set (match_dup 0) (match_dup 4))])
15538 [(set (match_operand:SWI24 0 "memory_operand")
15539 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15541 (use (match_operand:HI 2 "memory_operand"))
15542 (use (match_operand:HI 3 "memory_operand"))
15543 (clobber (match_operand:SWI24 4 "memory_operand"))]
15545 [(parallel [(set (match_dup 0)
15546 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15547 (use (match_dup 2))
15548 (use (match_dup 3))])])
15550 (define_expand "l<rounding_insn>xf<mode>2"
15551 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15552 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15554 (clobber (reg:CC FLAGS_REG))])]
15555 "TARGET_USE_FANCY_MATH_387
15556 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15557 && flag_unsafe_math_optimizations")
15559 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15560 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15561 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15563 (clobber (reg:CC FLAGS_REG))])]
15564 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15565 && !flag_trapping_math"
15567 if (TARGET_64BIT && optimize_insn_for_size_p ())
15570 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15571 ix86_expand_lfloorceil (operands[0], operands[1], true);
15572 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15573 ix86_expand_lfloorceil (operands[0], operands[1], false);
15575 gcc_unreachable ();
15580 (define_insn "fxam<mode>2_i387"
15581 [(set (match_operand:HI 0 "register_operand" "=a")
15583 [(match_operand:X87MODEF 1 "register_operand" "f")]
15585 "TARGET_USE_FANCY_MATH_387"
15586 "fxam\n\tfnstsw\t%0"
15587 [(set_attr "type" "multi")
15588 (set_attr "length" "4")
15589 (set_attr "unit" "i387")
15590 (set_attr "mode" "<MODE>")])
15592 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15593 [(set (match_operand:HI 0 "register_operand")
15595 [(match_operand:MODEF 1 "memory_operand")]
15597 "TARGET_USE_FANCY_MATH_387
15598 && can_create_pseudo_p ()"
15601 [(set (match_dup 2)(match_dup 1))
15603 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15605 operands[2] = gen_reg_rtx (<MODE>mode);
15607 MEM_VOLATILE_P (operands[1]) = 1;
15609 [(set_attr "type" "multi")
15610 (set_attr "unit" "i387")
15611 (set_attr "mode" "<MODE>")])
15613 (define_expand "isinfxf2"
15614 [(use (match_operand:SI 0 "register_operand"))
15615 (use (match_operand:XF 1 "register_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && ix86_libc_has_function (function_c99_misc)"
15619 rtx mask = GEN_INT (0x45);
15620 rtx val = GEN_INT (0x05);
15624 rtx scratch = gen_reg_rtx (HImode);
15625 rtx res = gen_reg_rtx (QImode);
15627 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15629 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15630 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15631 cond = gen_rtx_fmt_ee (EQ, QImode,
15632 gen_rtx_REG (CCmode, FLAGS_REG),
15634 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15635 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15639 (define_expand "isinf<mode>2"
15640 [(use (match_operand:SI 0 "register_operand"))
15641 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15642 "TARGET_USE_FANCY_MATH_387
15643 && ix86_libc_has_function (function_c99_misc)
15644 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15646 rtx mask = GEN_INT (0x45);
15647 rtx val = GEN_INT (0x05);
15651 rtx scratch = gen_reg_rtx (HImode);
15652 rtx res = gen_reg_rtx (QImode);
15654 /* Remove excess precision by forcing value through memory. */
15655 if (memory_operand (operands[1], VOIDmode))
15656 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15659 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15661 emit_move_insn (temp, operands[1]);
15662 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15665 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15666 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15667 cond = gen_rtx_fmt_ee (EQ, QImode,
15668 gen_rtx_REG (CCmode, FLAGS_REG),
15670 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15671 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15675 (define_expand "signbitxf2"
15676 [(use (match_operand:SI 0 "register_operand"))
15677 (use (match_operand:XF 1 "register_operand"))]
15678 "TARGET_USE_FANCY_MATH_387"
15680 rtx scratch = gen_reg_rtx (HImode);
15682 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15683 emit_insn (gen_andsi3 (operands[0],
15684 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15688 (define_insn "movmsk_df"
15689 [(set (match_operand:SI 0 "register_operand" "=r")
15691 [(match_operand:DF 1 "register_operand" "x")]
15693 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15694 "%vmovmskpd\t{%1, %0|%0, %1}"
15695 [(set_attr "type" "ssemov")
15696 (set_attr "prefix" "maybe_vex")
15697 (set_attr "mode" "DF")])
15699 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15700 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15701 (define_expand "signbitdf2"
15702 [(use (match_operand:SI 0 "register_operand"))
15703 (use (match_operand:DF 1 "register_operand"))]
15704 "TARGET_USE_FANCY_MATH_387
15705 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15707 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15709 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15710 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15714 rtx scratch = gen_reg_rtx (HImode);
15716 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15717 emit_insn (gen_andsi3 (operands[0],
15718 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15723 (define_expand "signbitsf2"
15724 [(use (match_operand:SI 0 "register_operand"))
15725 (use (match_operand:SF 1 "register_operand"))]
15726 "TARGET_USE_FANCY_MATH_387
15727 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15729 rtx scratch = gen_reg_rtx (HImode);
15731 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15732 emit_insn (gen_andsi3 (operands[0],
15733 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15737 ;; Block operation instructions
15740 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15743 [(set_attr "length" "1")
15744 (set_attr "length_immediate" "0")
15745 (set_attr "modrm" "0")])
15747 (define_expand "movmem<mode>"
15748 [(use (match_operand:BLK 0 "memory_operand"))
15749 (use (match_operand:BLK 1 "memory_operand"))
15750 (use (match_operand:SWI48 2 "nonmemory_operand"))
15751 (use (match_operand:SWI48 3 "const_int_operand"))
15752 (use (match_operand:SI 4 "const_int_operand"))
15753 (use (match_operand:SI 5 "const_int_operand"))
15754 (use (match_operand:SI 6 ""))
15755 (use (match_operand:SI 7 ""))
15756 (use (match_operand:SI 8 ""))]
15759 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15760 operands[2], NULL, operands[3],
15761 operands[4], operands[5],
15762 operands[6], operands[7],
15763 operands[8], false))
15769 ;; Most CPUs don't like single string operations
15770 ;; Handle this case here to simplify previous expander.
15772 (define_expand "strmov"
15773 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15774 (set (match_operand 1 "memory_operand") (match_dup 4))
15775 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15776 (clobber (reg:CC FLAGS_REG))])
15777 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15778 (clobber (reg:CC FLAGS_REG))])]
15781 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15783 /* If .md ever supports :P for Pmode, these can be directly
15784 in the pattern above. */
15785 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15786 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15788 /* Can't use this if the user has appropriated esi or edi. */
15789 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15790 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15792 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15793 operands[2], operands[3],
15794 operands[5], operands[6]));
15798 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15801 (define_expand "strmov_singleop"
15802 [(parallel [(set (match_operand 1 "memory_operand")
15803 (match_operand 3 "memory_operand"))
15804 (set (match_operand 0 "register_operand")
15806 (set (match_operand 2 "register_operand")
15807 (match_operand 5))])]
15809 "ix86_current_function_needs_cld = 1;")
15811 (define_insn "*strmovdi_rex_1"
15812 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15813 (mem:DI (match_operand:P 3 "register_operand" "1")))
15814 (set (match_operand:P 0 "register_operand" "=D")
15815 (plus:P (match_dup 2)
15817 (set (match_operand:P 1 "register_operand" "=S")
15818 (plus:P (match_dup 3)
15821 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15823 [(set_attr "type" "str")
15824 (set_attr "memory" "both")
15825 (set_attr "mode" "DI")])
15827 (define_insn "*strmovsi_1"
15828 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15829 (mem:SI (match_operand:P 3 "register_operand" "1")))
15830 (set (match_operand:P 0 "register_operand" "=D")
15831 (plus:P (match_dup 2)
15833 (set (match_operand:P 1 "register_operand" "=S")
15834 (plus:P (match_dup 3)
15836 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838 [(set_attr "type" "str")
15839 (set_attr "memory" "both")
15840 (set_attr "mode" "SI")])
15842 (define_insn "*strmovhi_1"
15843 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15844 (mem:HI (match_operand:P 3 "register_operand" "1")))
15845 (set (match_operand:P 0 "register_operand" "=D")
15846 (plus:P (match_dup 2)
15848 (set (match_operand:P 1 "register_operand" "=S")
15849 (plus:P (match_dup 3)
15851 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15853 [(set_attr "type" "str")
15854 (set_attr "memory" "both")
15855 (set_attr "mode" "HI")])
15857 (define_insn "*strmovqi_1"
15858 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15859 (mem:QI (match_operand:P 3 "register_operand" "1")))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (match_dup 2)
15863 (set (match_operand:P 1 "register_operand" "=S")
15864 (plus:P (match_dup 3)
15866 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15868 [(set_attr "type" "str")
15869 (set_attr "memory" "both")
15870 (set (attr "prefix_rex")
15872 (match_test "<P:MODE>mode == DImode")
15874 (const_string "*")))
15875 (set_attr "mode" "QI")])
15877 (define_expand "rep_mov"
15878 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15879 (set (match_operand 0 "register_operand")
15881 (set (match_operand 2 "register_operand")
15883 (set (match_operand 1 "memory_operand")
15884 (match_operand 3 "memory_operand"))
15885 (use (match_dup 4))])]
15887 "ix86_current_function_needs_cld = 1;")
15889 (define_insn "*rep_movdi_rex64"
15890 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15894 (match_operand:P 3 "register_operand" "0")))
15895 (set (match_operand:P 1 "register_operand" "=S")
15896 (plus:P (ashift:P (match_dup 5) (const_int 3))
15897 (match_operand:P 4 "register_operand" "1")))
15898 (set (mem:BLK (match_dup 3))
15899 (mem:BLK (match_dup 4)))
15900 (use (match_dup 5))]
15902 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15904 [(set_attr "type" "str")
15905 (set_attr "prefix_rep" "1")
15906 (set_attr "memory" "both")
15907 (set_attr "mode" "DI")])
15909 (define_insn "*rep_movsi"
15910 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15911 (set (match_operand:P 0 "register_operand" "=D")
15912 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15914 (match_operand:P 3 "register_operand" "0")))
15915 (set (match_operand:P 1 "register_operand" "=S")
15916 (plus:P (ashift:P (match_dup 5) (const_int 2))
15917 (match_operand:P 4 "register_operand" "1")))
15918 (set (mem:BLK (match_dup 3))
15919 (mem:BLK (match_dup 4)))
15920 (use (match_dup 5))]
15921 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15922 "%^rep{%;} movs{l|d}"
15923 [(set_attr "type" "str")
15924 (set_attr "prefix_rep" "1")
15925 (set_attr "memory" "both")
15926 (set_attr "mode" "SI")])
15928 (define_insn "*rep_movqi"
15929 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15930 (set (match_operand:P 0 "register_operand" "=D")
15931 (plus:P (match_operand:P 3 "register_operand" "0")
15932 (match_operand:P 5 "register_operand" "2")))
15933 (set (match_operand:P 1 "register_operand" "=S")
15934 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15935 (set (mem:BLK (match_dup 3))
15936 (mem:BLK (match_dup 4)))
15937 (use (match_dup 5))]
15938 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15940 [(set_attr "type" "str")
15941 (set_attr "prefix_rep" "1")
15942 (set_attr "memory" "both")
15943 (set_attr "mode" "QI")])
15945 (define_expand "setmem<mode>"
15946 [(use (match_operand:BLK 0 "memory_operand"))
15947 (use (match_operand:SWI48 1 "nonmemory_operand"))
15948 (use (match_operand:QI 2 "nonmemory_operand"))
15949 (use (match_operand 3 "const_int_operand"))
15950 (use (match_operand:SI 4 "const_int_operand"))
15951 (use (match_operand:SI 5 "const_int_operand"))
15952 (use (match_operand:SI 6 ""))
15953 (use (match_operand:SI 7 ""))
15954 (use (match_operand:SI 8 ""))]
15957 if (ix86_expand_set_or_movmem (operands[0], NULL,
15958 operands[1], operands[2],
15959 operands[3], operands[4],
15960 operands[5], operands[6],
15961 operands[7], operands[8], true))
15967 ;; Most CPUs don't like single string operations
15968 ;; Handle this case here to simplify previous expander.
15970 (define_expand "strset"
15971 [(set (match_operand 1 "memory_operand")
15972 (match_operand 2 "register_operand"))
15973 (parallel [(set (match_operand 0 "register_operand")
15975 (clobber (reg:CC FLAGS_REG))])]
15978 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15979 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15981 /* If .md ever supports :P for Pmode, this can be directly
15982 in the pattern above. */
15983 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15984 GEN_INT (GET_MODE_SIZE (GET_MODE
15986 /* Can't use this if the user has appropriated eax or edi. */
15987 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15988 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15990 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15996 (define_expand "strset_singleop"
15997 [(parallel [(set (match_operand 1 "memory_operand")
15998 (match_operand 2 "register_operand"))
15999 (set (match_operand 0 "register_operand")
16001 (unspec [(const_int 0)] UNSPEC_STOS)])]
16003 "ix86_current_function_needs_cld = 1;")
16005 (define_insn "*strsetdi_rex_1"
16006 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16007 (match_operand:DI 2 "register_operand" "a"))
16008 (set (match_operand:P 0 "register_operand" "=D")
16009 (plus:P (match_dup 1)
16011 (unspec [(const_int 0)] UNSPEC_STOS)]
16013 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16015 [(set_attr "type" "str")
16016 (set_attr "memory" "store")
16017 (set_attr "mode" "DI")])
16019 (define_insn "*strsetsi_1"
16020 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16021 (match_operand:SI 2 "register_operand" "a"))
16022 (set (match_operand:P 0 "register_operand" "=D")
16023 (plus:P (match_dup 1)
16025 (unspec [(const_int 0)] UNSPEC_STOS)]
16026 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16028 [(set_attr "type" "str")
16029 (set_attr "memory" "store")
16030 (set_attr "mode" "SI")])
16032 (define_insn "*strsethi_1"
16033 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16034 (match_operand:HI 2 "register_operand" "a"))
16035 (set (match_operand:P 0 "register_operand" "=D")
16036 (plus:P (match_dup 1)
16038 (unspec [(const_int 0)] UNSPEC_STOS)]
16039 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16041 [(set_attr "type" "str")
16042 (set_attr "memory" "store")
16043 (set_attr "mode" "HI")])
16045 (define_insn "*strsetqi_1"
16046 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16047 (match_operand:QI 2 "register_operand" "a"))
16048 (set (match_operand:P 0 "register_operand" "=D")
16049 (plus:P (match_dup 1)
16051 (unspec [(const_int 0)] UNSPEC_STOS)]
16052 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16054 [(set_attr "type" "str")
16055 (set_attr "memory" "store")
16056 (set (attr "prefix_rex")
16058 (match_test "<P:MODE>mode == DImode")
16060 (const_string "*")))
16061 (set_attr "mode" "QI")])
16063 (define_expand "rep_stos"
16064 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16065 (set (match_operand 0 "register_operand")
16067 (set (match_operand 2 "memory_operand") (const_int 0))
16068 (use (match_operand 3 "register_operand"))
16069 (use (match_dup 1))])]
16071 "ix86_current_function_needs_cld = 1;")
16073 (define_insn "*rep_stosdi_rex64"
16074 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16075 (set (match_operand:P 0 "register_operand" "=D")
16076 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16078 (match_operand:P 3 "register_operand" "0")))
16079 (set (mem:BLK (match_dup 3))
16081 (use (match_operand:DI 2 "register_operand" "a"))
16082 (use (match_dup 4))]
16084 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16086 [(set_attr "type" "str")
16087 (set_attr "prefix_rep" "1")
16088 (set_attr "memory" "store")
16089 (set_attr "mode" "DI")])
16091 (define_insn "*rep_stossi"
16092 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16093 (set (match_operand:P 0 "register_operand" "=D")
16094 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16096 (match_operand:P 3 "register_operand" "0")))
16097 (set (mem:BLK (match_dup 3))
16099 (use (match_operand:SI 2 "register_operand" "a"))
16100 (use (match_dup 4))]
16101 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16102 "%^rep{%;} stos{l|d}"
16103 [(set_attr "type" "str")
16104 (set_attr "prefix_rep" "1")
16105 (set_attr "memory" "store")
16106 (set_attr "mode" "SI")])
16108 (define_insn "*rep_stosqi"
16109 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16110 (set (match_operand:P 0 "register_operand" "=D")
16111 (plus:P (match_operand:P 3 "register_operand" "0")
16112 (match_operand:P 4 "register_operand" "1")))
16113 (set (mem:BLK (match_dup 3))
16115 (use (match_operand:QI 2 "register_operand" "a"))
16116 (use (match_dup 4))]
16117 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16119 [(set_attr "type" "str")
16120 (set_attr "prefix_rep" "1")
16121 (set_attr "memory" "store")
16122 (set (attr "prefix_rex")
16124 (match_test "<P:MODE>mode == DImode")
16126 (const_string "*")))
16127 (set_attr "mode" "QI")])
16129 (define_expand "cmpstrnsi"
16130 [(set (match_operand:SI 0 "register_operand")
16131 (compare:SI (match_operand:BLK 1 "general_operand")
16132 (match_operand:BLK 2 "general_operand")))
16133 (use (match_operand 3 "general_operand"))
16134 (use (match_operand 4 "immediate_operand"))]
16137 rtx addr1, addr2, out, outlow, count, countreg, align;
16139 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16142 /* Can't use this if the user has appropriated ecx, esi or edi. */
16143 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16148 out = gen_reg_rtx (SImode);
16150 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16151 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16152 if (addr1 != XEXP (operands[1], 0))
16153 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16154 if (addr2 != XEXP (operands[2], 0))
16155 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16157 count = operands[3];
16158 countreg = ix86_zero_extend_to_Pmode (count);
16160 /* %%% Iff we are testing strict equality, we can use known alignment
16161 to good advantage. This may be possible with combine, particularly
16162 once cc0 is dead. */
16163 align = operands[4];
16165 if (CONST_INT_P (count))
16167 if (INTVAL (count) == 0)
16169 emit_move_insn (operands[0], const0_rtx);
16172 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16173 operands[1], operands[2]));
16177 rtx (*gen_cmp) (rtx, rtx);
16179 gen_cmp = (TARGET_64BIT
16180 ? gen_cmpdi_1 : gen_cmpsi_1);
16182 emit_insn (gen_cmp (countreg, countreg));
16183 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16184 operands[1], operands[2]));
16187 outlow = gen_lowpart (QImode, out);
16188 emit_insn (gen_cmpintqi (outlow));
16189 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16191 if (operands[0] != out)
16192 emit_move_insn (operands[0], out);
16197 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16199 (define_expand "cmpintqi"
16200 [(set (match_dup 1)
16201 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16203 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16204 (parallel [(set (match_operand:QI 0 "register_operand")
16205 (minus:QI (match_dup 1)
16207 (clobber (reg:CC FLAGS_REG))])]
16210 operands[1] = gen_reg_rtx (QImode);
16211 operands[2] = gen_reg_rtx (QImode);
16214 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16215 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16217 (define_expand "cmpstrnqi_nz_1"
16218 [(parallel [(set (reg:CC FLAGS_REG)
16219 (compare:CC (match_operand 4 "memory_operand")
16220 (match_operand 5 "memory_operand")))
16221 (use (match_operand 2 "register_operand"))
16222 (use (match_operand:SI 3 "immediate_operand"))
16223 (clobber (match_operand 0 "register_operand"))
16224 (clobber (match_operand 1 "register_operand"))
16225 (clobber (match_dup 2))])]
16227 "ix86_current_function_needs_cld = 1;")
16229 (define_insn "*cmpstrnqi_nz_1"
16230 [(set (reg:CC FLAGS_REG)
16231 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16232 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16233 (use (match_operand:P 6 "register_operand" "2"))
16234 (use (match_operand:SI 3 "immediate_operand" "i"))
16235 (clobber (match_operand:P 0 "register_operand" "=S"))
16236 (clobber (match_operand:P 1 "register_operand" "=D"))
16237 (clobber (match_operand:P 2 "register_operand" "=c"))]
16238 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16240 [(set_attr "type" "str")
16241 (set_attr "mode" "QI")
16242 (set (attr "prefix_rex")
16244 (match_test "<P:MODE>mode == DImode")
16246 (const_string "*")))
16247 (set_attr "prefix_rep" "1")])
16249 ;; The same, but the count is not known to not be zero.
16251 (define_expand "cmpstrnqi_1"
16252 [(parallel [(set (reg:CC FLAGS_REG)
16253 (if_then_else:CC (ne (match_operand 2 "register_operand")
16255 (compare:CC (match_operand 4 "memory_operand")
16256 (match_operand 5 "memory_operand"))
16258 (use (match_operand:SI 3 "immediate_operand"))
16259 (use (reg:CC FLAGS_REG))
16260 (clobber (match_operand 0 "register_operand"))
16261 (clobber (match_operand 1 "register_operand"))
16262 (clobber (match_dup 2))])]
16264 "ix86_current_function_needs_cld = 1;")
16266 (define_insn "*cmpstrnqi_1"
16267 [(set (reg:CC FLAGS_REG)
16268 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16270 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16271 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16273 (use (match_operand:SI 3 "immediate_operand" "i"))
16274 (use (reg:CC FLAGS_REG))
16275 (clobber (match_operand:P 0 "register_operand" "=S"))
16276 (clobber (match_operand:P 1 "register_operand" "=D"))
16277 (clobber (match_operand:P 2 "register_operand" "=c"))]
16278 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16280 [(set_attr "type" "str")
16281 (set_attr "mode" "QI")
16282 (set (attr "prefix_rex")
16284 (match_test "<P:MODE>mode == DImode")
16286 (const_string "*")))
16287 (set_attr "prefix_rep" "1")])
16289 (define_expand "strlen<mode>"
16290 [(set (match_operand:P 0 "register_operand")
16291 (unspec:P [(match_operand:BLK 1 "general_operand")
16292 (match_operand:QI 2 "immediate_operand")
16293 (match_operand 3 "immediate_operand")]
16297 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16303 (define_expand "strlenqi_1"
16304 [(parallel [(set (match_operand 0 "register_operand")
16306 (clobber (match_operand 1 "register_operand"))
16307 (clobber (reg:CC FLAGS_REG))])]
16309 "ix86_current_function_needs_cld = 1;")
16311 (define_insn "*strlenqi_1"
16312 [(set (match_operand:P 0 "register_operand" "=&c")
16313 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16314 (match_operand:QI 2 "register_operand" "a")
16315 (match_operand:P 3 "immediate_operand" "i")
16316 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16317 (clobber (match_operand:P 1 "register_operand" "=D"))
16318 (clobber (reg:CC FLAGS_REG))]
16319 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16320 "%^repnz{%;} scasb"
16321 [(set_attr "type" "str")
16322 (set_attr "mode" "QI")
16323 (set (attr "prefix_rex")
16325 (match_test "<P:MODE>mode == DImode")
16327 (const_string "*")))
16328 (set_attr "prefix_rep" "1")])
16330 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16331 ;; handled in combine, but it is not currently up to the task.
16332 ;; When used for their truth value, the cmpstrn* expanders generate
16341 ;; The intermediate three instructions are unnecessary.
16343 ;; This one handles cmpstrn*_nz_1...
16346 (set (reg:CC FLAGS_REG)
16347 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16348 (mem:BLK (match_operand 5 "register_operand"))))
16349 (use (match_operand 6 "register_operand"))
16350 (use (match_operand:SI 3 "immediate_operand"))
16351 (clobber (match_operand 0 "register_operand"))
16352 (clobber (match_operand 1 "register_operand"))
16353 (clobber (match_operand 2 "register_operand"))])
16354 (set (match_operand:QI 7 "register_operand")
16355 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16356 (set (match_operand:QI 8 "register_operand")
16357 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16358 (set (reg FLAGS_REG)
16359 (compare (match_dup 7) (match_dup 8)))
16361 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16363 (set (reg:CC FLAGS_REG)
16364 (compare:CC (mem:BLK (match_dup 4))
16365 (mem:BLK (match_dup 5))))
16366 (use (match_dup 6))
16367 (use (match_dup 3))
16368 (clobber (match_dup 0))
16369 (clobber (match_dup 1))
16370 (clobber (match_dup 2))])])
16372 ;; ...and this one handles cmpstrn*_1.
16375 (set (reg:CC FLAGS_REG)
16376 (if_then_else:CC (ne (match_operand 6 "register_operand")
16378 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16379 (mem:BLK (match_operand 5 "register_operand")))
16381 (use (match_operand:SI 3 "immediate_operand"))
16382 (use (reg:CC FLAGS_REG))
16383 (clobber (match_operand 0 "register_operand"))
16384 (clobber (match_operand 1 "register_operand"))
16385 (clobber (match_operand 2 "register_operand"))])
16386 (set (match_operand:QI 7 "register_operand")
16387 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16388 (set (match_operand:QI 8 "register_operand")
16389 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16390 (set (reg FLAGS_REG)
16391 (compare (match_dup 7) (match_dup 8)))
16393 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16395 (set (reg:CC FLAGS_REG)
16396 (if_then_else:CC (ne (match_dup 6)
16398 (compare:CC (mem:BLK (match_dup 4))
16399 (mem:BLK (match_dup 5)))
16401 (use (match_dup 3))
16402 (use (reg:CC FLAGS_REG))
16403 (clobber (match_dup 0))
16404 (clobber (match_dup 1))
16405 (clobber (match_dup 2))])])
16407 ;; Conditional move instructions.
16409 (define_expand "mov<mode>cc"
16410 [(set (match_operand:SWIM 0 "register_operand")
16411 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16412 (match_operand:SWIM 2 "<general_operand>")
16413 (match_operand:SWIM 3 "<general_operand>")))]
16415 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16417 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16418 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16419 ;; So just document what we're doing explicitly.
16421 (define_expand "x86_mov<mode>cc_0_m1"
16423 [(set (match_operand:SWI48 0 "register_operand")
16424 (if_then_else:SWI48
16425 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16426 [(match_operand 1 "flags_reg_operand")
16430 (clobber (reg:CC FLAGS_REG))])])
16432 (define_insn "*x86_mov<mode>cc_0_m1"
16433 [(set (match_operand:SWI48 0 "register_operand" "=r")
16434 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16435 [(reg FLAGS_REG) (const_int 0)])
16438 (clobber (reg:CC FLAGS_REG))]
16440 "sbb{<imodesuffix>}\t%0, %0"
16441 ; Since we don't have the proper number of operands for an alu insn,
16442 ; fill in all the blanks.
16443 [(set_attr "type" "alu")
16444 (set_attr "use_carry" "1")
16445 (set_attr "pent_pair" "pu")
16446 (set_attr "memory" "none")
16447 (set_attr "imm_disp" "false")
16448 (set_attr "mode" "<MODE>")
16449 (set_attr "length_immediate" "0")])
16451 (define_insn "*x86_mov<mode>cc_0_m1_se"
16452 [(set (match_operand:SWI48 0 "register_operand" "=r")
16453 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16457 (clobber (reg:CC FLAGS_REG))]
16459 "sbb{<imodesuffix>}\t%0, %0"
16460 [(set_attr "type" "alu")
16461 (set_attr "use_carry" "1")
16462 (set_attr "pent_pair" "pu")
16463 (set_attr "memory" "none")
16464 (set_attr "imm_disp" "false")
16465 (set_attr "mode" "<MODE>")
16466 (set_attr "length_immediate" "0")])
16468 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16469 [(set (match_operand:SWI48 0 "register_operand" "=r")
16470 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16471 [(reg FLAGS_REG) (const_int 0)])))
16472 (clobber (reg:CC FLAGS_REG))]
16474 "sbb{<imodesuffix>}\t%0, %0"
16475 [(set_attr "type" "alu")
16476 (set_attr "use_carry" "1")
16477 (set_attr "pent_pair" "pu")
16478 (set_attr "memory" "none")
16479 (set_attr "imm_disp" "false")
16480 (set_attr "mode" "<MODE>")
16481 (set_attr "length_immediate" "0")])
16483 (define_insn "*mov<mode>cc_noc"
16484 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16485 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16486 [(reg FLAGS_REG) (const_int 0)])
16487 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16488 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16489 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16491 cmov%O2%C1\t{%2, %0|%0, %2}
16492 cmov%O2%c1\t{%3, %0|%0, %3}"
16493 [(set_attr "type" "icmov")
16494 (set_attr "mode" "<MODE>")])
16496 ;; Don't do conditional moves with memory inputs. This splitter helps
16497 ;; register starved x86_32 by forcing inputs into registers before reload.
16499 [(set (match_operand:SWI248 0 "register_operand")
16500 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16501 [(reg FLAGS_REG) (const_int 0)])
16502 (match_operand:SWI248 2 "nonimmediate_operand")
16503 (match_operand:SWI248 3 "nonimmediate_operand")))]
16504 "!TARGET_64BIT && TARGET_CMOVE
16505 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16506 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16507 && can_create_pseudo_p ()
16508 && optimize_insn_for_speed_p ()"
16509 [(set (match_dup 0)
16510 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16512 if (MEM_P (operands[2]))
16513 operands[2] = force_reg (<MODE>mode, operands[2]);
16514 if (MEM_P (operands[3]))
16515 operands[3] = force_reg (<MODE>mode, operands[3]);
16518 (define_insn "*movqicc_noc"
16519 [(set (match_operand:QI 0 "register_operand" "=r,r")
16520 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:QI 2 "register_operand" "r,0")
16523 (match_operand:QI 3 "register_operand" "0,r")))]
16524 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16526 [(set_attr "type" "icmov")
16527 (set_attr "mode" "QI")])
16530 [(set (match_operand:SWI12 0 "register_operand")
16531 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16532 [(reg FLAGS_REG) (const_int 0)])
16533 (match_operand:SWI12 2 "register_operand")
16534 (match_operand:SWI12 3 "register_operand")))]
16535 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16536 && reload_completed"
16537 [(set (match_dup 0)
16538 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16540 operands[0] = gen_lowpart (SImode, operands[0]);
16541 operands[2] = gen_lowpart (SImode, operands[2]);
16542 operands[3] = gen_lowpart (SImode, operands[3]);
16545 ;; Don't do conditional moves with memory inputs
16547 [(match_scratch:SWI248 2 "r")
16548 (set (match_operand:SWI248 0 "register_operand")
16549 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16550 [(reg FLAGS_REG) (const_int 0)])
16552 (match_operand:SWI248 3 "memory_operand")))]
16553 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16554 && optimize_insn_for_speed_p ()"
16555 [(set (match_dup 2) (match_dup 3))
16557 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16560 [(match_scratch:SWI248 2 "r")
16561 (set (match_operand:SWI248 0 "register_operand")
16562 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16563 [(reg FLAGS_REG) (const_int 0)])
16564 (match_operand:SWI248 3 "memory_operand")
16566 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16567 && optimize_insn_for_speed_p ()"
16568 [(set (match_dup 2) (match_dup 3))
16570 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16572 (define_expand "mov<mode>cc"
16573 [(set (match_operand:X87MODEF 0 "register_operand")
16574 (if_then_else:X87MODEF
16575 (match_operand 1 "comparison_operator")
16576 (match_operand:X87MODEF 2 "register_operand")
16577 (match_operand:X87MODEF 3 "register_operand")))]
16578 "(TARGET_80387 && TARGET_CMOVE)
16579 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16580 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16582 (define_insn "*movxfcc_1"
16583 [(set (match_operand:XF 0 "register_operand" "=f,f")
16584 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16585 [(reg FLAGS_REG) (const_int 0)])
16586 (match_operand:XF 2 "register_operand" "f,0")
16587 (match_operand:XF 3 "register_operand" "0,f")))]
16588 "TARGET_80387 && TARGET_CMOVE"
16590 fcmov%F1\t{%2, %0|%0, %2}
16591 fcmov%f1\t{%3, %0|%0, %3}"
16592 [(set_attr "type" "fcmov")
16593 (set_attr "mode" "XF")])
16595 (define_insn "*movdfcc_1"
16596 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16597 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16598 [(reg FLAGS_REG) (const_int 0)])
16599 (match_operand:DF 2 "nonimmediate_operand"
16601 (match_operand:DF 3 "nonimmediate_operand"
16602 "0 ,f,0 ,rm,0, rm")))]
16603 "TARGET_80387 && TARGET_CMOVE
16604 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16606 fcmov%F1\t{%2, %0|%0, %2}
16607 fcmov%f1\t{%3, %0|%0, %3}
16610 cmov%O2%C1\t{%2, %0|%0, %2}
16611 cmov%O2%c1\t{%3, %0|%0, %3}"
16612 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16613 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16614 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16617 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16618 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16619 [(reg FLAGS_REG) (const_int 0)])
16620 (match_operand:DF 2 "nonimmediate_operand")
16621 (match_operand:DF 3 "nonimmediate_operand")))]
16622 "!TARGET_64BIT && reload_completed"
16623 [(set (match_dup 2)
16624 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16626 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16628 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16629 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16632 (define_insn "*movsfcc_1_387"
16633 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16634 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16635 [(reg FLAGS_REG) (const_int 0)])
16636 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16637 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16638 "TARGET_80387 && TARGET_CMOVE
16639 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16641 fcmov%F1\t{%2, %0|%0, %2}
16642 fcmov%f1\t{%3, %0|%0, %3}
16643 cmov%O2%C1\t{%2, %0|%0, %2}
16644 cmov%O2%c1\t{%3, %0|%0, %3}"
16645 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16646 (set_attr "mode" "SF,SF,SI,SI")])
16648 ;; Don't do conditional moves with memory inputs. This splitter helps
16649 ;; register starved x86_32 by forcing inputs into registers before reload.
16651 [(set (match_operand:MODEF 0 "register_operand")
16652 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16653 [(reg FLAGS_REG) (const_int 0)])
16654 (match_operand:MODEF 2 "nonimmediate_operand")
16655 (match_operand:MODEF 3 "nonimmediate_operand")))]
16656 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16657 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16658 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16659 && can_create_pseudo_p ()
16660 && optimize_insn_for_speed_p ()"
16661 [(set (match_dup 0)
16662 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16664 if (MEM_P (operands[2]))
16665 operands[2] = force_reg (<MODE>mode, operands[2]);
16666 if (MEM_P (operands[3]))
16667 operands[3] = force_reg (<MODE>mode, operands[3]);
16670 ;; Don't do conditional moves with memory inputs
16672 [(match_scratch:MODEF 2 "r")
16673 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16674 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16675 [(reg FLAGS_REG) (const_int 0)])
16677 (match_operand:MODEF 3 "memory_operand")))]
16678 "(<MODE>mode != DFmode || TARGET_64BIT)
16679 && TARGET_80387 && TARGET_CMOVE
16680 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16681 && optimize_insn_for_speed_p ()"
16682 [(set (match_dup 2) (match_dup 3))
16684 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16687 [(match_scratch:MODEF 2 "r")
16688 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16689 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16690 [(reg FLAGS_REG) (const_int 0)])
16691 (match_operand:MODEF 3 "memory_operand")
16693 "(<MODE>mode != DFmode || TARGET_64BIT)
16694 && TARGET_80387 && TARGET_CMOVE
16695 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16696 && optimize_insn_for_speed_p ()"
16697 [(set (match_dup 2) (match_dup 3))
16699 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16701 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16702 ;; the scalar versions to have only XMM registers as operands.
16704 ;; XOP conditional move
16705 (define_insn "*xop_pcmov_<mode>"
16706 [(set (match_operand:MODEF 0 "register_operand" "=x")
16707 (if_then_else:MODEF
16708 (match_operand:MODEF 1 "register_operand" "x")
16709 (match_operand:MODEF 2 "register_operand" "x")
16710 (match_operand:MODEF 3 "register_operand" "x")))]
16712 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16713 [(set_attr "type" "sse4arg")])
16715 ;; These versions of the min/max patterns are intentionally ignorant of
16716 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16717 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16718 ;; are undefined in this condition, we're certain this is correct.
16720 (define_insn "<code><mode>3"
16721 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16723 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16724 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16725 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16727 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16728 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16729 [(set_attr "isa" "noavx,avx")
16730 (set_attr "prefix" "orig,vex")
16731 (set_attr "type" "sseadd")
16732 (set_attr "mode" "<MODE>")])
16734 ;; These versions of the min/max patterns implement exactly the operations
16735 ;; min = (op1 < op2 ? op1 : op2)
16736 ;; max = (!(op1 < op2) ? op1 : op2)
16737 ;; Their operands are not commutative, and thus they may be used in the
16738 ;; presence of -0.0 and NaN.
16740 (define_int_iterator IEEE_MAXMIN
16744 (define_int_attr ieee_maxmin
16745 [(UNSPEC_IEEE_MAX "max")
16746 (UNSPEC_IEEE_MIN "min")])
16748 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16749 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16751 [(match_operand:MODEF 1 "register_operand" "0,x")
16752 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16756 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16757 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16758 [(set_attr "isa" "noavx,avx")
16759 (set_attr "prefix" "orig,vex")
16760 (set_attr "type" "sseadd")
16761 (set_attr "mode" "<MODE>")])
16763 ;; Make two stack loads independent:
16765 ;; fld %st(0) -> fld bb
16766 ;; fmul bb fmul %st(1), %st
16768 ;; Actually we only match the last two instructions for simplicity.
16770 [(set (match_operand 0 "fp_register_operand")
16771 (match_operand 1 "fp_register_operand"))
16773 (match_operator 2 "binary_fp_operator"
16775 (match_operand 3 "memory_operand")]))]
16776 "REGNO (operands[0]) != REGNO (operands[1])"
16777 [(set (match_dup 0) (match_dup 3))
16778 (set (match_dup 0) (match_dup 4))]
16780 ;; The % modifier is not operational anymore in peephole2's, so we have to
16781 ;; swap the operands manually in the case of addition and multiplication.
16785 if (COMMUTATIVE_ARITH_P (operands[2]))
16786 op0 = operands[0], op1 = operands[1];
16788 op0 = operands[1], op1 = operands[0];
16790 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16791 GET_MODE (operands[2]),
16795 ;; Conditional addition patterns
16796 (define_expand "add<mode>cc"
16797 [(match_operand:SWI 0 "register_operand")
16798 (match_operand 1 "ordered_comparison_operator")
16799 (match_operand:SWI 2 "register_operand")
16800 (match_operand:SWI 3 "const_int_operand")]
16802 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16804 ;; Misc patterns (?)
16806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16807 ;; Otherwise there will be nothing to keep
16809 ;; [(set (reg ebp) (reg esp))]
16810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16811 ;; (clobber (eflags)]
16812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16814 ;; in proper program order.
16816 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16817 [(set (match_operand:P 0 "register_operand" "=r,r")
16818 (plus:P (match_operand:P 1 "register_operand" "0,r")
16819 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16820 (clobber (reg:CC FLAGS_REG))
16821 (clobber (mem:BLK (scratch)))]
16824 switch (get_attr_type (insn))
16827 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16830 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16831 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16832 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16834 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16837 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16838 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16841 [(set (attr "type")
16842 (cond [(and (eq_attr "alternative" "0")
16843 (not (match_test "TARGET_OPT_AGU")))
16844 (const_string "alu")
16845 (match_operand:<MODE> 2 "const0_operand")
16846 (const_string "imov")
16848 (const_string "lea")))
16849 (set (attr "length_immediate")
16850 (cond [(eq_attr "type" "imov")
16852 (and (eq_attr "type" "alu")
16853 (match_operand 2 "const128_operand"))
16856 (const_string "*")))
16857 (set_attr "mode" "<MODE>")])
16859 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16860 [(set (match_operand:P 0 "register_operand" "=r")
16861 (minus:P (match_operand:P 1 "register_operand" "0")
16862 (match_operand:P 2 "register_operand" "r")))
16863 (clobber (reg:CC FLAGS_REG))
16864 (clobber (mem:BLK (scratch)))]
16866 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16867 [(set_attr "type" "alu")
16868 (set_attr "mode" "<MODE>")])
16870 (define_insn "allocate_stack_worker_probe_<mode>"
16871 [(set (match_operand:P 0 "register_operand" "=a")
16872 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16873 UNSPECV_STACK_PROBE))
16874 (clobber (reg:CC FLAGS_REG))]
16875 "ix86_target_stack_probe ()"
16876 "call\t___chkstk_ms"
16877 [(set_attr "type" "multi")
16878 (set_attr "length" "5")])
16880 (define_expand "allocate_stack"
16881 [(match_operand 0 "register_operand")
16882 (match_operand 1 "general_operand")]
16883 "ix86_target_stack_probe ()"
16887 #ifndef CHECK_STACK_LIMIT
16888 #define CHECK_STACK_LIMIT 0
16891 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16892 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16896 rtx (*insn) (rtx, rtx);
16898 x = copy_to_mode_reg (Pmode, operands[1]);
16900 insn = (TARGET_64BIT
16901 ? gen_allocate_stack_worker_probe_di
16902 : gen_allocate_stack_worker_probe_si);
16904 emit_insn (insn (x, x));
16907 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16908 stack_pointer_rtx, 0, OPTAB_DIRECT);
16910 if (x != stack_pointer_rtx)
16911 emit_move_insn (stack_pointer_rtx, x);
16913 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16917 ;; Use IOR for stack probes, this is shorter.
16918 (define_expand "probe_stack"
16919 [(match_operand 0 "memory_operand")]
16922 rtx (*gen_ior3) (rtx, rtx, rtx);
16924 gen_ior3 = (GET_MODE (operands[0]) == DImode
16925 ? gen_iordi3 : gen_iorsi3);
16927 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16931 (define_insn "adjust_stack_and_probe<mode>"
16932 [(set (match_operand:P 0 "register_operand" "=r")
16933 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16934 UNSPECV_PROBE_STACK_RANGE))
16935 (set (reg:P SP_REG)
16936 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16937 (clobber (reg:CC FLAGS_REG))
16938 (clobber (mem:BLK (scratch)))]
16940 "* return output_adjust_stack_and_probe (operands[0]);"
16941 [(set_attr "type" "multi")])
16943 (define_insn "probe_stack_range<mode>"
16944 [(set (match_operand:P 0 "register_operand" "=r")
16945 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16946 (match_operand:P 2 "const_int_operand" "n")]
16947 UNSPECV_PROBE_STACK_RANGE))
16948 (clobber (reg:CC FLAGS_REG))]
16950 "* return output_probe_stack_range (operands[0], operands[2]);"
16951 [(set_attr "type" "multi")])
16953 (define_expand "builtin_setjmp_receiver"
16954 [(label_ref (match_operand 0))]
16955 "!TARGET_64BIT && flag_pic"
16961 rtx_code_label *label_rtx = gen_label_rtx ();
16962 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16963 xops[0] = xops[1] = pic_offset_table_rtx;
16964 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16965 ix86_expand_binary_operator (MINUS, SImode, xops);
16969 emit_insn (gen_set_got (pic_offset_table_rtx));
16973 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16974 ;; Do not split instructions with mask registers.
16976 [(set (match_operand 0 "general_reg_operand")
16977 (match_operator 3 "promotable_binary_operator"
16978 [(match_operand 1 "general_reg_operand")
16979 (match_operand 2 "aligned_operand")]))
16980 (clobber (reg:CC FLAGS_REG))]
16981 "! TARGET_PARTIAL_REG_STALL && reload_completed
16982 && ((GET_MODE (operands[0]) == HImode
16983 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16984 /* ??? next two lines just !satisfies_constraint_K (...) */
16985 || !CONST_INT_P (operands[2])
16986 || satisfies_constraint_K (operands[2])))
16987 || (GET_MODE (operands[0]) == QImode
16988 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16989 [(parallel [(set (match_dup 0)
16990 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16991 (clobber (reg:CC FLAGS_REG))])]
16993 operands[0] = gen_lowpart (SImode, operands[0]);
16994 operands[1] = gen_lowpart (SImode, operands[1]);
16995 if (GET_CODE (operands[3]) != ASHIFT)
16996 operands[2] = gen_lowpart (SImode, operands[2]);
16997 PUT_MODE (operands[3], SImode);
17000 ; Promote the QImode tests, as i386 has encoding of the AND
17001 ; instruction with 32-bit sign-extended immediate and thus the
17002 ; instruction size is unchanged, except in the %eax case for
17003 ; which it is increased by one byte, hence the ! optimize_size.
17005 [(set (match_operand 0 "flags_reg_operand")
17006 (match_operator 2 "compare_operator"
17007 [(and (match_operand 3 "aligned_operand")
17008 (match_operand 4 "const_int_operand"))
17010 (set (match_operand 1 "register_operand")
17011 (and (match_dup 3) (match_dup 4)))]
17012 "! TARGET_PARTIAL_REG_STALL && reload_completed
17013 && optimize_insn_for_speed_p ()
17014 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17015 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17016 /* Ensure that the operand will remain sign-extended immediate. */
17017 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17018 [(parallel [(set (match_dup 0)
17019 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17022 (and:SI (match_dup 3) (match_dup 4)))])]
17025 = gen_int_mode (INTVAL (operands[4])
17026 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17027 operands[1] = gen_lowpart (SImode, operands[1]);
17028 operands[3] = gen_lowpart (SImode, operands[3]);
17031 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17032 ; the TEST instruction with 32-bit sign-extended immediate and thus
17033 ; the instruction size would at least double, which is not what we
17034 ; want even with ! optimize_size.
17036 [(set (match_operand 0 "flags_reg_operand")
17037 (match_operator 1 "compare_operator"
17038 [(and (match_operand:HI 2 "aligned_operand")
17039 (match_operand:HI 3 "const_int_operand"))
17041 "! TARGET_PARTIAL_REG_STALL && reload_completed
17042 && ! TARGET_FAST_PREFIX
17043 && optimize_insn_for_speed_p ()
17044 /* Ensure that the operand will remain sign-extended immediate. */
17045 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17046 [(set (match_dup 0)
17047 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17051 = gen_int_mode (INTVAL (operands[3])
17052 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17053 operands[2] = gen_lowpart (SImode, operands[2]);
17057 [(set (match_operand 0 "register_operand")
17058 (neg (match_operand 1 "register_operand")))
17059 (clobber (reg:CC FLAGS_REG))]
17060 "! TARGET_PARTIAL_REG_STALL && reload_completed
17061 && (GET_MODE (operands[0]) == HImode
17062 || (GET_MODE (operands[0]) == QImode
17063 && (TARGET_PROMOTE_QImode
17064 || optimize_insn_for_size_p ())))"
17065 [(parallel [(set (match_dup 0)
17066 (neg:SI (match_dup 1)))
17067 (clobber (reg:CC FLAGS_REG))])]
17069 operands[0] = gen_lowpart (SImode, operands[0]);
17070 operands[1] = gen_lowpart (SImode, operands[1]);
17073 ;; Do not split instructions with mask regs.
17075 [(set (match_operand 0 "general_reg_operand")
17076 (not (match_operand 1 "general_reg_operand")))]
17077 "! TARGET_PARTIAL_REG_STALL && reload_completed
17078 && (GET_MODE (operands[0]) == HImode
17079 || (GET_MODE (operands[0]) == QImode
17080 && (TARGET_PROMOTE_QImode
17081 || optimize_insn_for_size_p ())))"
17082 [(set (match_dup 0)
17083 (not:SI (match_dup 1)))]
17085 operands[0] = gen_lowpart (SImode, operands[0]);
17086 operands[1] = gen_lowpart (SImode, operands[1]);
17089 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17090 ;; transform a complex memory operation into two memory to register operations.
17092 ;; Don't push memory operands
17094 [(set (match_operand:SWI 0 "push_operand")
17095 (match_operand:SWI 1 "memory_operand"))
17096 (match_scratch:SWI 2 "<r>")]
17097 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17098 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17099 [(set (match_dup 2) (match_dup 1))
17100 (set (match_dup 0) (match_dup 2))])
17102 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17105 [(set (match_operand:SF 0 "push_operand")
17106 (match_operand:SF 1 "memory_operand"))
17107 (match_scratch:SF 2 "r")]
17108 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17109 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17110 [(set (match_dup 2) (match_dup 1))
17111 (set (match_dup 0) (match_dup 2))])
17113 ;; Don't move an immediate directly to memory when the instruction
17114 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17116 [(match_scratch:SWI124 1 "<r>")
17117 (set (match_operand:SWI124 0 "memory_operand")
17119 "optimize_insn_for_speed_p ()
17120 && ((<MODE>mode == HImode
17121 && TARGET_LCP_STALL)
17122 || (!TARGET_USE_MOV0
17123 && TARGET_SPLIT_LONG_MOVES
17124 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17125 && peep2_regno_dead_p (0, FLAGS_REG)"
17126 [(parallel [(set (match_dup 2) (const_int 0))
17127 (clobber (reg:CC FLAGS_REG))])
17128 (set (match_dup 0) (match_dup 1))]
17129 "operands[2] = gen_lowpart (SImode, operands[1]);")
17132 [(match_scratch:SWI124 2 "<r>")
17133 (set (match_operand:SWI124 0 "memory_operand")
17134 (match_operand:SWI124 1 "immediate_operand"))]
17135 "optimize_insn_for_speed_p ()
17136 && ((<MODE>mode == HImode
17137 && TARGET_LCP_STALL)
17138 || (TARGET_SPLIT_LONG_MOVES
17139 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17140 [(set (match_dup 2) (match_dup 1))
17141 (set (match_dup 0) (match_dup 2))])
17143 ;; Don't compare memory with zero, load and use a test instead.
17145 [(set (match_operand 0 "flags_reg_operand")
17146 (match_operator 1 "compare_operator"
17147 [(match_operand:SI 2 "memory_operand")
17149 (match_scratch:SI 3 "r")]
17150 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17151 [(set (match_dup 3) (match_dup 2))
17152 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17154 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17155 ;; Don't split NOTs with a displacement operand, because resulting XOR
17156 ;; will not be pairable anyway.
17158 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17159 ;; represented using a modRM byte. The XOR replacement is long decoded,
17160 ;; so this split helps here as well.
17162 ;; Note: Can't do this as a regular split because we can't get proper
17163 ;; lifetime information then.
17166 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17167 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17168 "optimize_insn_for_speed_p ()
17169 && ((TARGET_NOT_UNPAIRABLE
17170 && (!MEM_P (operands[0])
17171 || !memory_displacement_operand (operands[0], <MODE>mode)))
17172 || (TARGET_NOT_VECTORMODE
17173 && long_memory_operand (operands[0], <MODE>mode)))
17174 && peep2_regno_dead_p (0, FLAGS_REG)"
17175 [(parallel [(set (match_dup 0)
17176 (xor:SWI124 (match_dup 1) (const_int -1)))
17177 (clobber (reg:CC FLAGS_REG))])])
17179 ;; Non pairable "test imm, reg" instructions can be translated to
17180 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17181 ;; byte opcode instead of two, have a short form for byte operands),
17182 ;; so do it for other CPUs as well. Given that the value was dead,
17183 ;; this should not create any new dependencies. Pass on the sub-word
17184 ;; versions if we're concerned about partial register stalls.
17187 [(set (match_operand 0 "flags_reg_operand")
17188 (match_operator 1 "compare_operator"
17189 [(and:SI (match_operand:SI 2 "register_operand")
17190 (match_operand:SI 3 "immediate_operand"))
17192 "ix86_match_ccmode (insn, CCNOmode)
17193 && (true_regnum (operands[2]) != AX_REG
17194 || satisfies_constraint_K (operands[3]))
17195 && peep2_reg_dead_p (1, operands[2])"
17197 [(set (match_dup 0)
17198 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17201 (and:SI (match_dup 2) (match_dup 3)))])])
17203 ;; We don't need to handle HImode case, because it will be promoted to SImode
17204 ;; on ! TARGET_PARTIAL_REG_STALL
17207 [(set (match_operand 0 "flags_reg_operand")
17208 (match_operator 1 "compare_operator"
17209 [(and:QI (match_operand:QI 2 "register_operand")
17210 (match_operand:QI 3 "immediate_operand"))
17212 "! TARGET_PARTIAL_REG_STALL
17213 && ix86_match_ccmode (insn, CCNOmode)
17214 && true_regnum (operands[2]) != AX_REG
17215 && peep2_reg_dead_p (1, operands[2])"
17217 [(set (match_dup 0)
17218 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17221 (and:QI (match_dup 2) (match_dup 3)))])])
17224 [(set (match_operand 0 "flags_reg_operand")
17225 (match_operator 1 "compare_operator"
17228 (match_operand 2 "ext_register_operand")
17231 (match_operand 3 "const_int_operand"))
17233 "! TARGET_PARTIAL_REG_STALL
17234 && ix86_match_ccmode (insn, CCNOmode)
17235 && true_regnum (operands[2]) != AX_REG
17236 && peep2_reg_dead_p (1, operands[2])"
17237 [(parallel [(set (match_dup 0)
17246 (set (zero_extract:SI (match_dup 2)
17254 (match_dup 3)))])])
17256 ;; Don't do logical operations with memory inputs.
17258 [(match_scratch:SI 2 "r")
17259 (parallel [(set (match_operand:SI 0 "register_operand")
17260 (match_operator:SI 3 "arith_or_logical_operator"
17262 (match_operand:SI 1 "memory_operand")]))
17263 (clobber (reg:CC FLAGS_REG))])]
17264 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17265 [(set (match_dup 2) (match_dup 1))
17266 (parallel [(set (match_dup 0)
17267 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17268 (clobber (reg:CC FLAGS_REG))])])
17271 [(match_scratch:SI 2 "r")
17272 (parallel [(set (match_operand:SI 0 "register_operand")
17273 (match_operator:SI 3 "arith_or_logical_operator"
17274 [(match_operand:SI 1 "memory_operand")
17276 (clobber (reg:CC FLAGS_REG))])]
17277 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17278 [(set (match_dup 2) (match_dup 1))
17279 (parallel [(set (match_dup 0)
17280 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17281 (clobber (reg:CC FLAGS_REG))])])
17283 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17284 ;; refers to the destination of the load!
17287 [(set (match_operand:SI 0 "register_operand")
17288 (match_operand:SI 1 "register_operand"))
17289 (parallel [(set (match_dup 0)
17290 (match_operator:SI 3 "commutative_operator"
17292 (match_operand:SI 2 "memory_operand")]))
17293 (clobber (reg:CC FLAGS_REG))])]
17294 "REGNO (operands[0]) != REGNO (operands[1])
17295 && GENERAL_REGNO_P (REGNO (operands[0]))
17296 && GENERAL_REGNO_P (REGNO (operands[1]))"
17297 [(set (match_dup 0) (match_dup 4))
17298 (parallel [(set (match_dup 0)
17299 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17300 (clobber (reg:CC FLAGS_REG))])]
17301 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17304 [(set (match_operand 0 "register_operand")
17305 (match_operand 1 "register_operand"))
17307 (match_operator 3 "commutative_operator"
17309 (match_operand 2 "memory_operand")]))]
17310 "REGNO (operands[0]) != REGNO (operands[1])
17311 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17312 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17313 [(set (match_dup 0) (match_dup 2))
17315 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17317 ; Don't do logical operations with memory outputs
17319 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17320 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17321 ; the same decoder scheduling characteristics as the original.
17324 [(match_scratch:SI 2 "r")
17325 (parallel [(set (match_operand:SI 0 "memory_operand")
17326 (match_operator:SI 3 "arith_or_logical_operator"
17328 (match_operand:SI 1 "nonmemory_operand")]))
17329 (clobber (reg:CC FLAGS_REG))])]
17330 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17331 /* Do not split stack checking probes. */
17332 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17333 [(set (match_dup 2) (match_dup 0))
17334 (parallel [(set (match_dup 2)
17335 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17336 (clobber (reg:CC FLAGS_REG))])
17337 (set (match_dup 0) (match_dup 2))])
17340 [(match_scratch:SI 2 "r")
17341 (parallel [(set (match_operand:SI 0 "memory_operand")
17342 (match_operator:SI 3 "arith_or_logical_operator"
17343 [(match_operand:SI 1 "nonmemory_operand")
17345 (clobber (reg:CC FLAGS_REG))])]
17346 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17347 /* Do not split stack checking probes. */
17348 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17349 [(set (match_dup 2) (match_dup 0))
17350 (parallel [(set (match_dup 2)
17351 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17352 (clobber (reg:CC FLAGS_REG))])
17353 (set (match_dup 0) (match_dup 2))])
17355 ;; Attempt to use arith or logical operations with memory outputs with
17356 ;; setting of flags.
17358 [(set (match_operand:SWI 0 "register_operand")
17359 (match_operand:SWI 1 "memory_operand"))
17360 (parallel [(set (match_dup 0)
17361 (match_operator:SWI 3 "plusminuslogic_operator"
17363 (match_operand:SWI 2 "<nonmemory_operand>")]))
17364 (clobber (reg:CC FLAGS_REG))])
17365 (set (match_dup 1) (match_dup 0))
17366 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17367 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17368 && peep2_reg_dead_p (4, operands[0])
17369 && !reg_overlap_mentioned_p (operands[0], operands[1])
17370 && !reg_overlap_mentioned_p (operands[0], operands[2])
17371 && (<MODE>mode != QImode
17372 || immediate_operand (operands[2], QImode)
17373 || q_regs_operand (operands[2], QImode))
17374 && ix86_match_ccmode (peep2_next_insn (3),
17375 (GET_CODE (operands[3]) == PLUS
17376 || GET_CODE (operands[3]) == MINUS)
17377 ? CCGOCmode : CCNOmode)"
17378 [(parallel [(set (match_dup 4) (match_dup 5))
17379 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17380 (match_dup 2)]))])]
17382 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17383 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17384 copy_rtx (operands[1]),
17385 copy_rtx (operands[2]));
17386 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17387 operands[5], const0_rtx);
17391 [(parallel [(set (match_operand:SWI 0 "register_operand")
17392 (match_operator:SWI 2 "plusminuslogic_operator"
17394 (match_operand:SWI 1 "memory_operand")]))
17395 (clobber (reg:CC FLAGS_REG))])
17396 (set (match_dup 1) (match_dup 0))
17397 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17398 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17399 && GET_CODE (operands[2]) != MINUS
17400 && peep2_reg_dead_p (3, operands[0])
17401 && !reg_overlap_mentioned_p (operands[0], operands[1])
17402 && ix86_match_ccmode (peep2_next_insn (2),
17403 GET_CODE (operands[2]) == PLUS
17404 ? CCGOCmode : CCNOmode)"
17405 [(parallel [(set (match_dup 3) (match_dup 4))
17406 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17407 (match_dup 0)]))])]
17409 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17410 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17411 copy_rtx (operands[1]),
17412 copy_rtx (operands[0]));
17413 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17414 operands[4], const0_rtx);
17418 [(set (match_operand:SWI12 0 "register_operand")
17419 (match_operand:SWI12 1 "memory_operand"))
17420 (parallel [(set (match_operand:SI 4 "register_operand")
17421 (match_operator:SI 3 "plusminuslogic_operator"
17423 (match_operand:SI 2 "nonmemory_operand")]))
17424 (clobber (reg:CC FLAGS_REG))])
17425 (set (match_dup 1) (match_dup 0))
17426 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17427 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17428 && REG_P (operands[0]) && REG_P (operands[4])
17429 && REGNO (operands[0]) == REGNO (operands[4])
17430 && peep2_reg_dead_p (4, operands[0])
17431 && (<MODE>mode != QImode
17432 || immediate_operand (operands[2], SImode)
17433 || q_regs_operand (operands[2], SImode))
17434 && !reg_overlap_mentioned_p (operands[0], operands[1])
17435 && !reg_overlap_mentioned_p (operands[0], operands[2])
17436 && ix86_match_ccmode (peep2_next_insn (3),
17437 (GET_CODE (operands[3]) == PLUS
17438 || GET_CODE (operands[3]) == MINUS)
17439 ? CCGOCmode : CCNOmode)"
17440 [(parallel [(set (match_dup 4) (match_dup 5))
17441 (set (match_dup 1) (match_dup 6))])]
17443 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17444 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17445 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17446 copy_rtx (operands[1]), operands[2]);
17447 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17448 operands[5], const0_rtx);
17449 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17450 copy_rtx (operands[1]),
17451 copy_rtx (operands[2]));
17454 ;; Attempt to always use XOR for zeroing registers.
17456 [(set (match_operand 0 "register_operand")
17457 (match_operand 1 "const0_operand"))]
17458 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17459 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17460 && GENERAL_REG_P (operands[0])
17461 && peep2_regno_dead_p (0, FLAGS_REG)"
17462 [(parallel [(set (match_dup 0) (const_int 0))
17463 (clobber (reg:CC FLAGS_REG))])]
17464 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17467 [(set (strict_low_part (match_operand 0 "register_operand"))
17469 "(GET_MODE (operands[0]) == QImode
17470 || GET_MODE (operands[0]) == HImode)
17471 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17472 && peep2_regno_dead_p (0, FLAGS_REG)"
17473 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17474 (clobber (reg:CC FLAGS_REG))])])
17476 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17478 [(set (match_operand:SWI248 0 "register_operand")
17480 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17481 && peep2_regno_dead_p (0, FLAGS_REG)"
17482 [(parallel [(set (match_dup 0) (const_int -1))
17483 (clobber (reg:CC FLAGS_REG))])]
17485 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17486 operands[0] = gen_lowpart (SImode, operands[0]);
17489 ;; Attempt to convert simple lea to add/shift.
17490 ;; These can be created by move expanders.
17491 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17492 ;; relevant lea instructions were already split.
17495 [(set (match_operand:SWI48 0 "register_operand")
17496 (plus:SWI48 (match_dup 0)
17497 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17499 && peep2_regno_dead_p (0, FLAGS_REG)"
17500 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17501 (clobber (reg:CC FLAGS_REG))])])
17504 [(set (match_operand:SWI48 0 "register_operand")
17505 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17508 && peep2_regno_dead_p (0, FLAGS_REG)"
17509 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17510 (clobber (reg:CC FLAGS_REG))])])
17513 [(set (match_operand:DI 0 "register_operand")
17515 (plus:SI (match_operand:SI 1 "register_operand")
17516 (match_operand:SI 2 "nonmemory_operand"))))]
17517 "TARGET_64BIT && !TARGET_OPT_AGU
17518 && REGNO (operands[0]) == REGNO (operands[1])
17519 && peep2_regno_dead_p (0, FLAGS_REG)"
17520 [(parallel [(set (match_dup 0)
17521 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17522 (clobber (reg:CC FLAGS_REG))])])
17525 [(set (match_operand:DI 0 "register_operand")
17527 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17528 (match_operand:SI 2 "register_operand"))))]
17529 "TARGET_64BIT && !TARGET_OPT_AGU
17530 && REGNO (operands[0]) == REGNO (operands[2])
17531 && peep2_regno_dead_p (0, FLAGS_REG)"
17532 [(parallel [(set (match_dup 0)
17533 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17534 (clobber (reg:CC FLAGS_REG))])])
17537 [(set (match_operand:SWI48 0 "register_operand")
17538 (mult:SWI48 (match_dup 0)
17539 (match_operand:SWI48 1 "const_int_operand")))]
17540 "exact_log2 (INTVAL (operands[1])) >= 0
17541 && peep2_regno_dead_p (0, FLAGS_REG)"
17542 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17547 [(set (match_operand:DI 0 "register_operand")
17549 (mult:SI (match_operand:SI 1 "register_operand")
17550 (match_operand:SI 2 "const_int_operand"))))]
17552 && exact_log2 (INTVAL (operands[2])) >= 0
17553 && REGNO (operands[0]) == REGNO (operands[1])
17554 && peep2_regno_dead_p (0, FLAGS_REG)"
17555 [(parallel [(set (match_dup 0)
17556 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17557 (clobber (reg:CC FLAGS_REG))])]
17558 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17560 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17561 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17562 ;; On many CPUs it is also faster, since special hardware to avoid esp
17563 ;; dependencies is present.
17565 ;; While some of these conversions may be done using splitters, we use
17566 ;; peepholes in order to allow combine_stack_adjustments pass to see
17567 ;; nonobfuscated RTL.
17569 ;; Convert prologue esp subtractions to push.
17570 ;; We need register to push. In order to keep verify_flow_info happy we have
17572 ;; - use scratch and clobber it in order to avoid dependencies
17573 ;; - use already live register
17574 ;; We can't use the second way right now, since there is no reliable way how to
17575 ;; verify that given register is live. First choice will also most likely in
17576 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17577 ;; call clobbered registers are dead. We may want to use base pointer as an
17578 ;; alternative when no register is available later.
17581 [(match_scratch:W 1 "r")
17582 (parallel [(set (reg:P SP_REG)
17583 (plus:P (reg:P SP_REG)
17584 (match_operand:P 0 "const_int_operand")))
17585 (clobber (reg:CC FLAGS_REG))
17586 (clobber (mem:BLK (scratch)))])]
17587 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17588 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17589 [(clobber (match_dup 1))
17590 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17591 (clobber (mem:BLK (scratch)))])])
17594 [(match_scratch:W 1 "r")
17595 (parallel [(set (reg:P SP_REG)
17596 (plus:P (reg:P SP_REG)
17597 (match_operand:P 0 "const_int_operand")))
17598 (clobber (reg:CC FLAGS_REG))
17599 (clobber (mem:BLK (scratch)))])]
17600 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17601 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17602 [(clobber (match_dup 1))
17603 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17604 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17605 (clobber (mem:BLK (scratch)))])])
17607 ;; Convert esp subtractions to push.
17609 [(match_scratch:W 1 "r")
17610 (parallel [(set (reg:P SP_REG)
17611 (plus:P (reg:P SP_REG)
17612 (match_operand:P 0 "const_int_operand")))
17613 (clobber (reg:CC FLAGS_REG))])]
17614 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17615 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17616 [(clobber (match_dup 1))
17617 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17620 [(match_scratch:W 1 "r")
17621 (parallel [(set (reg:P SP_REG)
17622 (plus:P (reg:P SP_REG)
17623 (match_operand:P 0 "const_int_operand")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17626 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17627 [(clobber (match_dup 1))
17628 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17629 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17631 ;; Convert epilogue deallocator to pop.
17633 [(match_scratch:W 1 "r")
17634 (parallel [(set (reg:P SP_REG)
17635 (plus:P (reg:P SP_REG)
17636 (match_operand:P 0 "const_int_operand")))
17637 (clobber (reg:CC FLAGS_REG))
17638 (clobber (mem:BLK (scratch)))])]
17639 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17640 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17641 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17642 (clobber (mem:BLK (scratch)))])])
17644 ;; Two pops case is tricky, since pop causes dependency
17645 ;; on destination register. We use two registers if available.
17647 [(match_scratch:W 1 "r")
17648 (match_scratch:W 2 "r")
17649 (parallel [(set (reg:P SP_REG)
17650 (plus:P (reg:P SP_REG)
17651 (match_operand:P 0 "const_int_operand")))
17652 (clobber (reg:CC FLAGS_REG))
17653 (clobber (mem:BLK (scratch)))])]
17654 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17655 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17656 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17657 (clobber (mem:BLK (scratch)))])
17658 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17661 [(match_scratch:W 1 "r")
17662 (parallel [(set (reg:P SP_REG)
17663 (plus:P (reg:P SP_REG)
17664 (match_operand:P 0 "const_int_operand")))
17665 (clobber (reg:CC FLAGS_REG))
17666 (clobber (mem:BLK (scratch)))])]
17667 "optimize_insn_for_size_p ()
17668 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17669 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17670 (clobber (mem:BLK (scratch)))])
17671 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17673 ;; Convert esp additions to pop.
17675 [(match_scratch:W 1 "r")
17676 (parallel [(set (reg:P SP_REG)
17677 (plus:P (reg:P SP_REG)
17678 (match_operand:P 0 "const_int_operand")))
17679 (clobber (reg:CC FLAGS_REG))])]
17680 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17681 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17683 ;; Two pops case is tricky, since pop causes dependency
17684 ;; on destination register. We use two registers if available.
17686 [(match_scratch:W 1 "r")
17687 (match_scratch:W 2 "r")
17688 (parallel [(set (reg:P SP_REG)
17689 (plus:P (reg:P SP_REG)
17690 (match_operand:P 0 "const_int_operand")))
17691 (clobber (reg:CC FLAGS_REG))])]
17692 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17693 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17694 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17697 [(match_scratch:W 1 "r")
17698 (parallel [(set (reg:P SP_REG)
17699 (plus:P (reg:P SP_REG)
17700 (match_operand:P 0 "const_int_operand")))
17701 (clobber (reg:CC FLAGS_REG))])]
17702 "optimize_insn_for_size_p ()
17703 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17704 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17705 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17707 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17708 ;; required and register dies. Similarly for 128 to -128.
17710 [(set (match_operand 0 "flags_reg_operand")
17711 (match_operator 1 "compare_operator"
17712 [(match_operand 2 "register_operand")
17713 (match_operand 3 "const_int_operand")]))]
17714 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17715 && incdec_operand (operands[3], GET_MODE (operands[3])))
17716 || (!TARGET_FUSE_CMP_AND_BRANCH
17717 && INTVAL (operands[3]) == 128))
17718 && ix86_match_ccmode (insn, CCGCmode)
17719 && peep2_reg_dead_p (1, operands[2])"
17720 [(parallel [(set (match_dup 0)
17721 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17722 (clobber (match_dup 2))])])
17724 ;; Convert imul by three, five and nine into lea
17727 [(set (match_operand:SWI48 0 "register_operand")
17728 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17729 (match_operand:SWI48 2 "const359_operand")))
17730 (clobber (reg:CC FLAGS_REG))])]
17731 "!TARGET_PARTIAL_REG_STALL
17732 || <MODE>mode == SImode
17733 || optimize_function_for_size_p (cfun)"
17734 [(set (match_dup 0)
17735 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17737 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17741 [(set (match_operand:SWI48 0 "register_operand")
17742 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17743 (match_operand:SWI48 2 "const359_operand")))
17744 (clobber (reg:CC FLAGS_REG))])]
17745 "optimize_insn_for_speed_p ()
17746 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17747 [(set (match_dup 0) (match_dup 1))
17749 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17751 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17753 ;; imul $32bit_imm, mem, reg is vector decoded, while
17754 ;; imul $32bit_imm, reg, reg is direct decoded.
17756 [(match_scratch:SWI48 3 "r")
17757 (parallel [(set (match_operand:SWI48 0 "register_operand")
17758 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17759 (match_operand:SWI48 2 "immediate_operand")))
17760 (clobber (reg:CC FLAGS_REG))])]
17761 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17762 && !satisfies_constraint_K (operands[2])"
17763 [(set (match_dup 3) (match_dup 1))
17764 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17765 (clobber (reg:CC FLAGS_REG))])])
17768 [(match_scratch:SI 3 "r")
17769 (parallel [(set (match_operand:DI 0 "register_operand")
17771 (mult:SI (match_operand:SI 1 "memory_operand")
17772 (match_operand:SI 2 "immediate_operand"))))
17773 (clobber (reg:CC FLAGS_REG))])]
17775 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17776 && !satisfies_constraint_K (operands[2])"
17777 [(set (match_dup 3) (match_dup 1))
17778 (parallel [(set (match_dup 0)
17779 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17780 (clobber (reg:CC FLAGS_REG))])])
17782 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17783 ;; Convert it into imul reg, reg
17784 ;; It would be better to force assembler to encode instruction using long
17785 ;; immediate, but there is apparently no way to do so.
17787 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17789 (match_operand:SWI248 1 "nonimmediate_operand")
17790 (match_operand:SWI248 2 "const_int_operand")))
17791 (clobber (reg:CC FLAGS_REG))])
17792 (match_scratch:SWI248 3 "r")]
17793 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17794 && satisfies_constraint_K (operands[2])"
17795 [(set (match_dup 3) (match_dup 2))
17796 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17797 (clobber (reg:CC FLAGS_REG))])]
17799 if (!rtx_equal_p (operands[0], operands[1]))
17800 emit_move_insn (operands[0], operands[1]);
17803 ;; After splitting up read-modify operations, array accesses with memory
17804 ;; operands might end up in form:
17806 ;; movl 4(%esp), %edx
17808 ;; instead of pre-splitting:
17810 ;; addl 4(%esp), %eax
17812 ;; movl 4(%esp), %edx
17813 ;; leal (%edx,%eax,4), %eax
17816 [(match_scratch:W 5 "r")
17817 (parallel [(set (match_operand 0 "register_operand")
17818 (ashift (match_operand 1 "register_operand")
17819 (match_operand 2 "const_int_operand")))
17820 (clobber (reg:CC FLAGS_REG))])
17821 (parallel [(set (match_operand 3 "register_operand")
17822 (plus (match_dup 0)
17823 (match_operand 4 "x86_64_general_operand")))
17824 (clobber (reg:CC FLAGS_REG))])]
17825 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17826 /* Validate MODE for lea. */
17827 && ((!TARGET_PARTIAL_REG_STALL
17828 && (GET_MODE (operands[0]) == QImode
17829 || GET_MODE (operands[0]) == HImode))
17830 || GET_MODE (operands[0]) == SImode
17831 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17832 && (rtx_equal_p (operands[0], operands[3])
17833 || peep2_reg_dead_p (2, operands[0]))
17834 /* We reorder load and the shift. */
17835 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17836 [(set (match_dup 5) (match_dup 4))
17837 (set (match_dup 0) (match_dup 1))]
17839 machine_mode op1mode = GET_MODE (operands[1]);
17840 machine_mode mode = op1mode == DImode ? DImode : SImode;
17841 int scale = 1 << INTVAL (operands[2]);
17842 rtx index = gen_lowpart (word_mode, operands[1]);
17843 rtx base = gen_lowpart (word_mode, operands[5]);
17844 rtx dest = gen_lowpart (mode, operands[3]);
17846 operands[1] = gen_rtx_PLUS (word_mode, base,
17847 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17848 operands[5] = base;
17849 if (mode != word_mode)
17850 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17851 if (op1mode != word_mode)
17852 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17853 operands[0] = dest;
17856 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17857 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17858 ;; caught for use by garbage collectors and the like. Using an insn that
17859 ;; maps to SIGILL makes it more likely the program will rightfully die.
17860 ;; Keeping with tradition, "6" is in honor of #UD.
17861 (define_insn "trap"
17862 [(trap_if (const_int 1) (const_int 6))]
17865 #ifdef HAVE_AS_IX86_UD2
17868 return ASM_SHORT "0x0b0f";
17871 [(set_attr "length" "2")])
17873 (define_expand "prefetch"
17874 [(prefetch (match_operand 0 "address_operand")
17875 (match_operand:SI 1 "const_int_operand")
17876 (match_operand:SI 2 "const_int_operand"))]
17877 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17879 bool write = INTVAL (operands[1]) != 0;
17880 int locality = INTVAL (operands[2]);
17882 gcc_assert (IN_RANGE (locality, 0, 3));
17884 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17885 supported by SSE counterpart or the SSE prefetch is not available
17886 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17888 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17889 operands[2] = const2_rtx;
17890 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17891 operands[2] = GEN_INT (3);
17893 operands[1] = const0_rtx;
17896 (define_insn "*prefetch_sse"
17897 [(prefetch (match_operand 0 "address_operand" "p")
17899 (match_operand:SI 1 "const_int_operand"))]
17900 "TARGET_PREFETCH_SSE"
17902 static const char * const patterns[4] = {
17903 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17906 int locality = INTVAL (operands[1]);
17907 gcc_assert (IN_RANGE (locality, 0, 3));
17909 return patterns[locality];
17911 [(set_attr "type" "sse")
17912 (set_attr "atom_sse_attr" "prefetch")
17913 (set (attr "length_address")
17914 (symbol_ref "memory_address_length (operands[0], false)"))
17915 (set_attr "memory" "none")])
17917 (define_insn "*prefetch_3dnow"
17918 [(prefetch (match_operand 0 "address_operand" "p")
17919 (match_operand:SI 1 "const_int_operand" "n")
17923 if (INTVAL (operands[1]) == 0)
17924 return "prefetch\t%a0";
17926 return "prefetchw\t%a0";
17928 [(set_attr "type" "mmx")
17929 (set (attr "length_address")
17930 (symbol_ref "memory_address_length (operands[0], false)"))
17931 (set_attr "memory" "none")])
17933 (define_insn "*prefetch_prefetchwt1_<mode>"
17934 [(prefetch (match_operand:P 0 "address_operand" "p")
17937 "TARGET_PREFETCHWT1"
17938 "prefetchwt1\t%a0";
17939 [(set_attr "type" "sse")
17940 (set (attr "length_address")
17941 (symbol_ref "memory_address_length (operands[0], false)"))
17942 (set_attr "memory" "none")])
17944 (define_expand "stack_protect_set"
17945 [(match_operand 0 "memory_operand")
17946 (match_operand 1 "memory_operand")]
17947 "TARGET_SSP_TLS_GUARD"
17949 rtx (*insn)(rtx, rtx);
17951 #ifdef TARGET_THREAD_SSP_OFFSET
17952 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17953 insn = (TARGET_LP64
17954 ? gen_stack_tls_protect_set_di
17955 : gen_stack_tls_protect_set_si);
17957 insn = (TARGET_LP64
17958 ? gen_stack_protect_set_di
17959 : gen_stack_protect_set_si);
17962 emit_insn (insn (operands[0], operands[1]));
17966 (define_insn "stack_protect_set_<mode>"
17967 [(set (match_operand:PTR 0 "memory_operand" "=m")
17968 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17970 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17971 (clobber (reg:CC FLAGS_REG))]
17972 "TARGET_SSP_TLS_GUARD"
17973 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17974 [(set_attr "type" "multi")])
17976 (define_insn "stack_tls_protect_set_<mode>"
17977 [(set (match_operand:PTR 0 "memory_operand" "=m")
17978 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17979 UNSPEC_SP_TLS_SET))
17980 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17981 (clobber (reg:CC FLAGS_REG))]
17983 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17984 [(set_attr "type" "multi")])
17986 (define_expand "stack_protect_test"
17987 [(match_operand 0 "memory_operand")
17988 (match_operand 1 "memory_operand")
17990 "TARGET_SSP_TLS_GUARD"
17992 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17994 rtx (*insn)(rtx, rtx, rtx);
17996 #ifdef TARGET_THREAD_SSP_OFFSET
17997 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17998 insn = (TARGET_LP64
17999 ? gen_stack_tls_protect_test_di
18000 : gen_stack_tls_protect_test_si);
18002 insn = (TARGET_LP64
18003 ? gen_stack_protect_test_di
18004 : gen_stack_protect_test_si);
18007 emit_insn (insn (flags, operands[0], operands[1]));
18009 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18010 flags, const0_rtx, operands[2]));
18014 (define_insn "stack_protect_test_<mode>"
18015 [(set (match_operand:CCZ 0 "flags_reg_operand")
18016 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18017 (match_operand:PTR 2 "memory_operand" "m")]
18019 (clobber (match_scratch:PTR 3 "=&r"))]
18020 "TARGET_SSP_TLS_GUARD"
18021 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18022 [(set_attr "type" "multi")])
18024 (define_insn "stack_tls_protect_test_<mode>"
18025 [(set (match_operand:CCZ 0 "flags_reg_operand")
18026 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18027 (match_operand:PTR 2 "const_int_operand" "i")]
18028 UNSPEC_SP_TLS_TEST))
18029 (clobber (match_scratch:PTR 3 "=r"))]
18031 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18032 [(set_attr "type" "multi")])
18034 (define_insn "sse4_2_crc32<mode>"
18035 [(set (match_operand:SI 0 "register_operand" "=r")
18037 [(match_operand:SI 1 "register_operand" "0")
18038 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18040 "TARGET_SSE4_2 || TARGET_CRC32"
18041 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18042 [(set_attr "type" "sselog1")
18043 (set_attr "prefix_rep" "1")
18044 (set_attr "prefix_extra" "1")
18045 (set (attr "prefix_data16")
18046 (if_then_else (match_operand:HI 2)
18048 (const_string "*")))
18049 (set (attr "prefix_rex")
18050 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18052 (const_string "*")))
18053 (set_attr "mode" "SI")])
18055 (define_insn "sse4_2_crc32di"
18056 [(set (match_operand:DI 0 "register_operand" "=r")
18058 [(match_operand:DI 1 "register_operand" "0")
18059 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18061 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18062 "crc32{q}\t{%2, %0|%0, %2}"
18063 [(set_attr "type" "sselog1")
18064 (set_attr "prefix_rep" "1")
18065 (set_attr "prefix_extra" "1")
18066 (set_attr "mode" "DI")])
18068 (define_insn "rdpmc"
18069 [(set (match_operand:DI 0 "register_operand" "=A")
18070 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18074 [(set_attr "type" "other")
18075 (set_attr "length" "2")])
18077 (define_insn "rdpmc_rex64"
18078 [(set (match_operand:DI 0 "register_operand" "=a")
18079 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18081 (set (match_operand:DI 1 "register_operand" "=d")
18082 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18085 [(set_attr "type" "other")
18086 (set_attr "length" "2")])
18088 (define_insn "rdtsc"
18089 [(set (match_operand:DI 0 "register_operand" "=A")
18090 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18093 [(set_attr "type" "other")
18094 (set_attr "length" "2")])
18096 (define_insn "rdtsc_rex64"
18097 [(set (match_operand:DI 0 "register_operand" "=a")
18098 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18099 (set (match_operand:DI 1 "register_operand" "=d")
18100 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18103 [(set_attr "type" "other")
18104 (set_attr "length" "2")])
18106 (define_insn "rdtscp"
18107 [(set (match_operand:DI 0 "register_operand" "=A")
18108 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18109 (set (match_operand:SI 1 "register_operand" "=c")
18110 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18113 [(set_attr "type" "other")
18114 (set_attr "length" "3")])
18116 (define_insn "rdtscp_rex64"
18117 [(set (match_operand:DI 0 "register_operand" "=a")
18118 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18119 (set (match_operand:DI 1 "register_operand" "=d")
18120 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18121 (set (match_operand:SI 2 "register_operand" "=c")
18122 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18125 [(set_attr "type" "other")
18126 (set_attr "length" "3")])
18128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18130 ;; FXSR, XSAVE and XSAVEOPT instructions
18132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18134 (define_insn "fxsave"
18135 [(set (match_operand:BLK 0 "memory_operand" "=m")
18136 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18139 [(set_attr "type" "other")
18140 (set_attr "memory" "store")
18141 (set (attr "length")
18142 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18144 (define_insn "fxsave64"
18145 [(set (match_operand:BLK 0 "memory_operand" "=m")
18146 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18147 "TARGET_64BIT && TARGET_FXSR"
18149 [(set_attr "type" "other")
18150 (set_attr "memory" "store")
18151 (set (attr "length")
18152 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18154 (define_insn "fxrstor"
18155 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18159 [(set_attr "type" "other")
18160 (set_attr "memory" "load")
18161 (set (attr "length")
18162 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18164 (define_insn "fxrstor64"
18165 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18166 UNSPECV_FXRSTOR64)]
18167 "TARGET_64BIT && TARGET_FXSR"
18169 [(set_attr "type" "other")
18170 (set_attr "memory" "load")
18171 (set (attr "length")
18172 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18174 (define_int_iterator ANY_XSAVE
18176 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18177 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18178 (UNSPECV_XSAVES "TARGET_XSAVES")])
18180 (define_int_iterator ANY_XSAVE64
18182 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18183 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18184 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18186 (define_int_attr xsave
18187 [(UNSPECV_XSAVE "xsave")
18188 (UNSPECV_XSAVE64 "xsave64")
18189 (UNSPECV_XSAVEOPT "xsaveopt")
18190 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18191 (UNSPECV_XSAVEC "xsavec")
18192 (UNSPECV_XSAVEC64 "xsavec64")
18193 (UNSPECV_XSAVES "xsaves")
18194 (UNSPECV_XSAVES64 "xsaves64")])
18196 (define_int_iterator ANY_XRSTOR
18198 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18200 (define_int_iterator ANY_XRSTOR64
18202 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18204 (define_int_attr xrstor
18205 [(UNSPECV_XRSTOR "xrstor")
18206 (UNSPECV_XRSTOR64 "xrstor")
18207 (UNSPECV_XRSTORS "xrstors")
18208 (UNSPECV_XRSTORS64 "xrstors")])
18210 (define_insn "<xsave>"
18211 [(set (match_operand:BLK 0 "memory_operand" "=m")
18212 (unspec_volatile:BLK
18213 [(match_operand:DI 1 "register_operand" "A")]
18215 "!TARGET_64BIT && TARGET_XSAVE"
18217 [(set_attr "type" "other")
18218 (set_attr "memory" "store")
18219 (set (attr "length")
18220 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18222 (define_insn "<xsave>_rex64"
18223 [(set (match_operand:BLK 0 "memory_operand" "=m")
18224 (unspec_volatile:BLK
18225 [(match_operand:SI 1 "register_operand" "a")
18226 (match_operand:SI 2 "register_operand" "d")]
18228 "TARGET_64BIT && TARGET_XSAVE"
18230 [(set_attr "type" "other")
18231 (set_attr "memory" "store")
18232 (set (attr "length")
18233 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18235 (define_insn "<xsave>"
18236 [(set (match_operand:BLK 0 "memory_operand" "=m")
18237 (unspec_volatile:BLK
18238 [(match_operand:SI 1 "register_operand" "a")
18239 (match_operand:SI 2 "register_operand" "d")]
18241 "TARGET_64BIT && TARGET_XSAVE"
18243 [(set_attr "type" "other")
18244 (set_attr "memory" "store")
18245 (set (attr "length")
18246 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18248 (define_insn "<xrstor>"
18249 [(unspec_volatile:BLK
18250 [(match_operand:BLK 0 "memory_operand" "m")
18251 (match_operand:DI 1 "register_operand" "A")]
18253 "!TARGET_64BIT && TARGET_XSAVE"
18255 [(set_attr "type" "other")
18256 (set_attr "memory" "load")
18257 (set (attr "length")
18258 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18260 (define_insn "<xrstor>_rex64"
18261 [(unspec_volatile:BLK
18262 [(match_operand:BLK 0 "memory_operand" "m")
18263 (match_operand:SI 1 "register_operand" "a")
18264 (match_operand:SI 2 "register_operand" "d")]
18266 "TARGET_64BIT && TARGET_XSAVE"
18268 [(set_attr "type" "other")
18269 (set_attr "memory" "load")
18270 (set (attr "length")
18271 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18273 (define_insn "<xrstor>64"
18274 [(unspec_volatile:BLK
18275 [(match_operand:BLK 0 "memory_operand" "m")
18276 (match_operand:SI 1 "register_operand" "a")
18277 (match_operand:SI 2 "register_operand" "d")]
18279 "TARGET_64BIT && TARGET_XSAVE"
18281 [(set_attr "type" "other")
18282 (set_attr "memory" "load")
18283 (set (attr "length")
18284 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18286 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18288 ;; Floating-point instructions for atomic compound assignments
18290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18292 ; Clobber all floating-point registers on environment save and restore
18293 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18294 (define_insn "fnstenv"
18295 [(set (match_operand:BLK 0 "memory_operand" "=m")
18296 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18297 (clobber (reg:HI FPCR_REG))
18298 (clobber (reg:XF ST0_REG))
18299 (clobber (reg:XF ST1_REG))
18300 (clobber (reg:XF ST2_REG))
18301 (clobber (reg:XF ST3_REG))
18302 (clobber (reg:XF ST4_REG))
18303 (clobber (reg:XF ST5_REG))
18304 (clobber (reg:XF ST6_REG))
18305 (clobber (reg:XF ST7_REG))]
18308 [(set_attr "type" "other")
18309 (set_attr "memory" "store")
18310 (set (attr "length")
18311 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18313 (define_insn "fldenv"
18314 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18316 (clobber (reg:CCFP FPSR_REG))
18317 (clobber (reg:HI FPCR_REG))
18318 (clobber (reg:XF ST0_REG))
18319 (clobber (reg:XF ST1_REG))
18320 (clobber (reg:XF ST2_REG))
18321 (clobber (reg:XF ST3_REG))
18322 (clobber (reg:XF ST4_REG))
18323 (clobber (reg:XF ST5_REG))
18324 (clobber (reg:XF ST6_REG))
18325 (clobber (reg:XF ST7_REG))]
18328 [(set_attr "type" "other")
18329 (set_attr "memory" "load")
18330 (set (attr "length")
18331 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18333 (define_insn "fnstsw"
18334 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18335 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18338 [(set_attr "type" "other,other")
18339 (set_attr "memory" "none,store")
18340 (set (attr "length")
18341 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18343 (define_insn "fnclex"
18344 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18347 [(set_attr "type" "other")
18348 (set_attr "memory" "none")
18349 (set_attr "length" "2")])
18351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18353 ;; LWP instructions
18355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18357 (define_expand "lwp_llwpcb"
18358 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18359 UNSPECV_LLWP_INTRINSIC)]
18362 (define_insn "*lwp_llwpcb<mode>1"
18363 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18364 UNSPECV_LLWP_INTRINSIC)]
18367 [(set_attr "type" "lwp")
18368 (set_attr "mode" "<MODE>")
18369 (set_attr "length" "5")])
18371 (define_expand "lwp_slwpcb"
18372 [(set (match_operand 0 "register_operand" "=r")
18373 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18378 insn = (Pmode == DImode
18380 : gen_lwp_slwpcbsi);
18382 emit_insn (insn (operands[0]));
18386 (define_insn "lwp_slwpcb<mode>"
18387 [(set (match_operand:P 0 "register_operand" "=r")
18388 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18391 [(set_attr "type" "lwp")
18392 (set_attr "mode" "<MODE>")
18393 (set_attr "length" "5")])
18395 (define_expand "lwp_lwpval<mode>3"
18396 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18397 (match_operand:SI 2 "nonimmediate_operand" "rm")
18398 (match_operand:SI 3 "const_int_operand" "i")]
18399 UNSPECV_LWPVAL_INTRINSIC)]
18401 ;; Avoid unused variable warning.
18402 "(void) operands[0];")
18404 (define_insn "*lwp_lwpval<mode>3_1"
18405 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18406 (match_operand:SI 1 "nonimmediate_operand" "rm")
18407 (match_operand:SI 2 "const_int_operand" "i")]
18408 UNSPECV_LWPVAL_INTRINSIC)]
18410 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18411 [(set_attr "type" "lwp")
18412 (set_attr "mode" "<MODE>")
18413 (set (attr "length")
18414 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18416 (define_expand "lwp_lwpins<mode>3"
18417 [(set (reg:CCC FLAGS_REG)
18418 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18419 (match_operand:SI 2 "nonimmediate_operand" "rm")
18420 (match_operand:SI 3 "const_int_operand" "i")]
18421 UNSPECV_LWPINS_INTRINSIC))
18422 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18423 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18426 (define_insn "*lwp_lwpins<mode>3_1"
18427 [(set (reg:CCC FLAGS_REG)
18428 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18429 (match_operand:SI 1 "nonimmediate_operand" "rm")
18430 (match_operand:SI 2 "const_int_operand" "i")]
18431 UNSPECV_LWPINS_INTRINSIC))]
18433 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18434 [(set_attr "type" "lwp")
18435 (set_attr "mode" "<MODE>")
18436 (set (attr "length")
18437 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18439 (define_int_iterator RDFSGSBASE
18443 (define_int_iterator WRFSGSBASE
18447 (define_int_attr fsgs
18448 [(UNSPECV_RDFSBASE "fs")
18449 (UNSPECV_RDGSBASE "gs")
18450 (UNSPECV_WRFSBASE "fs")
18451 (UNSPECV_WRGSBASE "gs")])
18453 (define_insn "rd<fsgs>base<mode>"
18454 [(set (match_operand:SWI48 0 "register_operand" "=r")
18455 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18456 "TARGET_64BIT && TARGET_FSGSBASE"
18458 [(set_attr "type" "other")
18459 (set_attr "prefix_extra" "2")])
18461 (define_insn "wr<fsgs>base<mode>"
18462 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18464 "TARGET_64BIT && TARGET_FSGSBASE"
18466 [(set_attr "type" "other")
18467 (set_attr "prefix_extra" "2")])
18469 (define_insn "rdrand<mode>_1"
18470 [(set (match_operand:SWI248 0 "register_operand" "=r")
18471 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18472 (set (reg:CCC FLAGS_REG)
18473 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18476 [(set_attr "type" "other")
18477 (set_attr "prefix_extra" "1")])
18479 (define_insn "rdseed<mode>_1"
18480 [(set (match_operand:SWI248 0 "register_operand" "=r")
18481 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18482 (set (reg:CCC FLAGS_REG)
18483 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18486 [(set_attr "type" "other")
18487 (set_attr "prefix_extra" "1")])
18489 (define_expand "pause"
18490 [(set (match_dup 0)
18491 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18494 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18495 MEM_VOLATILE_P (operands[0]) = 1;
18498 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18499 ;; They have the same encoding.
18500 (define_insn "*pause"
18501 [(set (match_operand:BLK 0)
18502 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18505 [(set_attr "length" "2")
18506 (set_attr "memory" "unknown")])
18508 (define_expand "xbegin"
18509 [(set (match_operand:SI 0 "register_operand")
18510 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18513 rtx_code_label *label = gen_label_rtx ();
18515 /* xbegin is emitted as jump_insn, so reload won't be able
18516 to reload its operand. Force the value into AX hard register. */
18517 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18518 emit_move_insn (ax_reg, constm1_rtx);
18520 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18522 emit_label (label);
18523 LABEL_NUSES (label) = 1;
18525 emit_move_insn (operands[0], ax_reg);
18530 (define_insn "xbegin_1"
18532 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18534 (label_ref (match_operand 1))
18536 (set (match_operand:SI 0 "register_operand" "+a")
18537 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18540 [(set_attr "type" "other")
18541 (set_attr "length" "6")])
18543 (define_insn "xend"
18544 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18547 [(set_attr "type" "other")
18548 (set_attr "length" "3")])
18550 (define_insn "xabort"
18551 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18555 [(set_attr "type" "other")
18556 (set_attr "length" "3")])
18558 (define_expand "xtest"
18559 [(set (match_operand:QI 0 "register_operand")
18560 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18563 emit_insn (gen_xtest_1 ());
18565 ix86_expand_setcc (operands[0], NE,
18566 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18570 (define_insn "xtest_1"
18571 [(set (reg:CCZ FLAGS_REG)
18572 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18575 [(set_attr "type" "other")
18576 (set_attr "length" "3")])
18578 (define_insn "clflushopt"
18579 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18580 UNSPECV_CLFLUSHOPT)]
18581 "TARGET_CLFLUSHOPT"
18583 [(set_attr "type" "sse")
18584 (set_attr "atom_sse_attr" "fence")
18585 (set_attr "memory" "unknown")])
18587 ;; MPX instructions
18589 (define_expand "<mode>_mk"
18590 [(set (match_operand:BND 0 "register_operand")
18594 [(match_operand:<bnd_ptr> 1 "register_operand")
18595 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18599 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18601 UNSPEC_BNDMK_ADDR);
18604 (define_insn "*<mode>_mk"
18605 [(set (match_operand:BND 0 "register_operand" "=w")
18607 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18609 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18610 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18611 UNSPEC_BNDMK_ADDR)])]
18614 "bndmk\t{%3, %0|%0, %3}"
18615 [(set_attr "type" "mpxmk")])
18617 (define_expand "mov<mode>"
18618 [(set (match_operand:BND 0 "general_operand")
18619 (match_operand:BND 1 "general_operand"))]
18622 ix86_expand_move (<MODE>mode, operands);DONE;
18625 (define_insn "*mov<mode>_internal_mpx"
18626 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18627 (match_operand:BND 1 "general_operand" "wm,w"))]
18629 "bndmov\t{%1, %0|%0, %1}"
18630 [(set_attr "type" "mpxmov")])
18632 (define_expand "<mode>_<bndcheck>"
18633 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18634 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18636 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18639 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18640 MEM_VOLATILE_P (operands[2]) = 1;
18643 (define_insn "*<mode>_<bndcheck>"
18644 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18645 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18646 (set (match_operand:BLK 2 "bnd_mem_operator")
18647 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18649 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18650 [(set_attr "type" "mpxchk")])
18652 (define_expand "<mode>_ldx"
18653 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18657 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18658 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18660 (use (mem:BLK (match_dup 1)))])]
18663 /* Avoid registers which connot be used as index. */
18664 if (!index_register_operand (operands[2], Pmode))
18666 rtx temp = gen_reg_rtx (Pmode);
18667 emit_move_insn (temp, operands[2]);
18668 operands[2] = temp;
18671 /* If it was a register originally then it may have
18672 mode other than Pmode. We need to extend in such
18673 case because bndldx may work only with Pmode regs. */
18674 if (GET_MODE (operands[2]) != Pmode)
18675 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18677 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18679 UNSPEC_BNDLDX_ADDR);
18682 (define_insn "*<mode>_ldx"
18683 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18685 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18687 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18688 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18689 UNSPEC_BNDLDX_ADDR)])]
18691 (use (mem:BLK (match_dup 1)))])]
18693 "bndldx\t{%3, %0|%0, %3}"
18694 [(set_attr "type" "mpxld")])
18696 (define_expand "<mode>_stx"
18697 [(parallel [(unspec [(mem:<bnd_ptr>
18699 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18700 (match_operand:<bnd_ptr> 1 "register_operand")]))
18701 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18703 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18706 /* Avoid registers which connot be used as index. */
18707 if (!index_register_operand (operands[1], Pmode))
18709 rtx temp = gen_reg_rtx (Pmode);
18710 emit_move_insn (temp, operands[1]);
18711 operands[1] = temp;
18714 /* If it was a register originally then it may have
18715 mode other than Pmode. We need to extend in such
18716 case because bndstx may work only with Pmode regs. */
18717 if (GET_MODE (operands[1]) != Pmode)
18718 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18720 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18722 UNSPEC_BNDLDX_ADDR);
18723 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18724 MEM_VOLATILE_P (operands[4]) = 1;
18727 (define_insn "*<mode>_stx"
18728 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18730 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18731 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18732 UNSPEC_BNDLDX_ADDR)])
18733 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18734 (set (match_operand:BLK 4 "bnd_mem_operator")
18735 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18737 "bndstx\t{%2, %3|%3, %2}"
18738 [(set_attr "type" "mpxst")])
18740 (define_insn "move_size_reloc_<mode>"
18741 [(set (match_operand:SWI48 0 "register_operand" "=r")
18743 [(match_operand:SWI48 1 "symbol_operand")]
18747 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18748 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18750 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18752 [(set_attr "type" "imov")
18753 (set_attr "mode" "<MODE>")])
18757 (include "sync.md")