1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
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 a segment register of thread base pointer load
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
132 UNSPEC_MS_TO_SYSV_CALL
134 ;; Generic math support
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
139 ;; x87 Floating point
155 UNSPEC_FRNDINT_MASK_PM
159 ;; x87 Double output FP
191 ;; For SSE4.1 support
201 ;; For SSE4.2 support
208 UNSPEC_XOP_UNSIGNED_CMP
219 UNSPEC_AESKEYGENASSIST
221 ;; For PCLMUL support
244 ;; For RDRAND support
252 (define_c_enum "unspecv" [
255 UNSPECV_PROBE_STACK_RANGE
275 UNSPECV_LLWP_INTRINSIC
276 UNSPECV_SLWP_INTRINSIC
277 UNSPECV_LWPVAL_INTRINSIC
278 UNSPECV_LWPINS_INTRINSIC
283 UNSPECV_SPLIT_STACK_RETURN
286 ;; Constants to represent rounding modes in the ROUND instruction
295 ;; Constants to represent pcomtrue/pcomfalse variants
305 ;; Constants used in the XOP pperm instruction
307 [(PPERM_SRC 0x00) /* copy source */
308 (PPERM_INVERT 0x20) /* invert source */
309 (PPERM_REVERSE 0x40) /* bit reverse source */
310 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
311 (PPERM_ZERO 0x80) /* all 0's */
312 (PPERM_ONES 0xa0) /* all 1's */
313 (PPERM_SIGN 0xc0) /* propagate sign bit */
314 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
315 (PPERM_SRC1 0x00) /* use first source byte */
316 (PPERM_SRC2 0x10) /* use second source byte */
319 ;; Registers by name.
372 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
375 ;; In C guard expressions, put expressions which may be compile-time
376 ;; constants first. This allows for better optimization. For
377 ;; example, write "TARGET_64BIT && reload_completed", not
378 ;; "reload_completed && TARGET_64BIT".
382 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
383 atom,generic64,amdfam10,bdver1,bdver2,btver1"
384 (const (symbol_ref "ix86_schedule")))
386 ;; A basic instruction type. Refinements due to arguments to be
387 ;; provided in other attributes.
390 alu,alu1,negnot,imov,imovx,lea,
391 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
392 icmp,test,ibr,setcc,icmov,
393 push,pop,call,callv,leave,
395 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
396 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
397 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
398 ssemuladd,sse4arg,lwp,
399 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
400 (const_string "other"))
402 ;; Main data type used by the insn
404 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
405 (const_string "unknown"))
407 ;; The CPU unit operations uses.
408 (define_attr "unit" "integer,i387,sse,mmx,unknown"
409 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
410 (const_string "i387")
411 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
412 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
413 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
415 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
417 (eq_attr "type" "other")
418 (const_string "unknown")]
419 (const_string "integer")))
421 ;; The (bounding maximum) length of an instruction immediate.
422 (define_attr "length_immediate" ""
423 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
426 (eq_attr "unit" "i387,sse,mmx")
428 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
429 rotate,rotatex,rotate1,imul,icmp,push,pop")
430 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
431 (eq_attr "type" "imov,test")
432 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
433 (eq_attr "type" "call")
434 (if_then_else (match_operand 0 "constant_call_address_operand" "")
437 (eq_attr "type" "callv")
438 (if_then_else (match_operand 1 "constant_call_address_operand" "")
441 ;; We don't know the size before shorten_branches. Expect
442 ;; the instruction to fit for better scheduling.
443 (eq_attr "type" "ibr")
446 (symbol_ref "/* Update immediate_length and other attributes! */
447 gcc_unreachable (),1")))
449 ;; The (bounding maximum) length of an instruction address.
450 (define_attr "length_address" ""
451 (cond [(eq_attr "type" "str,other,multi,fxch")
453 (and (eq_attr "type" "call")
454 (match_operand 0 "constant_call_address_operand" ""))
456 (and (eq_attr "type" "callv")
457 (match_operand 1 "constant_call_address_operand" ""))
460 (symbol_ref "ix86_attr_length_address_default (insn)")))
462 ;; Set when length prefix is used.
463 (define_attr "prefix_data16" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (eq_attr "mode" "HI")
468 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
473 ;; Set when string REP prefix is used.
474 (define_attr "prefix_rep" ""
475 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
477 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
482 ;; Set when 0f opcode prefix is used.
483 (define_attr "prefix_0f" ""
485 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
486 (eq_attr "unit" "sse,mmx"))
490 ;; Set when REX opcode prefix is used.
491 (define_attr "prefix_rex" ""
492 (cond [(not (match_test "TARGET_64BIT"))
494 (and (eq_attr "mode" "DI")
495 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
496 (eq_attr "unit" "!mmx")))
498 (and (eq_attr "mode" "QI")
499 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
501 (match_test "x86_extended_reg_mentioned_p (insn)")
503 (and (eq_attr "type" "imovx")
504 (match_operand:QI 1 "ext_QIreg_operand" ""))
509 ;; There are also additional prefixes in 3DNOW, SSSE3.
510 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
511 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
512 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
513 (define_attr "prefix_extra" ""
514 (cond [(eq_attr "type" "ssemuladd,sse4arg")
516 (eq_attr "type" "sseiadd1,ssecvt1")
521 ;; Prefix used: original, VEX or maybe VEX.
522 (define_attr "prefix" "orig,vex,maybe_vex"
523 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
525 (const_string "orig")))
527 ;; VEX W bit is used.
528 (define_attr "prefix_vex_w" "" (const_int 0))
530 ;; The length of VEX prefix
531 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
532 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
533 ;; still prefix_0f 1, with prefix_extra 1.
534 (define_attr "length_vex" ""
535 (if_then_else (and (eq_attr "prefix_0f" "1")
536 (eq_attr "prefix_extra" "0"))
537 (if_then_else (eq_attr "prefix_vex_w" "1")
538 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
539 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
540 (if_then_else (eq_attr "prefix_vex_w" "1")
541 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
542 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
544 ;; Set when modrm byte is used.
545 (define_attr "modrm" ""
546 (cond [(eq_attr "type" "str,leave")
548 (eq_attr "unit" "i387")
550 (and (eq_attr "type" "incdec")
551 (and (not (match_test "TARGET_64BIT"))
552 (ior (match_operand:SI 1 "register_operand" "")
553 (match_operand:HI 1 "register_operand" ""))))
555 (and (eq_attr "type" "push")
556 (not (match_operand 1 "memory_operand" "")))
558 (and (eq_attr "type" "pop")
559 (not (match_operand 0 "memory_operand" "")))
561 (and (eq_attr "type" "imov")
562 (and (not (eq_attr "mode" "DI"))
563 (ior (and (match_operand 0 "register_operand" "")
564 (match_operand 1 "immediate_operand" ""))
565 (ior (and (match_operand 0 "ax_reg_operand" "")
566 (match_operand 1 "memory_displacement_only_operand" ""))
567 (and (match_operand 0 "memory_displacement_only_operand" "")
568 (match_operand 1 "ax_reg_operand" ""))))))
570 (and (eq_attr "type" "call")
571 (match_operand 0 "constant_call_address_operand" ""))
573 (and (eq_attr "type" "callv")
574 (match_operand 1 "constant_call_address_operand" ""))
576 (and (eq_attr "type" "alu,alu1,icmp,test")
577 (match_operand 0 "ax_reg_operand" ""))
578 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
582 ;; The (bounding maximum) length of an instruction in bytes.
583 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
584 ;; Later we may want to split them and compute proper length as for
586 (define_attr "length" ""
587 (cond [(eq_attr "type" "other,multi,fistp,frndint")
589 (eq_attr "type" "fcmp")
591 (eq_attr "unit" "i387")
593 (plus (attr "prefix_data16")
594 (attr "length_address")))
595 (ior (eq_attr "prefix" "vex")
596 (and (eq_attr "prefix" "maybe_vex")
597 (match_test "TARGET_AVX")))
598 (plus (attr "length_vex")
599 (plus (attr "length_immediate")
601 (attr "length_address"))))]
602 (plus (plus (attr "modrm")
603 (plus (attr "prefix_0f")
604 (plus (attr "prefix_rex")
605 (plus (attr "prefix_extra")
607 (plus (attr "prefix_rep")
608 (plus (attr "prefix_data16")
609 (plus (attr "length_immediate")
610 (attr "length_address")))))))
612 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
613 ;; `store' if there is a simple memory reference therein, or `unknown'
614 ;; if the instruction is complex.
616 (define_attr "memory" "none,load,store,both,unknown"
617 (cond [(eq_attr "type" "other,multi,str,lwp")
618 (const_string "unknown")
619 (eq_attr "type" "lea,fcmov,fpspc")
620 (const_string "none")
621 (eq_attr "type" "fistp,leave")
622 (const_string "both")
623 (eq_attr "type" "frndint")
624 (const_string "load")
625 (eq_attr "type" "push")
626 (if_then_else (match_operand 1 "memory_operand" "")
627 (const_string "both")
628 (const_string "store"))
629 (eq_attr "type" "pop")
630 (if_then_else (match_operand 0 "memory_operand" "")
631 (const_string "both")
632 (const_string "load"))
633 (eq_attr "type" "setcc")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "store")
636 (const_string "none"))
637 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
638 (if_then_else (ior (match_operand 0 "memory_operand" "")
639 (match_operand 1 "memory_operand" ""))
640 (const_string "load")
641 (const_string "none"))
642 (eq_attr "type" "ibr")
643 (if_then_else (match_operand 0 "memory_operand" "")
644 (const_string "load")
645 (const_string "none"))
646 (eq_attr "type" "call")
647 (if_then_else (match_operand 0 "constant_call_address_operand" "")
648 (const_string "none")
649 (const_string "load"))
650 (eq_attr "type" "callv")
651 (if_then_else (match_operand 1 "constant_call_address_operand" "")
652 (const_string "none")
653 (const_string "load"))
654 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
655 (match_operand 1 "memory_operand" ""))
656 (const_string "both")
657 (and (match_operand 0 "memory_operand" "")
658 (match_operand 1 "memory_operand" ""))
659 (const_string "both")
660 (match_operand 0 "memory_operand" "")
661 (const_string "store")
662 (match_operand 1 "memory_operand" "")
663 (const_string "load")
665 "!alu1,negnot,ishift1,
666 imov,imovx,icmp,test,bitmanip,
668 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
669 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
670 (match_operand 2 "memory_operand" ""))
671 (const_string "load")
672 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
673 (match_operand 3 "memory_operand" ""))
674 (const_string "load")
676 (const_string "none")))
678 ;; Indicates if an instruction has both an immediate and a displacement.
680 (define_attr "imm_disp" "false,true,unknown"
681 (cond [(eq_attr "type" "other,multi")
682 (const_string "unknown")
683 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
684 (and (match_operand 0 "memory_displacement_operand" "")
685 (match_operand 1 "immediate_operand" "")))
686 (const_string "true")
687 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
688 (and (match_operand 0 "memory_displacement_operand" "")
689 (match_operand 2 "immediate_operand" "")))
690 (const_string "true")
692 (const_string "false")))
694 ;; Indicates if an FP operation has an integer source.
696 (define_attr "fp_int_src" "false,true"
697 (const_string "false"))
699 ;; Defines rounding mode of an FP operation.
701 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
702 (const_string "any"))
704 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
705 (define_attr "use_carry" "0,1" (const_string "0"))
707 ;; Define attribute to indicate unaligned ssemov insns
708 (define_attr "movu" "0,1" (const_string "0"))
710 ;; Used to control the "enabled" attribute on a per-instruction basis.
711 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
712 (const_string "base"))
714 (define_attr "enabled" ""
715 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
716 (eq_attr "isa" "sse2_noavx")
717 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
718 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
719 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
720 (eq_attr "isa" "sse4_noavx")
721 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
722 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
723 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
724 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
728 ;; Describe a user's asm statement.
729 (define_asm_attributes
730 [(set_attr "length" "128")
731 (set_attr "type" "multi")])
733 (define_code_iterator plusminus [plus minus])
735 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
737 ;; Base name for define_insn
738 (define_code_attr plusminus_insn
739 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
740 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr plusminus_mnemonic
744 [(plus "add") (ss_plus "adds") (us_plus "addus")
745 (minus "sub") (ss_minus "subs") (us_minus "subus")])
746 (define_code_attr plusminus_carry_mnemonic
747 [(plus "adc") (minus "sbb")])
749 ;; Mark commutative operators as such in constraints.
750 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
751 (minus "") (ss_minus "") (us_minus "")])
753 ;; Mapping of max and min
754 (define_code_iterator maxmin [smax smin umax umin])
756 ;; Mapping of signed max and min
757 (define_code_iterator smaxmin [smax smin])
759 ;; Mapping of unsigned max and min
760 (define_code_iterator umaxmin [umax umin])
762 ;; Base name for integer and FP insn mnemonic
763 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
764 (umax "maxu") (umin "minu")])
765 (define_code_attr maxmin_float [(smax "max") (smin "min")])
767 ;; Mapping of logic operators
768 (define_code_iterator any_logic [and ior xor])
769 (define_code_iterator any_or [ior xor])
771 ;; Base name for insn mnemonic.
772 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
774 ;; Mapping of shift-right operators
775 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
777 ;; Base name for define_insn
778 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
780 ;; Base name for insn mnemonic.
781 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
783 ;; Mapping of rotate operators
784 (define_code_iterator any_rotate [rotate rotatert])
786 ;; Base name for define_insn
787 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
789 ;; Base name for insn mnemonic.
790 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
792 ;; Mapping of abs neg operators
793 (define_code_iterator absneg [abs neg])
795 ;; Base name for x87 insn mnemonic.
796 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
798 ;; Used in signed and unsigned widening multiplications.
799 (define_code_iterator any_extend [sign_extend zero_extend])
801 ;; Prefix for insn menmonic.
802 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
804 ;; Prefix for define_insn
805 (define_code_attr u [(sign_extend "") (zero_extend "u")])
806 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
808 ;; All integer modes.
809 (define_mode_iterator SWI1248x [QI HI SI DI])
811 ;; All integer modes without QImode.
812 (define_mode_iterator SWI248x [HI SI DI])
814 ;; All integer modes without QImode and HImode.
815 (define_mode_iterator SWI48x [SI DI])
817 ;; All integer modes without SImode and DImode.
818 (define_mode_iterator SWI12 [QI HI])
820 ;; All integer modes without DImode.
821 (define_mode_iterator SWI124 [QI HI SI])
823 ;; All integer modes without QImode and DImode.
824 (define_mode_iterator SWI24 [HI SI])
826 ;; Single word integer modes.
827 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
829 ;; Single word integer modes without QImode.
830 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
832 ;; Single word integer modes without QImode and HImode.
833 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
835 ;; All math-dependant single and double word integer modes.
836 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
837 (HI "TARGET_HIMODE_MATH")
838 SI DI (TI "TARGET_64BIT")])
840 ;; Math-dependant single word integer modes.
841 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
842 (HI "TARGET_HIMODE_MATH")
843 SI (DI "TARGET_64BIT")])
845 ;; Math-dependant integer modes without DImode.
846 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
847 (HI "TARGET_HIMODE_MATH")
850 ;; Math-dependant single word integer modes without QImode.
851 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
852 SI (DI "TARGET_64BIT")])
854 ;; Double word integer modes.
855 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
856 (TI "TARGET_64BIT")])
858 ;; Double word integer modes as mode attribute.
859 (define_mode_attr DWI [(SI "DI") (DI "TI")])
860 (define_mode_attr dwi [(SI "di") (DI "ti")])
862 ;; Half mode for double word integer modes.
863 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
864 (DI "TARGET_64BIT")])
866 ;; Instruction suffix for integer modes.
867 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
869 ;; Pointer size prefix for integer modes (Intel asm dialect)
870 (define_mode_attr iptrsize [(QI "BYTE")
875 ;; Register class for integer modes.
876 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
878 ;; Immediate operand constraint for integer modes.
879 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
881 ;; General operand constraint for word modes.
882 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
884 ;; Immediate operand constraint for double integer modes.
885 (define_mode_attr di [(SI "nF") (DI "e")])
887 ;; Immediate operand constraint for shifts.
888 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
890 ;; General operand predicate for integer modes.
891 (define_mode_attr general_operand
892 [(QI "general_operand")
893 (HI "general_operand")
894 (SI "x86_64_general_operand")
895 (DI "x86_64_general_operand")
896 (TI "x86_64_general_operand")])
898 ;; General sign/zero extend operand predicate for integer modes.
899 (define_mode_attr general_szext_operand
900 [(QI "general_operand")
901 (HI "general_operand")
902 (SI "x86_64_szext_general_operand")
903 (DI "x86_64_szext_general_operand")])
905 ;; Immediate operand predicate for integer modes.
906 (define_mode_attr immediate_operand
907 [(QI "immediate_operand")
908 (HI "immediate_operand")
909 (SI "x86_64_immediate_operand")
910 (DI "x86_64_immediate_operand")])
912 ;; Nonmemory operand predicate for integer modes.
913 (define_mode_attr nonmemory_operand
914 [(QI "nonmemory_operand")
915 (HI "nonmemory_operand")
916 (SI "x86_64_nonmemory_operand")
917 (DI "x86_64_nonmemory_operand")])
919 ;; Operand predicate for shifts.
920 (define_mode_attr shift_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "shiftdi_operand")
925 (TI "register_operand")])
927 ;; Operand predicate for shift argument.
928 (define_mode_attr shift_immediate_operand
929 [(QI "const_1_to_31_operand")
930 (HI "const_1_to_31_operand")
931 (SI "const_1_to_31_operand")
932 (DI "const_1_to_63_operand")])
934 ;; Input operand predicate for arithmetic left shifts.
935 (define_mode_attr ashl_input_operand
936 [(QI "nonimmediate_operand")
937 (HI "nonimmediate_operand")
938 (SI "nonimmediate_operand")
939 (DI "ashldi_input_operand")
940 (TI "reg_or_pm1_operand")])
942 ;; SSE and x87 SFmode and DFmode floating point modes
943 (define_mode_iterator MODEF [SF DF])
945 ;; All x87 floating point modes
946 (define_mode_iterator X87MODEF [SF DF XF])
948 ;; SSE instruction suffix for various modes
949 (define_mode_attr ssemodesuffix
951 (V8SF "ps") (V4DF "pd")
952 (V4SF "ps") (V2DF "pd")
953 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
954 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
956 ;; SSE vector suffix for floating point modes
957 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
959 ;; SSE vector mode corresponding to a scalar mode
960 (define_mode_attr ssevecmode
961 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
963 ;; Instruction suffix for REX 64bit operators.
964 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
966 ;; This mode iterator allows :P to be used for patterns that operate on
967 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
968 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
970 ;; This mode iterator allows :PTR to be used for patterns that operate on
971 ;; ptr_mode sized quantities.
972 (define_mode_iterator PTR
973 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
975 ;; Scheduling descriptions
977 (include "pentium.md")
980 (include "athlon.md")
981 (include "bdver1.md")
987 ;; Operand and operator predicates and constraints
989 (include "predicates.md")
990 (include "constraints.md")
993 ;; Compare and branch/compare and store instructions.
995 (define_expand "cbranch<mode>4"
996 [(set (reg:CC FLAGS_REG)
997 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
998 (match_operand:SDWIM 2 "<general_operand>" "")))
999 (set (pc) (if_then_else
1000 (match_operator 0 "ordered_comparison_operator"
1001 [(reg:CC FLAGS_REG) (const_int 0)])
1002 (label_ref (match_operand 3 "" ""))
1006 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1007 operands[1] = force_reg (<MODE>mode, operands[1]);
1008 ix86_expand_branch (GET_CODE (operands[0]),
1009 operands[1], operands[2], operands[3]);
1013 (define_expand "cstore<mode>4"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1016 (match_operand:SWIM 3 "<general_operand>" "")))
1017 (set (match_operand:QI 0 "register_operand" "")
1018 (match_operator 1 "ordered_comparison_operator"
1019 [(reg:CC FLAGS_REG) (const_int 0)]))]
1022 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1023 operands[2] = force_reg (<MODE>mode, operands[2]);
1024 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1025 operands[2], operands[3]);
1029 (define_expand "cmp<mode>_1"
1030 [(set (reg:CC FLAGS_REG)
1031 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1032 (match_operand:SWI48 1 "<general_operand>" "")))])
1034 (define_insn "*cmp<mode>_ccno_1"
1035 [(set (reg FLAGS_REG)
1036 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1037 (match_operand:SWI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1040 test{<imodesuffix>}\t%0, %0
1041 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1042 [(set_attr "type" "test,icmp")
1043 (set_attr "length_immediate" "0,1")
1044 (set_attr "mode" "<MODE>")])
1046 (define_insn "*cmp<mode>_1"
1047 [(set (reg FLAGS_REG)
1048 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1049 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1050 "ix86_match_ccmode (insn, CCmode)"
1051 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1052 [(set_attr "type" "icmp")
1053 (set_attr "mode" "<MODE>")])
1055 (define_insn "*cmp<mode>_minus_1"
1056 [(set (reg FLAGS_REG)
1058 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1059 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1061 "ix86_match_ccmode (insn, CCGOCmode)"
1062 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1063 [(set_attr "type" "icmp")
1064 (set_attr "mode" "<MODE>")])
1066 (define_insn "*cmpqi_ext_1"
1067 [(set (reg FLAGS_REG)
1069 (match_operand:QI 0 "general_operand" "Qm")
1072 (match_operand 1 "ext_register_operand" "Q")
1074 (const_int 8)) 0)))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%h1, %0|%0, %h1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "mode" "QI")])
1080 (define_insn "*cmpqi_ext_1_rex64"
1081 [(set (reg FLAGS_REG)
1083 (match_operand:QI 0 "register_operand" "Q")
1086 (match_operand 1 "ext_register_operand" "Q")
1088 (const_int 8)) 0)))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%h1, %0|%0, %h1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "mode" "QI")])
1094 (define_insn "*cmpqi_ext_2"
1095 [(set (reg FLAGS_REG)
1099 (match_operand 0 "ext_register_operand" "Q")
1102 (match_operand:QI 1 "const0_operand" "")))]
1103 "ix86_match_ccmode (insn, CCNOmode)"
1105 [(set_attr "type" "test")
1106 (set_attr "length_immediate" "0")
1107 (set_attr "mode" "QI")])
1109 (define_expand "cmpqi_ext_3"
1110 [(set (reg:CC FLAGS_REG)
1114 (match_operand 0 "ext_register_operand" "")
1117 (match_operand:QI 1 "immediate_operand" "")))])
1119 (define_insn "*cmpqi_ext_3_insn"
1120 [(set (reg FLAGS_REG)
1124 (match_operand 0 "ext_register_operand" "Q")
1127 (match_operand:QI 1 "general_operand" "Qmn")))]
1128 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1129 "cmp{b}\t{%1, %h0|%h0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "modrm" "1")
1132 (set_attr "mode" "QI")])
1134 (define_insn "*cmpqi_ext_3_insn_rex64"
1135 [(set (reg FLAGS_REG)
1139 (match_operand 0 "ext_register_operand" "Q")
1142 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1143 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1144 "cmp{b}\t{%1, %h0|%h0, %1}"
1145 [(set_attr "type" "icmp")
1146 (set_attr "modrm" "1")
1147 (set_attr "mode" "QI")])
1149 (define_insn "*cmpqi_ext_4"
1150 [(set (reg FLAGS_REG)
1154 (match_operand 0 "ext_register_operand" "Q")
1159 (match_operand 1 "ext_register_operand" "Q")
1161 (const_int 8)) 0)))]
1162 "ix86_match_ccmode (insn, CCmode)"
1163 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1164 [(set_attr "type" "icmp")
1165 (set_attr "mode" "QI")])
1167 ;; These implement float point compares.
1168 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1169 ;; which would allow mix and match FP modes on the compares. Which is what
1170 ;; the old patterns did, but with many more of them.
1172 (define_expand "cbranchxf4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1175 (match_operand:XF 2 "nonmemory_operand" "")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ix86_fp_comparison_operator"
1180 (label_ref (match_operand 3 "" ""))
1184 ix86_expand_branch (GET_CODE (operands[0]),
1185 operands[1], operands[2], operands[3]);
1189 (define_expand "cstorexf4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1192 (match_operand:XF 3 "nonmemory_operand" "")))
1193 (set (match_operand:QI 0 "register_operand" "")
1194 (match_operator 1 "ix86_fp_comparison_operator"
1199 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200 operands[2], operands[3]);
1204 (define_expand "cbranch<mode>4"
1205 [(set (reg:CC FLAGS_REG)
1206 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1207 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1208 (set (pc) (if_then_else
1209 (match_operator 0 "ix86_fp_comparison_operator"
1212 (label_ref (match_operand 3 "" ""))
1214 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1216 ix86_expand_branch (GET_CODE (operands[0]),
1217 operands[1], operands[2], operands[3]);
1221 (define_expand "cstore<mode>4"
1222 [(set (reg:CC FLAGS_REG)
1223 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1224 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1225 (set (match_operand:QI 0 "register_operand" "")
1226 (match_operator 1 "ix86_fp_comparison_operator"
1229 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1231 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1232 operands[2], operands[3]);
1236 (define_expand "cbranchcc4"
1237 [(set (pc) (if_then_else
1238 (match_operator 0 "comparison_operator"
1239 [(match_operand 1 "flags_reg_operand" "")
1240 (match_operand 2 "const0_operand" "")])
1241 (label_ref (match_operand 3 "" ""))
1245 ix86_expand_branch (GET_CODE (operands[0]),
1246 operands[1], operands[2], operands[3]);
1250 (define_expand "cstorecc4"
1251 [(set (match_operand:QI 0 "register_operand" "")
1252 (match_operator 1 "comparison_operator"
1253 [(match_operand 2 "flags_reg_operand" "")
1254 (match_operand 3 "const0_operand" "")]))]
1257 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1258 operands[2], operands[3]);
1263 ;; FP compares, step 1:
1264 ;; Set the FP condition codes.
1266 ;; CCFPmode compare with exceptions
1267 ;; CCFPUmode compare with no exceptions
1269 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1270 ;; used to manage the reg stack popping would not be preserved.
1272 (define_insn "*cmpfp_0"
1273 [(set (match_operand:HI 0 "register_operand" "=a")
1276 (match_operand 1 "register_operand" "f")
1277 (match_operand 2 "const0_operand" ""))]
1279 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281 "* return output_fp_compare (insn, operands, false, false);"
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1285 (cond [(match_operand:SF 1 "" "")
1287 (match_operand:DF 1 "" "")
1290 (const_string "XF")))])
1292 (define_insn_and_split "*cmpfp_0_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1295 (match_operand 1 "register_operand" "f")
1296 (match_operand 2 "const0_operand" "")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1298 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1299 && TARGET_SAHF && !TARGET_CMOVE
1300 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1302 "&& reload_completed"
1305 [(compare:CCFP (match_dup 1)(match_dup 2))]
1307 (set (reg:CC FLAGS_REG)
1308 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1313 (cond [(match_operand:SF 1 "" "")
1315 (match_operand:DF 1 "" "")
1318 (const_string "XF")))])
1320 (define_insn "*cmpfp_xf"
1321 [(set (match_operand:HI 0 "register_operand" "=a")
1324 (match_operand:XF 1 "register_operand" "f")
1325 (match_operand:XF 2 "register_operand" "f"))]
1328 "* return output_fp_compare (insn, operands, false, false);"
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "XF")])
1333 (define_insn_and_split "*cmpfp_xf_cc"
1334 [(set (reg:CCFP FLAGS_REG)
1336 (match_operand:XF 1 "register_operand" "f")
1337 (match_operand:XF 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1340 && TARGET_SAHF && !TARGET_CMOVE"
1342 "&& reload_completed"
1345 [(compare:CCFP (match_dup 1)(match_dup 2))]
1347 (set (reg:CC FLAGS_REG)
1348 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350 [(set_attr "type" "multi")
1351 (set_attr "unit" "i387")
1352 (set_attr "mode" "XF")])
1354 (define_insn "*cmpfp_<mode>"
1355 [(set (match_operand:HI 0 "register_operand" "=a")
1358 (match_operand:MODEF 1 "register_operand" "f")
1359 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1362 "* return output_fp_compare (insn, operands, false, false);"
1363 [(set_attr "type" "multi")
1364 (set_attr "unit" "i387")
1365 (set_attr "mode" "<MODE>")])
1367 (define_insn_and_split "*cmpfp_<mode>_cc"
1368 [(set (reg:CCFP FLAGS_REG)
1370 (match_operand:MODEF 1 "register_operand" "f")
1371 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1372 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1374 && TARGET_SAHF && !TARGET_CMOVE"
1376 "&& reload_completed"
1379 [(compare:CCFP (match_dup 1)(match_dup 2))]
1381 (set (reg:CC FLAGS_REG)
1382 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1384 [(set_attr "type" "multi")
1385 (set_attr "unit" "i387")
1386 (set_attr "mode" "<MODE>")])
1388 (define_insn "*cmpfp_u"
1389 [(set (match_operand:HI 0 "register_operand" "=a")
1392 (match_operand 1 "register_operand" "f")
1393 (match_operand 2 "register_operand" "f"))]
1395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397 "* return output_fp_compare (insn, operands, false, true);"
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1401 (cond [(match_operand:SF 1 "" "")
1403 (match_operand:DF 1 "" "")
1406 (const_string "XF")))])
1408 (define_insn_and_split "*cmpfp_u_cc"
1409 [(set (reg:CCFPU FLAGS_REG)
1411 (match_operand 1 "register_operand" "f")
1412 (match_operand 2 "register_operand" "f")))
1413 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1415 && TARGET_SAHF && !TARGET_CMOVE
1416 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1418 "&& reload_completed"
1421 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1423 (set (reg:CC FLAGS_REG)
1424 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1426 [(set_attr "type" "multi")
1427 (set_attr "unit" "i387")
1429 (cond [(match_operand:SF 1 "" "")
1431 (match_operand:DF 1 "" "")
1434 (const_string "XF")))])
1436 (define_insn "*cmpfp_<mode>"
1437 [(set (match_operand:HI 0 "register_operand" "=a")
1440 (match_operand 1 "register_operand" "f")
1441 (match_operator 3 "float_operator"
1442 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1446 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1447 "* return output_fp_compare (insn, operands, false, false);"
1448 [(set_attr "type" "multi")
1449 (set_attr "unit" "i387")
1450 (set_attr "fp_int_src" "true")
1451 (set_attr "mode" "<MODE>")])
1453 (define_insn_and_split "*cmpfp_<mode>_cc"
1454 [(set (reg:CCFP FLAGS_REG)
1456 (match_operand 1 "register_operand" "f")
1457 (match_operator 3 "float_operator"
1458 [(match_operand:SWI24 2 "memory_operand" "m")])))
1459 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1460 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1461 && TARGET_SAHF && !TARGET_CMOVE
1462 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1463 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1465 "&& reload_completed"
1470 (match_op_dup 3 [(match_dup 2)]))]
1472 (set (reg:CC FLAGS_REG)
1473 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1475 [(set_attr "type" "multi")
1476 (set_attr "unit" "i387")
1477 (set_attr "fp_int_src" "true")
1478 (set_attr "mode" "<MODE>")])
1480 ;; FP compares, step 2
1481 ;; Move the fpsw to ax.
1483 (define_insn "x86_fnstsw_1"
1484 [(set (match_operand:HI 0 "register_operand" "=a")
1485 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1488 [(set (attr "length")
1489 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1490 (set_attr "mode" "SI")
1491 (set_attr "unit" "i387")])
1493 ;; FP compares, step 3
1494 ;; Get ax into flags, general case.
1496 (define_insn "x86_sahf_1"
1497 [(set (reg:CC FLAGS_REG)
1498 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1502 #ifndef HAVE_AS_IX86_SAHF
1504 return ASM_BYTE "0x9e";
1509 [(set_attr "length" "1")
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")
1512 (set_attr "bdver1_decode" "direct")
1513 (set_attr "mode" "SI")])
1515 ;; Pentium Pro can do steps 1 through 3 in one go.
1516 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1517 ;; (these i387 instructions set flags directly)
1518 (define_insn "*cmpfp_i_mixed"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1521 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1522 "TARGET_MIX_SSE_I387
1523 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, false);"
1526 [(set_attr "type" "fcmp,ssecomi")
1527 (set_attr "prefix" "orig,maybe_vex")
1529 (if_then_else (match_operand:SF 1 "" "")
1531 (const_string "DF")))
1532 (set (attr "prefix_rep")
1533 (if_then_else (eq_attr "type" "ssecomi")
1535 (const_string "*")))
1536 (set (attr "prefix_data16")
1537 (cond [(eq_attr "type" "fcmp")
1539 (eq_attr "mode" "DF")
1542 (const_string "0")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1547 (define_insn "*cmpfp_i_sse"
1548 [(set (reg:CCFP FLAGS_REG)
1549 (compare:CCFP (match_operand 0 "register_operand" "x")
1550 (match_operand 1 "nonimmediate_operand" "xm")))]
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, false);"
1555 [(set_attr "type" "ssecomi")
1556 (set_attr "prefix" "maybe_vex")
1558 (if_then_else (match_operand:SF 1 "" "")
1560 (const_string "DF")))
1561 (set_attr "prefix_rep" "0")
1562 (set (attr "prefix_data16")
1563 (if_then_else (eq_attr "mode" "DF")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")
1568 (set_attr "bdver1_decode" "double")])
1570 (define_insn "*cmpfp_i_i387"
1571 [(set (reg:CCFP FLAGS_REG)
1572 (compare:CCFP (match_operand 0 "register_operand" "f")
1573 (match_operand 1 "register_operand" "f")))]
1574 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1577 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1578 "* return output_fp_compare (insn, operands, true, false);"
1579 [(set_attr "type" "fcmp")
1581 (cond [(match_operand:SF 1 "" "")
1583 (match_operand:DF 1 "" "")
1586 (const_string "XF")))
1587 (set_attr "athlon_decode" "vector")
1588 (set_attr "amdfam10_decode" "direct")
1589 (set_attr "bdver1_decode" "double")])
1591 (define_insn "*cmpfp_iu_mixed"
1592 [(set (reg:CCFPU FLAGS_REG)
1593 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1594 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1595 "TARGET_MIX_SSE_I387
1596 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, true, true);"
1599 [(set_attr "type" "fcmp,ssecomi")
1600 (set_attr "prefix" "orig,maybe_vex")
1602 (if_then_else (match_operand:SF 1 "" "")
1604 (const_string "DF")))
1605 (set (attr "prefix_rep")
1606 (if_then_else (eq_attr "type" "ssecomi")
1608 (const_string "*")))
1609 (set (attr "prefix_data16")
1610 (cond [(eq_attr "type" "fcmp")
1612 (eq_attr "mode" "DF")
1615 (const_string "0")))
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "double")])
1620 (define_insn "*cmpfp_iu_sse"
1621 [(set (reg:CCFPU FLAGS_REG)
1622 (compare:CCFPU (match_operand 0 "register_operand" "x")
1623 (match_operand 1 "nonimmediate_operand" "xm")))]
1625 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1626 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1627 "* return output_fp_compare (insn, operands, true, true);"
1628 [(set_attr "type" "ssecomi")
1629 (set_attr "prefix" "maybe_vex")
1631 (if_then_else (match_operand:SF 1 "" "")
1633 (const_string "DF")))
1634 (set_attr "prefix_rep" "0")
1635 (set (attr "prefix_data16")
1636 (if_then_else (eq_attr "mode" "DF")
1638 (const_string "0")))
1639 (set_attr "athlon_decode" "vector")
1640 (set_attr "amdfam10_decode" "direct")
1641 (set_attr "bdver1_decode" "double")])
1643 (define_insn "*cmpfp_iu_387"
1644 [(set (reg:CCFPU FLAGS_REG)
1645 (compare:CCFPU (match_operand 0 "register_operand" "f")
1646 (match_operand 1 "register_operand" "f")))]
1647 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1649 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1650 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1651 "* return output_fp_compare (insn, operands, true, true);"
1652 [(set_attr "type" "fcmp")
1654 (cond [(match_operand:SF 1 "" "")
1656 (match_operand:DF 1 "" "")
1659 (const_string "XF")))
1660 (set_attr "athlon_decode" "vector")
1661 (set_attr "amdfam10_decode" "direct")
1662 (set_attr "bdver1_decode" "direct")])
1664 ;; Push/pop instructions.
1666 (define_insn "*push<mode>2"
1667 [(set (match_operand:DWI 0 "push_operand" "=<")
1668 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1671 [(set_attr "type" "multi")
1672 (set_attr "mode" "<MODE>")])
1675 [(set (match_operand:TI 0 "push_operand" "")
1676 (match_operand:TI 1 "general_operand" ""))]
1677 "TARGET_64BIT && reload_completed
1678 && !SSE_REG_P (operands[1])"
1680 "ix86_split_long_move (operands); DONE;")
1682 (define_insn "*pushdi2_rex64"
1683 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1684 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1689 [(set_attr "type" "push,multi")
1690 (set_attr "mode" "DI")])
1692 ;; Convert impossible pushes of immediate to existing instructions.
1693 ;; First try to get scratch register and go through it. In case this
1694 ;; fails, push sign extended lower part first and then overwrite
1695 ;; upper part by 32bit move.
1697 [(match_scratch:DI 2 "r")
1698 (set (match_operand:DI 0 "push_operand" "")
1699 (match_operand:DI 1 "immediate_operand" ""))]
1700 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1701 && !x86_64_immediate_operand (operands[1], DImode)"
1702 [(set (match_dup 2) (match_dup 1))
1703 (set (match_dup 0) (match_dup 2))])
1705 ;; We need to define this as both peepholer and splitter for case
1706 ;; peephole2 pass is not run.
1707 ;; "&& 1" is needed to keep it from matching the previous pattern.
1709 [(set (match_operand:DI 0 "push_operand" "")
1710 (match_operand:DI 1 "immediate_operand" ""))]
1711 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1712 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1713 [(set (match_dup 0) (match_dup 1))
1714 (set (match_dup 2) (match_dup 3))]
1716 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1718 operands[1] = gen_lowpart (DImode, operands[2]);
1719 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1724 [(set (match_operand:DI 0 "push_operand" "")
1725 (match_operand:DI 1 "immediate_operand" ""))]
1726 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1727 ? epilogue_completed : reload_completed)
1728 && !symbolic_operand (operands[1], DImode)
1729 && !x86_64_immediate_operand (operands[1], DImode)"
1730 [(set (match_dup 0) (match_dup 1))
1731 (set (match_dup 2) (match_dup 3))]
1733 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1735 operands[1] = gen_lowpart (DImode, operands[2]);
1736 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1741 [(set (match_operand:DI 0 "push_operand" "")
1742 (match_operand:DI 1 "general_operand" ""))]
1743 "!TARGET_64BIT && reload_completed
1744 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1746 "ix86_split_long_move (operands); DONE;")
1748 (define_insn "*pushsi2"
1749 [(set (match_operand:SI 0 "push_operand" "=<")
1750 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1753 [(set_attr "type" "push")
1754 (set_attr "mode" "SI")])
1756 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1757 ;; "push a byte/word". But actually we use pushl, which has the effect
1758 ;; of rounding the amount pushed up to a word.
1760 ;; For TARGET_64BIT we always round up to 8 bytes.
1761 (define_insn "*push<mode>2_rex64"
1762 [(set (match_operand:SWI124 0 "push_operand" "=X")
1763 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1766 [(set_attr "type" "push")
1767 (set_attr "mode" "DI")])
1769 (define_insn "*push<mode>2"
1770 [(set (match_operand:SWI12 0 "push_operand" "=X")
1771 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1774 [(set_attr "type" "push")
1775 (set_attr "mode" "SI")])
1777 (define_insn "*push<mode>2_prologue"
1778 [(set (match_operand:P 0 "push_operand" "=<")
1779 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1780 (clobber (mem:BLK (scratch)))]
1782 "push{<imodesuffix>}\t%1"
1783 [(set_attr "type" "push")
1784 (set_attr "mode" "<MODE>")])
1786 (define_insn "*pop<mode>1"
1787 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1788 (match_operand:P 1 "pop_operand" ">"))]
1790 "pop{<imodesuffix>}\t%0"
1791 [(set_attr "type" "pop")
1792 (set_attr "mode" "<MODE>")])
1794 (define_insn "*pop<mode>1_epilogue"
1795 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1796 (match_operand:P 1 "pop_operand" ">"))
1797 (clobber (mem:BLK (scratch)))]
1799 "pop{<imodesuffix>}\t%0"
1800 [(set_attr "type" "pop")
1801 (set_attr "mode" "<MODE>")])
1803 ;; Move instructions.
1805 (define_expand "movoi"
1806 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1807 (match_operand:OI 1 "general_operand" ""))]
1809 "ix86_expand_move (OImode, operands); DONE;")
1811 (define_expand "movti"
1812 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1813 (match_operand:TI 1 "nonimmediate_operand" ""))]
1814 "TARGET_64BIT || TARGET_SSE"
1817 ix86_expand_move (TImode, operands);
1818 else if (push_operand (operands[0], TImode))
1819 ix86_expand_push (TImode, operands[1]);
1821 ix86_expand_vector_move (TImode, operands);
1825 ;; This expands to what emit_move_complex would generate if we didn't
1826 ;; have a movti pattern. Having this avoids problems with reload on
1827 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1828 ;; to have around all the time.
1829 (define_expand "movcdi"
1830 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1831 (match_operand:CDI 1 "general_operand" ""))]
1834 if (push_operand (operands[0], CDImode))
1835 emit_move_complex_push (CDImode, operands[0], operands[1]);
1837 emit_move_complex_parts (operands[0], operands[1]);
1841 (define_expand "mov<mode>"
1842 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1843 (match_operand:SWI1248x 1 "general_operand" ""))]
1845 "ix86_expand_move (<MODE>mode, operands); DONE;")
1847 (define_insn "*mov<mode>_xor"
1848 [(set (match_operand:SWI48 0 "register_operand" "=r")
1849 (match_operand:SWI48 1 "const0_operand" ""))
1850 (clobber (reg:CC FLAGS_REG))]
1853 [(set_attr "type" "alu1")
1854 (set_attr "mode" "SI")
1855 (set_attr "length_immediate" "0")])
1857 (define_insn "*mov<mode>_or"
1858 [(set (match_operand:SWI48 0 "register_operand" "=r")
1859 (match_operand:SWI48 1 "const_int_operand" ""))
1860 (clobber (reg:CC FLAGS_REG))]
1862 && operands[1] == constm1_rtx"
1863 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1864 [(set_attr "type" "alu1")
1865 (set_attr "mode" "<MODE>")
1866 (set_attr "length_immediate" "1")])
1868 (define_insn "*movoi_internal_avx"
1869 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1870 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1871 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 switch (which_alternative)
1876 return standard_sse_constant_opcode (insn, operands[1]);
1879 if (misaligned_operand (operands[0], OImode)
1880 || misaligned_operand (operands[1], OImode))
1881 return "vmovdqu\t{%1, %0|%0, %1}";
1883 return "vmovdqa\t{%1, %0|%0, %1}";
1888 [(set_attr "type" "sselog1,ssemov,ssemov")
1889 (set_attr "prefix" "vex")
1890 (set_attr "mode" "OI")])
1892 (define_insn "*movti_internal_rex64"
1893 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1894 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1895 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1897 switch (which_alternative)
1903 return standard_sse_constant_opcode (insn, operands[1]);
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1927 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1930 (cond [(eq_attr "alternative" "2,3")
1932 (match_test "optimize_function_for_size_p (cfun)")
1933 (const_string "V4SF")
1934 (const_string "TI"))
1935 (eq_attr "alternative" "4")
1937 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1938 (match_test "optimize_function_for_size_p (cfun)"))
1939 (const_string "V4SF")
1940 (const_string "TI"))]
1941 (const_string "DI")))])
1944 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1945 (match_operand:TI 1 "general_operand" ""))]
1947 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1949 "ix86_split_long_move (operands); DONE;")
1951 (define_insn "*movti_internal_sse"
1952 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1953 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1954 "TARGET_SSE && !TARGET_64BIT
1955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1957 switch (which_alternative)
1960 return standard_sse_constant_opcode (insn, operands[1]);
1963 /* TDmode values are passed as TImode on the stack. Moving them
1964 to stack may result in unaligned memory access. */
1965 if (misaligned_operand (operands[0], TImode)
1966 || misaligned_operand (operands[1], TImode))
1968 if (get_attr_mode (insn) == MODE_V4SF)
1969 return "%vmovups\t{%1, %0|%0, %1}";
1971 return "%vmovdqu\t{%1, %0|%0, %1}";
1975 if (get_attr_mode (insn) == MODE_V4SF)
1976 return "%vmovaps\t{%1, %0|%0, %1}";
1978 return "%vmovdqa\t{%1, %0|%0, %1}";
1984 [(set_attr "type" "sselog1,ssemov,ssemov")
1985 (set_attr "prefix" "maybe_vex")
1987 (cond [(ior (not (match_test "TARGET_SSE2"))
1988 (match_test "optimize_function_for_size_p (cfun)"))
1989 (const_string "V4SF")
1990 (and (eq_attr "alternative" "2")
1991 (match_test "TARGET_SSE_TYPELESS_STORES"))
1992 (const_string "V4SF")]
1993 (const_string "TI")))])
1995 (define_insn "*movdi_internal_rex64"
1996 [(set (match_operand:DI 0 "nonimmediate_operand"
1997 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1998 (match_operand:DI 1 "general_operand"
1999 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2000 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2002 switch (get_attr_type (insn))
2005 if (SSE_REG_P (operands[0]))
2006 return "movq2dq\t{%1, %0|%0, %1}";
2008 return "movdq2q\t{%1, %0|%0, %1}";
2011 if (get_attr_mode (insn) == MODE_TI)
2012 return "%vmovdqa\t{%1, %0|%0, %1}";
2013 /* Handle broken assemblers that require movd instead of movq. */
2014 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015 return "%vmovd\t{%1, %0|%0, %1}";
2017 return "%vmovq\t{%1, %0|%0, %1}";
2020 /* Handle broken assemblers that require movd instead of movq. */
2021 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2022 return "movd\t{%1, %0|%0, %1}";
2024 return "movq\t{%1, %0|%0, %1}";
2027 return standard_sse_constant_opcode (insn, operands[1]);
2030 return "pxor\t%0, %0";
2036 return "lea{q}\t{%a1, %0|%0, %a1}";
2039 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2040 if (get_attr_mode (insn) == MODE_SI)
2041 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2042 else if (which_alternative == 2)
2043 return "movabs{q}\t{%1, %0|%0, %1}";
2045 return "mov{q}\t{%1, %0|%0, %1}";
2049 (cond [(eq_attr "alternative" "4")
2050 (const_string "multi")
2051 (eq_attr "alternative" "5")
2052 (const_string "mmx")
2053 (eq_attr "alternative" "6,7,8,9")
2054 (const_string "mmxmov")
2055 (eq_attr "alternative" "10")
2056 (const_string "sselog1")
2057 (eq_attr "alternative" "11,12,13,14,15")
2058 (const_string "ssemov")
2059 (eq_attr "alternative" "16,17")
2060 (const_string "ssecvt")
2061 (match_operand 1 "pic_32bit_operand" "")
2062 (const_string "lea")
2064 (const_string "imov")))
2067 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2069 (const_string "*")))
2070 (set (attr "length_immediate")
2072 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2074 (const_string "*")))
2075 (set (attr "prefix_rex")
2076 (if_then_else (eq_attr "alternative" "8,9")
2078 (const_string "*")))
2079 (set (attr "prefix_data16")
2080 (if_then_else (eq_attr "alternative" "11")
2082 (const_string "*")))
2083 (set (attr "prefix")
2084 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2085 (const_string "maybe_vex")
2086 (const_string "orig")))
2087 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2089 ;; Reload patterns to support multi-word load/store
2090 ;; with non-offsetable address.
2091 (define_expand "reload_noff_store"
2092 [(parallel [(match_operand 0 "memory_operand" "=m")
2093 (match_operand 1 "register_operand" "r")
2094 (match_operand:DI 2 "register_operand" "=&r")])]
2097 rtx mem = operands[0];
2098 rtx addr = XEXP (mem, 0);
2100 emit_move_insn (operands[2], addr);
2101 mem = replace_equiv_address_nv (mem, operands[2]);
2103 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2107 (define_expand "reload_noff_load"
2108 [(parallel [(match_operand 0 "register_operand" "=r")
2109 (match_operand 1 "memory_operand" "m")
2110 (match_operand:DI 2 "register_operand" "=r")])]
2113 rtx mem = operands[1];
2114 rtx addr = XEXP (mem, 0);
2116 emit_move_insn (operands[2], addr);
2117 mem = replace_equiv_address_nv (mem, operands[2]);
2119 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2123 ;; Convert impossible stores of immediate to existing instructions.
2124 ;; First try to get scratch register and go through it. In case this
2125 ;; fails, move by 32bit parts.
2127 [(match_scratch:DI 2 "r")
2128 (set (match_operand:DI 0 "memory_operand" "")
2129 (match_operand:DI 1 "immediate_operand" ""))]
2130 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131 && !x86_64_immediate_operand (operands[1], DImode)"
2132 [(set (match_dup 2) (match_dup 1))
2133 (set (match_dup 0) (match_dup 2))])
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? epilogue_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2158 (define_insn "*movdi_internal"
2159 [(set (match_operand:DI 0 "nonimmediate_operand"
2160 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2161 (match_operand:DI 1 "general_operand"
2162 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2163 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2165 switch (get_attr_type (insn))
2168 if (SSE_REG_P (operands[0]))
2169 return "movq2dq\t{%1, %0|%0, %1}";
2171 return "movdq2q\t{%1, %0|%0, %1}";
2174 switch (get_attr_mode (insn))
2177 return "%vmovdqa\t{%1, %0|%0, %1}";
2179 return "%vmovq\t{%1, %0|%0, %1}";
2181 return "movaps\t{%1, %0|%0, %1}";
2183 return "movlps\t{%1, %0|%0, %1}";
2189 return "movq\t{%1, %0|%0, %1}";
2192 return standard_sse_constant_opcode (insn, operands[1]);
2195 return "pxor\t%0, %0";
2205 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2206 (const_string "sse2")
2207 (eq_attr "alternative" "9,10,11,12")
2208 (const_string "noavx")
2210 (const_string "*")))
2212 (cond [(eq_attr "alternative" "0,1")
2213 (const_string "multi")
2214 (eq_attr "alternative" "2")
2215 (const_string "mmx")
2216 (eq_attr "alternative" "3,4")
2217 (const_string "mmxmov")
2218 (eq_attr "alternative" "5,9")
2219 (const_string "sselog1")
2220 (eq_attr "alternative" "13,14")
2221 (const_string "ssecvt")
2223 (const_string "ssemov")))
2224 (set (attr "prefix")
2225 (if_then_else (eq_attr "alternative" "5,6,7,8")
2226 (const_string "maybe_vex")
2227 (const_string "orig")))
2228 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2231 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2232 (match_operand:DI 1 "general_operand" ""))]
2233 "!TARGET_64BIT && reload_completed
2234 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2235 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2237 "ix86_split_long_move (operands); DONE;")
2239 (define_insn "*movsi_internal"
2240 [(set (match_operand:SI 0 "nonimmediate_operand"
2241 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2242 (match_operand:SI 1 "general_operand"
2243 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2244 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2246 switch (get_attr_type (insn))
2249 return standard_sse_constant_opcode (insn, operands[1]);
2252 switch (get_attr_mode (insn))
2255 return "%vmovdqa\t{%1, %0|%0, %1}";
2257 return "%vmovaps\t{%1, %0|%0, %1}";
2259 return "%vmovd\t{%1, %0|%0, %1}";
2261 return "%vmovss\t{%1, %0|%0, %1}";
2267 return "pxor\t%0, %0";
2270 if (get_attr_mode (insn) == MODE_DI)
2271 return "movq\t{%1, %0|%0, %1}";
2272 return "movd\t{%1, %0|%0, %1}";
2275 return "lea{l}\t{%a1, %0|%0, %a1}";
2278 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2279 return "mov{l}\t{%1, %0|%0, %1}";
2283 (cond [(eq_attr "alternative" "2")
2284 (const_string "mmx")
2285 (eq_attr "alternative" "3,4,5")
2286 (const_string "mmxmov")
2287 (eq_attr "alternative" "6")
2288 (const_string "sselog1")
2289 (eq_attr "alternative" "7,8,9,10,11")
2290 (const_string "ssemov")
2291 (match_operand 1 "pic_32bit_operand" "")
2292 (const_string "lea")
2294 (const_string "imov")))
2295 (set (attr "prefix")
2296 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2297 (const_string "orig")
2298 (const_string "maybe_vex")))
2299 (set (attr "prefix_data16")
2300 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2302 (const_string "*")))
2304 (cond [(eq_attr "alternative" "2,3")
2306 (eq_attr "alternative" "6,7")
2308 (not (match_test "TARGET_SSE2"))
2309 (const_string "V4SF")
2310 (const_string "TI"))
2311 (and (eq_attr "alternative" "8,9,10,11")
2312 (not (match_test "TARGET_SSE2")))
2315 (const_string "SI")))])
2317 (define_insn "*movhi_internal"
2318 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2319 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2320 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2322 switch (get_attr_type (insn))
2325 /* movzwl is faster than movw on p2 due to partial word stalls,
2326 though not as fast as an aligned movl. */
2327 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2329 if (get_attr_mode (insn) == MODE_SI)
2330 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2332 return "mov{w}\t{%1, %0|%0, %1}";
2336 (cond [(match_test "optimize_function_for_size_p (cfun)")
2337 (const_string "imov")
2338 (and (eq_attr "alternative" "0")
2339 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2340 (not (match_test "TARGET_HIMODE_MATH"))))
2341 (const_string "imov")
2342 (and (eq_attr "alternative" "1,2")
2343 (match_operand:HI 1 "aligned_operand" ""))
2344 (const_string "imov")
2345 (and (match_test "TARGET_MOVX")
2346 (eq_attr "alternative" "0,2"))
2347 (const_string "imovx")
2349 (const_string "imov")))
2351 (cond [(eq_attr "type" "imovx")
2353 (and (eq_attr "alternative" "1,2")
2354 (match_operand:HI 1 "aligned_operand" ""))
2356 (and (eq_attr "alternative" "0")
2357 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2358 (not (match_test "TARGET_HIMODE_MATH"))))
2361 (const_string "HI")))])
2363 ;; Situation is quite tricky about when to choose full sized (SImode) move
2364 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2365 ;; partial register dependency machines (such as AMD Athlon), where QImode
2366 ;; moves issue extra dependency and for partial register stalls machines
2367 ;; that don't use QImode patterns (and QImode move cause stall on the next
2370 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2371 ;; register stall machines with, where we use QImode instructions, since
2372 ;; partial register stall can be caused there. Then we use movzx.
2373 (define_insn "*movqi_internal"
2374 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2375 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2376 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2378 switch (get_attr_type (insn))
2381 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2382 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2384 if (get_attr_mode (insn) == MODE_SI)
2385 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387 return "mov{b}\t{%1, %0|%0, %1}";
2391 (cond [(and (eq_attr "alternative" "5")
2392 (not (match_operand:QI 1 "aligned_operand" "")))
2393 (const_string "imovx")
2394 (match_test "optimize_function_for_size_p (cfun)")
2395 (const_string "imov")
2396 (and (eq_attr "alternative" "3")
2397 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2398 (not (match_test "TARGET_QIMODE_MATH"))))
2399 (const_string "imov")
2400 (eq_attr "alternative" "3,5")
2401 (const_string "imovx")
2402 (and (match_test "TARGET_MOVX")
2403 (eq_attr "alternative" "2"))
2404 (const_string "imovx")
2406 (const_string "imov")))
2408 (cond [(eq_attr "alternative" "3,4,5")
2410 (eq_attr "alternative" "6")
2412 (eq_attr "type" "imovx")
2414 (and (eq_attr "type" "imov")
2415 (and (eq_attr "alternative" "0,1")
2416 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2417 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2418 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2420 ;; Avoid partial register stalls when not using QImode arithmetic
2421 (and (eq_attr "type" "imov")
2422 (and (eq_attr "alternative" "0,1")
2423 (and (match_test "TARGET_PARTIAL_REG_STALL")
2424 (not (match_test "TARGET_QIMODE_MATH")))))
2427 (const_string "QI")))])
2429 ;; Stores and loads of ax to arbitrary constant address.
2430 ;; We fake an second form of instruction to force reload to load address
2431 ;; into register when rax is not available
2432 (define_insn "*movabs<mode>_1"
2433 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2434 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2435 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2437 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2438 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2439 [(set_attr "type" "imov")
2440 (set_attr "modrm" "0,*")
2441 (set_attr "length_address" "8,0")
2442 (set_attr "length_immediate" "0,*")
2443 (set_attr "memory" "store")
2444 (set_attr "mode" "<MODE>")])
2446 (define_insn "*movabs<mode>_2"
2447 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2448 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2449 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2451 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2452 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2453 [(set_attr "type" "imov")
2454 (set_attr "modrm" "0,*")
2455 (set_attr "length_address" "8,0")
2456 (set_attr "length_immediate" "0")
2457 (set_attr "memory" "load")
2458 (set_attr "mode" "<MODE>")])
2460 (define_insn "*swap<mode>"
2461 [(set (match_operand:SWI48 0 "register_operand" "+r")
2462 (match_operand:SWI48 1 "register_operand" "+r"))
2466 "xchg{<imodesuffix>}\t%1, %0"
2467 [(set_attr "type" "imov")
2468 (set_attr "mode" "<MODE>")
2469 (set_attr "pent_pair" "np")
2470 (set_attr "athlon_decode" "vector")
2471 (set_attr "amdfam10_decode" "double")
2472 (set_attr "bdver1_decode" "double")])
2474 (define_insn "*swap<mode>_1"
2475 [(set (match_operand:SWI12 0 "register_operand" "+r")
2476 (match_operand:SWI12 1 "register_operand" "+r"))
2479 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2481 [(set_attr "type" "imov")
2482 (set_attr "mode" "SI")
2483 (set_attr "pent_pair" "np")
2484 (set_attr "athlon_decode" "vector")
2485 (set_attr "amdfam10_decode" "double")
2486 (set_attr "bdver1_decode" "double")])
2488 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2489 ;; is disabled for AMDFAM10
2490 (define_insn "*swap<mode>_2"
2491 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2492 (match_operand:SWI12 1 "register_operand" "+<r>"))
2495 "TARGET_PARTIAL_REG_STALL"
2496 "xchg{<imodesuffix>}\t%1, %0"
2497 [(set_attr "type" "imov")
2498 (set_attr "mode" "<MODE>")
2499 (set_attr "pent_pair" "np")
2500 (set_attr "athlon_decode" "vector")])
2502 (define_expand "movstrict<mode>"
2503 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2504 (match_operand:SWI12 1 "general_operand" ""))]
2507 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2509 if (GET_CODE (operands[0]) == SUBREG
2510 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2512 /* Don't generate memory->memory moves, go through a register */
2513 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2514 operands[1] = force_reg (<MODE>mode, operands[1]);
2517 (define_insn "*movstrict<mode>_1"
2518 [(set (strict_low_part
2519 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2520 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2521 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2522 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2523 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2524 [(set_attr "type" "imov")
2525 (set_attr "mode" "<MODE>")])
2527 (define_insn "*movstrict<mode>_xor"
2528 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2529 (match_operand:SWI12 1 "const0_operand" ""))
2530 (clobber (reg:CC FLAGS_REG))]
2532 "xor{<imodesuffix>}\t%0, %0"
2533 [(set_attr "type" "alu1")
2534 (set_attr "mode" "<MODE>")
2535 (set_attr "length_immediate" "0")])
2537 (define_insn "*mov<mode>_extv_1"
2538 [(set (match_operand:SWI24 0 "register_operand" "=R")
2539 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2543 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2544 [(set_attr "type" "imovx")
2545 (set_attr "mode" "SI")])
2547 (define_insn "*movqi_extv_1_rex64"
2548 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2549 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2554 switch (get_attr_type (insn))
2557 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2559 return "mov{b}\t{%h1, %0|%0, %h1}";
2563 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2564 (match_test "TARGET_MOVX"))
2565 (const_string "imovx")
2566 (const_string "imov")))
2568 (if_then_else (eq_attr "type" "imovx")
2570 (const_string "QI")))])
2572 (define_insn "*movqi_extv_1"
2573 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2574 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2579 switch (get_attr_type (insn))
2582 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2584 return "mov{b}\t{%h1, %0|%0, %h1}";
2588 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2589 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2590 (match_test "TARGET_MOVX")))
2591 (const_string "imovx")
2592 (const_string "imov")))
2594 (if_then_else (eq_attr "type" "imovx")
2596 (const_string "QI")))])
2598 (define_insn "*mov<mode>_extzv_1"
2599 [(set (match_operand:SWI48 0 "register_operand" "=R")
2600 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2604 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2605 [(set_attr "type" "imovx")
2606 (set_attr "mode" "SI")])
2608 (define_insn "*movqi_extzv_2_rex64"
2609 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2611 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2616 switch (get_attr_type (insn))
2619 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2621 return "mov{b}\t{%h1, %0|%0, %h1}";
2625 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2626 (match_test "TARGET_MOVX"))
2627 (const_string "imovx")
2628 (const_string "imov")))
2630 (if_then_else (eq_attr "type" "imovx")
2632 (const_string "QI")))])
2634 (define_insn "*movqi_extzv_2"
2635 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2637 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2642 switch (get_attr_type (insn))
2645 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2647 return "mov{b}\t{%h1, %0|%0, %h1}";
2651 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2652 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2653 (match_test "TARGET_MOVX")))
2654 (const_string "imovx")
2655 (const_string "imov")))
2657 (if_then_else (eq_attr "type" "imovx")
2659 (const_string "QI")))])
2661 (define_expand "mov<mode>_insv_1"
2662 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2665 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2667 (define_insn "*mov<mode>_insv_1_rex64"
2668 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2671 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2673 "mov{b}\t{%b1, %h0|%h0, %b1}"
2674 [(set_attr "type" "imov")
2675 (set_attr "mode" "QI")])
2677 (define_insn "*movsi_insv_1"
2678 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2681 (match_operand:SI 1 "general_operand" "Qmn"))]
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2687 (define_insn "*movqi_insv_2"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2691 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2694 "mov{b}\t{%h1, %h0|%h0, %h1}"
2695 [(set_attr "type" "imov")
2696 (set_attr "mode" "QI")])
2698 ;; Floating point push instructions.
2700 (define_insn "*pushtf"
2701 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2702 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2705 /* This insn should be already split before reg-stack. */
2708 [(set_attr "type" "multi")
2709 (set_attr "unit" "sse,*,*")
2710 (set_attr "mode" "TF,SI,SI")])
2712 ;; %%% Kill this when call knows how to work this out.
2714 [(set (match_operand:TF 0 "push_operand" "")
2715 (match_operand:TF 1 "sse_reg_operand" ""))]
2716 "TARGET_SSE2 && reload_completed"
2717 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2718 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2720 (define_insn "*pushxf"
2721 [(set (match_operand:XF 0 "push_operand" "=<,<")
2722 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2723 "optimize_function_for_speed_p (cfun)"
2725 /* This insn should be already split before reg-stack. */
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "i387,*")
2730 (set_attr "mode" "XF,SI")])
2732 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2733 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2734 ;; Pushing using integer instructions is longer except for constants
2735 ;; and direct memory references (assuming that any given constant is pushed
2736 ;; only once, but this ought to be handled elsewhere).
2738 (define_insn "*pushxf_nointeger"
2739 [(set (match_operand:XF 0 "push_operand" "=<,<")
2740 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2741 "optimize_function_for_size_p (cfun)"
2743 /* This insn should be already split before reg-stack. */
2746 [(set_attr "type" "multi")
2747 (set_attr "unit" "i387,*")
2748 (set_attr "mode" "XF,SI")])
2750 ;; %%% Kill this when call knows how to work this out.
2752 [(set (match_operand:XF 0 "push_operand" "")
2753 (match_operand:XF 1 "fp_register_operand" ""))]
2755 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2756 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2757 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2759 (define_insn "*pushdf_rex64"
2760 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2761 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2764 /* This insn should be already split before reg-stack. */
2767 [(set_attr "type" "multi")
2768 (set_attr "unit" "i387,*,*")
2769 (set_attr "mode" "DF,DI,DF")])
2771 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2772 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2773 ;; On the average, pushdf using integers can be still shorter.
2775 (define_insn "*pushdf"
2776 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2777 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2780 /* This insn should be already split before reg-stack. */
2783 [(set_attr "isa" "*,*,sse2")
2784 (set_attr "type" "multi")
2785 (set_attr "unit" "i387,*,*")
2786 (set_attr "mode" "DF,DI,DF")])
2788 ;; %%% Kill this when call knows how to work this out.
2790 [(set (match_operand:DF 0 "push_operand" "")
2791 (match_operand:DF 1 "any_fp_register_operand" ""))]
2793 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2794 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2796 (define_insn "*pushsf_rex64"
2797 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2798 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2801 /* Anything else should be already split before reg-stack. */
2802 gcc_assert (which_alternative == 1);
2803 return "push{q}\t%q1";
2805 [(set_attr "type" "multi,push,multi")
2806 (set_attr "unit" "i387,*,*")
2807 (set_attr "mode" "SF,DI,SF")])
2809 (define_insn "*pushsf"
2810 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2811 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2814 /* Anything else should be already split before reg-stack. */
2815 gcc_assert (which_alternative == 1);
2816 return "push{l}\t%1";
2818 [(set_attr "type" "multi,push,multi")
2819 (set_attr "unit" "i387,*,*")
2820 (set_attr "mode" "SF,SI,SF")])
2822 ;; %%% Kill this when call knows how to work this out.
2824 [(set (match_operand:SF 0 "push_operand" "")
2825 (match_operand:SF 1 "any_fp_register_operand" ""))]
2827 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2828 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2829 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2832 [(set (match_operand:SF 0 "push_operand" "")
2833 (match_operand:SF 1 "memory_operand" ""))]
2835 && (operands[2] = find_constant_src (insn))"
2836 [(set (match_dup 0) (match_dup 2))])
2839 [(set (match_operand 0 "push_operand" "")
2840 (match_operand 1 "general_operand" ""))]
2842 && (GET_MODE (operands[0]) == TFmode
2843 || GET_MODE (operands[0]) == XFmode
2844 || GET_MODE (operands[0]) == DFmode)
2845 && !ANY_FP_REG_P (operands[1])"
2847 "ix86_split_long_move (operands); DONE;")
2849 ;; Floating point move instructions.
2851 (define_expand "movtf"
2852 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2853 (match_operand:TF 1 "nonimmediate_operand" ""))]
2856 ix86_expand_move (TFmode, operands);
2860 (define_expand "mov<mode>"
2861 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2862 (match_operand:X87MODEF 1 "general_operand" ""))]
2864 "ix86_expand_move (<MODE>mode, operands); DONE;")
2866 (define_insn "*movtf_internal"
2867 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2868 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && (!can_create_pseudo_p ()
2872 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2873 || GET_CODE (operands[1]) != CONST_DOUBLE
2874 || (optimize_function_for_size_p (cfun)
2875 && standard_sse_constant_p (operands[1])
2876 && !memory_operand (operands[0], TFmode))
2877 || (!TARGET_MEMORY_MISMATCH_STALL
2878 && memory_operand (operands[0], TFmode)))"
2880 switch (which_alternative)
2884 /* Handle misaligned load/store since we
2885 don't have movmisaligntf pattern. */
2886 if (misaligned_operand (operands[0], TFmode)
2887 || misaligned_operand (operands[1], TFmode))
2889 if (get_attr_mode (insn) == MODE_V4SF)
2890 return "%vmovups\t{%1, %0|%0, %1}";
2892 return "%vmovdqu\t{%1, %0|%0, %1}";
2896 if (get_attr_mode (insn) == MODE_V4SF)
2897 return "%vmovaps\t{%1, %0|%0, %1}";
2899 return "%vmovdqa\t{%1, %0|%0, %1}";
2903 return standard_sse_constant_opcode (insn, operands[1]);
2913 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2914 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2916 (cond [(eq_attr "alternative" "0,2")
2918 (match_test "optimize_function_for_size_p (cfun)")
2919 (const_string "V4SF")
2920 (const_string "TI"))
2921 (eq_attr "alternative" "1")
2923 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2924 (match_test "optimize_function_for_size_p (cfun)"))
2925 (const_string "V4SF")
2926 (const_string "TI"))]
2927 (const_string "DI")))])
2929 ;; Possible store forwarding (partial memory) stall in alternative 4.
2930 (define_insn "*movxf_internal"
2931 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2932 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2933 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2934 && (!can_create_pseudo_p ()
2935 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2936 || GET_CODE (operands[1]) != CONST_DOUBLE
2937 || (optimize_function_for_size_p (cfun)
2938 && standard_80387_constant_p (operands[1]) > 0
2939 && !memory_operand (operands[0], XFmode))
2940 || (!TARGET_MEMORY_MISMATCH_STALL
2941 && memory_operand (operands[0], XFmode)))"
2943 switch (which_alternative)
2947 return output_387_reg_move (insn, operands);
2950 return standard_80387_constant_opcode (operands[1]);
2960 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2961 (set_attr "mode" "XF,XF,XF,SI,SI")])
2963 (define_insn "*movdf_internal_rex64"
2964 [(set (match_operand:DF 0 "nonimmediate_operand"
2965 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2966 (match_operand:DF 1 "general_operand"
2967 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2969 && (!can_create_pseudo_p ()
2970 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2971 || GET_CODE (operands[1]) != CONST_DOUBLE
2972 || (optimize_function_for_size_p (cfun)
2973 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2974 && standard_80387_constant_p (operands[1]) > 0)
2975 || (TARGET_SSE2 && TARGET_SSE_MATH
2976 && standard_sse_constant_p (operands[1]))))
2977 || memory_operand (operands[0], DFmode))"
2979 switch (which_alternative)
2983 return output_387_reg_move (insn, operands);
2986 return standard_80387_constant_opcode (operands[1]);
2990 return "mov{q}\t{%1, %0|%0, %1}";
2993 return "movabs{q}\t{%1, %0|%0, %1}";
2999 return standard_sse_constant_opcode (insn, operands[1]);
3004 switch (get_attr_mode (insn))
3007 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3008 return "%vmovapd\t{%1, %0|%0, %1}";
3010 return "%vmovaps\t{%1, %0|%0, %1}";
3013 return "%vmovq\t{%1, %0|%0, %1}";
3015 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3016 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3017 return "%vmovsd\t{%1, %0|%0, %1}";
3019 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3021 return "%vmovlps\t{%1, %d0|%d0, %1}";
3028 /* Handle broken assemblers that require movd instead of movq. */
3029 return "%vmovd\t{%1, %0|%0, %1}";
3036 (cond [(eq_attr "alternative" "0,1,2")
3037 (const_string "fmov")
3038 (eq_attr "alternative" "3,4,5")
3039 (const_string "imov")
3040 (eq_attr "alternative" "6")
3041 (const_string "multi")
3042 (eq_attr "alternative" "7")
3043 (const_string "sselog1")
3045 (const_string "ssemov")))
3048 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3050 (const_string "*")))
3051 (set (attr "length_immediate")
3053 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3055 (const_string "*")))
3056 (set (attr "prefix")
3057 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3058 (const_string "orig")
3059 (const_string "maybe_vex")))
3060 (set (attr "prefix_data16")
3061 (if_then_else (eq_attr "mode" "V1DF")
3063 (const_string "*")))
3065 (cond [(eq_attr "alternative" "0,1,2")
3067 (eq_attr "alternative" "3,4,5,6,11,12")
3070 /* xorps is one byte shorter. */
3071 (eq_attr "alternative" "7")
3072 (cond [(match_test "optimize_function_for_size_p (cfun)")
3073 (const_string "V4SF")
3074 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3077 (const_string "V2DF"))
3079 /* For architectures resolving dependencies on
3080 whole SSE registers use APD move to break dependency
3081 chains, otherwise use short move to avoid extra work.
3083 movaps encodes one byte shorter. */
3084 (eq_attr "alternative" "8")
3086 [(match_test "optimize_function_for_size_p (cfun)")
3087 (const_string "V4SF")
3088 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3089 (const_string "V2DF")
3091 (const_string "DF"))
3092 /* For architectures resolving dependencies on register
3093 parts we may avoid extra work to zero out upper part
3095 (eq_attr "alternative" "9")
3097 (match_test "TARGET_SSE_SPLIT_REGS")
3098 (const_string "V1DF")
3099 (const_string "DF"))
3101 (const_string "DF")))])
3103 ;; Possible store forwarding (partial memory) stall in alternative 4.
3104 (define_insn "*movdf_internal"
3105 [(set (match_operand:DF 0 "nonimmediate_operand"
3106 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3107 (match_operand:DF 1 "general_operand"
3108 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3109 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3110 && (!can_create_pseudo_p ()
3111 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3112 || GET_CODE (operands[1]) != CONST_DOUBLE
3113 || (optimize_function_for_size_p (cfun)
3114 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3115 && standard_80387_constant_p (operands[1]) > 0)
3116 || (TARGET_SSE2 && TARGET_SSE_MATH
3117 && standard_sse_constant_p (operands[1])))
3118 && !memory_operand (operands[0], DFmode))
3119 || (!TARGET_MEMORY_MISMATCH_STALL
3120 && memory_operand (operands[0], DFmode)))"
3122 switch (which_alternative)
3126 return output_387_reg_move (insn, operands);
3129 return standard_80387_constant_opcode (operands[1]);
3137 return standard_sse_constant_opcode (insn, operands[1]);
3145 switch (get_attr_mode (insn))
3148 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3149 return "%vmovapd\t{%1, %0|%0, %1}";
3151 return "%vmovaps\t{%1, %0|%0, %1}";
3154 return "%vmovq\t{%1, %0|%0, %1}";
3156 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3157 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3158 return "%vmovsd\t{%1, %0|%0, %1}";
3160 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3162 return "%vmovlps\t{%1, %d0|%d0, %1}";
3172 (if_then_else (eq_attr "alternative" "5,6,7,8")
3173 (const_string "sse2")
3174 (const_string "*")))
3176 (cond [(eq_attr "alternative" "0,1,2")
3177 (const_string "fmov")
3178 (eq_attr "alternative" "3,4")
3179 (const_string "multi")
3180 (eq_attr "alternative" "5,9")
3181 (const_string "sselog1")
3183 (const_string "ssemov")))
3184 (set (attr "prefix")
3185 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3186 (const_string "orig")
3187 (const_string "maybe_vex")))
3188 (set (attr "prefix_data16")
3189 (if_then_else (eq_attr "mode" "V1DF")
3191 (const_string "*")))
3193 (cond [(eq_attr "alternative" "0,1,2")
3195 (eq_attr "alternative" "3,4")
3198 /* For SSE1, we have many fewer alternatives. */
3199 (not (match_test "TARGET_SSE2"))
3201 (eq_attr "alternative" "5,6,9,10")
3202 (const_string "V4SF")
3203 (const_string "V2SF"))
3205 /* xorps is one byte shorter. */
3206 (eq_attr "alternative" "5,9")
3207 (cond [(match_test "optimize_function_for_size_p (cfun)")
3208 (const_string "V4SF")
3209 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3212 (const_string "V2DF"))
3214 /* For architectures resolving dependencies on
3215 whole SSE registers use APD move to break dependency
3216 chains, otherwise use short move to avoid extra work.
3218 movaps encodes one byte shorter. */
3219 (eq_attr "alternative" "6,10")
3221 [(match_test "optimize_function_for_size_p (cfun)")
3222 (const_string "V4SF")
3223 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3224 (const_string "V2DF")
3226 (const_string "DF"))
3227 /* For architectures resolving dependencies on register
3228 parts we may avoid extra work to zero out upper part
3230 (eq_attr "alternative" "7,11")
3232 (match_test "TARGET_SSE_SPLIT_REGS")
3233 (const_string "V1DF")
3234 (const_string "DF"))
3236 (const_string "DF")))])
3238 (define_insn "*movsf_internal"
3239 [(set (match_operand:SF 0 "nonimmediate_operand"
3240 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3241 (match_operand:SF 1 "general_operand"
3242 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3243 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3244 && (!can_create_pseudo_p ()
3245 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3246 || GET_CODE (operands[1]) != CONST_DOUBLE
3247 || (optimize_function_for_size_p (cfun)
3248 && ((!TARGET_SSE_MATH
3249 && standard_80387_constant_p (operands[1]) > 0)
3251 && standard_sse_constant_p (operands[1]))))
3252 || memory_operand (operands[0], SFmode))"
3254 switch (which_alternative)
3258 return output_387_reg_move (insn, operands);
3261 return standard_80387_constant_opcode (operands[1]);
3265 return "mov{l}\t{%1, %0|%0, %1}";
3268 return standard_sse_constant_opcode (insn, operands[1]);
3271 if (get_attr_mode (insn) == MODE_V4SF)
3272 return "%vmovaps\t{%1, %0|%0, %1}";
3274 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3278 return "%vmovss\t{%1, %0|%0, %1}";
3284 return "movd\t{%1, %0|%0, %1}";
3287 return "movq\t{%1, %0|%0, %1}";
3291 return "%vmovd\t{%1, %0|%0, %1}";
3298 (cond [(eq_attr "alternative" "0,1,2")
3299 (const_string "fmov")
3300 (eq_attr "alternative" "3,4")
3301 (const_string "multi")
3302 (eq_attr "alternative" "5")
3303 (const_string "sselog1")
3304 (eq_attr "alternative" "9,10,11,14,15")
3305 (const_string "mmxmov")
3307 (const_string "ssemov")))
3308 (set (attr "prefix")
3309 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3310 (const_string "maybe_vex")
3311 (const_string "orig")))
3313 (cond [(eq_attr "alternative" "3,4,9,10")
3315 (eq_attr "alternative" "5")
3317 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3318 (match_test "TARGET_SSE2"))
3319 (not (match_test "optimize_function_for_size_p (cfun)")))
3321 (const_string "V4SF"))
3322 /* For architectures resolving dependencies on
3323 whole SSE registers use APS move to break dependency
3324 chains, otherwise use short move to avoid extra work.
3326 Do the same for architectures resolving dependencies on
3327 the parts. While in DF mode it is better to always handle
3328 just register parts, the SF mode is different due to lack
3329 of instructions to load just part of the register. It is
3330 better to maintain the whole registers in single format
3331 to avoid problems on using packed logical operations. */
3332 (eq_attr "alternative" "6")
3334 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3335 (match_test "TARGET_SSE_SPLIT_REGS"))
3336 (const_string "V4SF")
3337 (const_string "SF"))
3338 (eq_attr "alternative" "11")
3339 (const_string "DI")]
3340 (const_string "SF")))])
3343 [(set (match_operand 0 "any_fp_register_operand" "")
3344 (match_operand 1 "memory_operand" ""))]
3346 && (GET_MODE (operands[0]) == TFmode
3347 || GET_MODE (operands[0]) == XFmode
3348 || GET_MODE (operands[0]) == DFmode
3349 || GET_MODE (operands[0]) == SFmode)
3350 && (operands[2] = find_constant_src (insn))"
3351 [(set (match_dup 0) (match_dup 2))]
3353 rtx c = operands[2];
3354 int r = REGNO (operands[0]);
3356 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3357 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3362 [(set (match_operand 0 "any_fp_register_operand" "")
3363 (float_extend (match_operand 1 "memory_operand" "")))]
3365 && (GET_MODE (operands[0]) == TFmode
3366 || GET_MODE (operands[0]) == XFmode
3367 || GET_MODE (operands[0]) == DFmode)
3368 && (operands[2] = find_constant_src (insn))"
3369 [(set (match_dup 0) (match_dup 2))]
3371 rtx c = operands[2];
3372 int r = REGNO (operands[0]);
3374 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3375 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3379 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3381 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3382 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3384 && (standard_80387_constant_p (operands[1]) == 8
3385 || standard_80387_constant_p (operands[1]) == 9)"
3386 [(set (match_dup 0)(match_dup 1))
3388 (neg:X87MODEF (match_dup 0)))]
3392 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3393 if (real_isnegzero (&r))
3394 operands[1] = CONST0_RTX (<MODE>mode);
3396 operands[1] = CONST1_RTX (<MODE>mode);
3400 [(set (match_operand 0 "nonimmediate_operand" "")
3401 (match_operand 1 "general_operand" ""))]
3403 && (GET_MODE (operands[0]) == TFmode
3404 || GET_MODE (operands[0]) == XFmode
3405 || GET_MODE (operands[0]) == DFmode)
3406 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3408 "ix86_split_long_move (operands); DONE;")
3410 (define_insn "swapxf"
3411 [(set (match_operand:XF 0 "register_operand" "+f")
3412 (match_operand:XF 1 "register_operand" "+f"))
3417 if (STACK_TOP_P (operands[0]))
3422 [(set_attr "type" "fxch")
3423 (set_attr "mode" "XF")])
3425 (define_insn "*swap<mode>"
3426 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3427 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3430 "TARGET_80387 || reload_completed"
3432 if (STACK_TOP_P (operands[0]))
3437 [(set_attr "type" "fxch")
3438 (set_attr "mode" "<MODE>")])
3440 ;; Zero extension instructions
3442 (define_expand "zero_extendsidi2"
3443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3449 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3454 (define_insn "*zero_extendsidi2_rex64"
3455 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3457 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3460 mov\t{%k1, %k0|%k0, %k1}
3462 movd\t{%1, %0|%0, %1}
3463 movd\t{%1, %0|%0, %1}
3464 %vmovd\t{%1, %0|%0, %1}
3465 %vmovd\t{%1, %0|%0, %1}"
3466 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3467 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3468 (set_attr "prefix_0f" "0,*,*,*,*,*")
3469 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3472 [(set (match_operand:DI 0 "memory_operand" "")
3473 (zero_extend:DI (match_dup 0)))]
3475 [(set (match_dup 4) (const_int 0))]
3476 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3478 ;; %%% Kill me once multi-word ops are sane.
3479 (define_insn "zero_extendsidi2_1"
3480 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3482 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3483 (clobber (reg:CC FLAGS_REG))]
3489 movd\t{%1, %0|%0, %1}
3490 movd\t{%1, %0|%0, %1}
3491 %vmovd\t{%1, %0|%0, %1}
3492 %vmovd\t{%1, %0|%0, %1}"
3493 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3494 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3495 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3496 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3499 [(set (match_operand:DI 0 "register_operand" "")
3500 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "!TARGET_64BIT && reload_completed
3503 && true_regnum (operands[0]) == true_regnum (operands[1])"
3504 [(set (match_dup 4) (const_int 0))]
3505 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3509 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3510 (clobber (reg:CC FLAGS_REG))]
3511 "!TARGET_64BIT && reload_completed
3512 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3513 [(set (match_dup 3) (match_dup 1))
3514 (set (match_dup 4) (const_int 0))]
3515 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3517 (define_insn "zero_extend<mode>di2"
3518 [(set (match_operand:DI 0 "register_operand" "=r")
3520 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3522 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3523 [(set_attr "type" "imovx")
3524 (set_attr "mode" "SI")])
3526 (define_expand "zero_extendhisi2"
3527 [(set (match_operand:SI 0 "register_operand" "")
3528 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3531 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3533 operands[1] = force_reg (HImode, operands[1]);
3534 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3539 (define_insn_and_split "zero_extendhisi2_and"
3540 [(set (match_operand:SI 0 "register_operand" "=r")
3541 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3542 (clobber (reg:CC FLAGS_REG))]
3543 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3545 "&& reload_completed"
3546 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3547 (clobber (reg:CC FLAGS_REG))])]
3549 [(set_attr "type" "alu1")
3550 (set_attr "mode" "SI")])
3552 (define_insn "*zero_extendhisi2_movzwl"
3553 [(set (match_operand:SI 0 "register_operand" "=r")
3554 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3555 "!TARGET_ZERO_EXTEND_WITH_AND
3556 || optimize_function_for_size_p (cfun)"
3557 "movz{wl|x}\t{%1, %0|%0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3561 (define_expand "zero_extendqi<mode>2"
3563 [(set (match_operand:SWI24 0 "register_operand" "")
3564 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3565 (clobber (reg:CC FLAGS_REG))])])
3567 (define_insn "*zero_extendqi<mode>2_and"
3568 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3569 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3570 (clobber (reg:CC FLAGS_REG))]
3571 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3573 [(set_attr "type" "alu1")
3574 (set_attr "mode" "<MODE>")])
3576 ;; When source and destination does not overlap, clear destination
3577 ;; first and then do the movb
3579 [(set (match_operand:SWI24 0 "register_operand" "")
3580 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3581 (clobber (reg:CC FLAGS_REG))]
3583 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3584 && ANY_QI_REG_P (operands[0])
3585 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3586 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3587 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3589 operands[2] = gen_lowpart (QImode, operands[0]);
3590 ix86_expand_clear (operands[0]);
3593 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3594 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3595 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3596 (clobber (reg:CC FLAGS_REG))]
3597 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3599 [(set_attr "type" "imovx,alu1")
3600 (set_attr "mode" "<MODE>")])
3602 ;; For the movzbl case strip only the clobber
3604 [(set (match_operand:SWI24 0 "register_operand" "")
3605 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3606 (clobber (reg:CC FLAGS_REG))]
3608 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3609 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3611 (zero_extend:SWI24 (match_dup 1)))])
3613 ; zero extend to SImode to avoid partial register stalls
3614 (define_insn "*zero_extendqi<mode>2_movzbl"
3615 [(set (match_operand:SWI24 0 "register_operand" "=r")
3616 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3618 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3619 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3620 [(set_attr "type" "imovx")
3621 (set_attr "mode" "SI")])
3623 ;; Rest is handled by single and.
3625 [(set (match_operand:SWI24 0 "register_operand" "")
3626 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3627 (clobber (reg:CC FLAGS_REG))]
3629 && true_regnum (operands[0]) == true_regnum (operands[1])"
3630 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3631 (clobber (reg:CC FLAGS_REG))])])
3633 ;; Sign extension instructions
3635 (define_expand "extendsidi2"
3636 [(set (match_operand:DI 0 "register_operand" "")
3637 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3642 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3647 (define_insn "*extendsidi2_rex64"
3648 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3649 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3653 movs{lq|x}\t{%1, %0|%0, %1}"
3654 [(set_attr "type" "imovx")
3655 (set_attr "mode" "DI")
3656 (set_attr "prefix_0f" "0")
3657 (set_attr "modrm" "0,1")])
3659 (define_insn "extendsidi2_1"
3660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3661 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3662 (clobber (reg:CC FLAGS_REG))
3663 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3667 ;; Extend to memory case when source register does die.
3669 [(set (match_operand:DI 0 "memory_operand" "")
3670 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3671 (clobber (reg:CC FLAGS_REG))
3672 (clobber (match_operand:SI 2 "register_operand" ""))]
3674 && dead_or_set_p (insn, operands[1])
3675 && !reg_mentioned_p (operands[1], operands[0]))"
3676 [(set (match_dup 3) (match_dup 1))
3677 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3678 (clobber (reg:CC FLAGS_REG))])
3679 (set (match_dup 4) (match_dup 1))]
3680 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3682 ;; Extend to memory case when source register does not die.
3684 [(set (match_operand:DI 0 "memory_operand" "")
3685 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))
3687 (clobber (match_operand:SI 2 "register_operand" ""))]
3691 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3693 emit_move_insn (operands[3], operands[1]);
3695 /* Generate a cltd if possible and doing so it profitable. */
3696 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3697 && true_regnum (operands[1]) == AX_REG
3698 && true_regnum (operands[2]) == DX_REG)
3700 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3704 emit_move_insn (operands[2], operands[1]);
3705 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3707 emit_move_insn (operands[4], operands[2]);
3711 ;; Extend to register case. Optimize case where source and destination
3712 ;; registers match and cases where we can use cltd.
3714 [(set (match_operand:DI 0 "register_operand" "")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))
3717 (clobber (match_scratch:SI 2 ""))]
3721 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3723 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3724 emit_move_insn (operands[3], operands[1]);
3726 /* Generate a cltd if possible and doing so it profitable. */
3727 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3728 && true_regnum (operands[3]) == AX_REG
3729 && true_regnum (operands[4]) == DX_REG)
3731 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3735 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3736 emit_move_insn (operands[4], operands[1]);
3738 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3742 (define_insn "extend<mode>di2"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3745 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3747 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "DI")])
3751 (define_insn "extendhisi2"
3752 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3753 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3756 switch (get_attr_prefix_0f (insn))
3759 return "{cwtl|cwde}";
3761 return "movs{wl|x}\t{%1, %0|%0, %1}";
3764 [(set_attr "type" "imovx")
3765 (set_attr "mode" "SI")
3766 (set (attr "prefix_0f")
3767 ;; movsx is short decodable while cwtl is vector decoded.
3768 (if_then_else (and (eq_attr "cpu" "!k6")
3769 (eq_attr "alternative" "0"))
3771 (const_string "1")))
3773 (if_then_else (eq_attr "prefix_0f" "0")
3775 (const_string "1")))])
3777 (define_insn "*extendhisi2_zext"
3778 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3781 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3784 switch (get_attr_prefix_0f (insn))
3787 return "{cwtl|cwde}";
3789 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "SI")
3794 (set (attr "prefix_0f")
3795 ;; movsx is short decodable while cwtl is vector decoded.
3796 (if_then_else (and (eq_attr "cpu" "!k6")
3797 (eq_attr "alternative" "0"))
3799 (const_string "1")))
3801 (if_then_else (eq_attr "prefix_0f" "0")
3803 (const_string "1")))])
3805 (define_insn "extendqisi2"
3806 [(set (match_operand:SI 0 "register_operand" "=r")
3807 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3809 "movs{bl|x}\t{%1, %0|%0, %1}"
3810 [(set_attr "type" "imovx")
3811 (set_attr "mode" "SI")])
3813 (define_insn "*extendqisi2_zext"
3814 [(set (match_operand:DI 0 "register_operand" "=r")
3816 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3818 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3819 [(set_attr "type" "imovx")
3820 (set_attr "mode" "SI")])
3822 (define_insn "extendqihi2"
3823 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3824 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3827 switch (get_attr_prefix_0f (insn))
3830 return "{cbtw|cbw}";
3832 return "movs{bw|x}\t{%1, %0|%0, %1}";
3835 [(set_attr "type" "imovx")
3836 (set_attr "mode" "HI")
3837 (set (attr "prefix_0f")
3838 ;; movsx is short decodable while cwtl is vector decoded.
3839 (if_then_else (and (eq_attr "cpu" "!k6")
3840 (eq_attr "alternative" "0"))
3842 (const_string "1")))
3844 (if_then_else (eq_attr "prefix_0f" "0")
3846 (const_string "1")))])
3848 ;; Conversions between float and double.
3850 ;; These are all no-ops in the model used for the 80387.
3851 ;; So just emit moves.
3853 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3855 [(set (match_operand:DF 0 "push_operand" "")
3856 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3858 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3859 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3862 [(set (match_operand:XF 0 "push_operand" "")
3863 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3865 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3866 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3867 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3869 (define_expand "extendsfdf2"
3870 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3871 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3872 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3874 /* ??? Needed for compress_float_constant since all fp constants
3875 are TARGET_LEGITIMATE_CONSTANT_P. */
3876 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3878 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3879 && standard_80387_constant_p (operands[1]) > 0)
3881 operands[1] = simplify_const_unary_operation
3882 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3883 emit_move_insn_1 (operands[0], operands[1]);
3886 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3890 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3892 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3894 We do the conversion post reload to avoid producing of 128bit spills
3895 that might lead to ICE on 32bit target. The sequence unlikely combine
3898 [(set (match_operand:DF 0 "register_operand" "")
3900 (match_operand:SF 1 "nonimmediate_operand" "")))]
3901 "TARGET_USE_VECTOR_FP_CONVERTS
3902 && optimize_insn_for_speed_p ()
3903 && reload_completed && SSE_REG_P (operands[0])"
3908 (parallel [(const_int 0) (const_int 1)]))))]
3910 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3911 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3912 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3913 Try to avoid move when unpacking can be done in source. */
3914 if (REG_P (operands[1]))
3916 /* If it is unsafe to overwrite upper half of source, we need
3917 to move to destination and unpack there. */
3918 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3919 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3920 && true_regnum (operands[0]) != true_regnum (operands[1]))
3922 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3923 emit_move_insn (tmp, operands[1]);
3926 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3927 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3931 emit_insn (gen_vec_setv4sf_0 (operands[3],
3932 CONST0_RTX (V4SFmode), operands[1]));
3935 (define_insn "*extendsfdf2_mixed"
3936 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3938 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3939 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3941 switch (which_alternative)
3945 return output_387_reg_move (insn, operands);
3948 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3954 [(set_attr "type" "fmov,fmov,ssecvt")
3955 (set_attr "prefix" "orig,orig,maybe_vex")
3956 (set_attr "mode" "SF,XF,DF")])
3958 (define_insn "*extendsfdf2_sse"
3959 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3960 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3961 "TARGET_SSE2 && TARGET_SSE_MATH"
3962 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3963 [(set_attr "type" "ssecvt")
3964 (set_attr "prefix" "maybe_vex")
3965 (set_attr "mode" "DF")])
3967 (define_insn "*extendsfdf2_i387"
3968 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3969 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3971 "* return output_387_reg_move (insn, operands);"
3972 [(set_attr "type" "fmov")
3973 (set_attr "mode" "SF,XF")])
3975 (define_expand "extend<mode>xf2"
3976 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3977 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3980 /* ??? Needed for compress_float_constant since all fp constants
3981 are TARGET_LEGITIMATE_CONSTANT_P. */
3982 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3984 if (standard_80387_constant_p (operands[1]) > 0)
3986 operands[1] = simplify_const_unary_operation
3987 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3988 emit_move_insn_1 (operands[0], operands[1]);
3991 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3995 (define_insn "*extend<mode>xf2_i387"
3996 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3998 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4000 "* return output_387_reg_move (insn, operands);"
4001 [(set_attr "type" "fmov")
4002 (set_attr "mode" "<MODE>,XF")])
4004 ;; %%% This seems bad bad news.
4005 ;; This cannot output into an f-reg because there is no way to be sure
4006 ;; of truncating in that case. Otherwise this is just like a simple move
4007 ;; insn. So we pretend we can output to a reg in order to get better
4008 ;; register preferencing, but we really use a stack slot.
4010 ;; Conversion from DFmode to SFmode.
4012 (define_expand "truncdfsf2"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4015 (match_operand:DF 1 "nonimmediate_operand" "")))]
4016 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4018 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4020 else if (flag_unsafe_math_optimizations)
4024 enum ix86_stack_slot slot = (virtuals_instantiated
4027 rtx temp = assign_386_stack_local (SFmode, slot);
4028 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4033 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4035 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4037 We do the conversion post reload to avoid producing of 128bit spills
4038 that might lead to ICE on 32bit target. The sequence unlikely combine
4041 [(set (match_operand:SF 0 "register_operand" "")
4043 (match_operand:DF 1 "nonimmediate_operand" "")))]
4044 "TARGET_USE_VECTOR_FP_CONVERTS
4045 && optimize_insn_for_speed_p ()
4046 && reload_completed && SSE_REG_P (operands[0])"
4049 (float_truncate:V2SF
4053 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4054 operands[3] = CONST0_RTX (V2SFmode);
4055 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4056 /* Use movsd for loading from memory, unpcklpd for registers.
4057 Try to avoid move when unpacking can be done in source, or SSE3
4058 movddup is available. */
4059 if (REG_P (operands[1]))
4062 && true_regnum (operands[0]) != true_regnum (operands[1])
4063 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4064 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4066 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4067 emit_move_insn (tmp, operands[1]);
4070 else if (!TARGET_SSE3)
4071 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4072 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4075 emit_insn (gen_sse2_loadlpd (operands[4],
4076 CONST0_RTX (V2DFmode), operands[1]));
4079 (define_expand "truncdfsf2_with_temp"
4080 [(parallel [(set (match_operand:SF 0 "" "")
4081 (float_truncate:SF (match_operand:DF 1 "" "")))
4082 (clobber (match_operand:SF 2 "" ""))])])
4084 (define_insn "*truncdfsf_fast_mixed"
4085 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4087 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4088 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4090 switch (which_alternative)
4093 return output_387_reg_move (insn, operands);
4095 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4100 [(set_attr "type" "fmov,ssecvt")
4101 (set_attr "prefix" "orig,maybe_vex")
4102 (set_attr "mode" "SF")])
4104 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4105 ;; because nothing we do here is unsafe.
4106 (define_insn "*truncdfsf_fast_sse"
4107 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4109 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4110 "TARGET_SSE2 && TARGET_SSE_MATH"
4111 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4112 [(set_attr "type" "ssecvt")
4113 (set_attr "prefix" "maybe_vex")
4114 (set_attr "mode" "SF")])
4116 (define_insn "*truncdfsf_fast_i387"
4117 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4119 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4120 "TARGET_80387 && flag_unsafe_math_optimizations"
4121 "* return output_387_reg_move (insn, operands);"
4122 [(set_attr "type" "fmov")
4123 (set_attr "mode" "SF")])
4125 (define_insn "*truncdfsf_mixed"
4126 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4128 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4129 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4130 "TARGET_MIX_SSE_I387"
4132 switch (which_alternative)
4135 return output_387_reg_move (insn, operands);
4137 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4143 [(set_attr "isa" "*,sse2,*,*,*")
4144 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4145 (set_attr "unit" "*,*,i387,i387,i387")
4146 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4147 (set_attr "mode" "SF")])
4149 (define_insn "*truncdfsf_i387"
4150 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4152 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4153 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4156 switch (which_alternative)
4159 return output_387_reg_move (insn, operands);
4165 [(set_attr "type" "fmov,multi,multi,multi")
4166 (set_attr "unit" "*,i387,i387,i387")
4167 (set_attr "mode" "SF")])
4169 (define_insn "*truncdfsf2_i387_1"
4170 [(set (match_operand:SF 0 "memory_operand" "=m")
4172 (match_operand:DF 1 "register_operand" "f")))]
4174 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4175 && !TARGET_MIX_SSE_I387"
4176 "* return output_387_reg_move (insn, operands);"
4177 [(set_attr "type" "fmov")
4178 (set_attr "mode" "SF")])
4181 [(set (match_operand:SF 0 "register_operand" "")
4183 (match_operand:DF 1 "fp_register_operand" "")))
4184 (clobber (match_operand 2 "" ""))]
4186 [(set (match_dup 2) (match_dup 1))
4187 (set (match_dup 0) (match_dup 2))]
4188 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4190 ;; Conversion from XFmode to {SF,DF}mode
4192 (define_expand "truncxf<mode>2"
4193 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_dup 2))])]
4199 if (flag_unsafe_math_optimizations)
4201 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4202 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4203 if (reg != operands[0])
4204 emit_move_insn (operands[0], reg);
4209 enum ix86_stack_slot slot = (virtuals_instantiated
4212 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4216 (define_insn "*truncxfsf2_mixed"
4217 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4219 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4220 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4223 gcc_assert (!which_alternative);
4224 return output_387_reg_move (insn, operands);
4226 [(set_attr "type" "fmov,multi,multi,multi")
4227 (set_attr "unit" "*,i387,i387,i387")
4228 (set_attr "mode" "SF")])
4230 (define_insn "*truncxfdf2_mixed"
4231 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4233 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4234 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4237 gcc_assert (!which_alternative);
4238 return output_387_reg_move (insn, operands);
4240 [(set_attr "isa" "*,*,sse2,*")
4241 (set_attr "type" "fmov,multi,multi,multi")
4242 (set_attr "unit" "*,i387,i387,i387")
4243 (set_attr "mode" "DF")])
4245 (define_insn "truncxf<mode>2_i387_noop"
4246 [(set (match_operand:MODEF 0 "register_operand" "=f")
4247 (float_truncate:MODEF
4248 (match_operand:XF 1 "register_operand" "f")))]
4249 "TARGET_80387 && flag_unsafe_math_optimizations"
4250 "* return output_387_reg_move (insn, operands);"
4251 [(set_attr "type" "fmov")
4252 (set_attr "mode" "<MODE>")])
4254 (define_insn "*truncxf<mode>2_i387"
4255 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4256 (float_truncate:MODEF
4257 (match_operand:XF 1 "register_operand" "f")))]
4259 "* return output_387_reg_move (insn, operands);"
4260 [(set_attr "type" "fmov")
4261 (set_attr "mode" "<MODE>")])
4264 [(set (match_operand:MODEF 0 "register_operand" "")
4265 (float_truncate:MODEF
4266 (match_operand:XF 1 "register_operand" "")))
4267 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4268 "TARGET_80387 && reload_completed"
4269 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4270 (set (match_dup 0) (match_dup 2))])
4273 [(set (match_operand:MODEF 0 "memory_operand" "")
4274 (float_truncate:MODEF
4275 (match_operand:XF 1 "register_operand" "")))
4276 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4278 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4280 ;; Signed conversion to DImode.
4282 (define_expand "fix_truncxfdi2"
4283 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4284 (fix:DI (match_operand:XF 1 "register_operand" "")))
4285 (clobber (reg:CC FLAGS_REG))])]
4290 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4295 (define_expand "fix_trunc<mode>di2"
4296 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4297 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4298 (clobber (reg:CC FLAGS_REG))])]
4299 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4307 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4309 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4310 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4311 if (out != operands[0])
4312 emit_move_insn (operands[0], out);
4317 ;; Signed conversion to SImode.
4319 (define_expand "fix_truncxfsi2"
4320 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4321 (fix:SI (match_operand:XF 1 "register_operand" "")))
4322 (clobber (reg:CC FLAGS_REG))])]
4327 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4332 (define_expand "fix_trunc<mode>si2"
4333 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4334 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4335 (clobber (reg:CC FLAGS_REG))])]
4336 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4339 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4341 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4344 if (SSE_FLOAT_MODE_P (<MODE>mode))
4346 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4347 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4348 if (out != operands[0])
4349 emit_move_insn (operands[0], out);
4354 ;; Signed conversion to HImode.
4356 (define_expand "fix_trunc<mode>hi2"
4357 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4358 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4359 (clobber (reg:CC FLAGS_REG))])]
4361 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4365 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4370 ;; Unsigned conversion to SImode.
4372 (define_expand "fixuns_trunc<mode>si2"
4374 [(set (match_operand:SI 0 "register_operand" "")
4376 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4378 (clobber (match_scratch:<ssevecmode> 3 ""))
4379 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4380 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4382 enum machine_mode mode = <MODE>mode;
4383 enum machine_mode vecmode = <ssevecmode>mode;
4384 REAL_VALUE_TYPE TWO31r;
4387 if (optimize_insn_for_size_p ())
4390 real_ldexp (&TWO31r, &dconst1, 31);
4391 two31 = const_double_from_real_value (TWO31r, mode);
4392 two31 = ix86_build_const_vector (vecmode, true, two31);
4393 operands[2] = force_reg (vecmode, two31);
4396 (define_insn_and_split "*fixuns_trunc<mode>_1"
4397 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4399 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4400 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4401 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4402 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4403 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4404 && optimize_function_for_speed_p (cfun)"
4406 "&& reload_completed"
4409 ix86_split_convert_uns_si_sse (operands);
4413 ;; Unsigned conversion to HImode.
4414 ;; Without these patterns, we'll try the unsigned SI conversion which
4415 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4417 (define_expand "fixuns_trunc<mode>hi2"
4419 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4420 (set (match_operand:HI 0 "nonimmediate_operand" "")
4421 (subreg:HI (match_dup 2) 0))]
4422 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4423 "operands[2] = gen_reg_rtx (SImode);")
4425 ;; When SSE is available, it is always faster to use it!
4426 (define_insn "fix_trunc<mode>di_sse"
4427 [(set (match_operand:DI 0 "register_operand" "=r,r")
4428 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4429 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4430 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4432 [(set_attr "type" "sseicvt")
4433 (set_attr "prefix" "maybe_vex")
4434 (set_attr "prefix_rex" "1")
4435 (set_attr "mode" "<MODE>")
4436 (set_attr "athlon_decode" "double,vector")
4437 (set_attr "amdfam10_decode" "double,double")
4438 (set_attr "bdver1_decode" "double,double")])
4440 (define_insn "fix_trunc<mode>si_sse"
4441 [(set (match_operand:SI 0 "register_operand" "=r,r")
4442 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4443 "SSE_FLOAT_MODE_P (<MODE>mode)
4444 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4445 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4446 [(set_attr "type" "sseicvt")
4447 (set_attr "prefix" "maybe_vex")
4448 (set_attr "mode" "<MODE>")
4449 (set_attr "athlon_decode" "double,vector")
4450 (set_attr "amdfam10_decode" "double,double")
4451 (set_attr "bdver1_decode" "double,double")])
4453 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4455 [(set (match_operand:MODEF 0 "register_operand" "")
4456 (match_operand:MODEF 1 "memory_operand" ""))
4457 (set (match_operand:SWI48x 2 "register_operand" "")
4458 (fix:SWI48x (match_dup 0)))]
4459 "TARGET_SHORTEN_X87_SSE
4460 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4461 && peep2_reg_dead_p (2, operands[0])"
4462 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4464 ;; Avoid vector decoded forms of the instruction.
4466 [(match_scratch:DF 2 "x")
4467 (set (match_operand:SWI48x 0 "register_operand" "")
4468 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4469 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4470 [(set (match_dup 2) (match_dup 1))
4471 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4474 [(match_scratch:SF 2 "x")
4475 (set (match_operand:SWI48x 0 "register_operand" "")
4476 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4477 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4478 [(set (match_dup 2) (match_dup 1))
4479 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4481 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4482 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4483 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4484 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4486 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && (TARGET_64BIT || <MODE>mode != DImode))
4489 && can_create_pseudo_p ()"
4494 if (memory_operand (operands[0], VOIDmode))
4495 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4498 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4499 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4505 [(set_attr "type" "fisttp")
4506 (set_attr "mode" "<MODE>")])
4508 (define_insn "fix_trunc<mode>_i387_fisttp"
4509 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4510 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4511 (clobber (match_scratch:XF 2 "=&1f"))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && (TARGET_64BIT || <MODE>mode != DImode))
4516 && TARGET_SSE_MATH)"
4517 "* return output_fix_trunc (insn, operands, true);"
4518 [(set_attr "type" "fisttp")
4519 (set_attr "mode" "<MODE>")])
4521 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4522 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4523 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4524 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4525 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4526 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && (TARGET_64BIT || <MODE>mode != DImode))
4530 && TARGET_SSE_MATH)"
4532 [(set_attr "type" "fisttp")
4533 (set_attr "mode" "<MODE>")])
4536 [(set (match_operand:SWI248x 0 "register_operand" "")
4537 (fix:SWI248x (match_operand 1 "register_operand" "")))
4538 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4539 (clobber (match_scratch 3 ""))]
4541 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4542 (clobber (match_dup 3))])
4543 (set (match_dup 0) (match_dup 2))])
4546 [(set (match_operand:SWI248x 0 "memory_operand" "")
4547 (fix:SWI248x (match_operand 1 "register_operand" "")))
4548 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4549 (clobber (match_scratch 3 ""))]
4551 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4552 (clobber (match_dup 3))])])
4554 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4555 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4556 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4557 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4558 ;; function in i386.c.
4559 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4560 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4561 (fix:SWI248x (match_operand 1 "register_operand" "")))
4562 (clobber (reg:CC FLAGS_REG))]
4563 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && (TARGET_64BIT || <MODE>mode != DImode))
4567 && can_create_pseudo_p ()"
4572 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4574 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4575 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4576 if (memory_operand (operands[0], VOIDmode))
4577 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4578 operands[2], operands[3]));
4581 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4582 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4583 operands[2], operands[3],
4588 [(set_attr "type" "fistp")
4589 (set_attr "i387_cw" "trunc")
4590 (set_attr "mode" "<MODE>")])
4592 (define_insn "fix_truncdi_i387"
4593 [(set (match_operand:DI 0 "memory_operand" "=m")
4594 (fix:DI (match_operand 1 "register_operand" "f")))
4595 (use (match_operand:HI 2 "memory_operand" "m"))
4596 (use (match_operand:HI 3 "memory_operand" "m"))
4597 (clobber (match_scratch:XF 4 "=&1f"))]
4598 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4601 "* return output_fix_trunc (insn, operands, false);"
4602 [(set_attr "type" "fistp")
4603 (set_attr "i387_cw" "trunc")
4604 (set_attr "mode" "DI")])
4606 (define_insn "fix_truncdi_i387_with_temp"
4607 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4608 (fix:DI (match_operand 1 "register_operand" "f,f")))
4609 (use (match_operand:HI 2 "memory_operand" "m,m"))
4610 (use (match_operand:HI 3 "memory_operand" "m,m"))
4611 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4612 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4613 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617 [(set_attr "type" "fistp")
4618 (set_attr "i387_cw" "trunc")
4619 (set_attr "mode" "DI")])
4622 [(set (match_operand:DI 0 "register_operand" "")
4623 (fix:DI (match_operand 1 "register_operand" "")))
4624 (use (match_operand:HI 2 "memory_operand" ""))
4625 (use (match_operand:HI 3 "memory_operand" ""))
4626 (clobber (match_operand:DI 4 "memory_operand" ""))
4627 (clobber (match_scratch 5 ""))]
4629 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4632 (clobber (match_dup 5))])
4633 (set (match_dup 0) (match_dup 4))])
4636 [(set (match_operand:DI 0 "memory_operand" "")
4637 (fix:DI (match_operand 1 "register_operand" "")))
4638 (use (match_operand:HI 2 "memory_operand" ""))
4639 (use (match_operand:HI 3 "memory_operand" ""))
4640 (clobber (match_operand:DI 4 "memory_operand" ""))
4641 (clobber (match_scratch 5 ""))]
4643 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4646 (clobber (match_dup 5))])])
4648 (define_insn "fix_trunc<mode>_i387"
4649 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4650 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4651 (use (match_operand:HI 2 "memory_operand" "m"))
4652 (use (match_operand:HI 3 "memory_operand" "m"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656 "* return output_fix_trunc (insn, operands, false);"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "<MODE>")])
4661 (define_insn "fix_trunc<mode>_i387_with_temp"
4662 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4663 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4664 (use (match_operand:HI 2 "memory_operand" "m,m"))
4665 (use (match_operand:HI 3 "memory_operand" "m,m"))
4666 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4667 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4671 [(set_attr "type" "fistp")
4672 (set_attr "i387_cw" "trunc")
4673 (set_attr "mode" "<MODE>")])
4676 [(set (match_operand:SWI24 0 "register_operand" "")
4677 (fix:SWI24 (match_operand 1 "register_operand" "")))
4678 (use (match_operand:HI 2 "memory_operand" ""))
4679 (use (match_operand:HI 3 "memory_operand" ""))
4680 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4682 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4684 (use (match_dup 3))])
4685 (set (match_dup 0) (match_dup 4))])
4688 [(set (match_operand:SWI24 0 "memory_operand" "")
4689 (fix:SWI24 (match_operand 1 "register_operand" "")))
4690 (use (match_operand:HI 2 "memory_operand" ""))
4691 (use (match_operand:HI 3 "memory_operand" ""))
4692 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4694 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4696 (use (match_dup 3))])])
4698 (define_insn "x86_fnstcw_1"
4699 [(set (match_operand:HI 0 "memory_operand" "=m")
4700 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4703 [(set (attr "length")
4704 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4705 (set_attr "mode" "HI")
4706 (set_attr "unit" "i387")
4707 (set_attr "bdver1_decode" "vector")])
4709 (define_insn "x86_fldcw_1"
4710 [(set (reg:HI FPCR_REG)
4711 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4714 [(set (attr "length")
4715 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4716 (set_attr "mode" "HI")
4717 (set_attr "unit" "i387")
4718 (set_attr "athlon_decode" "vector")
4719 (set_attr "amdfam10_decode" "vector")
4720 (set_attr "bdver1_decode" "vector")])
4722 ;; Conversion between fixed point and floating point.
4724 ;; Even though we only accept memory inputs, the backend _really_
4725 ;; wants to be able to do this between registers.
4727 (define_expand "floathi<mode>2"
4728 [(set (match_operand:X87MODEF 0 "register_operand" "")
4729 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4732 || TARGET_MIX_SSE_I387)")
4734 ;; Pre-reload splitter to add memory clobber to the pattern.
4735 (define_insn_and_split "*floathi<mode>2_1"
4736 [(set (match_operand:X87MODEF 0 "register_operand" "")
4737 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4740 || TARGET_MIX_SSE_I387)
4741 && can_create_pseudo_p ()"
4744 [(parallel [(set (match_dup 0)
4745 (float:X87MODEF (match_dup 1)))
4746 (clobber (match_dup 2))])]
4747 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4749 (define_insn "*floathi<mode>2_i387_with_temp"
4750 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4751 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4752 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4755 || TARGET_MIX_SSE_I387)"
4757 [(set_attr "type" "fmov,multi")
4758 (set_attr "mode" "<MODE>")
4759 (set_attr "unit" "*,i387")
4760 (set_attr "fp_int_src" "true")])
4762 (define_insn "*floathi<mode>2_i387"
4763 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4764 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4767 || TARGET_MIX_SSE_I387)"
4769 [(set_attr "type" "fmov")
4770 (set_attr "mode" "<MODE>")
4771 (set_attr "fp_int_src" "true")])
4774 [(set (match_operand:X87MODEF 0 "register_operand" "")
4775 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4776 (clobber (match_operand:HI 2 "memory_operand" ""))]
4778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4779 || TARGET_MIX_SSE_I387)
4780 && reload_completed"
4781 [(set (match_dup 2) (match_dup 1))
4782 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4785 [(set (match_operand:X87MODEF 0 "register_operand" "")
4786 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4787 (clobber (match_operand:HI 2 "memory_operand" ""))]
4789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4790 || TARGET_MIX_SSE_I387)
4791 && reload_completed"
4792 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4794 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4795 [(set (match_operand:X87MODEF 0 "register_operand" "")
4797 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4799 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4800 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4802 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4803 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4804 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4806 rtx reg = gen_reg_rtx (XFmode);
4807 rtx (*insn)(rtx, rtx);
4809 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4811 if (<X87MODEF:MODE>mode == SFmode)
4812 insn = gen_truncxfsf2;
4813 else if (<X87MODEF:MODE>mode == DFmode)
4814 insn = gen_truncxfdf2;
4818 emit_insn (insn (operands[0], reg));
4823 ;; Pre-reload splitter to add memory clobber to the pattern.
4824 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4825 [(set (match_operand:X87MODEF 0 "register_operand" "")
4826 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4828 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4829 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4830 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387))
4832 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4834 && ((<SWI48x:MODE>mode == SImode
4835 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4836 && optimize_function_for_speed_p (cfun)
4837 && flag_trapping_math)
4838 || !(TARGET_INTER_UNIT_CONVERSIONS
4839 || optimize_function_for_size_p (cfun)))))
4840 && can_create_pseudo_p ()"
4843 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4844 (clobber (match_dup 2))])]
4846 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4848 /* Avoid store forwarding (partial memory) stall penalty
4849 by passing DImode value through XMM registers. */
4850 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4851 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4852 && optimize_function_for_speed_p (cfun))
4854 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4861 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4862 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4864 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4865 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4866 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4867 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4869 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4870 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4871 (set_attr "unit" "*,i387,*,*,*")
4872 (set_attr "athlon_decode" "*,*,double,direct,double")
4873 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4874 (set_attr "bdver1_decode" "*,*,double,direct,double")
4875 (set_attr "fp_int_src" "true")])
4877 (define_insn "*floatsi<mode>2_vector_mixed"
4878 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4879 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4880 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4881 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4885 [(set_attr "type" "fmov,sseicvt")
4886 (set_attr "mode" "<MODE>,<ssevecmode>")
4887 (set_attr "unit" "i387,*")
4888 (set_attr "athlon_decode" "*,direct")
4889 (set_attr "amdfam10_decode" "*,double")
4890 (set_attr "bdver1_decode" "*,direct")
4891 (set_attr "fp_int_src" "true")])
4893 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4894 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4896 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4897 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4898 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4899 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "<MODEF:MODE>")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "bdver1_decode" "*,*,double,direct")
4907 (set_attr "fp_int_src" "true")])
4910 [(set (match_operand:MODEF 0 "register_operand" "")
4911 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4912 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4913 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4914 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4915 && TARGET_INTER_UNIT_CONVERSIONS
4917 && (SSE_REG_P (operands[0])
4918 || (GET_CODE (operands[0]) == SUBREG
4919 && SSE_REG_P (operands[0])))"
4920 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4923 [(set (match_operand:MODEF 0 "register_operand" "")
4924 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4925 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4926 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4927 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4928 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4930 && (SSE_REG_P (operands[0])
4931 || (GET_CODE (operands[0]) == SUBREG
4932 && SSE_REG_P (operands[0])))"
4933 [(set (match_dup 2) (match_dup 1))
4934 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4936 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4937 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4939 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4940 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4941 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4942 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4945 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4946 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4947 [(set_attr "type" "fmov,sseicvt,sseicvt")
4948 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4949 (set_attr "mode" "<MODEF:MODE>")
4950 (set (attr "prefix_rex")
4952 (and (eq_attr "prefix" "maybe_vex")
4953 (match_test "<SWI48x:MODE>mode == DImode"))
4955 (const_string "*")))
4956 (set_attr "unit" "i387,*,*")
4957 (set_attr "athlon_decode" "*,double,direct")
4958 (set_attr "amdfam10_decode" "*,vector,double")
4959 (set_attr "bdver1_decode" "*,double,direct")
4960 (set_attr "fp_int_src" "true")])
4962 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4963 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4965 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4966 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4967 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4968 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4971 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4972 [(set_attr "type" "fmov,sseicvt")
4973 (set_attr "prefix" "orig,maybe_vex")
4974 (set_attr "mode" "<MODEF:MODE>")
4975 (set (attr "prefix_rex")
4977 (and (eq_attr "prefix" "maybe_vex")
4978 (match_test "<SWI48x:MODE>mode == DImode"))
4980 (const_string "*")))
4981 (set_attr "athlon_decode" "*,direct")
4982 (set_attr "amdfam10_decode" "*,double")
4983 (set_attr "bdver1_decode" "*,direct")
4984 (set_attr "fp_int_src" "true")])
4986 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4987 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4989 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4990 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4994 [(set_attr "type" "sseicvt")
4995 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4996 (set_attr "athlon_decode" "double,direct,double")
4997 (set_attr "amdfam10_decode" "vector,double,double")
4998 (set_attr "bdver1_decode" "double,direct,double")
4999 (set_attr "fp_int_src" "true")])
5001 (define_insn "*floatsi<mode>2_vector_sse"
5002 [(set (match_operand:MODEF 0 "register_operand" "=x")
5003 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5004 "TARGET_SSE2 && TARGET_SSE_MATH
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007 [(set_attr "type" "sseicvt")
5008 (set_attr "mode" "<MODE>")
5009 (set_attr "athlon_decode" "direct")
5010 (set_attr "amdfam10_decode" "double")
5011 (set_attr "bdver1_decode" "direct")
5012 (set_attr "fp_int_src" "true")])
5015 [(set (match_operand:MODEF 0 "register_operand" "")
5016 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5017 (clobber (match_operand:SI 2 "memory_operand" ""))]
5018 "TARGET_SSE2 && TARGET_SSE_MATH
5019 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5021 && (SSE_REG_P (operands[0])
5022 || (GET_CODE (operands[0]) == SUBREG
5023 && SSE_REG_P (operands[0])))"
5026 rtx op1 = operands[1];
5028 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5030 if (GET_CODE (op1) == SUBREG)
5031 op1 = SUBREG_REG (op1);
5033 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5036 emit_insn (gen_sse2_loadld (operands[4],
5037 CONST0_RTX (V4SImode), operands[1]));
5039 /* We can ignore possible trapping value in the
5040 high part of SSE register for non-trapping math. */
5041 else if (SSE_REG_P (op1) && !flag_trapping_math)
5042 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5045 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5046 emit_move_insn (operands[2], operands[1]);
5047 emit_insn (gen_sse2_loadld (operands[4],
5048 CONST0_RTX (V4SImode), operands[2]));
5051 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5056 [(set (match_operand:MODEF 0 "register_operand" "")
5057 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5058 (clobber (match_operand:SI 2 "memory_operand" ""))]
5059 "TARGET_SSE2 && TARGET_SSE_MATH
5060 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5062 && (SSE_REG_P (operands[0])
5063 || (GET_CODE (operands[0]) == SUBREG
5064 && SSE_REG_P (operands[0])))"
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5074 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5079 [(set (match_operand:MODEF 0 "register_operand" "")
5080 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5081 "TARGET_SSE2 && TARGET_SSE_MATH
5082 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5084 && (SSE_REG_P (operands[0])
5085 || (GET_CODE (operands[0]) == SUBREG
5086 && SSE_REG_P (operands[0])))"
5089 rtx op1 = operands[1];
5091 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5093 if (GET_CODE (op1) == SUBREG)
5094 op1 = SUBREG_REG (op1);
5096 if (GENERAL_REG_P (op1))
5098 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5099 if (TARGET_INTER_UNIT_MOVES)
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5104 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5106 emit_insn (gen_sse2_loadld (operands[4],
5107 CONST0_RTX (V4SImode), operands[5]));
5108 ix86_free_from_memory (GET_MODE (operands[1]));
5111 /* We can ignore possible trapping value in the
5112 high part of SSE register for non-trapping math. */
5113 else if (SSE_REG_P (op1) && !flag_trapping_math)
5114 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5118 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5123 [(set (match_operand:MODEF 0 "register_operand" "")
5124 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5125 "TARGET_SSE2 && TARGET_SSE_MATH
5126 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5128 && (SSE_REG_P (operands[0])
5129 || (GET_CODE (operands[0]) == SUBREG
5130 && SSE_REG_P (operands[0])))"
5133 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5135 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5137 emit_insn (gen_sse2_loadld (operands[4],
5138 CONST0_RTX (V4SImode), operands[1]));
5140 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5144 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5145 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5147 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5152 [(set_attr "type" "sseicvt")
5153 (set_attr "mode" "<MODEF:MODE>")
5154 (set_attr "athlon_decode" "double,direct")
5155 (set_attr "amdfam10_decode" "vector,double")
5156 (set_attr "bdver1_decode" "double,direct")
5157 (set_attr "fp_int_src" "true")])
5159 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5160 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5162 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5166 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5167 [(set_attr "type" "sseicvt")
5168 (set_attr "prefix" "maybe_vex")
5169 (set_attr "mode" "<MODEF:MODE>")
5170 (set (attr "prefix_rex")
5172 (and (eq_attr "prefix" "maybe_vex")
5173 (match_test "<SWI48x:MODE>mode == DImode"))
5175 (const_string "*")))
5176 (set_attr "athlon_decode" "double,direct")
5177 (set_attr "amdfam10_decode" "vector,double")
5178 (set_attr "bdver1_decode" "double,direct")
5179 (set_attr "fp_int_src" "true")])
5182 [(set (match_operand:MODEF 0 "register_operand" "")
5183 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5185 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5186 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5187 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5189 && (SSE_REG_P (operands[0])
5190 || (GET_CODE (operands[0]) == SUBREG
5191 && SSE_REG_P (operands[0])))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5194 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5195 [(set (match_operand:MODEF 0 "register_operand" "=x")
5197 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5201 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5202 [(set_attr "type" "sseicvt")
5203 (set_attr "prefix" "maybe_vex")
5204 (set_attr "mode" "<MODEF:MODE>")
5205 (set (attr "prefix_rex")
5207 (and (eq_attr "prefix" "maybe_vex")
5208 (match_test "<SWI48x:MODE>mode == DImode"))
5210 (const_string "*")))
5211 (set_attr "athlon_decode" "direct")
5212 (set_attr "amdfam10_decode" "double")
5213 (set_attr "bdver1_decode" "direct")
5214 (set_attr "fp_int_src" "true")])
5217 [(set (match_operand:MODEF 0 "register_operand" "")
5218 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5221 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5222 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5224 && (SSE_REG_P (operands[0])
5225 || (GET_CODE (operands[0]) == SUBREG
5226 && SSE_REG_P (operands[0])))"
5227 [(set (match_dup 2) (match_dup 1))
5228 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5231 [(set (match_operand:MODEF 0 "register_operand" "")
5232 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5233 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5234 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5237 && (SSE_REG_P (operands[0])
5238 || (GET_CODE (operands[0]) == SUBREG
5239 && SSE_REG_P (operands[0])))"
5240 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5242 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5243 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5245 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5246 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5248 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5252 [(set_attr "type" "fmov,multi")
5253 (set_attr "mode" "<X87MODEF:MODE>")
5254 (set_attr "unit" "*,i387")
5255 (set_attr "fp_int_src" "true")])
5257 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5258 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5260 (match_operand:SWI48x 1 "memory_operand" "m")))]
5262 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5264 [(set_attr "type" "fmov")
5265 (set_attr "mode" "<X87MODEF:MODE>")
5266 (set_attr "fp_int_src" "true")])
5269 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5270 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5271 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5273 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5274 && reload_completed"
5275 [(set (match_dup 2) (match_dup 1))
5276 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5279 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5280 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5281 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5283 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5284 && reload_completed"
5285 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5287 ;; Avoid store forwarding (partial memory) stall penalty
5288 ;; by passing DImode value through XMM registers. */
5290 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5291 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5293 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5294 (clobber (match_scratch:V4SI 3 "=X,x"))
5295 (clobber (match_scratch:V4SI 4 "=X,x"))
5296 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5297 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5298 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5299 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5301 [(set_attr "type" "multi")
5302 (set_attr "mode" "<X87MODEF:MODE>")
5303 (set_attr "unit" "i387")
5304 (set_attr "fp_int_src" "true")])
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5308 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5309 (clobber (match_scratch:V4SI 3 ""))
5310 (clobber (match_scratch:V4SI 4 ""))
5311 (clobber (match_operand:DI 2 "memory_operand" ""))]
5312 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5314 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5317 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5319 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5320 Assemble the 64-bit DImode value in an xmm register. */
5321 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5322 gen_rtx_SUBREG (SImode, operands[1], 0)));
5323 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5324 gen_rtx_SUBREG (SImode, operands[1], 4)));
5325 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5328 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5332 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5333 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5334 (clobber (match_scratch:V4SI 3 ""))
5335 (clobber (match_scratch:V4SI 4 ""))
5336 (clobber (match_operand:DI 2 "memory_operand" ""))]
5337 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5338 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5339 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5340 && reload_completed"
5341 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5343 ;; Avoid store forwarding (partial memory) stall penalty by extending
5344 ;; SImode value to DImode through XMM register instead of pushing two
5345 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5346 ;; targets benefit from this optimization. Also note that fild
5347 ;; loads from memory only.
5349 (define_insn "*floatunssi<mode>2_1"
5350 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351 (unsigned_float:X87MODEF
5352 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5353 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5354 (clobber (match_scratch:SI 3 "=X,x"))]
5356 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5359 [(set_attr "type" "multi")
5360 (set_attr "mode" "<MODE>")])
5363 [(set (match_operand:X87MODEF 0 "register_operand" "")
5364 (unsigned_float:X87MODEF
5365 (match_operand:SI 1 "register_operand" "")))
5366 (clobber (match_operand:DI 2 "memory_operand" ""))
5367 (clobber (match_scratch:SI 3 ""))]
5369 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 && reload_completed"
5372 [(set (match_dup 2) (match_dup 1))
5374 (float:X87MODEF (match_dup 2)))]
5375 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5378 [(set (match_operand:X87MODEF 0 "register_operand" "")
5379 (unsigned_float:X87MODEF
5380 (match_operand:SI 1 "memory_operand" "")))
5381 (clobber (match_operand:DI 2 "memory_operand" ""))
5382 (clobber (match_scratch:SI 3 ""))]
5384 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5386 && reload_completed"
5387 [(set (match_dup 2) (match_dup 3))
5389 (float:X87MODEF (match_dup 2)))]
5391 emit_move_insn (operands[3], operands[1]);
5392 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5395 (define_expand "floatunssi<mode>2"
5397 [(set (match_operand:X87MODEF 0 "register_operand" "")
5398 (unsigned_float:X87MODEF
5399 (match_operand:SI 1 "nonimmediate_operand" "")))
5400 (clobber (match_dup 2))
5401 (clobber (match_scratch:SI 3 ""))])]
5403 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5405 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5407 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5409 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5414 enum ix86_stack_slot slot = (virtuals_instantiated
5417 operands[2] = assign_386_stack_local (DImode, slot);
5421 (define_expand "floatunsdisf2"
5422 [(use (match_operand:SF 0 "register_operand" ""))
5423 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5424 "TARGET_64BIT && TARGET_SSE_MATH"
5425 "x86_emit_floatuns (operands); DONE;")
5427 (define_expand "floatunsdidf2"
5428 [(use (match_operand:DF 0 "register_operand" ""))
5429 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5430 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5431 && TARGET_SSE2 && TARGET_SSE_MATH"
5434 x86_emit_floatuns (operands);
5436 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5442 (define_expand "add<mode>3"
5443 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5444 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5445 (match_operand:SDWIM 2 "<general_operand>" "")))]
5447 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5449 (define_insn_and_split "*add<dwi>3_doubleword"
5450 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5452 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5453 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5454 (clobber (reg:CC FLAGS_REG))]
5455 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5458 [(parallel [(set (reg:CC FLAGS_REG)
5459 (unspec:CC [(match_dup 1) (match_dup 2)]
5462 (plus:DWIH (match_dup 1) (match_dup 2)))])
5463 (parallel [(set (match_dup 3)
5467 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5469 (clobber (reg:CC FLAGS_REG))])]
5470 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5472 (define_insn "*add<mode>3_cc"
5473 [(set (reg:CC FLAGS_REG)
5475 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5476 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5478 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5479 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5480 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5481 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5482 [(set_attr "type" "alu")
5483 (set_attr "mode" "<MODE>")])
5485 (define_insn "addqi3_cc"
5486 [(set (reg:CC FLAGS_REG)
5488 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5489 (match_operand:QI 2 "general_operand" "qn,qm")]
5491 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5492 (plus:QI (match_dup 1) (match_dup 2)))]
5493 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5494 "add{b}\t{%2, %0|%0, %2}"
5495 [(set_attr "type" "alu")
5496 (set_attr "mode" "QI")])
5498 (define_insn_and_split "*lea_1"
5499 [(set (match_operand:SI 0 "register_operand" "=r")
5500 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5502 "lea{l}\t{%a1, %0|%0, %a1}"
5503 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5506 ix86_split_lea_for_addr (operands, SImode);
5509 [(set_attr "type" "lea")
5510 (set_attr "mode" "SI")])
5512 (define_insn_and_split "*lea<mode>_2"
5513 [(set (match_operand:SWI48 0 "register_operand" "=r")
5514 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5516 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5517 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5520 ix86_split_lea_for_addr (operands, <MODE>mode);
5523 [(set_attr "type" "lea")
5524 (set_attr "mode" "<MODE>")])
5526 (define_insn "*lea_3_zext"
5527 [(set (match_operand:DI 0 "register_operand" "=r")
5529 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5531 "lea{l}\t{%a1, %k0|%k0, %a1}"
5532 [(set_attr "type" "lea")
5533 (set_attr "mode" "SI")])
5535 (define_insn "*lea_4_zext"
5536 [(set (match_operand:DI 0 "register_operand" "=r")
5538 (match_operand:SI 1 "lea_address_operand" "p")))]
5540 "lea{l}\t{%a1, %k0|%k0, %a1}"
5541 [(set_attr "type" "lea")
5542 (set_attr "mode" "SI")])
5544 (define_insn "*lea_5_zext"
5545 [(set (match_operand:DI 0 "register_operand" "=r")
5547 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5548 (match_operand:DI 2 "const_32bit_mask" "n")))]
5550 "lea{l}\t{%a1, %k0|%k0, %a1}"
5551 [(set_attr "type" "lea")
5552 (set_attr "mode" "SI")])
5554 (define_insn "*lea_6_zext"
5555 [(set (match_operand:DI 0 "register_operand" "=r")
5557 (match_operand:DI 1 "lea_address_operand" "p")
5558 (match_operand:DI 2 "const_32bit_mask" "n")))]
5560 "lea{l}\t{%a1, %k0|%k0, %a1}"
5561 [(set_attr "type" "lea")
5562 (set_attr "mode" "SI")])
5564 (define_insn "*add<mode>_1"
5565 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5567 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5568 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5569 (clobber (reg:CC FLAGS_REG))]
5570 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5572 switch (get_attr_type (insn))
5578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579 if (operands[2] == const1_rtx)
5580 return "inc{<imodesuffix>}\t%0";
5583 gcc_assert (operands[2] == constm1_rtx);
5584 return "dec{<imodesuffix>}\t%0";
5588 /* For most processors, ADD is faster than LEA. This alternative
5589 was added to use ADD as much as possible. */
5590 if (which_alternative == 2)
5593 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5596 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5597 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5598 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5600 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5604 (cond [(eq_attr "alternative" "3")
5605 (const_string "lea")
5606 (match_operand:SWI48 2 "incdec_operand" "")
5607 (const_string "incdec")
5609 (const_string "alu")))
5610 (set (attr "length_immediate")
5612 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5614 (const_string "*")))
5615 (set_attr "mode" "<MODE>")])
5617 ;; It may seem that nonimmediate operand is proper one for operand 1.
5618 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5619 ;; we take care in ix86_binary_operator_ok to not allow two memory
5620 ;; operands so proper swapping will be done in reload. This allow
5621 ;; patterns constructed from addsi_1 to match.
5623 (define_insn "addsi_1_zext"
5624 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5626 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5627 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5628 (clobber (reg:CC FLAGS_REG))]
5629 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5631 switch (get_attr_type (insn))
5637 if (operands[2] == const1_rtx)
5638 return "inc{l}\t%k0";
5641 gcc_assert (operands[2] == constm1_rtx);
5642 return "dec{l}\t%k0";
5646 /* For most processors, ADD is faster than LEA. This alternative
5647 was added to use ADD as much as possible. */
5648 if (which_alternative == 1)
5651 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654 if (x86_maybe_negate_const_int (&operands[2], SImode))
5655 return "sub{l}\t{%2, %k0|%k0, %2}";
5657 return "add{l}\t{%2, %k0|%k0, %2}";
5661 (cond [(eq_attr "alternative" "2")
5662 (const_string "lea")
5663 (match_operand:SI 2 "incdec_operand" "")
5664 (const_string "incdec")
5666 (const_string "alu")))
5667 (set (attr "length_immediate")
5669 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5671 (const_string "*")))
5672 (set_attr "mode" "SI")])
5674 (define_insn "*addhi_1"
5675 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5676 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5677 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5678 (clobber (reg:CC FLAGS_REG))]
5679 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5681 switch (get_attr_type (insn))
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (operands[2] == const1_rtx)
5689 return "inc{w}\t%0";
5692 gcc_assert (operands[2] == constm1_rtx);
5693 return "dec{w}\t%0";
5697 /* For most processors, ADD is faster than LEA. This alternative
5698 was added to use ADD as much as possible. */
5699 if (which_alternative == 2)
5702 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706 if (x86_maybe_negate_const_int (&operands[2], HImode))
5707 return "sub{w}\t{%2, %0|%0, %2}";
5709 return "add{w}\t{%2, %0|%0, %2}";
5713 (cond [(eq_attr "alternative" "3")
5714 (const_string "lea")
5715 (match_operand:HI 2 "incdec_operand" "")
5716 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723 (const_string "*")))
5724 (set_attr "mode" "HI,HI,HI,SI")])
5726 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5727 (define_insn "*addqi_1"
5728 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5729 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5730 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5734 bool widen = (which_alternative == 3 || which_alternative == 4);
5736 switch (get_attr_type (insn))
5742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743 if (operands[2] == const1_rtx)
5744 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5747 gcc_assert (operands[2] == constm1_rtx);
5748 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5752 /* For most processors, ADD is faster than LEA. These alternatives
5753 were added to use ADD as much as possible. */
5754 if (which_alternative == 2 || which_alternative == 4)
5757 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5761 if (x86_maybe_negate_const_int (&operands[2], QImode))
5764 return "sub{l}\t{%2, %k0|%k0, %2}";
5766 return "sub{b}\t{%2, %0|%0, %2}";
5769 return "add{l}\t{%k2, %k0|%k0, %k2}";
5771 return "add{b}\t{%2, %0|%0, %2}";
5775 (cond [(eq_attr "alternative" "5")
5776 (const_string "lea")
5777 (match_operand:QI 2 "incdec_operand" "")
5778 (const_string "incdec")
5780 (const_string "alu")))
5781 (set (attr "length_immediate")
5783 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5785 (const_string "*")))
5786 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5788 (define_insn "*addqi_1_slp"
5789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5790 (plus:QI (match_dup 0)
5791 (match_operand:QI 1 "general_operand" "qn,qm")))
5792 (clobber (reg:CC FLAGS_REG))]
5793 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5794 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5796 switch (get_attr_type (insn))
5799 if (operands[1] == const1_rtx)
5800 return "inc{b}\t%0";
5803 gcc_assert (operands[1] == constm1_rtx);
5804 return "dec{b}\t%0";
5808 if (x86_maybe_negate_const_int (&operands[1], QImode))
5809 return "sub{b}\t{%1, %0|%0, %1}";
5811 return "add{b}\t{%1, %0|%0, %1}";
5815 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5816 (const_string "incdec")
5817 (const_string "alu1")))
5818 (set (attr "memory")
5819 (if_then_else (match_operand 1 "memory_operand" "")
5820 (const_string "load")
5821 (const_string "none")))
5822 (set_attr "mode" "QI")])
5824 ;; Split non destructive adds if we cannot use lea.
5826 [(set (match_operand:SWI48 0 "register_operand" "")
5827 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5828 (match_operand:SWI48 2 "nonmemory_operand" "")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5831 [(set (match_dup 0) (match_dup 1))
5832 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5833 (clobber (reg:CC FLAGS_REG))])])
5835 ;; Convert add to the lea pattern to avoid flags dependency.
5837 [(set (match_operand:SWI 0 "register_operand" "")
5838 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5839 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5840 (clobber (reg:CC FLAGS_REG))]
5841 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5844 enum machine_mode mode = <MODE>mode;
5847 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850 operands[0] = gen_lowpart (mode, operands[0]);
5851 operands[1] = gen_lowpart (mode, operands[1]);
5852 operands[2] = gen_lowpart (mode, operands[2]);
5855 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5857 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5861 ;; Convert add to the lea pattern to avoid flags dependency.
5863 [(set (match_operand:DI 0 "register_operand" "")
5865 (plus:SI (match_operand:SI 1 "register_operand" "")
5866 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5870 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5872 (define_insn "*add<mode>_2"
5873 [(set (reg FLAGS_REG)
5876 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5877 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5879 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5880 (plus:SWI (match_dup 1) (match_dup 2)))]
5881 "ix86_match_ccmode (insn, CCGOCmode)
5882 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5884 switch (get_attr_type (insn))
5887 if (operands[2] == const1_rtx)
5888 return "inc{<imodesuffix>}\t%0";
5891 gcc_assert (operands[2] == constm1_rtx);
5892 return "dec{<imodesuffix>}\t%0";
5896 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5897 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5899 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5903 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5904 (const_string "incdec")
5905 (const_string "alu")))
5906 (set (attr "length_immediate")
5908 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5910 (const_string "*")))
5911 (set_attr "mode" "<MODE>")])
5913 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5914 (define_insn "*addsi_2_zext"
5915 [(set (reg FLAGS_REG)
5917 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5918 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5920 (set (match_operand:DI 0 "register_operand" "=r")
5921 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5922 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5923 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5925 switch (get_attr_type (insn))
5928 if (operands[2] == const1_rtx)
5929 return "inc{l}\t%k0";
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return "dec{l}\t%k0";
5937 if (x86_maybe_negate_const_int (&operands[2], SImode))
5938 return "sub{l}\t{%2, %k0|%k0, %2}";
5940 return "add{l}\t{%2, %k0|%k0, %2}";
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set (attr "length_immediate")
5949 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5951 (const_string "*")))
5952 (set_attr "mode" "SI")])
5954 (define_insn "*add<mode>_3"
5955 [(set (reg FLAGS_REG)
5957 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5958 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5959 (clobber (match_scratch:SWI 0 "=<r>"))]
5960 "ix86_match_ccmode (insn, CCZmode)
5961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5963 switch (get_attr_type (insn))
5966 if (operands[2] == const1_rtx)
5967 return "inc{<imodesuffix>}\t%0";
5970 gcc_assert (operands[2] == constm1_rtx);
5971 return "dec{<imodesuffix>}\t%0";
5975 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5976 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5978 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5982 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu")))
5985 (set (attr "length_immediate")
5987 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5989 (const_string "*")))
5990 (set_attr "mode" "<MODE>")])
5992 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5993 (define_insn "*addsi_3_zext"
5994 [(set (reg FLAGS_REG)
5996 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5997 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5998 (set (match_operand:DI 0 "register_operand" "=r")
5999 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6000 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6001 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6003 switch (get_attr_type (insn))
6006 if (operands[2] == const1_rtx)
6007 return "inc{l}\t%k0";
6010 gcc_assert (operands[2] == constm1_rtx);
6011 return "dec{l}\t%k0";
6015 if (x86_maybe_negate_const_int (&operands[2], SImode))
6016 return "sub{l}\t{%2, %k0|%k0, %2}";
6018 return "add{l}\t{%2, %k0|%k0, %2}";
6022 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set (attr "length_immediate")
6027 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6029 (const_string "*")))
6030 (set_attr "mode" "SI")])
6032 ; For comparisons against 1, -1 and 128, we may generate better code
6033 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6034 ; is matched then. We can't accept general immediate, because for
6035 ; case of overflows, the result is messed up.
6036 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6037 ; only for comparisons not depending on it.
6039 (define_insn "*adddi_4"
6040 [(set (reg FLAGS_REG)
6042 (match_operand:DI 1 "nonimmediate_operand" "0")
6043 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6044 (clobber (match_scratch:DI 0 "=rm"))]
6046 && ix86_match_ccmode (insn, CCGCmode)"
6048 switch (get_attr_type (insn))
6051 if (operands[2] == constm1_rtx)
6052 return "inc{q}\t%0";
6055 gcc_assert (operands[2] == const1_rtx);
6056 return "dec{q}\t%0";
6060 if (x86_maybe_negate_const_int (&operands[2], DImode))
6061 return "add{q}\t{%2, %0|%0, %2}";
6063 return "sub{q}\t{%2, %0|%0, %2}";
6067 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set (attr "length_immediate")
6072 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6074 (const_string "*")))
6075 (set_attr "mode" "DI")])
6077 ; For comparisons against 1, -1 and 128, we may generate better code
6078 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6079 ; is matched then. We can't accept general immediate, because for
6080 ; case of overflows, the result is messed up.
6081 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6082 ; only for comparisons not depending on it.
6084 (define_insn "*add<mode>_4"
6085 [(set (reg FLAGS_REG)
6087 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6088 (match_operand:SWI124 2 "const_int_operand" "n")))
6089 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6090 "ix86_match_ccmode (insn, CCGCmode)"
6092 switch (get_attr_type (insn))
6095 if (operands[2] == constm1_rtx)
6096 return "inc{<imodesuffix>}\t%0";
6099 gcc_assert (operands[2] == const1_rtx);
6100 return "dec{<imodesuffix>}\t%0";
6104 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6105 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6107 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6111 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu")))
6114 (set (attr "length_immediate")
6116 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6118 (const_string "*")))
6119 (set_attr "mode" "<MODE>")])
6121 (define_insn "*add<mode>_5"
6122 [(set (reg FLAGS_REG)
6125 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6126 (match_operand:SWI 2 "<general_operand>" "<g>"))
6128 (clobber (match_scratch:SWI 0 "=<r>"))]
6129 "ix86_match_ccmode (insn, CCGOCmode)
6130 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6132 switch (get_attr_type (insn))
6135 if (operands[2] == const1_rtx)
6136 return "inc{<imodesuffix>}\t%0";
6139 gcc_assert (operands[2] == constm1_rtx);
6140 return "dec{<imodesuffix>}\t%0";
6144 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6145 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6147 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6151 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6158 (const_string "*")))
6159 (set_attr "mode" "<MODE>")])
6161 (define_insn "*addqi_ext_1_rex64"
6162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6167 (match_operand 1 "ext_register_operand" "0")
6170 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6171 (clobber (reg:CC FLAGS_REG))]
6174 switch (get_attr_type (insn))
6177 if (operands[2] == const1_rtx)
6178 return "inc{b}\t%h0";
6181 gcc_assert (operands[2] == constm1_rtx);
6182 return "dec{b}\t%h0";
6186 return "add{b}\t{%2, %h0|%h0, %2}";
6190 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "modrm" "1")
6194 (set_attr "mode" "QI")])
6196 (define_insn "addqi_ext_1"
6197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6202 (match_operand 1 "ext_register_operand" "0")
6205 (match_operand:QI 2 "general_operand" "Qmn")))
6206 (clobber (reg:CC FLAGS_REG))]
6209 switch (get_attr_type (insn))
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%h0";
6216 gcc_assert (operands[2] == constm1_rtx);
6217 return "dec{b}\t%h0";
6221 return "add{b}\t{%2, %h0|%h0, %2}";
6225 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "modrm" "1")
6229 (set_attr "mode" "QI")])
6231 (define_insn "*addqi_ext_2"
6232 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6237 (match_operand 1 "ext_register_operand" "%0")
6241 (match_operand 2 "ext_register_operand" "Q")
6244 (clobber (reg:CC FLAGS_REG))]
6246 "add{b}\t{%h2, %h0|%h0, %h2}"
6247 [(set_attr "type" "alu")
6248 (set_attr "mode" "QI")])
6250 ;; The lea patterns for modes less than 32 bits need to be matched by
6251 ;; several insns converted to real lea by splitters.
6253 (define_insn_and_split "*lea_general_1"
6254 [(set (match_operand 0 "register_operand" "=r")
6255 (plus (plus (match_operand 1 "index_register_operand" "l")
6256 (match_operand 2 "register_operand" "r"))
6257 (match_operand 3 "immediate_operand" "i")))]
6258 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6260 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6261 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6262 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6263 || GET_MODE (operands[3]) == VOIDmode)"
6265 "&& reload_completed"
6268 enum machine_mode mode = SImode;
6271 operands[0] = gen_lowpart (mode, operands[0]);
6272 operands[1] = gen_lowpart (mode, operands[1]);
6273 operands[2] = gen_lowpart (mode, operands[2]);
6274 operands[3] = gen_lowpart (mode, operands[3]);
6276 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6279 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6282 [(set_attr "type" "lea")
6283 (set_attr "mode" "SI")])
6285 (define_insn_and_split "*lea_general_2"
6286 [(set (match_operand 0 "register_operand" "=r")
6287 (plus (mult (match_operand 1 "index_register_operand" "l")
6288 (match_operand 2 "const248_operand" "n"))
6289 (match_operand 3 "nonmemory_operand" "ri")))]
6290 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6291 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6292 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6293 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6294 || GET_MODE (operands[3]) == VOIDmode)"
6296 "&& reload_completed"
6299 enum machine_mode mode = SImode;
6302 operands[0] = gen_lowpart (mode, operands[0]);
6303 operands[1] = gen_lowpart (mode, operands[1]);
6304 operands[3] = gen_lowpart (mode, operands[3]);
6306 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6309 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6312 [(set_attr "type" "lea")
6313 (set_attr "mode" "SI")])
6315 (define_insn_and_split "*lea_general_3"
6316 [(set (match_operand 0 "register_operand" "=r")
6317 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6318 (match_operand 2 "const248_operand" "n"))
6319 (match_operand 3 "register_operand" "r"))
6320 (match_operand 4 "immediate_operand" "i")))]
6321 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6323 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6324 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6326 "&& reload_completed"
6329 enum machine_mode mode = SImode;
6332 operands[0] = gen_lowpart (mode, operands[0]);
6333 operands[1] = gen_lowpart (mode, operands[1]);
6334 operands[3] = gen_lowpart (mode, operands[3]);
6335 operands[4] = gen_lowpart (mode, operands[4]);
6337 pat = gen_rtx_PLUS (mode,
6339 gen_rtx_MULT (mode, operands[1],
6344 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6347 [(set_attr "type" "lea")
6348 (set_attr "mode" "SI")])
6350 (define_insn_and_split "*lea_general_4"
6351 [(set (match_operand 0 "register_operand" "=r")
6353 (match_operand 1 "index_register_operand" "l")
6354 (match_operand 2 "const_int_operand" "n"))
6355 (match_operand 3 "const_int_operand" "n")))]
6356 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6357 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6358 || GET_MODE (operands[0]) == SImode
6359 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6360 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6361 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6362 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6363 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6365 "&& reload_completed"
6368 enum machine_mode mode = GET_MODE (operands[0]);
6371 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6374 operands[0] = gen_lowpart (mode, operands[0]);
6375 operands[1] = gen_lowpart (mode, operands[1]);
6378 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6380 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6381 INTVAL (operands[3]));
6383 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6386 [(set_attr "type" "lea")
6388 (if_then_else (match_operand:DI 0 "" "")
6390 (const_string "SI")))])
6392 ;; Subtract instructions
6394 (define_expand "sub<mode>3"
6395 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6396 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6397 (match_operand:SDWIM 2 "<general_operand>" "")))]
6399 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6401 (define_insn_and_split "*sub<dwi>3_doubleword"
6402 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6404 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6405 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6406 (clobber (reg:CC FLAGS_REG))]
6407 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6410 [(parallel [(set (reg:CC FLAGS_REG)
6411 (compare:CC (match_dup 1) (match_dup 2)))
6413 (minus:DWIH (match_dup 1) (match_dup 2)))])
6414 (parallel [(set (match_dup 3)
6418 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6420 (clobber (reg:CC FLAGS_REG))])]
6421 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6423 (define_insn "*sub<mode>_1"
6424 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6426 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6427 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6428 (clobber (reg:CC FLAGS_REG))]
6429 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6430 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6431 [(set_attr "type" "alu")
6432 (set_attr "mode" "<MODE>")])
6434 (define_insn "*subsi_1_zext"
6435 [(set (match_operand:DI 0 "register_operand" "=r")
6437 (minus:SI (match_operand:SI 1 "register_operand" "0")
6438 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6439 (clobber (reg:CC FLAGS_REG))]
6440 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6441 "sub{l}\t{%2, %k0|%k0, %2}"
6442 [(set_attr "type" "alu")
6443 (set_attr "mode" "SI")])
6445 (define_insn "*subqi_1_slp"
6446 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6447 (minus:QI (match_dup 0)
6448 (match_operand:QI 1 "general_operand" "qn,qm")))
6449 (clobber (reg:CC FLAGS_REG))]
6450 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6451 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6452 "sub{b}\t{%1, %0|%0, %1}"
6453 [(set_attr "type" "alu1")
6454 (set_attr "mode" "QI")])
6456 (define_insn "*sub<mode>_2"
6457 [(set (reg FLAGS_REG)
6460 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6463 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (minus:SWI (match_dup 1) (match_dup 2)))]
6465 "ix86_match_ccmode (insn, CCGOCmode)
6466 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6467 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6468 [(set_attr "type" "alu")
6469 (set_attr "mode" "<MODE>")])
6471 (define_insn "*subsi_2_zext"
6472 [(set (reg FLAGS_REG)
6474 (minus:SI (match_operand:SI 1 "register_operand" "0")
6475 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6477 (set (match_operand:DI 0 "register_operand" "=r")
6479 (minus:SI (match_dup 1)
6481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6482 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6483 "sub{l}\t{%2, %k0|%k0, %2}"
6484 [(set_attr "type" "alu")
6485 (set_attr "mode" "SI")])
6487 (define_insn "*sub<mode>_3"
6488 [(set (reg FLAGS_REG)
6489 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6490 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6491 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6492 (minus:SWI (match_dup 1) (match_dup 2)))]
6493 "ix86_match_ccmode (insn, CCmode)
6494 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6495 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6496 [(set_attr "type" "alu")
6497 (set_attr "mode" "<MODE>")])
6499 (define_insn "*subsi_3_zext"
6500 [(set (reg FLAGS_REG)
6501 (compare (match_operand:SI 1 "register_operand" "0")
6502 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6503 (set (match_operand:DI 0 "register_operand" "=r")
6505 (minus:SI (match_dup 1)
6507 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6508 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6509 "sub{l}\t{%2, %1|%1, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "SI")])
6513 ;; Add with carry and subtract with borrow
6515 (define_expand "<plusminus_insn><mode>3_carry"
6517 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6519 (match_operand:SWI 1 "nonimmediate_operand" "")
6520 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6521 [(match_operand 3 "flags_reg_operand" "")
6523 (match_operand:SWI 2 "<general_operand>" ""))))
6524 (clobber (reg:CC FLAGS_REG))])]
6525 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6527 (define_insn "*<plusminus_insn><mode>3_carry"
6528 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6532 (match_operator 3 "ix86_carry_flag_operator"
6533 [(reg FLAGS_REG) (const_int 0)])
6534 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "use_carry" "1")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "<MODE>")])
6543 (define_insn "*addsi3_carry_zext"
6544 [(set (match_operand:DI 0 "register_operand" "=r")
6546 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6547 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6548 [(reg FLAGS_REG) (const_int 0)])
6549 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6552 "adc{l}\t{%2, %k0|%k0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "use_carry" "1")
6555 (set_attr "pent_pair" "pu")
6556 (set_attr "mode" "SI")])
6558 (define_insn "*subsi3_carry_zext"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6561 (minus:SI (match_operand:SI 1 "register_operand" "0")
6562 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6563 [(reg FLAGS_REG) (const_int 0)])
6564 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6565 (clobber (reg:CC FLAGS_REG))]
6566 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6567 "sbb{l}\t{%2, %k0|%k0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "pent_pair" "pu")
6570 (set_attr "mode" "SI")])
6572 ;; Overflow setting add and subtract instructions
6574 (define_insn "*add<mode>3_cconly_overflow"
6575 [(set (reg:CCC FLAGS_REG)
6578 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6579 (match_operand:SWI 2 "<general_operand>" "<g>"))
6581 (clobber (match_scratch:SWI 0 "=<r>"))]
6582 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6583 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "mode" "<MODE>")])
6587 (define_insn "*sub<mode>3_cconly_overflow"
6588 [(set (reg:CCC FLAGS_REG)
6591 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6592 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6595 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6596 [(set_attr "type" "icmp")
6597 (set_attr "mode" "<MODE>")])
6599 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6600 [(set (reg:CCC FLAGS_REG)
6603 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6604 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6607 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6608 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6609 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6610 [(set_attr "type" "alu")
6611 (set_attr "mode" "<MODE>")])
6613 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6614 [(set (reg:CCC FLAGS_REG)
6617 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6618 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6620 (set (match_operand:DI 0 "register_operand" "=r")
6621 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6622 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6623 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "mode" "SI")])
6627 ;; The patterns that match these are at the end of this file.
6629 (define_expand "<plusminus_insn>xf3"
6630 [(set (match_operand:XF 0 "register_operand" "")
6632 (match_operand:XF 1 "register_operand" "")
6633 (match_operand:XF 2 "register_operand" "")))]
6636 (define_expand "<plusminus_insn><mode>3"
6637 [(set (match_operand:MODEF 0 "register_operand" "")
6639 (match_operand:MODEF 1 "register_operand" "")
6640 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6641 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6642 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6644 ;; Multiply instructions
6646 (define_expand "mul<mode>3"
6647 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6649 (match_operand:SWIM248 1 "register_operand" "")
6650 (match_operand:SWIM248 2 "<general_operand>" "")))
6651 (clobber (reg:CC FLAGS_REG))])])
6653 (define_expand "mulqi3"
6654 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6656 (match_operand:QI 1 "register_operand" "")
6657 (match_operand:QI 2 "nonimmediate_operand" "")))
6658 (clobber (reg:CC FLAGS_REG))])]
6659 "TARGET_QIMODE_MATH")
6662 ;; IMUL reg32/64, reg32/64, imm8 Direct
6663 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6664 ;; IMUL reg32/64, reg32/64, imm32 Direct
6665 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6666 ;; IMUL reg32/64, reg32/64 Direct
6667 ;; IMUL reg32/64, mem32/64 Direct
6669 ;; On BDVER1, all above IMULs use DirectPath
6671 (define_insn "*mul<mode>3_1"
6672 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6674 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6675 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6680 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6681 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "imul")
6683 (set_attr "prefix_0f" "0,0,1")
6684 (set (attr "athlon_decode")
6685 (cond [(eq_attr "cpu" "athlon")
6686 (const_string "vector")
6687 (eq_attr "alternative" "1")
6688 (const_string "vector")
6689 (and (eq_attr "alternative" "2")
6690 (match_operand 1 "memory_operand" ""))
6691 (const_string "vector")]
6692 (const_string "direct")))
6693 (set (attr "amdfam10_decode")
6694 (cond [(and (eq_attr "alternative" "0,1")
6695 (match_operand 1 "memory_operand" ""))
6696 (const_string "vector")]
6697 (const_string "direct")))
6698 (set_attr "bdver1_decode" "direct")
6699 (set_attr "mode" "<MODE>")])
6701 (define_insn "*mulsi3_1_zext"
6702 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6704 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6705 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6706 (clobber (reg:CC FLAGS_REG))]
6708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6711 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712 imul{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "imul")
6714 (set_attr "prefix_0f" "0,0,1")
6715 (set (attr "athlon_decode")
6716 (cond [(eq_attr "cpu" "athlon")
6717 (const_string "vector")
6718 (eq_attr "alternative" "1")
6719 (const_string "vector")
6720 (and (eq_attr "alternative" "2")
6721 (match_operand 1 "memory_operand" ""))
6722 (const_string "vector")]
6723 (const_string "direct")))
6724 (set (attr "amdfam10_decode")
6725 (cond [(and (eq_attr "alternative" "0,1")
6726 (match_operand 1 "memory_operand" ""))
6727 (const_string "vector")]
6728 (const_string "direct")))
6729 (set_attr "bdver1_decode" "direct")
6730 (set_attr "mode" "SI")])
6733 ;; IMUL reg16, reg16, imm8 VectorPath
6734 ;; IMUL reg16, mem16, imm8 VectorPath
6735 ;; IMUL reg16, reg16, imm16 VectorPath
6736 ;; IMUL reg16, mem16, imm16 VectorPath
6737 ;; IMUL reg16, reg16 Direct
6738 ;; IMUL reg16, mem16 Direct
6740 ;; On BDVER1, all HI MULs use DoublePath
6742 (define_insn "*mulhi3_1"
6743 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6744 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6745 (match_operand:HI 2 "general_operand" "K,n,mr")))
6746 (clobber (reg:CC FLAGS_REG))]
6748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6750 imul{w}\t{%2, %1, %0|%0, %1, %2}
6751 imul{w}\t{%2, %1, %0|%0, %1, %2}
6752 imul{w}\t{%2, %0|%0, %2}"
6753 [(set_attr "type" "imul")
6754 (set_attr "prefix_0f" "0,0,1")
6755 (set (attr "athlon_decode")
6756 (cond [(eq_attr "cpu" "athlon")
6757 (const_string "vector")
6758 (eq_attr "alternative" "1,2")
6759 (const_string "vector")]
6760 (const_string "direct")))
6761 (set (attr "amdfam10_decode")
6762 (cond [(eq_attr "alternative" "0,1")
6763 (const_string "vector")]
6764 (const_string "direct")))
6765 (set_attr "bdver1_decode" "double")
6766 (set_attr "mode" "HI")])
6768 ;;On AMDFAM10 and BDVER1
6772 (define_insn "*mulqi3_1"
6773 [(set (match_operand:QI 0 "register_operand" "=a")
6774 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6775 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6776 (clobber (reg:CC FLAGS_REG))]
6778 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780 [(set_attr "type" "imul")
6781 (set_attr "length_immediate" "0")
6782 (set (attr "athlon_decode")
6783 (if_then_else (eq_attr "cpu" "athlon")
6784 (const_string "vector")
6785 (const_string "direct")))
6786 (set_attr "amdfam10_decode" "direct")
6787 (set_attr "bdver1_decode" "direct")
6788 (set_attr "mode" "QI")])
6790 (define_expand "<u>mul<mode><dwi>3"
6791 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6794 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6796 (match_operand:DWIH 2 "register_operand" ""))))
6797 (clobber (reg:CC FLAGS_REG))])])
6799 (define_expand "<u>mulqihi3"
6800 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6803 (match_operand:QI 1 "nonimmediate_operand" ""))
6805 (match_operand:QI 2 "register_operand" ""))))
6806 (clobber (reg:CC FLAGS_REG))])]
6807 "TARGET_QIMODE_MATH")
6809 (define_insn "*bmi2_umulditi3_1"
6810 [(set (match_operand:DI 0 "register_operand" "=r")
6812 (match_operand:DI 2 "nonimmediate_operand" "%d")
6813 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6814 (set (match_operand:DI 1 "register_operand" "=r")
6817 (mult:TI (zero_extend:TI (match_dup 2))
6818 (zero_extend:TI (match_dup 3)))
6820 "TARGET_64BIT && TARGET_BMI2
6821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6822 "mulx\t{%3, %0, %1|%1, %0, %3}"
6823 [(set_attr "type" "imulx")
6824 (set_attr "prefix" "vex")
6825 (set_attr "mode" "DI")])
6827 (define_insn "*bmi2_umulsidi3_1"
6828 [(set (match_operand:SI 0 "register_operand" "=r")
6830 (match_operand:SI 2 "nonimmediate_operand" "%d")
6831 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6832 (set (match_operand:SI 1 "register_operand" "=r")
6835 (mult:DI (zero_extend:DI (match_dup 2))
6836 (zero_extend:DI (match_dup 3)))
6838 "!TARGET_64BIT && TARGET_BMI2
6839 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 "mulx\t{%3, %0, %1|%1, %0, %3}"
6841 [(set_attr "type" "imulx")
6842 (set_attr "prefix" "vex")
6843 (set_attr "mode" "SI")])
6845 (define_insn "*umul<mode><dwi>3_1"
6846 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6849 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6851 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6852 (clobber (reg:CC FLAGS_REG))]
6853 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 mul{<imodesuffix>}\t%2
6857 [(set_attr "isa" "*,bmi2")
6858 (set_attr "type" "imul,imulx")
6859 (set_attr "length_immediate" "0,*")
6860 (set (attr "athlon_decode")
6861 (cond [(eq_attr "alternative" "0")
6862 (if_then_else (eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (const_string "double"))]
6865 (const_string "*")))
6866 (set_attr "amdfam10_decode" "double,*")
6867 (set_attr "bdver1_decode" "direct,*")
6868 (set_attr "prefix" "orig,vex")
6869 (set_attr "mode" "<MODE>")])
6871 ;; Convert mul to the mulx pattern to avoid flags dependency.
6873 [(set (match_operand:<DWI> 0 "register_operand" "")
6876 (match_operand:DWIH 1 "register_operand" ""))
6878 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6879 (clobber (reg:CC FLAGS_REG))]
6880 "TARGET_BMI2 && reload_completed
6881 && true_regnum (operands[1]) == DX_REG"
6882 [(parallel [(set (match_dup 3)
6883 (mult:DWIH (match_dup 1) (match_dup 2)))
6887 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6888 (zero_extend:<DWI> (match_dup 2)))
6891 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6893 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6896 (define_insn "*mul<mode><dwi>3_1"
6897 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6900 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6902 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6903 (clobber (reg:CC FLAGS_REG))]
6904 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6905 "imul{<imodesuffix>}\t%2"
6906 [(set_attr "type" "imul")
6907 (set_attr "length_immediate" "0")
6908 (set (attr "athlon_decode")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "double")))
6912 (set_attr "amdfam10_decode" "double")
6913 (set_attr "bdver1_decode" "direct")
6914 (set_attr "mode" "<MODE>")])
6916 (define_insn "*<u>mulqihi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=a")
6920 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6922 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6923 (clobber (reg:CC FLAGS_REG))]
6925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926 "<sgnprefix>mul{b}\t%2"
6927 [(set_attr "type" "imul")
6928 (set_attr "length_immediate" "0")
6929 (set (attr "athlon_decode")
6930 (if_then_else (eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (const_string "direct")))
6933 (set_attr "amdfam10_decode" "direct")
6934 (set_attr "bdver1_decode" "direct")
6935 (set_attr "mode" "QI")])
6937 (define_expand "<s>mul<mode>3_highpart"
6938 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6943 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6945 (match_operand:SWI48 2 "register_operand" "")))
6947 (clobber (match_scratch:SWI48 3 ""))
6948 (clobber (reg:CC FLAGS_REG))])]
6950 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6952 (define_insn "*<s>muldi3_highpart_1"
6953 [(set (match_operand:DI 0 "register_operand" "=d")
6958 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6960 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6962 (clobber (match_scratch:DI 3 "=1"))
6963 (clobber (reg:CC FLAGS_REG))]
6965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 "<sgnprefix>mul{q}\t%2"
6967 [(set_attr "type" "imul")
6968 (set_attr "length_immediate" "0")
6969 (set (attr "athlon_decode")
6970 (if_then_else (eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (const_string "double")))
6973 (set_attr "amdfam10_decode" "double")
6974 (set_attr "bdver1_decode" "direct")
6975 (set_attr "mode" "DI")])
6977 (define_insn "*<s>mulsi3_highpart_1"
6978 [(set (match_operand:SI 0 "register_operand" "=d")
6983 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6985 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6987 (clobber (match_scratch:SI 3 "=1"))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 "<sgnprefix>mul{l}\t%2"
6991 [(set_attr "type" "imul")
6992 (set_attr "length_immediate" "0")
6993 (set (attr "athlon_decode")
6994 (if_then_else (eq_attr "cpu" "athlon")
6995 (const_string "vector")
6996 (const_string "double")))
6997 (set_attr "amdfam10_decode" "double")
6998 (set_attr "bdver1_decode" "direct")
6999 (set_attr "mode" "SI")])
7001 (define_insn "*<s>mulsi3_highpart_zext"
7002 [(set (match_operand:DI 0 "register_operand" "=d")
7003 (zero_extend:DI (truncate:SI
7005 (mult:DI (any_extend:DI
7006 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7008 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7010 (clobber (match_scratch:SI 3 "=1"))
7011 (clobber (reg:CC FLAGS_REG))]
7013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014 "<sgnprefix>mul{l}\t%2"
7015 [(set_attr "type" "imul")
7016 (set_attr "length_immediate" "0")
7017 (set (attr "athlon_decode")
7018 (if_then_else (eq_attr "cpu" "athlon")
7019 (const_string "vector")
7020 (const_string "double")))
7021 (set_attr "amdfam10_decode" "double")
7022 (set_attr "bdver1_decode" "direct")
7023 (set_attr "mode" "SI")])
7025 ;; The patterns that match these are at the end of this file.
7027 (define_expand "mulxf3"
7028 [(set (match_operand:XF 0 "register_operand" "")
7029 (mult:XF (match_operand:XF 1 "register_operand" "")
7030 (match_operand:XF 2 "register_operand" "")))]
7033 (define_expand "mul<mode>3"
7034 [(set (match_operand:MODEF 0 "register_operand" "")
7035 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7036 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7037 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7038 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7040 ;; Divide instructions
7042 ;; The patterns that match these are at the end of this file.
7044 (define_expand "divxf3"
7045 [(set (match_operand:XF 0 "register_operand" "")
7046 (div:XF (match_operand:XF 1 "register_operand" "")
7047 (match_operand:XF 2 "register_operand" "")))]
7050 (define_expand "divdf3"
7051 [(set (match_operand:DF 0 "register_operand" "")
7052 (div:DF (match_operand:DF 1 "register_operand" "")
7053 (match_operand:DF 2 "nonimmediate_operand" "")))]
7054 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7055 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7057 (define_expand "divsf3"
7058 [(set (match_operand:SF 0 "register_operand" "")
7059 (div:SF (match_operand:SF 1 "register_operand" "")
7060 (match_operand:SF 2 "nonimmediate_operand" "")))]
7061 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7066 && optimize_insn_for_speed_p ()
7067 && flag_finite_math_only && !flag_trapping_math
7068 && flag_unsafe_math_optimizations)
7070 ix86_emit_swdivsf (operands[0], operands[1],
7071 operands[2], SFmode);
7076 ;; Divmod instructions.
7078 (define_expand "divmod<mode>4"
7079 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7081 (match_operand:SWIM248 1 "register_operand" "")
7082 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7083 (set (match_operand:SWIM248 3 "register_operand" "")
7084 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7085 (clobber (reg:CC FLAGS_REG))])])
7087 ;; Split with 8bit unsigned divide:
7088 ;; if (dividend an divisor are in [0-255])
7089 ;; use 8bit unsigned integer divide
7091 ;; use original integer divide
7093 [(set (match_operand:SWI48 0 "register_operand" "")
7094 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7095 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7096 (set (match_operand:SWI48 1 "register_operand" "")
7097 (mod:SWI48 (match_dup 2) (match_dup 3)))
7098 (clobber (reg:CC FLAGS_REG))]
7099 "TARGET_USE_8BIT_IDIV
7100 && TARGET_QIMODE_MATH
7101 && can_create_pseudo_p ()
7102 && !optimize_insn_for_size_p ()"
7104 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7106 (define_insn_and_split "divmod<mode>4_1"
7107 [(set (match_operand:SWI48 0 "register_operand" "=a")
7108 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7109 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7110 (set (match_operand:SWI48 1 "register_operand" "=&d")
7111 (mod:SWI48 (match_dup 2) (match_dup 3)))
7112 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7113 (clobber (reg:CC FLAGS_REG))]
7117 [(parallel [(set (match_dup 1)
7118 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7119 (clobber (reg:CC FLAGS_REG))])
7120 (parallel [(set (match_dup 0)
7121 (div:SWI48 (match_dup 2) (match_dup 3)))
7123 (mod:SWI48 (match_dup 2) (match_dup 3)))
7125 (clobber (reg:CC FLAGS_REG))])]
7127 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7129 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7130 operands[4] = operands[2];
7133 /* Avoid use of cltd in favor of a mov+shift. */
7134 emit_move_insn (operands[1], operands[2]);
7135 operands[4] = operands[1];
7138 [(set_attr "type" "multi")
7139 (set_attr "mode" "<MODE>")])
7141 (define_insn_and_split "*divmod<mode>4"
7142 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7143 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7144 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7145 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7146 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))]
7151 [(parallel [(set (match_dup 1)
7152 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7153 (clobber (reg:CC FLAGS_REG))])
7154 (parallel [(set (match_dup 0)
7155 (div:SWIM248 (match_dup 2) (match_dup 3)))
7157 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7159 (clobber (reg:CC FLAGS_REG))])]
7161 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7163 if (<MODE>mode != HImode
7164 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7165 operands[4] = operands[2];
7168 /* Avoid use of cltd in favor of a mov+shift. */
7169 emit_move_insn (operands[1], operands[2]);
7170 operands[4] = operands[1];
7173 [(set_attr "type" "multi")
7174 (set_attr "mode" "<MODE>")])
7176 (define_insn "*divmod<mode>4_noext"
7177 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7178 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7179 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7180 (set (match_operand:SWIM248 1 "register_operand" "=d")
7181 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7182 (use (match_operand:SWIM248 4 "register_operand" "1"))
7183 (clobber (reg:CC FLAGS_REG))]
7185 "idiv{<imodesuffix>}\t%3"
7186 [(set_attr "type" "idiv")
7187 (set_attr "mode" "<MODE>")])
7189 (define_expand "divmodqi4"
7190 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7192 (match_operand:QI 1 "register_operand" "")
7193 (match_operand:QI 2 "nonimmediate_operand" "")))
7194 (set (match_operand:QI 3 "register_operand" "")
7195 (mod:QI (match_dup 1) (match_dup 2)))
7196 (clobber (reg:CC FLAGS_REG))])]
7197 "TARGET_QIMODE_MATH"
7202 tmp0 = gen_reg_rtx (HImode);
7203 tmp1 = gen_reg_rtx (HImode);
7205 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7207 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7208 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7210 /* Extract remainder from AH. */
7211 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7212 insn = emit_move_insn (operands[3], tmp1);
7214 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7215 set_unique_reg_note (insn, REG_EQUAL, mod);
7217 /* Extract quotient from AL. */
7218 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7220 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7221 set_unique_reg_note (insn, REG_EQUAL, div);
7226 ;; Divide AX by r/m8, with result stored in
7229 ;; Change div/mod to HImode and extend the second argument to HImode
7230 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7231 ;; combine may fail.
7232 (define_insn "divmodhiqi3"
7233 [(set (match_operand:HI 0 "register_operand" "=a")
7238 (mod:HI (match_operand:HI 1 "register_operand" "0")
7240 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7244 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_QIMODE_MATH"
7248 [(set_attr "type" "idiv")
7249 (set_attr "mode" "QI")])
7251 (define_expand "udivmod<mode>4"
7252 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7254 (match_operand:SWIM248 1 "register_operand" "")
7255 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7256 (set (match_operand:SWIM248 3 "register_operand" "")
7257 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7258 (clobber (reg:CC FLAGS_REG))])])
7260 ;; Split with 8bit unsigned divide:
7261 ;; if (dividend an divisor are in [0-255])
7262 ;; use 8bit unsigned integer divide
7264 ;; use original integer divide
7266 [(set (match_operand:SWI48 0 "register_operand" "")
7267 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7268 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7269 (set (match_operand:SWI48 1 "register_operand" "")
7270 (umod:SWI48 (match_dup 2) (match_dup 3)))
7271 (clobber (reg:CC FLAGS_REG))]
7272 "TARGET_USE_8BIT_IDIV
7273 && TARGET_QIMODE_MATH
7274 && can_create_pseudo_p ()
7275 && !optimize_insn_for_size_p ()"
7277 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7279 (define_insn_and_split "udivmod<mode>4_1"
7280 [(set (match_operand:SWI48 0 "register_operand" "=a")
7281 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7282 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWI48 1 "register_operand" "=&d")
7284 (umod:SWI48 (match_dup 2) (match_dup 3)))
7285 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7286 (clobber (reg:CC FLAGS_REG))]
7290 [(set (match_dup 1) (const_int 0))
7291 (parallel [(set (match_dup 0)
7292 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7294 (umod:SWI48 (match_dup 2) (match_dup 3)))
7296 (clobber (reg:CC FLAGS_REG))])]
7298 [(set_attr "type" "multi")
7299 (set_attr "mode" "<MODE>")])
7301 (define_insn_and_split "*udivmod<mode>4"
7302 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7303 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7304 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7305 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7306 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7307 (clobber (reg:CC FLAGS_REG))]
7311 [(set (match_dup 1) (const_int 0))
7312 (parallel [(set (match_dup 0)
7313 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7315 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7317 (clobber (reg:CC FLAGS_REG))])]
7319 [(set_attr "type" "multi")
7320 (set_attr "mode" "<MODE>")])
7322 (define_insn "*udivmod<mode>4_noext"
7323 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7324 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7325 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7326 (set (match_operand:SWIM248 1 "register_operand" "=d")
7327 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7328 (use (match_operand:SWIM248 4 "register_operand" "1"))
7329 (clobber (reg:CC FLAGS_REG))]
7331 "div{<imodesuffix>}\t%3"
7332 [(set_attr "type" "idiv")
7333 (set_attr "mode" "<MODE>")])
7335 (define_expand "udivmodqi4"
7336 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7338 (match_operand:QI 1 "register_operand" "")
7339 (match_operand:QI 2 "nonimmediate_operand" "")))
7340 (set (match_operand:QI 3 "register_operand" "")
7341 (umod:QI (match_dup 1) (match_dup 2)))
7342 (clobber (reg:CC FLAGS_REG))])]
7343 "TARGET_QIMODE_MATH"
7348 tmp0 = gen_reg_rtx (HImode);
7349 tmp1 = gen_reg_rtx (HImode);
7351 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7353 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7354 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7356 /* Extract remainder from AH. */
7357 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7358 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7359 insn = emit_move_insn (operands[3], tmp1);
7361 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7362 set_unique_reg_note (insn, REG_EQUAL, mod);
7364 /* Extract quotient from AL. */
7365 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7367 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7368 set_unique_reg_note (insn, REG_EQUAL, div);
7373 (define_insn "udivmodhiqi3"
7374 [(set (match_operand:HI 0 "register_operand" "=a")
7379 (mod:HI (match_operand:HI 1 "register_operand" "0")
7381 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7385 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "TARGET_QIMODE_MATH"
7389 [(set_attr "type" "idiv")
7390 (set_attr "mode" "QI")])
7392 ;; We cannot use div/idiv for double division, because it causes
7393 ;; "division by zero" on the overflow and that's not what we expect
7394 ;; from truncate. Because true (non truncating) double division is
7395 ;; never generated, we can't create this insn anyway.
7398 ; [(set (match_operand:SI 0 "register_operand" "=a")
7400 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7402 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7403 ; (set (match_operand:SI 3 "register_operand" "=d")
7405 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7406 ; (clobber (reg:CC FLAGS_REG))]
7408 ; "div{l}\t{%2, %0|%0, %2}"
7409 ; [(set_attr "type" "idiv")])
7411 ;;- Logical AND instructions
7413 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7414 ;; Note that this excludes ah.
7416 (define_expand "testsi_ccno_1"
7417 [(set (reg:CCNO FLAGS_REG)
7419 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7420 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7423 (define_expand "testqi_ccz_1"
7424 [(set (reg:CCZ FLAGS_REG)
7425 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7426 (match_operand:QI 1 "nonmemory_operand" ""))
7429 (define_expand "testdi_ccno_1"
7430 [(set (reg:CCNO FLAGS_REG)
7432 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7433 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7435 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7437 (define_insn "*testdi_1"
7438 [(set (reg FLAGS_REG)
7441 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7442 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7445 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447 test{l}\t{%k1, %k0|%k0, %k1}
7448 test{l}\t{%k1, %k0|%k0, %k1}
7449 test{q}\t{%1, %0|%0, %1}
7450 test{q}\t{%1, %0|%0, %1}
7451 test{q}\t{%1, %0|%0, %1}"
7452 [(set_attr "type" "test")
7453 (set_attr "modrm" "0,1,0,1,1")
7454 (set_attr "mode" "SI,SI,DI,DI,DI")])
7456 (define_insn "*testqi_1_maybe_si"
7457 [(set (reg FLAGS_REG)
7460 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7461 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7463 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7464 && ix86_match_ccmode (insn,
7465 CONST_INT_P (operands[1])
7466 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7468 if (which_alternative == 3)
7470 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7471 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7472 return "test{l}\t{%1, %k0|%k0, %1}";
7474 return "test{b}\t{%1, %0|%0, %1}";
7476 [(set_attr "type" "test")
7477 (set_attr "modrm" "0,1,1,1")
7478 (set_attr "mode" "QI,QI,QI,SI")
7479 (set_attr "pent_pair" "uv,np,uv,np")])
7481 (define_insn "*test<mode>_1"
7482 [(set (reg FLAGS_REG)
7485 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7486 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7488 "ix86_match_ccmode (insn, CCNOmode)
7489 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7490 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7491 [(set_attr "type" "test")
7492 (set_attr "modrm" "0,1,1")
7493 (set_attr "mode" "<MODE>")
7494 (set_attr "pent_pair" "uv,np,uv")])
7496 (define_expand "testqi_ext_ccno_0"
7497 [(set (reg:CCNO FLAGS_REG)
7501 (match_operand 0 "ext_register_operand" "")
7504 (match_operand 1 "const_int_operand" ""))
7507 (define_insn "*testqi_ext_0"
7508 [(set (reg FLAGS_REG)
7512 (match_operand 0 "ext_register_operand" "Q")
7515 (match_operand 1 "const_int_operand" "n"))
7517 "ix86_match_ccmode (insn, CCNOmode)"
7518 "test{b}\t{%1, %h0|%h0, %1}"
7519 [(set_attr "type" "test")
7520 (set_attr "mode" "QI")
7521 (set_attr "length_immediate" "1")
7522 (set_attr "modrm" "1")
7523 (set_attr "pent_pair" "np")])
7525 (define_insn "*testqi_ext_1_rex64"
7526 [(set (reg FLAGS_REG)
7530 (match_operand 0 "ext_register_operand" "Q")
7534 (match_operand:QI 1 "register_operand" "Q")))
7536 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537 "test{b}\t{%1, %h0|%h0, %1}"
7538 [(set_attr "type" "test")
7539 (set_attr "mode" "QI")])
7541 (define_insn "*testqi_ext_1"
7542 [(set (reg FLAGS_REG)
7546 (match_operand 0 "ext_register_operand" "Q")
7550 (match_operand:QI 1 "general_operand" "Qm")))
7552 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7553 "test{b}\t{%1, %h0|%h0, %1}"
7554 [(set_attr "type" "test")
7555 (set_attr "mode" "QI")])
7557 (define_insn "*testqi_ext_2"
7558 [(set (reg FLAGS_REG)
7562 (match_operand 0 "ext_register_operand" "Q")
7566 (match_operand 1 "ext_register_operand" "Q")
7570 "ix86_match_ccmode (insn, CCNOmode)"
7571 "test{b}\t{%h1, %h0|%h0, %h1}"
7572 [(set_attr "type" "test")
7573 (set_attr "mode" "QI")])
7575 (define_insn "*testqi_ext_3_rex64"
7576 [(set (reg FLAGS_REG)
7577 (compare (zero_extract:DI
7578 (match_operand 0 "nonimmediate_operand" "rm")
7579 (match_operand:DI 1 "const_int_operand" "")
7580 (match_operand:DI 2 "const_int_operand" ""))
7583 && ix86_match_ccmode (insn, CCNOmode)
7584 && INTVAL (operands[1]) > 0
7585 && INTVAL (operands[2]) >= 0
7586 /* Ensure that resulting mask is zero or sign extended operand. */
7587 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7588 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7589 && INTVAL (operands[1]) > 32))
7590 && (GET_MODE (operands[0]) == SImode
7591 || GET_MODE (operands[0]) == DImode
7592 || GET_MODE (operands[0]) == HImode
7593 || GET_MODE (operands[0]) == QImode)"
7596 ;; Combine likes to form bit extractions for some tests. Humor it.
7597 (define_insn "*testqi_ext_3"
7598 [(set (reg FLAGS_REG)
7599 (compare (zero_extract:SI
7600 (match_operand 0 "nonimmediate_operand" "rm")
7601 (match_operand:SI 1 "const_int_operand" "")
7602 (match_operand:SI 2 "const_int_operand" ""))
7604 "ix86_match_ccmode (insn, CCNOmode)
7605 && INTVAL (operands[1]) > 0
7606 && INTVAL (operands[2]) >= 0
7607 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7608 && (GET_MODE (operands[0]) == SImode
7609 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7610 || GET_MODE (operands[0]) == HImode
7611 || GET_MODE (operands[0]) == QImode)"
7615 [(set (match_operand 0 "flags_reg_operand" "")
7616 (match_operator 1 "compare_operator"
7618 (match_operand 2 "nonimmediate_operand" "")
7619 (match_operand 3 "const_int_operand" "")
7620 (match_operand 4 "const_int_operand" ""))
7622 "ix86_match_ccmode (insn, CCNOmode)"
7623 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7625 rtx val = operands[2];
7626 HOST_WIDE_INT len = INTVAL (operands[3]);
7627 HOST_WIDE_INT pos = INTVAL (operands[4]);
7629 enum machine_mode mode, submode;
7631 mode = GET_MODE (val);
7634 /* ??? Combine likes to put non-volatile mem extractions in QImode
7635 no matter the size of the test. So find a mode that works. */
7636 if (! MEM_VOLATILE_P (val))
7638 mode = smallest_mode_for_size (pos + len, MODE_INT);
7639 val = adjust_address (val, mode, 0);
7642 else if (GET_CODE (val) == SUBREG
7643 && (submode = GET_MODE (SUBREG_REG (val)),
7644 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7645 && pos + len <= GET_MODE_BITSIZE (submode)
7646 && GET_MODE_CLASS (submode) == MODE_INT)
7648 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7650 val = SUBREG_REG (val);
7652 else if (mode == HImode && pos + len <= 8)
7654 /* Small HImode tests can be converted to QImode. */
7656 val = gen_lowpart (QImode, val);
7659 if (len == HOST_BITS_PER_WIDE_INT)
7662 mask = ((HOST_WIDE_INT)1 << len) - 1;
7665 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7668 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7669 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7670 ;; this is relatively important trick.
7671 ;; Do the conversion only post-reload to avoid limiting of the register class
7674 [(set (match_operand 0 "flags_reg_operand" "")
7675 (match_operator 1 "compare_operator"
7676 [(and (match_operand 2 "register_operand" "")
7677 (match_operand 3 "const_int_operand" ""))
7680 && QI_REG_P (operands[2])
7681 && GET_MODE (operands[2]) != QImode
7682 && ((ix86_match_ccmode (insn, CCZmode)
7683 && !(INTVAL (operands[3]) & ~(255 << 8)))
7684 || (ix86_match_ccmode (insn, CCNOmode)
7685 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7688 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7691 "operands[2] = gen_lowpart (SImode, operands[2]);
7692 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7695 [(set (match_operand 0 "flags_reg_operand" "")
7696 (match_operator 1 "compare_operator"
7697 [(and (match_operand 2 "nonimmediate_operand" "")
7698 (match_operand 3 "const_int_operand" ""))
7701 && GET_MODE (operands[2]) != QImode
7702 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7703 && ((ix86_match_ccmode (insn, CCZmode)
7704 && !(INTVAL (operands[3]) & ~255))
7705 || (ix86_match_ccmode (insn, CCNOmode)
7706 && !(INTVAL (operands[3]) & ~127)))"
7708 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7710 "operands[2] = gen_lowpart (QImode, operands[2]);
7711 operands[3] = gen_lowpart (QImode, operands[3]);")
7713 ;; %%% This used to optimize known byte-wide and operations to memory,
7714 ;; and sometimes to QImode registers. If this is considered useful,
7715 ;; it should be done with splitters.
7717 (define_expand "and<mode>3"
7718 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7719 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7720 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7722 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7724 (define_insn "*anddi_1"
7725 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7727 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7728 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7729 (clobber (reg:CC FLAGS_REG))]
7730 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7732 switch (get_attr_type (insn))
7736 enum machine_mode mode;
7738 gcc_assert (CONST_INT_P (operands[2]));
7739 if (INTVAL (operands[2]) == 0xff)
7743 gcc_assert (INTVAL (operands[2]) == 0xffff);
7747 operands[1] = gen_lowpart (mode, operands[1]);
7749 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7751 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7756 if (get_attr_mode (insn) == MODE_SI)
7757 return "and{l}\t{%k2, %k0|%k0, %k2}";
7759 return "and{q}\t{%2, %0|%0, %2}";
7762 [(set_attr "type" "alu,alu,alu,imovx")
7763 (set_attr "length_immediate" "*,*,*,0")
7764 (set (attr "prefix_rex")
7766 (and (eq_attr "type" "imovx")
7767 (and (match_test "INTVAL (operands[2]) == 0xff")
7768 (match_operand 1 "ext_QIreg_operand" "")))
7770 (const_string "*")))
7771 (set_attr "mode" "SI,DI,DI,SI")])
7773 (define_insn "*andsi_1"
7774 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7775 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7776 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7777 (clobber (reg:CC FLAGS_REG))]
7778 "ix86_binary_operator_ok (AND, SImode, operands)"
7780 switch (get_attr_type (insn))
7784 enum machine_mode mode;
7786 gcc_assert (CONST_INT_P (operands[2]));
7787 if (INTVAL (operands[2]) == 0xff)
7791 gcc_assert (INTVAL (operands[2]) == 0xffff);
7795 operands[1] = gen_lowpart (mode, operands[1]);
7797 return "movz{bl|x}\t{%1, %0|%0, %1}";
7799 return "movz{wl|x}\t{%1, %0|%0, %1}";
7803 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7804 return "and{l}\t{%2, %0|%0, %2}";
7807 [(set_attr "type" "alu,alu,imovx")
7808 (set (attr "prefix_rex")
7810 (and (eq_attr "type" "imovx")
7811 (and (match_test "INTVAL (operands[2]) == 0xff")
7812 (match_operand 1 "ext_QIreg_operand" "")))
7814 (const_string "*")))
7815 (set_attr "length_immediate" "*,*,0")
7816 (set_attr "mode" "SI")])
7818 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7819 (define_insn "*andsi_1_zext"
7820 [(set (match_operand:DI 0 "register_operand" "=r")
7822 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7823 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7826 "and{l}\t{%2, %k0|%k0, %2}"
7827 [(set_attr "type" "alu")
7828 (set_attr "mode" "SI")])
7830 (define_insn "*andhi_1"
7831 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7832 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7833 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7834 (clobber (reg:CC FLAGS_REG))]
7835 "ix86_binary_operator_ok (AND, HImode, operands)"
7837 switch (get_attr_type (insn))
7840 gcc_assert (CONST_INT_P (operands[2]));
7841 gcc_assert (INTVAL (operands[2]) == 0xff);
7842 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847 return "and{w}\t{%2, %0|%0, %2}";
7850 [(set_attr "type" "alu,alu,imovx")
7851 (set_attr "length_immediate" "*,*,0")
7852 (set (attr "prefix_rex")
7854 (and (eq_attr "type" "imovx")
7855 (match_operand 1 "ext_QIreg_operand" ""))
7857 (const_string "*")))
7858 (set_attr "mode" "HI,HI,SI")])
7860 ;; %%% Potential partial reg stall on alternative 2. What to do?
7861 (define_insn "*andqi_1"
7862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7863 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7864 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "ix86_binary_operator_ok (AND, QImode, operands)"
7868 and{b}\t{%2, %0|%0, %2}
7869 and{b}\t{%2, %0|%0, %2}
7870 and{l}\t{%k2, %k0|%k0, %k2}"
7871 [(set_attr "type" "alu")
7872 (set_attr "mode" "QI,QI,SI")])
7874 (define_insn "*andqi_1_slp"
7875 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7876 (and:QI (match_dup 0)
7877 (match_operand:QI 1 "general_operand" "qn,qmn")))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7881 "and{b}\t{%1, %0|%0, %1}"
7882 [(set_attr "type" "alu1")
7883 (set_attr "mode" "QI")])
7886 [(set (match_operand 0 "register_operand" "")
7888 (const_int -65536)))
7889 (clobber (reg:CC FLAGS_REG))]
7890 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7891 || optimize_function_for_size_p (cfun)"
7892 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7893 "operands[1] = gen_lowpart (HImode, operands[0]);")
7896 [(set (match_operand 0 "ext_register_operand" "")
7899 (clobber (reg:CC FLAGS_REG))]
7900 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901 && reload_completed"
7902 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7903 "operands[1] = gen_lowpart (QImode, operands[0]);")
7906 [(set (match_operand 0 "ext_register_operand" "")
7908 (const_int -65281)))
7909 (clobber (reg:CC FLAGS_REG))]
7910 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7911 && reload_completed"
7912 [(parallel [(set (zero_extract:SI (match_dup 0)
7916 (zero_extract:SI (match_dup 0)
7919 (zero_extract:SI (match_dup 0)
7922 (clobber (reg:CC FLAGS_REG))])]
7923 "operands[0] = gen_lowpart (SImode, operands[0]);")
7925 (define_insn "*anddi_2"
7926 [(set (reg FLAGS_REG)
7929 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7930 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7932 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7933 (and:DI (match_dup 1) (match_dup 2)))]
7934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7935 && ix86_binary_operator_ok (AND, DImode, operands)"
7937 and{l}\t{%k2, %k0|%k0, %k2}
7938 and{q}\t{%2, %0|%0, %2}
7939 and{q}\t{%2, %0|%0, %2}"
7940 [(set_attr "type" "alu")
7941 (set_attr "mode" "SI,DI,DI")])
7943 (define_insn "*andqi_2_maybe_si"
7944 [(set (reg FLAGS_REG)
7946 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7949 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7950 (and:QI (match_dup 1) (match_dup 2)))]
7951 "ix86_binary_operator_ok (AND, QImode, operands)
7952 && ix86_match_ccmode (insn,
7953 CONST_INT_P (operands[2])
7954 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956 if (which_alternative == 2)
7958 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7959 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7960 return "and{l}\t{%2, %k0|%k0, %2}";
7962 return "and{b}\t{%2, %0|%0, %2}";
7964 [(set_attr "type" "alu")
7965 (set_attr "mode" "QI,QI,SI")])
7967 (define_insn "*and<mode>_2"
7968 [(set (reg FLAGS_REG)
7969 (compare (and:SWI124
7970 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7971 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7973 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7974 (and:SWI124 (match_dup 1) (match_dup 2)))]
7975 "ix86_match_ccmode (insn, CCNOmode)
7976 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7977 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "<MODE>")])
7981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7982 (define_insn "*andsi_2_zext"
7983 [(set (reg FLAGS_REG)
7985 (match_operand:SI 1 "nonimmediate_operand" "%0")
7986 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7988 (set (match_operand:DI 0 "register_operand" "=r")
7989 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7991 && ix86_binary_operator_ok (AND, SImode, operands)"
7992 "and{l}\t{%2, %k0|%k0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "SI")])
7996 (define_insn "*andqi_2_slp"
7997 [(set (reg FLAGS_REG)
7999 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8002 (set (strict_low_part (match_dup 0))
8003 (and:QI (match_dup 0) (match_dup 1)))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "and{b}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "alu1")
8009 (set_attr "mode" "QI")])
8011 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8012 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8013 ;; for a QImode operand, which of course failed.
8014 (define_insn "andqi_ext_0"
8015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8020 (match_operand 1 "ext_register_operand" "0")
8023 (match_operand 2 "const_int_operand" "n")))
8024 (clobber (reg:CC FLAGS_REG))]
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "1")
8029 (set_attr "modrm" "1")
8030 (set_attr "mode" "QI")])
8032 ;; Generated by peephole translating test to and. This shows up
8033 ;; often in fp comparisons.
8034 (define_insn "*andqi_ext_0_cc"
8035 [(set (reg FLAGS_REG)
8039 (match_operand 1 "ext_register_operand" "0")
8042 (match_operand 2 "const_int_operand" "n"))
8044 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053 "ix86_match_ccmode (insn, CCNOmode)"
8054 "and{b}\t{%2, %h0|%h0, %2}"
8055 [(set_attr "type" "alu")
8056 (set_attr "length_immediate" "1")
8057 (set_attr "modrm" "1")
8058 (set_attr "mode" "QI")])
8060 (define_insn "*andqi_ext_1_rex64"
8061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8066 (match_operand 1 "ext_register_operand" "0")
8070 (match_operand 2 "ext_register_operand" "Q"))))
8071 (clobber (reg:CC FLAGS_REG))]
8073 "and{b}\t{%2, %h0|%h0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "length_immediate" "0")
8076 (set_attr "mode" "QI")])
8078 (define_insn "*andqi_ext_1"
8079 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8084 (match_operand 1 "ext_register_operand" "0")
8088 (match_operand:QI 2 "general_operand" "Qm"))))
8089 (clobber (reg:CC FLAGS_REG))]
8091 "and{b}\t{%2, %h0|%h0, %2}"
8092 [(set_attr "type" "alu")
8093 (set_attr "length_immediate" "0")
8094 (set_attr "mode" "QI")])
8096 (define_insn "*andqi_ext_2"
8097 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8102 (match_operand 1 "ext_register_operand" "%0")
8106 (match_operand 2 "ext_register_operand" "Q")
8109 (clobber (reg:CC FLAGS_REG))]
8111 "and{b}\t{%h2, %h0|%h0, %h2}"
8112 [(set_attr "type" "alu")
8113 (set_attr "length_immediate" "0")
8114 (set_attr "mode" "QI")])
8116 ;; Convert wide AND instructions with immediate operand to shorter QImode
8117 ;; equivalents when possible.
8118 ;; Don't do the splitting with memory operands, since it introduces risk
8119 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8120 ;; for size, but that can (should?) be handled by generic code instead.
8122 [(set (match_operand 0 "register_operand" "")
8123 (and (match_operand 1 "register_operand" "")
8124 (match_operand 2 "const_int_operand" "")))
8125 (clobber (reg:CC FLAGS_REG))]
8127 && QI_REG_P (operands[0])
8128 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8129 && !(~INTVAL (operands[2]) & ~(255 << 8))
8130 && GET_MODE (operands[0]) != QImode"
8131 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8132 (and:SI (zero_extract:SI (match_dup 1)
8133 (const_int 8) (const_int 8))
8135 (clobber (reg:CC FLAGS_REG))])]
8136 "operands[0] = gen_lowpart (SImode, operands[0]);
8137 operands[1] = gen_lowpart (SImode, operands[1]);
8138 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8140 ;; Since AND can be encoded with sign extended immediate, this is only
8141 ;; profitable when 7th bit is not set.
8143 [(set (match_operand 0 "register_operand" "")
8144 (and (match_operand 1 "general_operand" "")
8145 (match_operand 2 "const_int_operand" "")))
8146 (clobber (reg:CC FLAGS_REG))]
8148 && ANY_QI_REG_P (operands[0])
8149 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8150 && !(~INTVAL (operands[2]) & ~255)
8151 && !(INTVAL (operands[2]) & 128)
8152 && GET_MODE (operands[0]) != QImode"
8153 [(parallel [(set (strict_low_part (match_dup 0))
8154 (and:QI (match_dup 1)
8156 (clobber (reg:CC FLAGS_REG))])]
8157 "operands[0] = gen_lowpart (QImode, operands[0]);
8158 operands[1] = gen_lowpart (QImode, operands[1]);
8159 operands[2] = gen_lowpart (QImode, operands[2]);")
8161 ;; Logical inclusive and exclusive OR instructions
8163 ;; %%% This used to optimize known byte-wide and operations to memory.
8164 ;; If this is considered useful, it should be done with splitters.
8166 (define_expand "<code><mode>3"
8167 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8168 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8169 (match_operand:SWIM 2 "<general_operand>" "")))]
8171 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8173 (define_insn "*<code><mode>_1"
8174 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8176 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8177 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8178 (clobber (reg:CC FLAGS_REG))]
8179 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8180 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "mode" "<MODE>")])
8184 ;; %%% Potential partial reg stall on alternative 2. What to do?
8185 (define_insn "*<code>qi_1"
8186 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8187 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8188 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8192 <logic>{b}\t{%2, %0|%0, %2}
8193 <logic>{b}\t{%2, %0|%0, %2}
8194 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "mode" "QI,QI,SI")])
8198 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8199 (define_insn "*<code>si_1_zext"
8200 [(set (match_operand:DI 0 "register_operand" "=r")
8202 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8203 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206 "<logic>{l}\t{%2, %k0|%k0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "SI")])
8210 (define_insn "*<code>si_1_zext_imm"
8211 [(set (match_operand:DI 0 "register_operand" "=r")
8213 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8214 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
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>qi_1_slp"
8222 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8223 (any_or:QI (match_dup 0)
8224 (match_operand:QI 1 "general_operand" "qmn,qn")))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228 "<logic>{b}\t{%1, %0|%0, %1}"
8229 [(set_attr "type" "alu1")
8230 (set_attr "mode" "QI")])
8232 (define_insn "*<code><mode>_2"
8233 [(set (reg FLAGS_REG)
8234 (compare (any_or:SWI
8235 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8236 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8238 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8239 (any_or:SWI (match_dup 1) (match_dup 2)))]
8240 "ix86_match_ccmode (insn, CCNOmode)
8241 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8242 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "<MODE>")])
8246 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8247 ;; ??? Special case for immediate operand is missing - it is tricky.
8248 (define_insn "*<code>si_2_zext"
8249 [(set (reg FLAGS_REG)
8250 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8251 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8253 (set (match_operand:DI 0 "register_operand" "=r")
8254 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8255 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8257 "<logic>{l}\t{%2, %k0|%k0, %2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "SI")])
8261 (define_insn "*<code>si_2_zext_imm"
8262 [(set (reg FLAGS_REG)
8264 (match_operand:SI 1 "nonimmediate_operand" "%0")
8265 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8267 (set (match_operand:DI 0 "register_operand" "=r")
8268 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8269 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8270 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8271 "<logic>{l}\t{%2, %k0|%k0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "mode" "SI")])
8275 (define_insn "*<code>qi_2_slp"
8276 [(set (reg FLAGS_REG)
8277 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8278 (match_operand:QI 1 "general_operand" "qmn,qn"))
8280 (set (strict_low_part (match_dup 0))
8281 (any_or:QI (match_dup 0) (match_dup 1)))]
8282 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8283 && ix86_match_ccmode (insn, CCNOmode)
8284 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8285 "<logic>{b}\t{%1, %0|%0, %1}"
8286 [(set_attr "type" "alu1")
8287 (set_attr "mode" "QI")])
8289 (define_insn "*<code><mode>_3"
8290 [(set (reg FLAGS_REG)
8291 (compare (any_or:SWI
8292 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8293 (match_operand:SWI 2 "<general_operand>" "<g>"))
8295 (clobber (match_scratch:SWI 0 "=<r>"))]
8296 "ix86_match_ccmode (insn, CCNOmode)
8297 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8298 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "<MODE>")])
8302 (define_insn "*<code>qi_ext_0"
8303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8308 (match_operand 1 "ext_register_operand" "0")
8311 (match_operand 2 "const_int_operand" "n")))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8314 "<logic>{b}\t{%2, %h0|%h0, %2}"
8315 [(set_attr "type" "alu")
8316 (set_attr "length_immediate" "1")
8317 (set_attr "modrm" "1")
8318 (set_attr "mode" "QI")])
8320 (define_insn "*<code>qi_ext_1_rex64"
8321 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8326 (match_operand 1 "ext_register_operand" "0")
8330 (match_operand 2 "ext_register_operand" "Q"))))
8331 (clobber (reg:CC FLAGS_REG))]
8333 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8334 "<logic>{b}\t{%2, %h0|%h0, %2}"
8335 [(set_attr "type" "alu")
8336 (set_attr "length_immediate" "0")
8337 (set_attr "mode" "QI")])
8339 (define_insn "*<code>qi_ext_1"
8340 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8345 (match_operand 1 "ext_register_operand" "0")
8349 (match_operand:QI 2 "general_operand" "Qm"))))
8350 (clobber (reg:CC FLAGS_REG))]
8352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8353 "<logic>{b}\t{%2, %h0|%h0, %2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "length_immediate" "0")
8356 (set_attr "mode" "QI")])
8358 (define_insn "*<code>qi_ext_2"
8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8363 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8366 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8369 (clobber (reg:CC FLAGS_REG))]
8370 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8371 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8372 [(set_attr "type" "alu")
8373 (set_attr "length_immediate" "0")
8374 (set_attr "mode" "QI")])
8377 [(set (match_operand 0 "register_operand" "")
8378 (any_or (match_operand 1 "register_operand" "")
8379 (match_operand 2 "const_int_operand" "")))
8380 (clobber (reg:CC FLAGS_REG))]
8382 && QI_REG_P (operands[0])
8383 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8384 && !(INTVAL (operands[2]) & ~(255 << 8))
8385 && GET_MODE (operands[0]) != QImode"
8386 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8387 (any_or:SI (zero_extract:SI (match_dup 1)
8388 (const_int 8) (const_int 8))
8390 (clobber (reg:CC FLAGS_REG))])]
8391 "operands[0] = gen_lowpart (SImode, operands[0]);
8392 operands[1] = gen_lowpart (SImode, operands[1]);
8393 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8395 ;; Since OR can be encoded with sign extended immediate, this is only
8396 ;; profitable when 7th bit is set.
8398 [(set (match_operand 0 "register_operand" "")
8399 (any_or (match_operand 1 "general_operand" "")
8400 (match_operand 2 "const_int_operand" "")))
8401 (clobber (reg:CC FLAGS_REG))]
8403 && ANY_QI_REG_P (operands[0])
8404 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405 && !(INTVAL (operands[2]) & ~255)
8406 && (INTVAL (operands[2]) & 128)
8407 && GET_MODE (operands[0]) != QImode"
8408 [(parallel [(set (strict_low_part (match_dup 0))
8409 (any_or:QI (match_dup 1)
8411 (clobber (reg:CC FLAGS_REG))])]
8412 "operands[0] = gen_lowpart (QImode, operands[0]);
8413 operands[1] = gen_lowpart (QImode, operands[1]);
8414 operands[2] = gen_lowpart (QImode, operands[2]);")
8416 (define_expand "xorqi_cc_ext_1"
8418 (set (reg:CCNO FLAGS_REG)
8422 (match_operand 1 "ext_register_operand" "")
8425 (match_operand:QI 2 "general_operand" ""))
8427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8437 (define_insn "*xorqi_cc_ext_1_rex64"
8438 [(set (reg FLAGS_REG)
8442 (match_operand 1 "ext_register_operand" "0")
8445 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8447 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8457 "xor{b}\t{%2, %h0|%h0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "modrm" "1")
8460 (set_attr "mode" "QI")])
8462 (define_insn "*xorqi_cc_ext_1"
8463 [(set (reg FLAGS_REG)
8467 (match_operand 1 "ext_register_operand" "0")
8470 (match_operand:QI 2 "general_operand" "qmn"))
8472 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8481 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8482 "xor{b}\t{%2, %h0|%h0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "modrm" "1")
8485 (set_attr "mode" "QI")])
8487 ;; Negation instructions
8489 (define_expand "neg<mode>2"
8490 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8491 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8493 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8495 (define_insn_and_split "*neg<dwi>2_doubleword"
8496 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8497 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8498 (clobber (reg:CC FLAGS_REG))]
8499 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8503 [(set (reg:CCZ FLAGS_REG)
8504 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8505 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8508 (plus:DWIH (match_dup 3)
8509 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8511 (clobber (reg:CC FLAGS_REG))])
8514 (neg:DWIH (match_dup 2)))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8518 (define_insn "*neg<mode>2_1"
8519 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8520 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8523 "neg{<imodesuffix>}\t%0"
8524 [(set_attr "type" "negnot")
8525 (set_attr "mode" "<MODE>")])
8527 ;; Combine is quite creative about this pattern.
8528 (define_insn "*negsi2_1_zext"
8529 [(set (match_operand:DI 0 "register_operand" "=r")
8531 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8534 (clobber (reg:CC FLAGS_REG))]
8535 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8537 [(set_attr "type" "negnot")
8538 (set_attr "mode" "SI")])
8540 ;; The problem with neg is that it does not perform (compare x 0),
8541 ;; it really performs (compare 0 x), which leaves us with the zero
8542 ;; flag being the only useful item.
8544 (define_insn "*neg<mode>2_cmpz"
8545 [(set (reg:CCZ FLAGS_REG)
8547 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8549 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8550 (neg:SWI (match_dup 1)))]
8551 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8552 "neg{<imodesuffix>}\t%0"
8553 [(set_attr "type" "negnot")
8554 (set_attr "mode" "<MODE>")])
8556 (define_insn "*negsi2_cmpz_zext"
8557 [(set (reg:CCZ FLAGS_REG)
8561 (match_operand:DI 1 "register_operand" "0")
8565 (set (match_operand:DI 0 "register_operand" "=r")
8566 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8569 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8571 [(set_attr "type" "negnot")
8572 (set_attr "mode" "SI")])
8574 ;; Changing of sign for FP values is doable using integer unit too.
8576 (define_expand "<code><mode>2"
8577 [(set (match_operand:X87MODEF 0 "register_operand" "")
8578 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8579 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8580 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8582 (define_insn "*absneg<mode>2_mixed"
8583 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8584 (match_operator:MODEF 3 "absneg_operator"
8585 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8586 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8587 (clobber (reg:CC FLAGS_REG))]
8588 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8591 (define_insn "*absneg<mode>2_sse"
8592 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8593 (match_operator:MODEF 3 "absneg_operator"
8594 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8595 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8600 (define_insn "*absneg<mode>2_i387"
8601 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8602 (match_operator:X87MODEF 3 "absneg_operator"
8603 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8604 (use (match_operand 2 "" ""))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8609 (define_expand "<code>tf2"
8610 [(set (match_operand:TF 0 "register_operand" "")
8611 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8613 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8615 (define_insn "*absnegtf2_sse"
8616 [(set (match_operand:TF 0 "register_operand" "=x,x")
8617 (match_operator:TF 3 "absneg_operator"
8618 [(match_operand:TF 1 "register_operand" "0,x")]))
8619 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8620 (clobber (reg:CC FLAGS_REG))]
8624 ;; Splitters for fp abs and neg.
8627 [(set (match_operand 0 "fp_register_operand" "")
8628 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8629 (use (match_operand 2 "" ""))
8630 (clobber (reg:CC FLAGS_REG))]
8632 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8635 [(set (match_operand 0 "register_operand" "")
8636 (match_operator 3 "absneg_operator"
8637 [(match_operand 1 "register_operand" "")]))
8638 (use (match_operand 2 "nonimmediate_operand" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "reload_completed && SSE_REG_P (operands[0])"
8641 [(set (match_dup 0) (match_dup 3))]
8643 enum machine_mode mode = GET_MODE (operands[0]);
8644 enum machine_mode vmode = GET_MODE (operands[2]);
8647 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8648 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8649 if (operands_match_p (operands[0], operands[2]))
8652 operands[1] = operands[2];
8655 if (GET_CODE (operands[3]) == ABS)
8656 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8658 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8663 [(set (match_operand:SF 0 "register_operand" "")
8664 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8665 (use (match_operand:V4SF 2 "" ""))
8666 (clobber (reg:CC FLAGS_REG))]
8668 [(parallel [(set (match_dup 0) (match_dup 1))
8669 (clobber (reg:CC FLAGS_REG))])]
8672 operands[0] = gen_lowpart (SImode, operands[0]);
8673 if (GET_CODE (operands[1]) == ABS)
8675 tmp = gen_int_mode (0x7fffffff, SImode);
8676 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8680 tmp = gen_int_mode (0x80000000, SImode);
8681 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8687 [(set (match_operand:DF 0 "register_operand" "")
8688 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8689 (use (match_operand 2 "" ""))
8690 (clobber (reg:CC FLAGS_REG))]
8692 [(parallel [(set (match_dup 0) (match_dup 1))
8693 (clobber (reg:CC FLAGS_REG))])]
8698 tmp = gen_lowpart (DImode, operands[0]);
8699 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8702 if (GET_CODE (operands[1]) == ABS)
8705 tmp = gen_rtx_NOT (DImode, tmp);
8709 operands[0] = gen_highpart (SImode, operands[0]);
8710 if (GET_CODE (operands[1]) == ABS)
8712 tmp = gen_int_mode (0x7fffffff, SImode);
8713 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8717 tmp = gen_int_mode (0x80000000, SImode);
8718 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8725 [(set (match_operand:XF 0 "register_operand" "")
8726 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8727 (use (match_operand 2 "" ""))
8728 (clobber (reg:CC FLAGS_REG))]
8730 [(parallel [(set (match_dup 0) (match_dup 1))
8731 (clobber (reg:CC FLAGS_REG))])]
8734 operands[0] = gen_rtx_REG (SImode,
8735 true_regnum (operands[0])
8736 + (TARGET_64BIT ? 1 : 2));
8737 if (GET_CODE (operands[1]) == ABS)
8739 tmp = GEN_INT (0x7fff);
8740 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8744 tmp = GEN_INT (0x8000);
8745 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8750 ;; Conditionalize these after reload. If they match before reload, we
8751 ;; lose the clobber and ability to use integer instructions.
8753 (define_insn "*<code><mode>2_1"
8754 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8755 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8757 && (reload_completed
8758 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8759 "f<absneg_mnemonic>"
8760 [(set_attr "type" "fsgn")
8761 (set_attr "mode" "<MODE>")])
8763 (define_insn "*<code>extendsfdf2"
8764 [(set (match_operand:DF 0 "register_operand" "=f")
8765 (absneg:DF (float_extend:DF
8766 (match_operand:SF 1 "register_operand" "0"))))]
8767 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8768 "f<absneg_mnemonic>"
8769 [(set_attr "type" "fsgn")
8770 (set_attr "mode" "DF")])
8772 (define_insn "*<code>extendsfxf2"
8773 [(set (match_operand:XF 0 "register_operand" "=f")
8774 (absneg:XF (float_extend:XF
8775 (match_operand:SF 1 "register_operand" "0"))))]
8777 "f<absneg_mnemonic>"
8778 [(set_attr "type" "fsgn")
8779 (set_attr "mode" "XF")])
8781 (define_insn "*<code>extenddfxf2"
8782 [(set (match_operand:XF 0 "register_operand" "=f")
8783 (absneg:XF (float_extend:XF
8784 (match_operand:DF 1 "register_operand" "0"))))]
8786 "f<absneg_mnemonic>"
8787 [(set_attr "type" "fsgn")
8788 (set_attr "mode" "XF")])
8790 ;; Copysign instructions
8792 (define_mode_iterator CSGNMODE [SF DF TF])
8793 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8795 (define_expand "copysign<mode>3"
8796 [(match_operand:CSGNMODE 0 "register_operand" "")
8797 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8798 (match_operand:CSGNMODE 2 "register_operand" "")]
8799 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8800 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8801 "ix86_expand_copysign (operands); DONE;")
8803 (define_insn_and_split "copysign<mode>3_const"
8804 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8806 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8807 (match_operand:CSGNMODE 2 "register_operand" "0")
8808 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8813 "&& reload_completed"
8815 "ix86_split_copysign_const (operands); DONE;")
8817 (define_insn "copysign<mode>3_var"
8818 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8820 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8821 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8822 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8823 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8825 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8826 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8827 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8831 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8833 [(match_operand:CSGNMODE 2 "register_operand" "")
8834 (match_operand:CSGNMODE 3 "register_operand" "")
8835 (match_operand:<CSGNVMODE> 4 "" "")
8836 (match_operand:<CSGNVMODE> 5 "" "")]
8838 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8839 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8840 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8841 && reload_completed"
8843 "ix86_split_copysign_var (operands); DONE;")
8845 ;; One complement instructions
8847 (define_expand "one_cmpl<mode>2"
8848 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8849 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8851 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8853 (define_insn "*one_cmpl<mode>2_1"
8854 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8855 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8856 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8857 "not{<imodesuffix>}\t%0"
8858 [(set_attr "type" "negnot")
8859 (set_attr "mode" "<MODE>")])
8861 ;; %%% Potential partial reg stall on alternative 1. What to do?
8862 (define_insn "*one_cmplqi2_1"
8863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8864 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8865 "ix86_unary_operator_ok (NOT, QImode, operands)"
8869 [(set_attr "type" "negnot")
8870 (set_attr "mode" "QI,SI")])
8872 ;; ??? Currently never generated - xor is used instead.
8873 (define_insn "*one_cmplsi2_1_zext"
8874 [(set (match_operand:DI 0 "register_operand" "=r")
8876 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8877 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8879 [(set_attr "type" "negnot")
8880 (set_attr "mode" "SI")])
8882 (define_insn "*one_cmpl<mode>2_2"
8883 [(set (reg FLAGS_REG)
8884 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8886 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8887 (not:SWI (match_dup 1)))]
8888 "ix86_match_ccmode (insn, CCNOmode)
8889 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8891 [(set_attr "type" "alu1")
8892 (set_attr "mode" "<MODE>")])
8895 [(set (match_operand 0 "flags_reg_operand" "")
8896 (match_operator 2 "compare_operator"
8897 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8899 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8900 (not:SWI (match_dup 3)))]
8901 "ix86_match_ccmode (insn, CCNOmode)"
8902 [(parallel [(set (match_dup 0)
8903 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8906 (xor:SWI (match_dup 3) (const_int -1)))])])
8908 ;; ??? Currently never generated - xor is used instead.
8909 (define_insn "*one_cmplsi2_2_zext"
8910 [(set (reg FLAGS_REG)
8911 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8913 (set (match_operand:DI 0 "register_operand" "=r")
8914 (zero_extend:DI (not:SI (match_dup 1))))]
8915 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8916 && ix86_unary_operator_ok (NOT, SImode, operands)"
8918 [(set_attr "type" "alu1")
8919 (set_attr "mode" "SI")])
8922 [(set (match_operand 0 "flags_reg_operand" "")
8923 (match_operator 2 "compare_operator"
8924 [(not:SI (match_operand:SI 3 "register_operand" ""))
8926 (set (match_operand:DI 1 "register_operand" "")
8927 (zero_extend:DI (not:SI (match_dup 3))))]
8928 "ix86_match_ccmode (insn, CCNOmode)"
8929 [(parallel [(set (match_dup 0)
8930 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8933 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8935 ;; Shift instructions
8937 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8938 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8939 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8940 ;; from the assembler input.
8942 ;; This instruction shifts the target reg/mem as usual, but instead of
8943 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8944 ;; is a left shift double, bits are taken from the high order bits of
8945 ;; reg, else if the insn is a shift right double, bits are taken from the
8946 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8947 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8949 ;; Since sh[lr]d does not change the `reg' operand, that is done
8950 ;; separately, making all shifts emit pairs of shift double and normal
8951 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8952 ;; support a 63 bit shift, each shift where the count is in a reg expands
8953 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8955 ;; If the shift count is a constant, we need never emit more than one
8956 ;; shift pair, instead using moves and sign extension for counts greater
8959 (define_expand "ashl<mode>3"
8960 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8961 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8962 (match_operand:QI 2 "nonmemory_operand" "")))]
8964 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8966 (define_insn "*ashl<mode>3_doubleword"
8967 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8968 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8969 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8970 (clobber (reg:CC FLAGS_REG))]
8973 [(set_attr "type" "multi")])
8976 [(set (match_operand:DWI 0 "register_operand" "")
8977 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8978 (match_operand:QI 2 "nonmemory_operand" "")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8982 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8984 ;; By default we don't ask for a scratch register, because when DWImode
8985 ;; values are manipulated, registers are already at a premium. But if
8986 ;; we have one handy, we won't turn it away.
8989 [(match_scratch:DWIH 3 "r")
8990 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8992 (match_operand:<DWI> 1 "nonmemory_operand" "")
8993 (match_operand:QI 2 "nonmemory_operand" "")))
8994 (clobber (reg:CC FLAGS_REG))])
8998 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9000 (define_insn "x86_64_shld"
9001 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9002 (ior:DI (ashift:DI (match_dup 0)
9003 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9004 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9005 (minus:QI (const_int 64) (match_dup 2)))))
9006 (clobber (reg:CC FLAGS_REG))]
9008 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9009 [(set_attr "type" "ishift")
9010 (set_attr "prefix_0f" "1")
9011 (set_attr "mode" "DI")
9012 (set_attr "athlon_decode" "vector")
9013 (set_attr "amdfam10_decode" "vector")
9014 (set_attr "bdver1_decode" "vector")])
9016 (define_insn "x86_shld"
9017 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9018 (ior:SI (ashift:SI (match_dup 0)
9019 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9020 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9021 (minus:QI (const_int 32) (match_dup 2)))))
9022 (clobber (reg:CC FLAGS_REG))]
9024 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9025 [(set_attr "type" "ishift")
9026 (set_attr "prefix_0f" "1")
9027 (set_attr "mode" "SI")
9028 (set_attr "pent_pair" "np")
9029 (set_attr "athlon_decode" "vector")
9030 (set_attr "amdfam10_decode" "vector")
9031 (set_attr "bdver1_decode" "vector")])
9033 (define_expand "x86_shift<mode>_adj_1"
9034 [(set (reg:CCZ FLAGS_REG)
9035 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9038 (set (match_operand:SWI48 0 "register_operand" "")
9039 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9040 (match_operand:SWI48 1 "register_operand" "")
9043 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9044 (match_operand:SWI48 3 "register_operand" "r")
9047 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9049 (define_expand "x86_shift<mode>_adj_2"
9050 [(use (match_operand:SWI48 0 "register_operand" ""))
9051 (use (match_operand:SWI48 1 "register_operand" ""))
9052 (use (match_operand:QI 2 "register_operand" ""))]
9055 rtx label = gen_label_rtx ();
9058 emit_insn (gen_testqi_ccz_1 (operands[2],
9059 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9061 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9062 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9063 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9064 gen_rtx_LABEL_REF (VOIDmode, label),
9066 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9067 JUMP_LABEL (tmp) = label;
9069 emit_move_insn (operands[0], operands[1]);
9070 ix86_expand_clear (operands[1]);
9073 LABEL_NUSES (label) = 1;
9078 ;; Avoid useless masking of count operand.
9079 (define_insn_and_split "*ashl<mode>3_mask"
9080 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9082 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9085 (match_operand:SI 2 "nonimmediate_operand" "c")
9086 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9087 (clobber (reg:CC FLAGS_REG))]
9088 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9089 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9090 == GET_MODE_BITSIZE (<MODE>mode)-1"
9093 [(parallel [(set (match_dup 0)
9094 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9095 (clobber (reg:CC FLAGS_REG))])]
9097 if (can_create_pseudo_p ())
9098 operands [2] = force_reg (SImode, operands[2]);
9100 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9102 [(set_attr "type" "ishift")
9103 (set_attr "mode" "<MODE>")])
9105 (define_insn "*bmi2_ashl<mode>3_1"
9106 [(set (match_operand:SWI48 0 "register_operand" "=r")
9107 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9108 (match_operand:SWI48 2 "register_operand" "r")))]
9110 "shlx\t{%2, %1, %0|%0, %1, %2}"
9111 [(set_attr "type" "ishiftx")
9112 (set_attr "mode" "<MODE>")])
9114 (define_insn "*ashl<mode>3_1"
9115 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9116 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9117 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9121 switch (get_attr_type (insn))
9128 gcc_assert (operands[2] == const1_rtx);
9129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9130 return "add{<imodesuffix>}\t%0, %0";
9133 if (operands[2] == const1_rtx
9134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9135 return "sal{<imodesuffix>}\t%0";
9137 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9140 [(set_attr "isa" "*,*,bmi2")
9142 (cond [(eq_attr "alternative" "1")
9143 (const_string "lea")
9144 (eq_attr "alternative" "2")
9145 (const_string "ishiftx")
9146 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9147 (match_operand 0 "register_operand" ""))
9148 (match_operand 2 "const1_operand" ""))
9149 (const_string "alu")
9151 (const_string "ishift")))
9152 (set (attr "length_immediate")
9154 (ior (eq_attr "type" "alu")
9155 (and (eq_attr "type" "ishift")
9156 (and (match_operand 2 "const1_operand" "")
9157 (ior (match_test "TARGET_SHIFT1")
9158 (match_test "optimize_function_for_size_p (cfun)")))))
9160 (const_string "*")))
9161 (set_attr "mode" "<MODE>")])
9163 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9165 [(set (match_operand:SWI48 0 "register_operand" "")
9166 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9167 (match_operand:QI 2 "register_operand" "")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "TARGET_BMI2 && reload_completed"
9171 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9172 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9174 (define_insn "*bmi2_ashlsi3_1_zext"
9175 [(set (match_operand:DI 0 "register_operand" "=r")
9177 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9178 (match_operand:SI 2 "register_operand" "r"))))]
9179 "TARGET_64BIT && TARGET_BMI2"
9180 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9181 [(set_attr "type" "ishiftx")
9182 (set_attr "mode" "SI")])
9184 (define_insn "*ashlsi3_1_zext"
9185 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9187 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9188 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9189 (clobber (reg:CC FLAGS_REG))]
9190 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9192 switch (get_attr_type (insn))
9199 gcc_assert (operands[2] == const1_rtx);
9200 return "add{l}\t%k0, %k0";
9203 if (operands[2] == const1_rtx
9204 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9205 return "sal{l}\t%k0";
9207 return "sal{l}\t{%2, %k0|%k0, %2}";
9210 [(set_attr "isa" "*,*,bmi2")
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (eq_attr "alternative" "2")
9215 (const_string "ishiftx")
9216 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9217 (match_operand 2 "const1_operand" ""))
9218 (const_string "alu")
9220 (const_string "ishift")))
9221 (set (attr "length_immediate")
9223 (ior (eq_attr "type" "alu")
9224 (and (eq_attr "type" "ishift")
9225 (and (match_operand 2 "const1_operand" "")
9226 (ior (match_test "TARGET_SHIFT1")
9227 (match_test "optimize_function_for_size_p (cfun)")))))
9229 (const_string "*")))
9230 (set_attr "mode" "SI")])
9232 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9234 [(set (match_operand:DI 0 "register_operand" "")
9236 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9237 (match_operand:QI 2 "register_operand" ""))))
9238 (clobber (reg:CC FLAGS_REG))]
9239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9241 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9242 "operands[2] = gen_lowpart (SImode, operands[2]);")
9244 (define_insn "*ashlhi3_1"
9245 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9246 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9247 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9251 switch (get_attr_type (insn))
9257 gcc_assert (operands[2] == const1_rtx);
9258 return "add{w}\t%0, %0";
9261 if (operands[2] == const1_rtx
9262 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263 return "sal{w}\t%0";
9265 return "sal{w}\t{%2, %0|%0, %2}";
9269 (cond [(eq_attr "alternative" "1")
9270 (const_string "lea")
9271 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9272 (match_operand 0 "register_operand" ""))
9273 (match_operand 2 "const1_operand" ""))
9274 (const_string "alu")
9276 (const_string "ishift")))
9277 (set (attr "length_immediate")
9279 (ior (eq_attr "type" "alu")
9280 (and (eq_attr "type" "ishift")
9281 (and (match_operand 2 "const1_operand" "")
9282 (ior (match_test "TARGET_SHIFT1")
9283 (match_test "optimize_function_for_size_p (cfun)")))))
9285 (const_string "*")))
9286 (set_attr "mode" "HI,SI")])
9288 ;; %%% Potential partial reg stall on alternative 1. What to do?
9289 (define_insn "*ashlqi3_1"
9290 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9291 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9292 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9296 switch (get_attr_type (insn))
9302 gcc_assert (operands[2] == const1_rtx);
9303 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9304 return "add{l}\t%k0, %k0";
9306 return "add{b}\t%0, %0";
9309 if (operands[2] == const1_rtx
9310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9312 if (get_attr_mode (insn) == MODE_SI)
9313 return "sal{l}\t%k0";
9315 return "sal{b}\t%0";
9319 if (get_attr_mode (insn) == MODE_SI)
9320 return "sal{l}\t{%2, %k0|%k0, %2}";
9322 return "sal{b}\t{%2, %0|%0, %2}";
9327 (cond [(eq_attr "alternative" "2")
9328 (const_string "lea")
9329 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9330 (match_operand 0 "register_operand" ""))
9331 (match_operand 2 "const1_operand" ""))
9332 (const_string "alu")
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand" "")
9340 (ior (match_test "TARGET_SHIFT1")
9341 (match_test "optimize_function_for_size_p (cfun)")))))
9343 (const_string "*")))
9344 (set_attr "mode" "QI,SI,SI")])
9346 (define_insn "*ashlqi3_1_slp"
9347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348 (ashift:QI (match_dup 0)
9349 (match_operand:QI 1 "nonmemory_operand" "cI")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "(optimize_function_for_size_p (cfun)
9352 || !TARGET_PARTIAL_FLAG_REG_STALL
9353 || (operands[1] == const1_rtx
9355 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9357 switch (get_attr_type (insn))
9360 gcc_assert (operands[1] == const1_rtx);
9361 return "add{b}\t%0, %0";
9364 if (operands[1] == const1_rtx
9365 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366 return "sal{b}\t%0";
9368 return "sal{b}\t{%1, %0|%0, %1}";
9372 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9373 (match_operand 0 "register_operand" ""))
9374 (match_operand 1 "const1_operand" ""))
9375 (const_string "alu")
9377 (const_string "ishift1")))
9378 (set (attr "length_immediate")
9380 (ior (eq_attr "type" "alu")
9381 (and (eq_attr "type" "ishift1")
9382 (and (match_operand 1 "const1_operand" "")
9383 (ior (match_test "TARGET_SHIFT1")
9384 (match_test "optimize_function_for_size_p (cfun)")))))
9386 (const_string "*")))
9387 (set_attr "mode" "QI")])
9389 ;; Convert ashift to the lea pattern to avoid flags dependency.
9391 [(set (match_operand 0 "register_operand" "")
9392 (ashift (match_operand 1 "index_register_operand" "")
9393 (match_operand:QI 2 "const_int_operand" "")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9397 && true_regnum (operands[0]) != true_regnum (operands[1])"
9400 enum machine_mode mode = GET_MODE (operands[0]);
9403 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9406 operands[0] = gen_lowpart (mode, operands[0]);
9407 operands[1] = gen_lowpart (mode, operands[1]);
9410 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9412 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9414 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9418 ;; Convert ashift to the lea pattern to avoid flags dependency.
9420 [(set (match_operand:DI 0 "register_operand" "")
9422 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9423 (match_operand:QI 2 "const_int_operand" ""))))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "TARGET_64BIT && reload_completed
9426 && true_regnum (operands[0]) != true_regnum (operands[1])"
9428 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9430 operands[1] = gen_lowpart (DImode, operands[1]);
9431 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9434 ;; This pattern can't accept a variable shift count, since shifts by
9435 ;; zero don't affect the flags. We assume that shifts by constant
9436 ;; zero are optimized away.
9437 (define_insn "*ashl<mode>3_cmp"
9438 [(set (reg FLAGS_REG)
9440 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9441 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9443 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9444 (ashift:SWI (match_dup 1) (match_dup 2)))]
9445 "(optimize_function_for_size_p (cfun)
9446 || !TARGET_PARTIAL_FLAG_REG_STALL
9447 || (operands[2] == const1_rtx
9449 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9450 && ix86_match_ccmode (insn, CCGOCmode)
9451 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9453 switch (get_attr_type (insn))
9456 gcc_assert (operands[2] == const1_rtx);
9457 return "add{<imodesuffix>}\t%0, %0";
9460 if (operands[2] == const1_rtx
9461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9462 return "sal{<imodesuffix>}\t%0";
9464 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9468 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9469 (match_operand 0 "register_operand" ""))
9470 (match_operand 2 "const1_operand" ""))
9471 (const_string "alu")
9473 (const_string "ishift")))
9474 (set (attr "length_immediate")
9476 (ior (eq_attr "type" "alu")
9477 (and (eq_attr "type" "ishift")
9478 (and (match_operand 2 "const1_operand" "")
9479 (ior (match_test "TARGET_SHIFT1")
9480 (match_test "optimize_function_for_size_p (cfun)")))))
9482 (const_string "*")))
9483 (set_attr "mode" "<MODE>")])
9485 (define_insn "*ashlsi3_cmp_zext"
9486 [(set (reg FLAGS_REG)
9488 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9489 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9491 (set (match_operand:DI 0 "register_operand" "=r")
9492 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9494 && (optimize_function_for_size_p (cfun)
9495 || !TARGET_PARTIAL_FLAG_REG_STALL
9496 || (operands[2] == const1_rtx
9498 || TARGET_DOUBLE_WITH_ADD)))
9499 && ix86_match_ccmode (insn, CCGOCmode)
9500 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9502 switch (get_attr_type (insn))
9505 gcc_assert (operands[2] == const1_rtx);
9506 return "add{l}\t%k0, %k0";
9509 if (operands[2] == const1_rtx
9510 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9511 return "sal{l}\t%k0";
9513 return "sal{l}\t{%2, %k0|%k0, %2}";
9517 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9518 (match_operand 2 "const1_operand" ""))
9519 (const_string "alu")
9521 (const_string "ishift")))
9522 (set (attr "length_immediate")
9524 (ior (eq_attr "type" "alu")
9525 (and (eq_attr "type" "ishift")
9526 (and (match_operand 2 "const1_operand" "")
9527 (ior (match_test "TARGET_SHIFT1")
9528 (match_test "optimize_function_for_size_p (cfun)")))))
9530 (const_string "*")))
9531 (set_attr "mode" "SI")])
9533 (define_insn "*ashl<mode>3_cconly"
9534 [(set (reg FLAGS_REG)
9536 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9537 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9539 (clobber (match_scratch:SWI 0 "=<r>"))]
9540 "(optimize_function_for_size_p (cfun)
9541 || !TARGET_PARTIAL_FLAG_REG_STALL
9542 || (operands[2] == const1_rtx
9544 || TARGET_DOUBLE_WITH_ADD)))
9545 && ix86_match_ccmode (insn, CCGOCmode)"
9547 switch (get_attr_type (insn))
9550 gcc_assert (operands[2] == const1_rtx);
9551 return "add{<imodesuffix>}\t%0, %0";
9554 if (operands[2] == const1_rtx
9555 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9556 return "sal{<imodesuffix>}\t%0";
9558 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9563 (match_operand 0 "register_operand" ""))
9564 (match_operand 2 "const1_operand" ""))
9565 (const_string "alu")
9567 (const_string "ishift")))
9568 (set (attr "length_immediate")
9570 (ior (eq_attr "type" "alu")
9571 (and (eq_attr "type" "ishift")
9572 (and (match_operand 2 "const1_operand" "")
9573 (ior (match_test "TARGET_SHIFT1")
9574 (match_test "optimize_function_for_size_p (cfun)")))))
9576 (const_string "*")))
9577 (set_attr "mode" "<MODE>")])
9579 ;; See comment above `ashl<mode>3' about how this works.
9581 (define_expand "<shiftrt_insn><mode>3"
9582 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9583 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9584 (match_operand:QI 2 "nonmemory_operand" "")))]
9586 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9588 ;; Avoid useless masking of count operand.
9589 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9590 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9592 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9595 (match_operand:SI 2 "nonimmediate_operand" "c")
9596 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9597 (clobber (reg:CC FLAGS_REG))]
9598 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9599 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9600 == GET_MODE_BITSIZE (<MODE>mode)-1"
9603 [(parallel [(set (match_dup 0)
9604 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9605 (clobber (reg:CC FLAGS_REG))])]
9607 if (can_create_pseudo_p ())
9608 operands [2] = force_reg (SImode, operands[2]);
9610 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9612 [(set_attr "type" "ishift")
9613 (set_attr "mode" "<MODE>")])
9615 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9616 [(set (match_operand:DWI 0 "register_operand" "=r")
9617 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9618 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9619 (clobber (reg:CC FLAGS_REG))]
9622 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9624 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9625 [(set_attr "type" "multi")])
9627 ;; By default we don't ask for a scratch register, because when DWImode
9628 ;; values are manipulated, registers are already at a premium. But if
9629 ;; we have one handy, we won't turn it away.
9632 [(match_scratch:DWIH 3 "r")
9633 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9635 (match_operand:<DWI> 1 "register_operand" "")
9636 (match_operand:QI 2 "nonmemory_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))])
9641 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9643 (define_insn "x86_64_shrd"
9644 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9645 (ior:DI (ashiftrt:DI (match_dup 0)
9646 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9647 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9648 (minus:QI (const_int 64) (match_dup 2)))))
9649 (clobber (reg:CC FLAGS_REG))]
9651 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9652 [(set_attr "type" "ishift")
9653 (set_attr "prefix_0f" "1")
9654 (set_attr "mode" "DI")
9655 (set_attr "athlon_decode" "vector")
9656 (set_attr "amdfam10_decode" "vector")
9657 (set_attr "bdver1_decode" "vector")])
9659 (define_insn "x86_shrd"
9660 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9661 (ior:SI (ashiftrt:SI (match_dup 0)
9662 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9663 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9664 (minus:QI (const_int 32) (match_dup 2)))))
9665 (clobber (reg:CC FLAGS_REG))]
9667 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9668 [(set_attr "type" "ishift")
9669 (set_attr "prefix_0f" "1")
9670 (set_attr "mode" "SI")
9671 (set_attr "pent_pair" "np")
9672 (set_attr "athlon_decode" "vector")
9673 (set_attr "amdfam10_decode" "vector")
9674 (set_attr "bdver1_decode" "vector")])
9676 (define_insn "ashrdi3_cvt"
9677 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9678 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9679 (match_operand:QI 2 "const_int_operand" "")))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "TARGET_64BIT && INTVAL (operands[2]) == 63
9682 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9683 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9686 sar{q}\t{%2, %0|%0, %2}"
9687 [(set_attr "type" "imovx,ishift")
9688 (set_attr "prefix_0f" "0,*")
9689 (set_attr "length_immediate" "0,*")
9690 (set_attr "modrm" "0,1")
9691 (set_attr "mode" "DI")])
9693 (define_insn "ashrsi3_cvt"
9694 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9696 (match_operand:QI 2 "const_int_operand" "")))
9697 (clobber (reg:CC FLAGS_REG))]
9698 "INTVAL (operands[2]) == 31
9699 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9700 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9703 sar{l}\t{%2, %0|%0, %2}"
9704 [(set_attr "type" "imovx,ishift")
9705 (set_attr "prefix_0f" "0,*")
9706 (set_attr "length_immediate" "0,*")
9707 (set_attr "modrm" "0,1")
9708 (set_attr "mode" "SI")])
9710 (define_insn "*ashrsi3_cvt_zext"
9711 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9713 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9714 (match_operand:QI 2 "const_int_operand" ""))))
9715 (clobber (reg:CC FLAGS_REG))]
9716 "TARGET_64BIT && INTVAL (operands[2]) == 31
9717 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9721 sar{l}\t{%2, %k0|%k0, %2}"
9722 [(set_attr "type" "imovx,ishift")
9723 (set_attr "prefix_0f" "0,*")
9724 (set_attr "length_immediate" "0,*")
9725 (set_attr "modrm" "0,1")
9726 (set_attr "mode" "SI")])
9728 (define_expand "x86_shift<mode>_adj_3"
9729 [(use (match_operand:SWI48 0 "register_operand" ""))
9730 (use (match_operand:SWI48 1 "register_operand" ""))
9731 (use (match_operand:QI 2 "register_operand" ""))]
9734 rtx label = gen_label_rtx ();
9737 emit_insn (gen_testqi_ccz_1 (operands[2],
9738 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9740 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9741 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9742 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9743 gen_rtx_LABEL_REF (VOIDmode, label),
9745 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9746 JUMP_LABEL (tmp) = label;
9748 emit_move_insn (operands[0], operands[1]);
9749 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9750 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9752 LABEL_NUSES (label) = 1;
9757 (define_insn "*bmi2_<shiftrt_insn><mode>3_1"
9758 [(set (match_operand:SWI48 0 "register_operand" "=r")
9759 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9760 (match_operand:SWI48 2 "register_operand" "r")))]
9762 "<shiftrt>x\t{%2, %1, %0|%0, %1, %2}"
9763 [(set_attr "type" "ishiftx")
9764 (set_attr "mode" "<MODE>")])
9766 (define_insn "*<shiftrt_insn><mode>3_1"
9767 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9769 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9770 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9774 switch (get_attr_type (insn))
9780 if (operands[2] == const1_rtx
9781 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9782 return "<shiftrt>{<imodesuffix>}\t%0";
9784 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9787 [(set_attr "isa" "*,bmi2")
9788 (set_attr "type" "ishift,ishiftx")
9789 (set (attr "length_immediate")
9791 (and (match_operand 2 "const1_operand" "")
9792 (ior (match_test "TARGET_SHIFT1")
9793 (match_test "optimize_function_for_size_p (cfun)")))
9795 (const_string "*")))
9796 (set_attr "mode" "<MODE>")])
9798 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9800 [(set (match_operand:SWI48 0 "register_operand" "")
9801 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9802 (match_operand:QI 2 "register_operand" "")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "TARGET_BMI2 && reload_completed"
9806 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9807 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9809 (define_insn "*bmi2_<shiftrt_insn>si3_1_zext"
9810 [(set (match_operand:DI 0 "register_operand" "=r")
9812 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9813 (match_operand:SI 2 "register_operand" "r"))))]
9814 "TARGET_64BIT && TARGET_BMI2"
9815 "<shiftrt>x\t{%2, %1, %k0|%k0, %1, %2}"
9816 [(set_attr "type" "ishiftx")
9817 (set_attr "mode" "SI")])
9819 (define_insn "*<shiftrt_insn>si3_1_zext"
9820 [(set (match_operand:DI 0 "register_operand" "=r,r")
9822 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9823 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9827 switch (get_attr_type (insn))
9833 if (operands[2] == const1_rtx
9834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9835 return "<shiftrt>{l}\t%k0";
9837 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9840 [(set_attr "isa" "*,bmi2")
9841 (set_attr "type" "ishift,ishiftx")
9842 (set (attr "length_immediate")
9844 (and (match_operand 2 "const1_operand" "")
9845 (ior (match_test "TARGET_SHIFT1")
9846 (match_test "optimize_function_for_size_p (cfun)")))
9848 (const_string "*")))
9849 (set_attr "mode" "SI")])
9851 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9853 [(set (match_operand:DI 0 "register_operand" "")
9855 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9856 (match_operand:QI 2 "register_operand" ""))))
9857 (clobber (reg:CC FLAGS_REG))]
9858 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9860 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9861 "operands[2] = gen_lowpart (SImode, operands[2]);")
9863 (define_insn "*<shiftrt_insn><mode>3_1"
9864 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9866 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9867 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9868 (clobber (reg:CC FLAGS_REG))]
9869 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9871 if (operands[2] == const1_rtx
9872 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9873 return "<shiftrt>{<imodesuffix>}\t%0";
9875 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9877 [(set_attr "type" "ishift")
9878 (set (attr "length_immediate")
9880 (and (match_operand 2 "const1_operand" "")
9881 (ior (match_test "TARGET_SHIFT1")
9882 (match_test "optimize_function_for_size_p (cfun)")))
9884 (const_string "*")))
9885 (set_attr "mode" "<MODE>")])
9887 (define_insn "*<shiftrt_insn>qi3_1_slp"
9888 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9889 (any_shiftrt:QI (match_dup 0)
9890 (match_operand:QI 1 "nonmemory_operand" "cI")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "(optimize_function_for_size_p (cfun)
9893 || !TARGET_PARTIAL_REG_STALL
9894 || (operands[1] == const1_rtx
9897 if (operands[1] == const1_rtx
9898 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9899 return "<shiftrt>{b}\t%0";
9901 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9903 [(set_attr "type" "ishift1")
9904 (set (attr "length_immediate")
9906 (and (match_operand 1 "const1_operand" "")
9907 (ior (match_test "TARGET_SHIFT1")
9908 (match_test "optimize_function_for_size_p (cfun)")))
9910 (const_string "*")))
9911 (set_attr "mode" "QI")])
9913 ;; This pattern can't accept a variable shift count, since shifts by
9914 ;; zero don't affect the flags. We assume that shifts by constant
9915 ;; zero are optimized away.
9916 (define_insn "*<shiftrt_insn><mode>3_cmp"
9917 [(set (reg FLAGS_REG)
9920 (match_operand:SWI 1 "nonimmediate_operand" "0")
9921 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9924 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9925 "(optimize_function_for_size_p (cfun)
9926 || !TARGET_PARTIAL_FLAG_REG_STALL
9927 || (operands[2] == const1_rtx
9929 && ix86_match_ccmode (insn, CCGOCmode)
9930 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9932 if (operands[2] == const1_rtx
9933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9934 return "<shiftrt>{<imodesuffix>}\t%0";
9936 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9938 [(set_attr "type" "ishift")
9939 (set (attr "length_immediate")
9941 (and (match_operand 2 "const1_operand" "")
9942 (ior (match_test "TARGET_SHIFT1")
9943 (match_test "optimize_function_for_size_p (cfun)")))
9945 (const_string "*")))
9946 (set_attr "mode" "<MODE>")])
9948 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9949 [(set (reg FLAGS_REG)
9951 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9952 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9954 (set (match_operand:DI 0 "register_operand" "=r")
9955 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9957 && (optimize_function_for_size_p (cfun)
9958 || !TARGET_PARTIAL_FLAG_REG_STALL
9959 || (operands[2] == const1_rtx
9961 && ix86_match_ccmode (insn, CCGOCmode)
9962 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9964 if (operands[2] == const1_rtx
9965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9966 return "<shiftrt>{l}\t%k0";
9968 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9970 [(set_attr "type" "ishift")
9971 (set (attr "length_immediate")
9973 (and (match_operand 2 "const1_operand" "")
9974 (ior (match_test "TARGET_SHIFT1")
9975 (match_test "optimize_function_for_size_p (cfun)")))
9977 (const_string "*")))
9978 (set_attr "mode" "SI")])
9980 (define_insn "*<shiftrt_insn><mode>3_cconly"
9981 [(set (reg FLAGS_REG)
9984 (match_operand:SWI 1 "register_operand" "0")
9985 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9987 (clobber (match_scratch:SWI 0 "=<r>"))]
9988 "(optimize_function_for_size_p (cfun)
9989 || !TARGET_PARTIAL_FLAG_REG_STALL
9990 || (operands[2] == const1_rtx
9992 && ix86_match_ccmode (insn, CCGOCmode)"
9994 if (operands[2] == const1_rtx
9995 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9996 return "<shiftrt>{<imodesuffix>}\t%0";
9998 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10000 [(set_attr "type" "ishift")
10001 (set (attr "length_immediate")
10003 (and (match_operand 2 "const1_operand" "")
10004 (ior (match_test "TARGET_SHIFT1")
10005 (match_test "optimize_function_for_size_p (cfun)")))
10007 (const_string "*")))
10008 (set_attr "mode" "<MODE>")])
10010 ;; Rotate instructions
10012 (define_expand "<rotate_insn>ti3"
10013 [(set (match_operand:TI 0 "register_operand" "")
10014 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10015 (match_operand:QI 2 "nonmemory_operand" "")))]
10018 if (const_1_to_63_operand (operands[2], VOIDmode))
10019 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10020 (operands[0], operands[1], operands[2]));
10027 (define_expand "<rotate_insn>di3"
10028 [(set (match_operand:DI 0 "shiftdi_operand" "")
10029 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10030 (match_operand:QI 2 "nonmemory_operand" "")))]
10034 ix86_expand_binary_operator (<CODE>, DImode, operands);
10035 else if (const_1_to_31_operand (operands[2], VOIDmode))
10036 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10037 (operands[0], operands[1], operands[2]));
10044 (define_expand "<rotate_insn><mode>3"
10045 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10046 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10047 (match_operand:QI 2 "nonmemory_operand" "")))]
10049 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10051 ;; Avoid useless masking of count operand.
10052 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10053 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10055 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10058 (match_operand:SI 2 "nonimmediate_operand" "c")
10059 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10060 (clobber (reg:CC FLAGS_REG))]
10061 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10062 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10063 == GET_MODE_BITSIZE (<MODE>mode)-1"
10066 [(parallel [(set (match_dup 0)
10067 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10068 (clobber (reg:CC FLAGS_REG))])]
10070 if (can_create_pseudo_p ())
10071 operands [2] = force_reg (SImode, operands[2]);
10073 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10075 [(set_attr "type" "rotate")
10076 (set_attr "mode" "<MODE>")])
10078 ;; Implement rotation using two double-precision
10079 ;; shift instructions and a scratch register.
10081 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10082 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10083 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10084 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10085 (clobber (reg:CC FLAGS_REG))
10086 (clobber (match_scratch:DWIH 3 "=&r"))]
10090 [(set (match_dup 3) (match_dup 4))
10092 [(set (match_dup 4)
10093 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10094 (lshiftrt:DWIH (match_dup 5)
10095 (minus:QI (match_dup 6) (match_dup 2)))))
10096 (clobber (reg:CC FLAGS_REG))])
10098 [(set (match_dup 5)
10099 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10100 (lshiftrt:DWIH (match_dup 3)
10101 (minus:QI (match_dup 6) (match_dup 2)))))
10102 (clobber (reg:CC FLAGS_REG))])]
10104 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10106 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10109 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10110 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10111 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10112 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10113 (clobber (reg:CC FLAGS_REG))
10114 (clobber (match_scratch:DWIH 3 "=&r"))]
10118 [(set (match_dup 3) (match_dup 4))
10120 [(set (match_dup 4)
10121 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10122 (ashift:DWIH (match_dup 5)
10123 (minus:QI (match_dup 6) (match_dup 2)))))
10124 (clobber (reg:CC FLAGS_REG))])
10126 [(set (match_dup 5)
10127 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10128 (ashift:DWIH (match_dup 3)
10129 (minus:QI (match_dup 6) (match_dup 2)))))
10130 (clobber (reg:CC FLAGS_REG))])]
10132 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10134 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10137 (define_insn "*bmi2_rorx<mode>3_1"
10138 [(set (match_operand:SWI48 0 "register_operand" "=r")
10139 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10140 (match_operand:QI 2 "immediate_operand" "<S>")))]
10142 "rorx\t{%2, %1, %0|%0, %1, %2}"
10143 [(set_attr "type" "rotatex")
10144 (set_attr "mode" "<MODE>")])
10146 (define_insn "*<rotate_insn><mode>3_1"
10147 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10149 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10150 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10154 switch (get_attr_type (insn))
10160 if (operands[2] == const1_rtx
10161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10162 return "<rotate>{<imodesuffix>}\t%0";
10164 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10167 [(set_attr "isa" "*,bmi2")
10168 (set_attr "type" "rotate,rotatex")
10169 (set (attr "length_immediate")
10171 (and (eq_attr "type" "rotate")
10172 (and (match_operand 2 "const1_operand" "")
10173 (ior (match_test "TARGET_SHIFT1")
10174 (match_test "optimize_function_for_size_p (cfun)"))))
10176 (const_string "*")))
10177 (set_attr "mode" "<MODE>")])
10179 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10181 [(set (match_operand:SWI48 0 "register_operand" "")
10182 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183 (match_operand:QI 2 "immediate_operand" "")))
10184 (clobber (reg:CC FLAGS_REG))]
10185 "TARGET_BMI2 && reload_completed"
10186 [(set (match_dup 0)
10187 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10190 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10194 [(set (match_operand:SWI48 0 "register_operand" "")
10195 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10196 (match_operand:QI 2 "immediate_operand" "")))
10197 (clobber (reg:CC FLAGS_REG))]
10198 "TARGET_BMI2 && reload_completed"
10199 [(set (match_dup 0)
10200 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10202 (define_insn "*bmi2_rorxsi3_1_zext"
10203 [(set (match_operand:DI 0 "register_operand" "=r")
10205 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10206 (match_operand:QI 2 "immediate_operand" "I"))))]
10207 "TARGET_64BIT && TARGET_BMI2"
10208 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10209 [(set_attr "type" "rotatex")
10210 (set_attr "mode" "SI")])
10212 (define_insn "*<rotate_insn>si3_1_zext"
10213 [(set (match_operand:DI 0 "register_operand" "=r,r")
10215 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10216 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10220 switch (get_attr_type (insn))
10226 if (operands[2] == const1_rtx
10227 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228 return "<rotate>{l}\t%k0";
10230 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10233 [(set_attr "isa" "*,bmi2")
10234 (set_attr "type" "rotate,rotatex")
10235 (set (attr "length_immediate")
10237 (and (eq_attr "type" "rotate")
10238 (and (match_operand 2 "const1_operand" "")
10239 (ior (match_test "TARGET_SHIFT1")
10240 (match_test "optimize_function_for_size_p (cfun)"))))
10242 (const_string "*")))
10243 (set_attr "mode" "SI")])
10245 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10247 [(set (match_operand:DI 0 "register_operand" "")
10249 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10250 (match_operand:QI 2 "immediate_operand" ""))))
10251 (clobber (reg:CC FLAGS_REG))]
10252 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10253 [(set (match_dup 0)
10254 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10257 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10261 [(set (match_operand:DI 0 "register_operand" "")
10263 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10264 (match_operand:QI 2 "immediate_operand" ""))))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10267 [(set (match_dup 0)
10268 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10270 (define_insn "*<rotate_insn><mode>3_1"
10271 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10272 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10273 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10277 if (operands[2] == const1_rtx
10278 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10279 return "<rotate>{<imodesuffix>}\t%0";
10281 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10283 [(set_attr "type" "rotate")
10284 (set (attr "length_immediate")
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 (define_insn "*<rotate_insn>qi3_1_slp"
10294 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10295 (any_rotate:QI (match_dup 0)
10296 (match_operand:QI 1 "nonmemory_operand" "cI")))
10297 (clobber (reg:CC FLAGS_REG))]
10298 "(optimize_function_for_size_p (cfun)
10299 || !TARGET_PARTIAL_REG_STALL
10300 || (operands[1] == const1_rtx
10301 && TARGET_SHIFT1))"
10303 if (operands[1] == const1_rtx
10304 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10305 return "<rotate>{b}\t%0";
10307 return "<rotate>{b}\t{%1, %0|%0, %1}";
10309 [(set_attr "type" "rotate1")
10310 (set (attr "length_immediate")
10312 (and (match_operand 1 "const1_operand" "")
10313 (ior (match_test "TARGET_SHIFT1")
10314 (match_test "optimize_function_for_size_p (cfun)")))
10316 (const_string "*")))
10317 (set_attr "mode" "QI")])
10320 [(set (match_operand:HI 0 "register_operand" "")
10321 (any_rotate:HI (match_dup 0) (const_int 8)))
10322 (clobber (reg:CC FLAGS_REG))]
10324 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10325 [(parallel [(set (strict_low_part (match_dup 0))
10326 (bswap:HI (match_dup 0)))
10327 (clobber (reg:CC FLAGS_REG))])])
10329 ;; Bit set / bit test instructions
10331 (define_expand "extv"
10332 [(set (match_operand:SI 0 "register_operand" "")
10333 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10334 (match_operand:SI 2 "const8_operand" "")
10335 (match_operand:SI 3 "const8_operand" "")))]
10338 /* Handle extractions from %ah et al. */
10339 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10342 /* From mips.md: extract_bit_field doesn't verify that our source
10343 matches the predicate, so check it again here. */
10344 if (! ext_register_operand (operands[1], VOIDmode))
10348 (define_expand "extzv"
10349 [(set (match_operand:SI 0 "register_operand" "")
10350 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10351 (match_operand:SI 2 "const8_operand" "")
10352 (match_operand:SI 3 "const8_operand" "")))]
10355 /* Handle extractions from %ah et al. */
10356 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10359 /* From mips.md: extract_bit_field doesn't verify that our source
10360 matches the predicate, so check it again here. */
10361 if (! ext_register_operand (operands[1], VOIDmode))
10365 (define_expand "insv"
10366 [(set (zero_extract (match_operand 0 "register_operand" "")
10367 (match_operand 1 "const_int_operand" "")
10368 (match_operand 2 "const_int_operand" ""))
10369 (match_operand 3 "register_operand" ""))]
10372 rtx (*gen_mov_insv_1) (rtx, rtx);
10374 if (ix86_expand_pinsr (operands))
10377 /* Handle insertions to %ah et al. */
10378 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10381 /* From mips.md: insert_bit_field doesn't verify that our source
10382 matches the predicate, so check it again here. */
10383 if (! ext_register_operand (operands[0], VOIDmode))
10386 gen_mov_insv_1 = (TARGET_64BIT
10387 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10389 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10393 ;; %%% bts, btr, btc, bt.
10394 ;; In general these instructions are *slow* when applied to memory,
10395 ;; since they enforce atomic operation. When applied to registers,
10396 ;; it depends on the cpu implementation. They're never faster than
10397 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10398 ;; no point. But in 64-bit, we can't hold the relevant immediates
10399 ;; within the instruction itself, so operating on bits in the high
10400 ;; 32-bits of a register becomes easier.
10402 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10403 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10404 ;; negdf respectively, so they can never be disabled entirely.
10406 (define_insn "*btsq"
10407 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10409 (match_operand:DI 1 "const_0_to_63_operand" ""))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10413 "bts{q}\t{%1, %0|%0, %1}"
10414 [(set_attr "type" "alu1")
10415 (set_attr "prefix_0f" "1")
10416 (set_attr "mode" "DI")])
10418 (define_insn "*btrq"
10419 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10421 (match_operand:DI 1 "const_0_to_63_operand" ""))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10425 "btr{q}\t{%1, %0|%0, %1}"
10426 [(set_attr "type" "alu1")
10427 (set_attr "prefix_0f" "1")
10428 (set_attr "mode" "DI")])
10430 (define_insn "*btcq"
10431 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10433 (match_operand:DI 1 "const_0_to_63_operand" ""))
10434 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10437 "btc{q}\t{%1, %0|%0, %1}"
10438 [(set_attr "type" "alu1")
10439 (set_attr "prefix_0f" "1")
10440 (set_attr "mode" "DI")])
10442 ;; Allow Nocona to avoid these instructions if a register is available.
10445 [(match_scratch:DI 2 "r")
10446 (parallel [(set (zero_extract:DI
10447 (match_operand:DI 0 "register_operand" "")
10449 (match_operand:DI 1 "const_0_to_63_operand" ""))
10451 (clobber (reg:CC FLAGS_REG))])]
10452 "TARGET_64BIT && !TARGET_USE_BT"
10455 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10458 if (HOST_BITS_PER_WIDE_INT >= 64)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 else if (i < HOST_BITS_PER_WIDE_INT)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10463 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10465 op1 = immed_double_const (lo, hi, DImode);
10468 emit_move_insn (operands[2], op1);
10472 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10477 [(match_scratch:DI 2 "r")
10478 (parallel [(set (zero_extract:DI
10479 (match_operand:DI 0 "register_operand" "")
10481 (match_operand:DI 1 "const_0_to_63_operand" ""))
10483 (clobber (reg:CC FLAGS_REG))])]
10484 "TARGET_64BIT && !TARGET_USE_BT"
10487 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10490 if (HOST_BITS_PER_WIDE_INT >= 64)
10491 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492 else if (i < HOST_BITS_PER_WIDE_INT)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10495 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10497 op1 = immed_double_const (~lo, ~hi, DImode);
10500 emit_move_insn (operands[2], op1);
10504 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10509 [(match_scratch:DI 2 "r")
10510 (parallel [(set (zero_extract:DI
10511 (match_operand:DI 0 "register_operand" "")
10513 (match_operand:DI 1 "const_0_to_63_operand" ""))
10514 (not:DI (zero_extract:DI
10515 (match_dup 0) (const_int 1) (match_dup 1))))
10516 (clobber (reg:CC FLAGS_REG))])]
10517 "TARGET_64BIT && !TARGET_USE_BT"
10520 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10523 if (HOST_BITS_PER_WIDE_INT >= 64)
10524 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 else if (i < HOST_BITS_PER_WIDE_INT)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10528 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10530 op1 = immed_double_const (lo, hi, DImode);
10533 emit_move_insn (operands[2], op1);
10537 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10541 (define_insn "*bt<mode>"
10542 [(set (reg:CCC FLAGS_REG)
10544 (zero_extract:SWI48
10545 (match_operand:SWI48 0 "register_operand" "r")
10547 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10549 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10550 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10551 [(set_attr "type" "alu1")
10552 (set_attr "prefix_0f" "1")
10553 (set_attr "mode" "<MODE>")])
10555 ;; Store-flag instructions.
10557 ;; For all sCOND expanders, also expand the compare or test insn that
10558 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10560 (define_insn_and_split "*setcc_di_1"
10561 [(set (match_operand:DI 0 "register_operand" "=q")
10562 (match_operator:DI 1 "ix86_comparison_operator"
10563 [(reg FLAGS_REG) (const_int 0)]))]
10564 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10566 "&& reload_completed"
10567 [(set (match_dup 2) (match_dup 1))
10568 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10570 PUT_MODE (operands[1], QImode);
10571 operands[2] = gen_lowpart (QImode, operands[0]);
10574 (define_insn_and_split "*setcc_si_1_and"
10575 [(set (match_operand:SI 0 "register_operand" "=q")
10576 (match_operator:SI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "!TARGET_PARTIAL_REG_STALL
10580 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10582 "&& reload_completed"
10583 [(set (match_dup 2) (match_dup 1))
10584 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10585 (clobber (reg:CC FLAGS_REG))])]
10587 PUT_MODE (operands[1], QImode);
10588 operands[2] = gen_lowpart (QImode, operands[0]);
10591 (define_insn_and_split "*setcc_si_1_movzbl"
10592 [(set (match_operand:SI 0 "register_operand" "=q")
10593 (match_operator:SI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10595 "!TARGET_PARTIAL_REG_STALL
10596 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10598 "&& reload_completed"
10599 [(set (match_dup 2) (match_dup 1))
10600 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10602 PUT_MODE (operands[1], QImode);
10603 operands[2] = gen_lowpart (QImode, operands[0]);
10606 (define_insn "*setcc_qi"
10607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10608 (match_operator:QI 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)]))]
10612 [(set_attr "type" "setcc")
10613 (set_attr "mode" "QI")])
10615 (define_insn "*setcc_qi_slp"
10616 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10617 (match_operator:QI 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)]))]
10621 [(set_attr "type" "setcc")
10622 (set_attr "mode" "QI")])
10624 ;; In general it is not safe to assume too much about CCmode registers,
10625 ;; so simplify-rtx stops when it sees a second one. Under certain
10626 ;; conditions this is safe on x86, so help combine not create
10633 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10634 (ne:QI (match_operator 1 "ix86_comparison_operator"
10635 [(reg FLAGS_REG) (const_int 0)])
10638 [(set (match_dup 0) (match_dup 1))]
10639 "PUT_MODE (operands[1], QImode);")
10642 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10643 (ne:QI (match_operator 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)])
10647 [(set (match_dup 0) (match_dup 1))]
10648 "PUT_MODE (operands[1], QImode);")
10651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10652 (eq:QI (match_operator 1 "ix86_comparison_operator"
10653 [(reg FLAGS_REG) (const_int 0)])
10656 [(set (match_dup 0) (match_dup 1))]
10658 rtx new_op1 = copy_rtx (operands[1]);
10659 operands[1] = new_op1;
10660 PUT_MODE (new_op1, QImode);
10661 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10662 GET_MODE (XEXP (new_op1, 0))));
10664 /* Make sure that (a) the CCmode we have for the flags is strong
10665 enough for the reversed compare or (b) we have a valid FP compare. */
10666 if (! ix86_comparison_operator (new_op1, VOIDmode))
10671 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10672 (eq:QI (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10676 [(set (match_dup 0) (match_dup 1))]
10678 rtx new_op1 = copy_rtx (operands[1]);
10679 operands[1] = new_op1;
10680 PUT_MODE (new_op1, QImode);
10681 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10682 GET_MODE (XEXP (new_op1, 0))));
10684 /* Make sure that (a) the CCmode we have for the flags is strong
10685 enough for the reversed compare or (b) we have a valid FP compare. */
10686 if (! ix86_comparison_operator (new_op1, VOIDmode))
10690 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10691 ;; subsequent logical operations are used to imitate conditional moves.
10692 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10695 (define_insn "setcc_<mode>_sse"
10696 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10697 (match_operator:MODEF 3 "sse_comparison_operator"
10698 [(match_operand:MODEF 1 "register_operand" "0,x")
10699 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10700 "SSE_FLOAT_MODE_P (<MODE>mode)"
10702 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10703 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10704 [(set_attr "isa" "noavx,avx")
10705 (set_attr "type" "ssecmp")
10706 (set_attr "length_immediate" "1")
10707 (set_attr "prefix" "orig,vex")
10708 (set_attr "mode" "<MODE>")])
10710 ;; Basic conditional jump instructions.
10711 ;; We ignore the overflow flag for signed branch instructions.
10713 (define_insn "*jcc_1"
10715 (if_then_else (match_operator 1 "ix86_comparison_operator"
10716 [(reg FLAGS_REG) (const_int 0)])
10717 (label_ref (match_operand 0 "" ""))
10721 [(set_attr "type" "ibr")
10722 (set_attr "modrm" "0")
10723 (set (attr "length")
10724 (if_then_else (and (ge (minus (match_dup 0) (pc))
10726 (lt (minus (match_dup 0) (pc))
10731 (define_insn "*jcc_2"
10733 (if_then_else (match_operator 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)])
10736 (label_ref (match_operand 0 "" ""))))]
10739 [(set_attr "type" "ibr")
10740 (set_attr "modrm" "0")
10741 (set (attr "length")
10742 (if_then_else (and (ge (minus (match_dup 0) (pc))
10744 (lt (minus (match_dup 0) (pc))
10749 ;; In general it is not safe to assume too much about CCmode registers,
10750 ;; so simplify-rtx stops when it sees a second one. Under certain
10751 ;; conditions this is safe on x86, so help combine not create
10759 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10760 [(reg FLAGS_REG) (const_int 0)])
10762 (label_ref (match_operand 1 "" ""))
10766 (if_then_else (match_dup 0)
10767 (label_ref (match_dup 1))
10769 "PUT_MODE (operands[0], VOIDmode);")
10773 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10774 [(reg FLAGS_REG) (const_int 0)])
10776 (label_ref (match_operand 1 "" ""))
10780 (if_then_else (match_dup 0)
10781 (label_ref (match_dup 1))
10784 rtx new_op0 = copy_rtx (operands[0]);
10785 operands[0] = new_op0;
10786 PUT_MODE (new_op0, VOIDmode);
10787 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10788 GET_MODE (XEXP (new_op0, 0))));
10790 /* Make sure that (a) the CCmode we have for the flags is strong
10791 enough for the reversed compare or (b) we have a valid FP compare. */
10792 if (! ix86_comparison_operator (new_op0, VOIDmode))
10796 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10797 ;; pass generates from shift insn with QImode operand. Actually, the mode
10798 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10799 ;; appropriate modulo of the bit offset value.
10801 (define_insn_and_split "*jcc_bt<mode>"
10803 (if_then_else (match_operator 0 "bt_comparison_operator"
10804 [(zero_extract:SWI48
10805 (match_operand:SWI48 1 "register_operand" "r")
10808 (match_operand:QI 2 "register_operand" "r")))
10810 (label_ref (match_operand 3 "" ""))
10812 (clobber (reg:CC FLAGS_REG))]
10813 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10816 [(set (reg:CCC FLAGS_REG)
10818 (zero_extract:SWI48
10824 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10825 (label_ref (match_dup 3))
10828 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10830 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10833 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10834 ;; also for DImode, this is what combine produces.
10835 (define_insn_and_split "*jcc_bt<mode>_mask"
10837 (if_then_else (match_operator 0 "bt_comparison_operator"
10838 [(zero_extract:SWI48
10839 (match_operand:SWI48 1 "register_operand" "r")
10842 (match_operand:SI 2 "register_operand" "r")
10843 (match_operand:SI 3 "const_int_operand" "n")))])
10844 (label_ref (match_operand 4 "" ""))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10848 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10849 == GET_MODE_BITSIZE (<MODE>mode)-1"
10852 [(set (reg:CCC FLAGS_REG)
10854 (zero_extract:SWI48
10860 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10861 (label_ref (match_dup 4))
10864 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10866 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10869 (define_insn_and_split "*jcc_btsi_1"
10871 (if_then_else (match_operator 0 "bt_comparison_operator"
10874 (match_operand:SI 1 "register_operand" "r")
10875 (match_operand:QI 2 "register_operand" "r"))
10878 (label_ref (match_operand 3 "" ""))
10880 (clobber (reg:CC FLAGS_REG))]
10881 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10884 [(set (reg:CCC FLAGS_REG)
10892 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10893 (label_ref (match_dup 3))
10896 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10898 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10901 ;; avoid useless masking of bit offset operand
10902 (define_insn_and_split "*jcc_btsi_mask_1"
10905 (match_operator 0 "bt_comparison_operator"
10908 (match_operand:SI 1 "register_operand" "r")
10911 (match_operand:SI 2 "register_operand" "r")
10912 (match_operand:SI 3 "const_int_operand" "n")) 0))
10915 (label_ref (match_operand 4 "" ""))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10919 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10922 [(set (reg:CCC FLAGS_REG)
10930 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10931 (label_ref (match_dup 4))
10933 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10935 ;; Define combination compare-and-branch fp compare instructions to help
10938 (define_insn "*fp_jcc_1_387"
10940 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10941 [(match_operand 1 "register_operand" "f")
10942 (match_operand 2 "nonimmediate_operand" "fm")])
10943 (label_ref (match_operand 3 "" ""))
10945 (clobber (reg:CCFP FPSR_REG))
10946 (clobber (reg:CCFP FLAGS_REG))
10947 (clobber (match_scratch:HI 4 "=a"))]
10949 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10951 && SELECT_CC_MODE (GET_CODE (operands[0]),
10952 operands[1], operands[2]) == CCFPmode
10956 (define_insn "*fp_jcc_1r_387"
10958 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10959 [(match_operand 1 "register_operand" "f")
10960 (match_operand 2 "nonimmediate_operand" "fm")])
10962 (label_ref (match_operand 3 "" ""))))
10963 (clobber (reg:CCFP FPSR_REG))
10964 (clobber (reg:CCFP FLAGS_REG))
10965 (clobber (match_scratch:HI 4 "=a"))]
10967 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10968 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10969 && SELECT_CC_MODE (GET_CODE (operands[0]),
10970 operands[1], operands[2]) == CCFPmode
10974 (define_insn "*fp_jcc_2_387"
10976 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10977 [(match_operand 1 "register_operand" "f")
10978 (match_operand 2 "register_operand" "f")])
10979 (label_ref (match_operand 3 "" ""))
10981 (clobber (reg:CCFP FPSR_REG))
10982 (clobber (reg:CCFP FLAGS_REG))
10983 (clobber (match_scratch:HI 4 "=a"))]
10984 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10985 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10989 (define_insn "*fp_jcc_2r_387"
10991 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10992 [(match_operand 1 "register_operand" "f")
10993 (match_operand 2 "register_operand" "f")])
10995 (label_ref (match_operand 3 "" ""))))
10996 (clobber (reg:CCFP FPSR_REG))
10997 (clobber (reg:CCFP FLAGS_REG))
10998 (clobber (match_scratch:HI 4 "=a"))]
10999 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11000 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11004 (define_insn "*fp_jcc_3_387"
11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007 [(match_operand 1 "register_operand" "f")
11008 (match_operand 2 "const0_operand" "")])
11009 (label_ref (match_operand 3 "" ""))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 4 "=a"))]
11014 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11015 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11016 && SELECT_CC_MODE (GET_CODE (operands[0]),
11017 operands[1], operands[2]) == CCFPmode
11023 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11024 [(match_operand 1 "register_operand" "")
11025 (match_operand 2 "nonimmediate_operand" "")])
11026 (match_operand 3 "" "")
11027 (match_operand 4 "" "")))
11028 (clobber (reg:CCFP FPSR_REG))
11029 (clobber (reg:CCFP FLAGS_REG))]
11033 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11034 operands[3], operands[4], NULL_RTX, NULL_RTX);
11040 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11041 [(match_operand 1 "register_operand" "")
11042 (match_operand 2 "general_operand" "")])
11043 (match_operand 3 "" "")
11044 (match_operand 4 "" "")))
11045 (clobber (reg:CCFP FPSR_REG))
11046 (clobber (reg:CCFP FLAGS_REG))
11047 (clobber (match_scratch:HI 5 "=a"))]
11051 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11052 operands[3], operands[4], operands[5], NULL_RTX);
11056 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11057 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11058 ;; with a precedence over other operators and is always put in the first
11059 ;; place. Swap condition and operands to match ficom instruction.
11061 (define_insn "*fp_jcc_4_<mode>_387"
11064 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11065 [(match_operator 1 "float_operator"
11066 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11067 (match_operand 3 "register_operand" "f,f")])
11068 (label_ref (match_operand 4 "" ""))
11070 (clobber (reg:CCFP FPSR_REG))
11071 (clobber (reg:CCFP FLAGS_REG))
11072 (clobber (match_scratch:HI 5 "=a,a"))]
11073 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11074 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11075 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11076 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11083 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11084 [(match_operator 1 "float_operator"
11085 [(match_operand:SWI24 2 "memory_operand" "")])
11086 (match_operand 3 "register_operand" "")])
11087 (match_operand 4 "" "")
11088 (match_operand 5 "" "")))
11089 (clobber (reg:CCFP FPSR_REG))
11090 (clobber (reg:CCFP FLAGS_REG))
11091 (clobber (match_scratch:HI 6 "=a"))]
11095 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11097 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11098 operands[3], operands[7],
11099 operands[4], operands[5], operands[6], NULL_RTX);
11103 ;; %%% Kill this when reload knows how to do it.
11107 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11108 [(match_operator 1 "float_operator"
11109 [(match_operand:SWI24 2 "register_operand" "")])
11110 (match_operand 3 "register_operand" "")])
11111 (match_operand 4 "" "")
11112 (match_operand 5 "" "")))
11113 (clobber (reg:CCFP FPSR_REG))
11114 (clobber (reg:CCFP FLAGS_REG))
11115 (clobber (match_scratch:HI 6 "=a"))]
11119 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11120 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11122 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11123 operands[3], operands[7],
11124 operands[4], operands[5], operands[6], operands[2]);
11128 ;; Unconditional and other jump instructions
11130 (define_insn "jump"
11132 (label_ref (match_operand 0 "" "")))]
11135 [(set_attr "type" "ibr")
11136 (set (attr "length")
11137 (if_then_else (and (ge (minus (match_dup 0) (pc))
11139 (lt (minus (match_dup 0) (pc))
11143 (set_attr "modrm" "0")])
11145 (define_expand "indirect_jump"
11146 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11148 (define_insn "*indirect_jump"
11149 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11152 [(set_attr "type" "ibr")
11153 (set_attr "length_immediate" "0")])
11155 (define_expand "tablejump"
11156 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11157 (use (label_ref (match_operand 1 "" "")))])]
11160 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161 relative. Convert the relative address to an absolute address. */
11165 enum rtx_code code;
11167 /* We can't use @GOTOFF for text labels on VxWorks;
11168 see gotoff_operand. */
11169 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11173 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11175 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11179 op1 = pic_offset_table_rtx;
11184 op0 = pic_offset_table_rtx;
11188 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11191 else if (TARGET_X32)
11192 operands[0] = convert_memory_address (Pmode, operands[0]);
11195 (define_insn "*tablejump_1"
11196 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11197 (use (label_ref (match_operand 1 "" "")))]
11200 [(set_attr "type" "ibr")
11201 (set_attr "length_immediate" "0")])
11203 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11206 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11207 (set (match_operand:QI 1 "register_operand" "")
11208 (match_operator:QI 2 "ix86_comparison_operator"
11209 [(reg FLAGS_REG) (const_int 0)]))
11210 (set (match_operand 3 "q_regs_operand" "")
11211 (zero_extend (match_dup 1)))]
11212 "(peep2_reg_dead_p (3, operands[1])
11213 || operands_match_p (operands[1], operands[3]))
11214 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11215 [(set (match_dup 4) (match_dup 0))
11216 (set (strict_low_part (match_dup 5))
11219 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11220 operands[5] = gen_lowpart (QImode, operands[3]);
11221 ix86_expand_clear (operands[3]);
11224 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11227 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11228 (set (match_operand:QI 1 "register_operand" "")
11229 (match_operator:QI 2 "ix86_comparison_operator"
11230 [(reg FLAGS_REG) (const_int 0)]))
11231 (parallel [(set (match_operand 3 "q_regs_operand" "")
11232 (zero_extend (match_dup 1)))
11233 (clobber (reg:CC FLAGS_REG))])]
11234 "(peep2_reg_dead_p (3, operands[1])
11235 || operands_match_p (operands[1], operands[3]))
11236 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11237 [(set (match_dup 4) (match_dup 0))
11238 (set (strict_low_part (match_dup 5))
11241 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11242 operands[5] = gen_lowpart (QImode, operands[3]);
11243 ix86_expand_clear (operands[3]);
11246 ;; Call instructions.
11248 ;; The predicates normally associated with named expanders are not properly
11249 ;; checked for calls. This is a bug in the generic code, but it isn't that
11250 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11252 ;; P6 processors will jump to the address after the decrement when %esp
11253 ;; is used as a call operand, so they will execute return address as a code.
11254 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11256 ;; Register constraint for call instruction.
11257 (define_mode_attr c [(SI "l") (DI "r")])
11259 ;; Call subroutine returning no value.
11261 (define_expand "call"
11262 [(call (match_operand:QI 0 "" "")
11263 (match_operand 1 "" ""))
11264 (use (match_operand 2 "" ""))]
11267 ix86_expand_call (NULL, operands[0], operands[1],
11268 operands[2], NULL, false);
11272 (define_expand "sibcall"
11273 [(call (match_operand:QI 0 "" "")
11274 (match_operand 1 "" ""))
11275 (use (match_operand 2 "" ""))]
11278 ix86_expand_call (NULL, operands[0], operands[1],
11279 operands[2], NULL, true);
11283 (define_insn_and_split "*call_vzeroupper"
11284 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11285 (match_operand 1 "" ""))
11286 (unspec [(match_operand 2 "const_int_operand" "")]
11287 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11288 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11290 "&& reload_completed"
11292 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11293 [(set_attr "type" "call")])
11295 (define_insn "*call"
11296 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11297 (match_operand 1 "" ""))]
11298 "!SIBLING_CALL_P (insn)"
11299 "* return ix86_output_call_insn (insn, operands[0]);"
11300 [(set_attr "type" "call")])
11302 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11303 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11304 (match_operand 1 "" ""))
11305 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11306 (clobber (reg:TI XMM6_REG))
11307 (clobber (reg:TI XMM7_REG))
11308 (clobber (reg:TI XMM8_REG))
11309 (clobber (reg:TI XMM9_REG))
11310 (clobber (reg:TI XMM10_REG))
11311 (clobber (reg:TI XMM11_REG))
11312 (clobber (reg:TI XMM12_REG))
11313 (clobber (reg:TI XMM13_REG))
11314 (clobber (reg:TI XMM14_REG))
11315 (clobber (reg:TI XMM15_REG))
11316 (clobber (reg:DI SI_REG))
11317 (clobber (reg:DI DI_REG))
11318 (unspec [(match_operand 2 "const_int_operand" "")]
11319 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11320 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11322 "&& reload_completed"
11324 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11325 [(set_attr "type" "call")])
11327 (define_insn "*call_rex64_ms_sysv"
11328 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11329 (match_operand 1 "" ""))
11330 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11331 (clobber (reg:TI XMM6_REG))
11332 (clobber (reg:TI XMM7_REG))
11333 (clobber (reg:TI XMM8_REG))
11334 (clobber (reg:TI XMM9_REG))
11335 (clobber (reg:TI XMM10_REG))
11336 (clobber (reg:TI XMM11_REG))
11337 (clobber (reg:TI XMM12_REG))
11338 (clobber (reg:TI XMM13_REG))
11339 (clobber (reg:TI XMM14_REG))
11340 (clobber (reg:TI XMM15_REG))
11341 (clobber (reg:DI SI_REG))
11342 (clobber (reg:DI DI_REG))]
11343 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11344 "* return ix86_output_call_insn (insn, operands[0]);"
11345 [(set_attr "type" "call")])
11347 (define_insn_and_split "*sibcall_vzeroupper"
11348 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11349 (match_operand 1 "" ""))
11350 (unspec [(match_operand 2 "const_int_operand" "")]
11351 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11352 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11354 "&& reload_completed"
11356 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11357 [(set_attr "type" "call")])
11359 (define_insn "*sibcall"
11360 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11361 (match_operand 1 "" ""))]
11362 "SIBLING_CALL_P (insn)"
11363 "* return ix86_output_call_insn (insn, operands[0]);"
11364 [(set_attr "type" "call")])
11366 (define_expand "call_pop"
11367 [(parallel [(call (match_operand:QI 0 "" "")
11368 (match_operand:SI 1 "" ""))
11369 (set (reg:SI SP_REG)
11370 (plus:SI (reg:SI SP_REG)
11371 (match_operand:SI 3 "" "")))])]
11374 ix86_expand_call (NULL, operands[0], operands[1],
11375 operands[2], operands[3], false);
11379 (define_insn_and_split "*call_pop_vzeroupper"
11380 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11381 (match_operand:SI 1 "" ""))
11382 (set (reg:SI SP_REG)
11383 (plus:SI (reg:SI SP_REG)
11384 (match_operand:SI 2 "immediate_operand" "i")))
11385 (unspec [(match_operand 3 "const_int_operand" "")]
11386 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11387 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11389 "&& reload_completed"
11391 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11392 [(set_attr "type" "call")])
11394 (define_insn "*call_pop"
11395 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11396 (match_operand 1 "" ""))
11397 (set (reg:SI SP_REG)
11398 (plus:SI (reg:SI SP_REG)
11399 (match_operand:SI 2 "immediate_operand" "i")))]
11400 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11401 "* return ix86_output_call_insn (insn, operands[0]);"
11402 [(set_attr "type" "call")])
11404 (define_insn_and_split "*sibcall_pop_vzeroupper"
11405 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11406 (match_operand 1 "" ""))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 2 "immediate_operand" "i")))
11410 (unspec [(match_operand 3 "const_int_operand" "")]
11411 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11414 "&& reload_completed"
11416 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11417 [(set_attr "type" "call")])
11419 (define_insn "*sibcall_pop"
11420 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11421 (match_operand 1 "" ""))
11422 (set (reg:SI SP_REG)
11423 (plus:SI (reg:SI SP_REG)
11424 (match_operand:SI 2 "immediate_operand" "i")))]
11425 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11426 "* return ix86_output_call_insn (insn, operands[0]);"
11427 [(set_attr "type" "call")])
11429 ;; Call subroutine, returning value in operand 0
11431 (define_expand "call_value"
11432 [(set (match_operand 0 "" "")
11433 (call (match_operand:QI 1 "" "")
11434 (match_operand 2 "" "")))
11435 (use (match_operand 3 "" ""))]
11438 ix86_expand_call (operands[0], operands[1], operands[2],
11439 operands[3], NULL, false);
11443 (define_expand "sibcall_value"
11444 [(set (match_operand 0 "" "")
11445 (call (match_operand:QI 1 "" "")
11446 (match_operand 2 "" "")))
11447 (use (match_operand 3 "" ""))]
11450 ix86_expand_call (operands[0], operands[1], operands[2],
11451 operands[3], NULL, true);
11455 (define_insn_and_split "*call_value_vzeroupper"
11456 [(set (match_operand 0 "" "")
11457 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458 (match_operand 2 "" "")))
11459 (unspec [(match_operand 3 "const_int_operand" "")]
11460 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11461 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11463 "&& reload_completed"
11465 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11466 [(set_attr "type" "callv")])
11468 (define_insn "*call_value"
11469 [(set (match_operand 0 "" "")
11470 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11471 (match_operand 2 "" "")))]
11472 "!SIBLING_CALL_P (insn)"
11473 "* return ix86_output_call_insn (insn, operands[1]);"
11474 [(set_attr "type" "callv")])
11476 (define_insn_and_split "*sibcall_value_vzeroupper"
11477 [(set (match_operand 0 "" "")
11478 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479 (match_operand 2 "" "")))
11480 (unspec [(match_operand 3 "const_int_operand" "")]
11481 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11482 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11484 "&& reload_completed"
11486 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11487 [(set_attr "type" "callv")])
11489 (define_insn "*sibcall_value"
11490 [(set (match_operand 0 "" "")
11491 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11492 (match_operand 2 "" "")))]
11493 "SIBLING_CALL_P (insn)"
11494 "* return ix86_output_call_insn (insn, operands[1]);"
11495 [(set_attr "type" "callv")])
11497 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11498 [(set (match_operand 0 "" "")
11499 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11500 (match_operand 2 "" "")))
11501 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11502 (clobber (reg:TI XMM6_REG))
11503 (clobber (reg:TI XMM7_REG))
11504 (clobber (reg:TI XMM8_REG))
11505 (clobber (reg:TI XMM9_REG))
11506 (clobber (reg:TI XMM10_REG))
11507 (clobber (reg:TI XMM11_REG))
11508 (clobber (reg:TI XMM12_REG))
11509 (clobber (reg:TI XMM13_REG))
11510 (clobber (reg:TI XMM14_REG))
11511 (clobber (reg:TI XMM15_REG))
11512 (clobber (reg:DI SI_REG))
11513 (clobber (reg:DI DI_REG))
11514 (unspec [(match_operand 3 "const_int_operand" "")]
11515 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11516 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11518 "&& reload_completed"
11520 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11521 [(set_attr "type" "callv")])
11523 (define_insn "*call_value_rex64_ms_sysv"
11524 [(set (match_operand 0 "" "")
11525 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11526 (match_operand 2 "" "")))
11527 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11528 (clobber (reg:TI XMM6_REG))
11529 (clobber (reg:TI XMM7_REG))
11530 (clobber (reg:TI XMM8_REG))
11531 (clobber (reg:TI XMM9_REG))
11532 (clobber (reg:TI XMM10_REG))
11533 (clobber (reg:TI XMM11_REG))
11534 (clobber (reg:TI XMM12_REG))
11535 (clobber (reg:TI XMM13_REG))
11536 (clobber (reg:TI XMM14_REG))
11537 (clobber (reg:TI XMM15_REG))
11538 (clobber (reg:DI SI_REG))
11539 (clobber (reg:DI DI_REG))]
11540 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[1]);"
11542 [(set_attr "type" "callv")])
11544 (define_expand "call_value_pop"
11545 [(parallel [(set (match_operand 0 "" "")
11546 (call (match_operand:QI 1 "" "")
11547 (match_operand:SI 2 "" "")))
11548 (set (reg:SI SP_REG)
11549 (plus:SI (reg:SI SP_REG)
11550 (match_operand:SI 4 "" "")))])]
11553 ix86_expand_call (operands[0], operands[1], operands[2],
11554 operands[3], operands[4], false);
11558 (define_insn_and_split "*call_value_pop_vzeroupper"
11559 [(set (match_operand 0 "" "")
11560 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11561 (match_operand 2 "" "")))
11562 (set (reg:SI SP_REG)
11563 (plus:SI (reg:SI SP_REG)
11564 (match_operand:SI 3 "immediate_operand" "i")))
11565 (unspec [(match_operand 4 "const_int_operand" "")]
11566 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11567 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11569 "&& reload_completed"
11571 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11572 [(set_attr "type" "callv")])
11574 (define_insn "*call_value_pop"
11575 [(set (match_operand 0 "" "")
11576 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11577 (match_operand 2 "" "")))
11578 (set (reg:SI SP_REG)
11579 (plus:SI (reg:SI SP_REG)
11580 (match_operand:SI 3 "immediate_operand" "i")))]
11581 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11582 "* return ix86_output_call_insn (insn, operands[1]);"
11583 [(set_attr "type" "callv")])
11585 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11586 [(set (match_operand 0 "" "")
11587 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11588 (match_operand 2 "" "")))
11589 (set (reg:SI SP_REG)
11590 (plus:SI (reg:SI SP_REG)
11591 (match_operand:SI 3 "immediate_operand" "i")))
11592 (unspec [(match_operand 4 "const_int_operand" "")]
11593 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11594 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11596 "&& reload_completed"
11598 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11599 [(set_attr "type" "callv")])
11601 (define_insn "*sibcall_value_pop"
11602 [(set (match_operand 0 "" "")
11603 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11604 (match_operand 2 "" "")))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 3 "immediate_operand" "i")))]
11608 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11609 "* return ix86_output_call_insn (insn, operands[1]);"
11610 [(set_attr "type" "callv")])
11612 ;; Call subroutine returning any type.
11614 (define_expand "untyped_call"
11615 [(parallel [(call (match_operand 0 "" "")
11617 (match_operand 1 "" "")
11618 (match_operand 2 "" "")])]
11623 /* In order to give reg-stack an easier job in validating two
11624 coprocessor registers as containing a possible return value,
11625 simply pretend the untyped call returns a complex long double
11628 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11629 and should have the default ABI. */
11631 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11632 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11633 operands[0], const0_rtx,
11634 GEN_INT ((TARGET_64BIT
11635 ? (ix86_abi == SYSV_ABI
11636 ? X86_64_SSE_REGPARM_MAX
11637 : X86_64_MS_SSE_REGPARM_MAX)
11638 : X86_32_SSE_REGPARM_MAX)
11642 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11644 rtx set = XVECEXP (operands[2], 0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11652 emit_insn (gen_blockage ());
11657 ;; Prologue and epilogue instructions
11659 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11660 ;; all of memory. This blocks insns from being moved across this point.
11662 (define_insn "blockage"
11663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11666 [(set_attr "length" "0")])
11668 ;; Do not schedule instructions accessing memory across this point.
11670 (define_expand "memory_blockage"
11671 [(set (match_dup 0)
11672 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11675 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11676 MEM_VOLATILE_P (operands[0]) = 1;
11679 (define_insn "*memory_blockage"
11680 [(set (match_operand:BLK 0 "" "")
11681 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11684 [(set_attr "length" "0")])
11686 ;; As USE insns aren't meaningful after reload, this is used instead
11687 ;; to prevent deleting instructions setting registers for PIC code
11688 (define_insn "prologue_use"
11689 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11692 [(set_attr "length" "0")])
11694 ;; Insn emitted into the body of a function to return from a function.
11695 ;; This is only done if the function's epilogue is known to be simple.
11696 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11698 (define_expand "return"
11700 "ix86_can_use_return_insn_p ()"
11702 if (crtl->args.pops_args)
11704 rtx popc = GEN_INT (crtl->args.pops_args);
11705 emit_jump_insn (gen_simple_return_pop_internal (popc));
11710 ;; We need to disable this for TARGET_SEH, as otherwise
11711 ;; shrink-wrapped prologue gets enabled too. This might exceed
11712 ;; the maximum size of prologue in unwind information.
11714 (define_expand "simple_return"
11718 if (crtl->args.pops_args)
11720 rtx popc = GEN_INT (crtl->args.pops_args);
11721 emit_jump_insn (gen_simple_return_pop_internal (popc));
11726 (define_insn "simple_return_internal"
11730 [(set_attr "length" "1")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11735 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11736 ;; instruction Athlon and K8 have.
11738 (define_insn "simple_return_internal_long"
11740 (unspec [(const_int 0)] UNSPEC_REP)]
11743 [(set_attr "length" "2")
11744 (set_attr "atom_unit" "jeu")
11745 (set_attr "length_immediate" "0")
11746 (set_attr "prefix_rep" "1")
11747 (set_attr "modrm" "0")])
11749 (define_insn "simple_return_pop_internal"
11751 (use (match_operand:SI 0 "const_int_operand" ""))]
11754 [(set_attr "length" "3")
11755 (set_attr "atom_unit" "jeu")
11756 (set_attr "length_immediate" "2")
11757 (set_attr "modrm" "0")])
11759 (define_insn "simple_return_indirect_internal"
11761 (use (match_operand:SI 0 "register_operand" "r"))]
11764 [(set_attr "type" "ibr")
11765 (set_attr "length_immediate" "0")])
11771 [(set_attr "length" "1")
11772 (set_attr "length_immediate" "0")
11773 (set_attr "modrm" "0")])
11775 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11776 (define_insn "nops"
11777 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11781 int num = INTVAL (operands[0]);
11783 gcc_assert (num >= 1 && num <= 8);
11786 fputs ("\tnop\n", asm_out_file);
11790 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11791 (set_attr "length_immediate" "0")
11792 (set_attr "modrm" "0")])
11794 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11795 ;; branch prediction penalty for the third jump in a 16-byte
11799 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11803 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11805 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11806 The align insn is used to avoid 3 jump instructions in the row to improve
11807 branch prediction and the benefits hardly outweigh the cost of extra 8
11808 nops on the average inserted by full alignment pseudo operation. */
11812 [(set_attr "length" "16")])
11814 (define_expand "prologue"
11817 "ix86_expand_prologue (); DONE;")
11819 (define_insn "set_got"
11820 [(set (match_operand:SI 0 "register_operand" "=r")
11821 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11822 (clobber (reg:CC FLAGS_REG))]
11824 "* return output_set_got (operands[0], NULL_RTX);"
11825 [(set_attr "type" "multi")
11826 (set_attr "length" "12")])
11828 (define_insn "set_got_labelled"
11829 [(set (match_operand:SI 0 "register_operand" "=r")
11830 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11832 (clobber (reg:CC FLAGS_REG))]
11834 "* return output_set_got (operands[0], operands[1]);"
11835 [(set_attr "type" "multi")
11836 (set_attr "length" "12")])
11838 (define_insn "set_got_rex64"
11839 [(set (match_operand:DI 0 "register_operand" "=r")
11840 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11842 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11843 [(set_attr "type" "lea")
11844 (set_attr "length_address" "4")
11845 (set_attr "mode" "DI")])
11847 (define_insn "set_rip_rex64"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11851 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11852 [(set_attr "type" "lea")
11853 (set_attr "length_address" "4")
11854 (set_attr "mode" "DI")])
11856 (define_insn "set_got_offset_rex64"
11857 [(set (match_operand:DI 0 "register_operand" "=r")
11859 [(label_ref (match_operand 1 "" ""))]
11860 UNSPEC_SET_GOT_OFFSET))]
11862 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11863 [(set_attr "type" "imov")
11864 (set_attr "length_immediate" "0")
11865 (set_attr "length_address" "8")
11866 (set_attr "mode" "DI")])
11868 (define_expand "epilogue"
11871 "ix86_expand_epilogue (1); DONE;")
11873 (define_expand "sibcall_epilogue"
11876 "ix86_expand_epilogue (0); DONE;")
11878 (define_expand "eh_return"
11879 [(use (match_operand 0 "register_operand" ""))]
11882 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11884 /* Tricky bit: we write the address of the handler to which we will
11885 be returning into someone else's stack frame, one word below the
11886 stack address we wish to restore. */
11887 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11888 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11889 tmp = gen_rtx_MEM (Pmode, tmp);
11890 emit_move_insn (tmp, ra);
11892 emit_jump_insn (gen_eh_return_internal ());
11897 (define_insn_and_split "eh_return_internal"
11901 "epilogue_completed"
11903 "ix86_expand_epilogue (2); DONE;")
11905 (define_insn "leave"
11906 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11907 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11908 (clobber (mem:BLK (scratch)))]
11911 [(set_attr "type" "leave")])
11913 (define_insn "leave_rex64"
11914 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11915 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11916 (clobber (mem:BLK (scratch)))]
11919 [(set_attr "type" "leave")])
11921 ;; Handle -fsplit-stack.
11923 (define_expand "split_stack_prologue"
11927 ix86_expand_split_stack_prologue ();
11931 ;; In order to support the call/return predictor, we use a return
11932 ;; instruction which the middle-end doesn't see.
11933 (define_insn "split_stack_return"
11934 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11935 UNSPECV_SPLIT_STACK_RETURN)]
11938 if (operands[0] == const0_rtx)
11943 [(set_attr "atom_unit" "jeu")
11944 (set_attr "modrm" "0")
11945 (set (attr "length")
11946 (if_then_else (match_operand:SI 0 "const0_operand" "")
11949 (set (attr "length_immediate")
11950 (if_then_else (match_operand:SI 0 "const0_operand" "")
11954 ;; If there are operand 0 bytes available on the stack, jump to
11957 (define_expand "split_stack_space_check"
11958 [(set (pc) (if_then_else
11959 (ltu (minus (reg SP_REG)
11960 (match_operand 0 "register_operand" ""))
11961 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11962 (label_ref (match_operand 1 "" ""))
11966 rtx reg, size, limit;
11968 reg = gen_reg_rtx (Pmode);
11969 size = force_reg (Pmode, operands[0]);
11970 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11971 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11972 UNSPEC_STACK_CHECK);
11973 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11974 ix86_expand_branch (GEU, reg, limit, operands[1]);
11979 ;; Bit manipulation instructions.
11981 (define_expand "ffs<mode>2"
11982 [(set (match_dup 2) (const_int -1))
11983 (parallel [(set (reg:CCZ FLAGS_REG)
11985 (match_operand:SWI48 1 "nonimmediate_operand" "")
11987 (set (match_operand:SWI48 0 "register_operand" "")
11988 (ctz:SWI48 (match_dup 1)))])
11989 (set (match_dup 0) (if_then_else:SWI48
11990 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11993 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11994 (clobber (reg:CC FLAGS_REG))])]
11997 if (<MODE>mode == SImode && !TARGET_CMOVE)
11999 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12002 operands[2] = gen_reg_rtx (<MODE>mode);
12005 (define_insn_and_split "ffssi2_no_cmove"
12006 [(set (match_operand:SI 0 "register_operand" "=r")
12007 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12008 (clobber (match_scratch:SI 2 "=&q"))
12009 (clobber (reg:CC FLAGS_REG))]
12012 "&& reload_completed"
12013 [(parallel [(set (reg:CCZ FLAGS_REG)
12014 (compare:CCZ (match_dup 1) (const_int 0)))
12015 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12016 (set (strict_low_part (match_dup 3))
12017 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12018 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12019 (clobber (reg:CC FLAGS_REG))])
12020 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12021 (clobber (reg:CC FLAGS_REG))])
12022 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12023 (clobber (reg:CC FLAGS_REG))])]
12025 operands[3] = gen_lowpart (QImode, operands[2]);
12026 ix86_expand_clear (operands[2]);
12029 (define_insn "*ffs<mode>_1"
12030 [(set (reg:CCZ FLAGS_REG)
12031 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12033 (set (match_operand:SWI48 0 "register_operand" "=r")
12034 (ctz:SWI48 (match_dup 1)))]
12036 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set_attr "mode" "<MODE>")])
12041 (define_insn "ctz<mode>2"
12042 [(set (match_operand:SWI248 0 "register_operand" "=r")
12043 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12044 (clobber (reg:CC FLAGS_REG))]
12048 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12050 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12052 [(set_attr "type" "alu1")
12053 (set_attr "prefix_0f" "1")
12054 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12055 (set_attr "mode" "<MODE>")])
12057 (define_expand "clz<mode>2"
12059 [(set (match_operand:SWI248 0 "register_operand" "")
12062 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12063 (clobber (reg:CC FLAGS_REG))])
12065 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12066 (clobber (reg:CC FLAGS_REG))])]
12071 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12074 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12077 (define_insn "clz<mode>2_lzcnt"
12078 [(set (match_operand:SWI248 0 "register_operand" "=r")
12079 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12080 (clobber (reg:CC FLAGS_REG))]
12082 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12083 [(set_attr "prefix_rep" "1")
12084 (set_attr "type" "bitmanip")
12085 (set_attr "mode" "<MODE>")])
12087 ;; BMI instructions.
12088 (define_insn "*bmi_andn_<mode>"
12089 [(set (match_operand:SWI48 0 "register_operand" "=r")
12092 (match_operand:SWI48 1 "register_operand" "r"))
12093 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12094 (clobber (reg:CC FLAGS_REG))]
12096 "andn\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "bitmanip")
12098 (set_attr "mode" "<MODE>")])
12100 (define_insn "bmi_bextr_<mode>"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12103 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12105 (clobber (reg:CC FLAGS_REG))]
12107 "bextr\t{%2, %1, %0|%0, %1, %2}"
12108 [(set_attr "type" "bitmanip")
12109 (set_attr "mode" "<MODE>")])
12111 (define_insn "*bmi_blsi_<mode>"
12112 [(set (match_operand:SWI48 0 "register_operand" "=r")
12115 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12117 (clobber (reg:CC FLAGS_REG))]
12119 "blsi\t{%1, %0|%0, %1}"
12120 [(set_attr "type" "bitmanip")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "*bmi_blsmsk_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (clobber (reg:CC FLAGS_REG))]
12132 "blsmsk\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12136 (define_insn "*bmi_blsr_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12143 (clobber (reg:CC FLAGS_REG))]
12145 "blsr\t{%1, %0|%0, %1}"
12146 [(set_attr "type" "bitmanip")
12147 (set_attr "mode" "<MODE>")])
12149 ;; BMI2 instructions.
12150 (define_insn "bmi2_bzhi_<mode>3"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12152 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12153 (lshiftrt:SWI48 (const_int -1)
12154 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12155 (clobber (reg:CC FLAGS_REG))]
12157 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "prefix" "vex")
12160 (set_attr "mode" "<MODE>")])
12162 (define_insn "bmi2_pdep_<mode>3"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12168 "pdep\t{%2, %1, %0|%0, %1, %2}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "prefix" "vex")
12171 (set_attr "mode" "<MODE>")])
12173 (define_insn "bmi2_pext_<mode>3"
12174 [(set (match_operand:SWI48 0 "register_operand" "=r")
12175 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12176 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12179 "pext\t{%2, %1, %0|%0, %1, %2}"
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "prefix" "vex")
12182 (set_attr "mode" "<MODE>")])
12184 ;; TBM instructions.
12185 (define_insn "tbm_bextri_<mode>"
12186 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (zero_extract:SWI48
12188 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12190 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12191 (clobber (reg:CC FLAGS_REG))]
12194 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12195 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12197 [(set_attr "type" "bitmanip")
12198 (set_attr "mode" "<MODE>")])
12200 (define_insn "*tbm_blcfill_<mode>"
12201 [(set (match_operand:SWI48 0 "register_operand" "=r")
12204 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207 (clobber (reg:CC FLAGS_REG))]
12209 "blcfill\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "bitmanip")
12211 (set_attr "mode" "<MODE>")])
12213 (define_insn "*tbm_blci_<mode>"
12214 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (clobber (reg:CC FLAGS_REG))]
12223 "blci\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "bitmanip")
12225 (set_attr "mode" "<MODE>")])
12227 (define_insn "*tbm_blcic_<mode>"
12228 [(set (match_operand:SWI48 0 "register_operand" "=r")
12231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (clobber (reg:CC FLAGS_REG))]
12237 "blcic\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12241 (define_insn "*tbm_blcmsk_<mode>"
12242 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12248 (clobber (reg:CC FLAGS_REG))]
12250 "blcmsk\t{%1, %0|%0, %1}"
12251 [(set_attr "type" "bitmanip")
12252 (set_attr "mode" "<MODE>")])
12254 (define_insn "*tbm_blcs_<mode>"
12255 [(set (match_operand:SWI48 0 "register_operand" "=r")
12258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261 (clobber (reg:CC FLAGS_REG))]
12263 "blcs\t{%1, %0|%0, %1}"
12264 [(set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12267 (define_insn "*tbm_blsfill_<mode>"
12268 [(set (match_operand:SWI48 0 "register_operand" "=r")
12271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274 (clobber (reg:CC FLAGS_REG))]
12276 "blsfill\t{%1, %0|%0, %1}"
12277 [(set_attr "type" "bitmanip")
12278 (set_attr "mode" "<MODE>")])
12280 (define_insn "*tbm_blsic_<mode>"
12281 [(set (match_operand:SWI48 0 "register_operand" "=r")
12284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288 (clobber (reg:CC FLAGS_REG))]
12290 "blsic\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "bitmanip")
12292 (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_t1mskc_<mode>"
12295 [(set (match_operand:SWI48 0 "register_operand" "=r")
12298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12302 (clobber (reg:CC FLAGS_REG))]
12304 "t1mskc\t{%1, %0|%0, %1}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12308 (define_insn "*tbm_tzmsk_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12316 (clobber (reg:CC FLAGS_REG))]
12318 "tzmsk\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "bsr_rex64"
12323 [(set (match_operand:DI 0 "register_operand" "=r")
12324 (minus:DI (const_int 63)
12325 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12326 (clobber (reg:CC FLAGS_REG))]
12328 "bsr{q}\t{%1, %0|%0, %1}"
12329 [(set_attr "type" "alu1")
12330 (set_attr "prefix_0f" "1")
12331 (set_attr "mode" "DI")])
12334 [(set (match_operand:SI 0 "register_operand" "=r")
12335 (minus:SI (const_int 31)
12336 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12337 (clobber (reg:CC FLAGS_REG))]
12339 "bsr{l}\t{%1, %0|%0, %1}"
12340 [(set_attr "type" "alu1")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "mode" "SI")])
12344 (define_insn "*bsrhi"
12345 [(set (match_operand:HI 0 "register_operand" "=r")
12346 (minus:HI (const_int 15)
12347 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12348 (clobber (reg:CC FLAGS_REG))]
12350 "bsr{w}\t{%1, %0|%0, %1}"
12351 [(set_attr "type" "alu1")
12352 (set_attr "prefix_0f" "1")
12353 (set_attr "mode" "HI")])
12355 (define_insn "popcount<mode>2"
12356 [(set (match_operand:SWI248 0 "register_operand" "=r")
12358 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12359 (clobber (reg:CC FLAGS_REG))]
12363 return "popcnt\t{%1, %0|%0, %1}";
12365 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12368 [(set_attr "prefix_rep" "1")
12369 (set_attr "type" "bitmanip")
12370 (set_attr "mode" "<MODE>")])
12372 (define_insn "*popcount<mode>2_cmp"
12373 [(set (reg FLAGS_REG)
12376 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12378 (set (match_operand:SWI248 0 "register_operand" "=r")
12379 (popcount:SWI248 (match_dup 1)))]
12380 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12383 return "popcnt\t{%1, %0|%0, %1}";
12385 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12388 [(set_attr "prefix_rep" "1")
12389 (set_attr "type" "bitmanip")
12390 (set_attr "mode" "<MODE>")])
12392 (define_insn "*popcountsi2_cmp_zext"
12393 [(set (reg FLAGS_REG)
12395 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12397 (set (match_operand:DI 0 "register_operand" "=r")
12398 (zero_extend:DI(popcount:SI (match_dup 1))))]
12399 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12402 return "popcnt\t{%1, %0|%0, %1}";
12404 return "popcnt{l}\t{%1, %0|%0, %1}";
12407 [(set_attr "prefix_rep" "1")
12408 (set_attr "type" "bitmanip")
12409 (set_attr "mode" "SI")])
12411 (define_expand "bswap<mode>2"
12412 [(set (match_operand:SWI48 0 "register_operand" "")
12413 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12416 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12418 rtx x = operands[0];
12420 emit_move_insn (x, operands[1]);
12421 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12422 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12428 (define_insn "*bswap<mode>2_movbe"
12429 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12430 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12432 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12435 movbe\t{%1, %0|%0, %1}
12436 movbe\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip,imov,imov")
12438 (set_attr "modrm" "0,1,1")
12439 (set_attr "prefix_0f" "*,1,1")
12440 (set_attr "prefix_extra" "*,1,1")
12441 (set_attr "mode" "<MODE>")])
12443 (define_insn "*bswap<mode>2_1"
12444 [(set (match_operand:SWI48 0 "register_operand" "=r")
12445 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12448 [(set_attr "type" "bitmanip")
12449 (set_attr "modrm" "0")
12450 (set_attr "mode" "<MODE>")])
12452 (define_insn "*bswaphi_lowpart_1"
12453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12454 (bswap:HI (match_dup 0)))
12455 (clobber (reg:CC FLAGS_REG))]
12456 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12458 xchg{b}\t{%h0, %b0|%b0, %h0}
12459 rol{w}\t{$8, %0|%0, 8}"
12460 [(set_attr "length" "2,4")
12461 (set_attr "mode" "QI,HI")])
12463 (define_insn "bswaphi_lowpart"
12464 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12465 (bswap:HI (match_dup 0)))
12466 (clobber (reg:CC FLAGS_REG))]
12468 "rol{w}\t{$8, %0|%0, 8}"
12469 [(set_attr "length" "4")
12470 (set_attr "mode" "HI")])
12472 (define_expand "paritydi2"
12473 [(set (match_operand:DI 0 "register_operand" "")
12474 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12477 rtx scratch = gen_reg_rtx (QImode);
12480 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12481 NULL_RTX, operands[1]));
12483 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12484 gen_rtx_REG (CCmode, FLAGS_REG),
12486 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12489 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12492 rtx tmp = gen_reg_rtx (SImode);
12494 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12495 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12500 (define_expand "paritysi2"
12501 [(set (match_operand:SI 0 "register_operand" "")
12502 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12505 rtx scratch = gen_reg_rtx (QImode);
12508 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12510 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12511 gen_rtx_REG (CCmode, FLAGS_REG),
12513 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12515 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12519 (define_insn_and_split "paritydi2_cmp"
12520 [(set (reg:CC FLAGS_REG)
12521 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12523 (clobber (match_scratch:DI 0 "=r"))
12524 (clobber (match_scratch:SI 1 "=&r"))
12525 (clobber (match_scratch:HI 2 "=Q"))]
12528 "&& reload_completed"
12530 [(set (match_dup 1)
12531 (xor:SI (match_dup 1) (match_dup 4)))
12532 (clobber (reg:CC FLAGS_REG))])
12534 [(set (reg:CC FLAGS_REG)
12535 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12536 (clobber (match_dup 1))
12537 (clobber (match_dup 2))])]
12539 operands[4] = gen_lowpart (SImode, operands[3]);
12543 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12544 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12547 operands[1] = gen_highpart (SImode, operands[3]);
12550 (define_insn_and_split "paritysi2_cmp"
12551 [(set (reg:CC FLAGS_REG)
12552 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12554 (clobber (match_scratch:SI 0 "=r"))
12555 (clobber (match_scratch:HI 1 "=&Q"))]
12558 "&& reload_completed"
12560 [(set (match_dup 1)
12561 (xor:HI (match_dup 1) (match_dup 3)))
12562 (clobber (reg:CC FLAGS_REG))])
12564 [(set (reg:CC FLAGS_REG)
12565 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12566 (clobber (match_dup 1))])]
12568 operands[3] = gen_lowpart (HImode, operands[2]);
12570 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12571 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12574 (define_insn "*parityhi2_cmp"
12575 [(set (reg:CC FLAGS_REG)
12576 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12578 (clobber (match_scratch:HI 0 "=Q"))]
12580 "xor{b}\t{%h0, %b0|%b0, %h0}"
12581 [(set_attr "length" "2")
12582 (set_attr "mode" "HI")])
12585 ;; Thread-local storage patterns for ELF.
12587 ;; Note that these code sequences must appear exactly as shown
12588 ;; in order to allow linker relaxation.
12590 (define_insn "*tls_global_dynamic_32_gnu"
12591 [(set (match_operand:SI 0 "register_operand" "=a")
12593 [(match_operand:SI 1 "register_operand" "b")
12594 (match_operand:SI 2 "tls_symbolic_operand" "")
12595 (match_operand:SI 3 "constant_call_address_operand" "z")]
12597 (clobber (match_scratch:SI 4 "=d"))
12598 (clobber (match_scratch:SI 5 "=c"))
12599 (clobber (reg:CC FLAGS_REG))]
12600 "!TARGET_64BIT && TARGET_GNU_TLS"
12603 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12604 if (TARGET_SUN_TLS)
12605 #ifdef HAVE_AS_IX86_TLSGDPLT
12606 return "call\t%a2@tlsgdplt";
12608 return "call\t%p3@plt";
12610 return "call\t%P3";
12612 [(set_attr "type" "multi")
12613 (set_attr "length" "12")])
12615 (define_expand "tls_global_dynamic_32"
12617 [(set (match_operand:SI 0 "register_operand" "")
12618 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12619 (match_operand:SI 1 "tls_symbolic_operand" "")
12620 (match_operand:SI 3 "constant_call_address_operand" "")]
12622 (clobber (match_scratch:SI 4 ""))
12623 (clobber (match_scratch:SI 5 ""))
12624 (clobber (reg:CC FLAGS_REG))])])
12626 (define_insn "*tls_global_dynamic_64"
12627 [(set (match_operand:DI 0 "register_operand" "=a")
12629 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12630 (match_operand:DI 3 "" "")))
12631 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12636 fputs (ASM_BYTE "0x66\n", asm_out_file);
12638 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12639 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12640 fputs ("\trex64\n", asm_out_file);
12641 if (TARGET_SUN_TLS)
12642 return "call\t%p2@plt";
12643 return "call\t%P2";
12645 [(set_attr "type" "multi")
12646 (set (attr "length")
12647 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12649 (define_expand "tls_global_dynamic_64"
12651 [(set (match_operand:DI 0 "register_operand" "")
12653 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12655 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12658 (define_insn "*tls_local_dynamic_base_32_gnu"
12659 [(set (match_operand:SI 0 "register_operand" "=a")
12661 [(match_operand:SI 1 "register_operand" "b")
12662 (match_operand:SI 2 "constant_call_address_operand" "z")]
12663 UNSPEC_TLS_LD_BASE))
12664 (clobber (match_scratch:SI 3 "=d"))
12665 (clobber (match_scratch:SI 4 "=c"))
12666 (clobber (reg:CC FLAGS_REG))]
12667 "!TARGET_64BIT && TARGET_GNU_TLS"
12670 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12671 if (TARGET_SUN_TLS)
12672 #ifdef HAVE_AS_IX86_TLSLDMPLT
12673 return "call\t%&@tlsldmplt";
12675 return "call\t%p2@plt";
12677 return "call\t%P2";
12679 [(set_attr "type" "multi")
12680 (set_attr "length" "11")])
12682 (define_expand "tls_local_dynamic_base_32"
12684 [(set (match_operand:SI 0 "register_operand" "")
12686 [(match_operand:SI 1 "register_operand" "")
12687 (match_operand:SI 2 "constant_call_address_operand" "")]
12688 UNSPEC_TLS_LD_BASE))
12689 (clobber (match_scratch:SI 3 ""))
12690 (clobber (match_scratch:SI 4 ""))
12691 (clobber (reg:CC FLAGS_REG))])])
12693 (define_insn "*tls_local_dynamic_base_64"
12694 [(set (match_operand:DI 0 "register_operand" "=a")
12696 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12697 (match_operand:DI 2 "" "")))
12698 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12702 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12703 if (TARGET_SUN_TLS)
12704 return "call\t%p1@plt";
12705 return "call\t%P1";
12707 [(set_attr "type" "multi")
12708 (set_attr "length" "12")])
12710 (define_expand "tls_local_dynamic_base_64"
12712 [(set (match_operand:DI 0 "register_operand" "")
12714 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12716 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12718 ;; Local dynamic of a single variable is a lose. Show combine how
12719 ;; to convert that back to global dynamic.
12721 (define_insn_and_split "*tls_local_dynamic_32_once"
12722 [(set (match_operand:SI 0 "register_operand" "=a")
12724 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12725 (match_operand:SI 2 "constant_call_address_operand" "z")]
12726 UNSPEC_TLS_LD_BASE)
12727 (const:SI (unspec:SI
12728 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12730 (clobber (match_scratch:SI 4 "=d"))
12731 (clobber (match_scratch:SI 5 "=c"))
12732 (clobber (reg:CC FLAGS_REG))]
12737 [(set (match_dup 0)
12738 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12740 (clobber (match_dup 4))
12741 (clobber (match_dup 5))
12742 (clobber (reg:CC FLAGS_REG))])])
12744 ;; Segment register for the thread base ptr load
12745 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12747 ;; Load and add the thread base pointer from %<tp_seg>:0.
12748 (define_insn "*load_tp_x32"
12749 [(set (match_operand:SI 0 "register_operand" "=r")
12750 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12752 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12753 [(set_attr "type" "imov")
12754 (set_attr "modrm" "0")
12755 (set_attr "length" "7")
12756 (set_attr "memory" "load")
12757 (set_attr "imm_disp" "false")])
12759 (define_insn "*load_tp_x32_zext"
12760 [(set (match_operand:DI 0 "register_operand" "=r")
12761 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12763 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12764 [(set_attr "type" "imov")
12765 (set_attr "modrm" "0")
12766 (set_attr "length" "7")
12767 (set_attr "memory" "load")
12768 (set_attr "imm_disp" "false")])
12770 (define_insn "*load_tp_<mode>"
12771 [(set (match_operand:P 0 "register_operand" "=r")
12772 (unspec:P [(const_int 0)] UNSPEC_TP))]
12774 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12775 [(set_attr "type" "imov")
12776 (set_attr "modrm" "0")
12777 (set_attr "length" "7")
12778 (set_attr "memory" "load")
12779 (set_attr "imm_disp" "false")])
12781 (define_insn "*add_tp_x32"
12782 [(set (match_operand:SI 0 "register_operand" "=r")
12783 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12784 (match_operand:SI 1 "register_operand" "0")))
12785 (clobber (reg:CC FLAGS_REG))]
12787 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12788 [(set_attr "type" "alu")
12789 (set_attr "modrm" "0")
12790 (set_attr "length" "7")
12791 (set_attr "memory" "load")
12792 (set_attr "imm_disp" "false")])
12794 (define_insn "*add_tp_x32_zext"
12795 [(set (match_operand:DI 0 "register_operand" "=r")
12797 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12798 (match_operand:SI 1 "register_operand" "0"))))
12799 (clobber (reg:CC FLAGS_REG))]
12801 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12802 [(set_attr "type" "alu")
12803 (set_attr "modrm" "0")
12804 (set_attr "length" "7")
12805 (set_attr "memory" "load")
12806 (set_attr "imm_disp" "false")])
12808 (define_insn "*add_tp_<mode>"
12809 [(set (match_operand:P 0 "register_operand" "=r")
12810 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12811 (match_operand:P 1 "register_operand" "0")))
12812 (clobber (reg:CC FLAGS_REG))]
12814 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12815 [(set_attr "type" "alu")
12816 (set_attr "modrm" "0")
12817 (set_attr "length" "7")
12818 (set_attr "memory" "load")
12819 (set_attr "imm_disp" "false")])
12821 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12822 ;; %rax as destination of the initial executable code sequence.
12823 (define_insn "tls_initial_exec_64_sun"
12824 [(set (match_operand:DI 0 "register_operand" "=a")
12826 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12827 UNSPEC_TLS_IE_SUN))
12828 (clobber (reg:CC FLAGS_REG))]
12829 "TARGET_64BIT && TARGET_SUN_TLS"
12832 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12833 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12835 [(set_attr "type" "multi")])
12837 ;; GNU2 TLS patterns can be split.
12839 (define_expand "tls_dynamic_gnu2_32"
12840 [(set (match_dup 3)
12841 (plus:SI (match_operand:SI 2 "register_operand" "")
12843 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12846 [(set (match_operand:SI 0 "register_operand" "")
12847 (unspec:SI [(match_dup 1) (match_dup 3)
12848 (match_dup 2) (reg:SI SP_REG)]
12850 (clobber (reg:CC FLAGS_REG))])]
12851 "!TARGET_64BIT && TARGET_GNU2_TLS"
12853 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12854 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12857 (define_insn "*tls_dynamic_gnu2_lea_32"
12858 [(set (match_operand:SI 0 "register_operand" "=r")
12859 (plus:SI (match_operand:SI 1 "register_operand" "b")
12861 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12862 UNSPEC_TLSDESC))))]
12863 "!TARGET_64BIT && TARGET_GNU2_TLS"
12864 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12865 [(set_attr "type" "lea")
12866 (set_attr "mode" "SI")
12867 (set_attr "length" "6")
12868 (set_attr "length_address" "4")])
12870 (define_insn "*tls_dynamic_gnu2_call_32"
12871 [(set (match_operand:SI 0 "register_operand" "=a")
12872 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12873 (match_operand:SI 2 "register_operand" "0")
12874 ;; we have to make sure %ebx still points to the GOT
12875 (match_operand:SI 3 "register_operand" "b")
12878 (clobber (reg:CC FLAGS_REG))]
12879 "!TARGET_64BIT && TARGET_GNU2_TLS"
12880 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12881 [(set_attr "type" "call")
12882 (set_attr "length" "2")
12883 (set_attr "length_address" "0")])
12885 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12886 [(set (match_operand:SI 0 "register_operand" "=&a")
12888 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12889 (match_operand:SI 4 "" "")
12890 (match_operand:SI 2 "register_operand" "b")
12893 (const:SI (unspec:SI
12894 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12896 (clobber (reg:CC FLAGS_REG))]
12897 "!TARGET_64BIT && TARGET_GNU2_TLS"
12900 [(set (match_dup 0) (match_dup 5))]
12902 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12906 (define_expand "tls_dynamic_gnu2_64"
12907 [(set (match_dup 2)
12908 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12911 [(set (match_operand:DI 0 "register_operand" "")
12912 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12914 (clobber (reg:CC FLAGS_REG))])]
12915 "TARGET_64BIT && TARGET_GNU2_TLS"
12917 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12918 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12921 (define_insn "*tls_dynamic_gnu2_lea_64"
12922 [(set (match_operand:DI 0 "register_operand" "=r")
12923 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12925 "TARGET_64BIT && TARGET_GNU2_TLS"
12926 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12927 [(set_attr "type" "lea")
12928 (set_attr "mode" "DI")
12929 (set_attr "length" "7")
12930 (set_attr "length_address" "4")])
12932 (define_insn "*tls_dynamic_gnu2_call_64"
12933 [(set (match_operand:DI 0 "register_operand" "=a")
12934 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12935 (match_operand:DI 2 "register_operand" "0")
12938 (clobber (reg:CC FLAGS_REG))]
12939 "TARGET_64BIT && TARGET_GNU2_TLS"
12940 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12941 [(set_attr "type" "call")
12942 (set_attr "length" "2")
12943 (set_attr "length_address" "0")])
12945 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12946 [(set (match_operand:DI 0 "register_operand" "=&a")
12948 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12949 (match_operand:DI 3 "" "")
12952 (const:DI (unspec:DI
12953 [(match_operand 1 "tls_symbolic_operand" "")]
12955 (clobber (reg:CC FLAGS_REG))]
12956 "TARGET_64BIT && TARGET_GNU2_TLS"
12959 [(set (match_dup 0) (match_dup 4))]
12961 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12962 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12965 ;; These patterns match the binary 387 instructions for addM3, subM3,
12966 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12967 ;; SFmode. The first is the normal insn, the second the same insn but
12968 ;; with one operand a conversion, and the third the same insn but with
12969 ;; the other operand a conversion. The conversion may be SFmode or
12970 ;; SImode if the target mode DFmode, but only SImode if the target mode
12973 ;; Gcc is slightly more smart about handling normal two address instructions
12974 ;; so use special patterns for add and mull.
12976 (define_insn "*fop_<mode>_comm_mixed"
12977 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12978 (match_operator:MODEF 3 "binary_fp_operator"
12979 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12980 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12981 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12982 && COMMUTATIVE_ARITH_P (operands[3])
12983 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12984 "* return output_387_binary_op (insn, operands);"
12985 [(set (attr "type")
12986 (if_then_else (eq_attr "alternative" "1,2")
12987 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12988 (const_string "ssemul")
12989 (const_string "sseadd"))
12990 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12991 (const_string "fmul")
12992 (const_string "fop"))))
12993 (set_attr "isa" "*,noavx,avx")
12994 (set_attr "prefix" "orig,orig,vex")
12995 (set_attr "mode" "<MODE>")])
12997 (define_insn "*fop_<mode>_comm_sse"
12998 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12999 (match_operator:MODEF 3 "binary_fp_operator"
13000 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13001 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13003 && COMMUTATIVE_ARITH_P (operands[3])
13004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13005 "* return output_387_binary_op (insn, operands);"
13006 [(set (attr "type")
13007 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13008 (const_string "ssemul")
13009 (const_string "sseadd")))
13010 (set_attr "isa" "noavx,avx")
13011 (set_attr "prefix" "orig,vex")
13012 (set_attr "mode" "<MODE>")])
13014 (define_insn "*fop_<mode>_comm_i387"
13015 [(set (match_operand:MODEF 0 "register_operand" "=f")
13016 (match_operator:MODEF 3 "binary_fp_operator"
13017 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13018 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13019 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13020 && COMMUTATIVE_ARITH_P (operands[3])
13021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022 "* return output_387_binary_op (insn, operands);"
13023 [(set (attr "type")
13024 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13025 (const_string "fmul")
13026 (const_string "fop")))
13027 (set_attr "mode" "<MODE>")])
13029 (define_insn "*fop_<mode>_1_mixed"
13030 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13034 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13035 && !COMMUTATIVE_ARITH_P (operands[3])
13036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13037 "* return output_387_binary_op (insn, operands);"
13038 [(set (attr "type")
13039 (cond [(and (eq_attr "alternative" "2,3")
13040 (match_operand:MODEF 3 "mult_operator" ""))
13041 (const_string "ssemul")
13042 (and (eq_attr "alternative" "2,3")
13043 (match_operand:MODEF 3 "div_operator" ""))
13044 (const_string "ssediv")
13045 (eq_attr "alternative" "2,3")
13046 (const_string "sseadd")
13047 (match_operand:MODEF 3 "mult_operator" "")
13048 (const_string "fmul")
13049 (match_operand:MODEF 3 "div_operator" "")
13050 (const_string "fdiv")
13052 (const_string "fop")))
13053 (set_attr "isa" "*,*,noavx,avx")
13054 (set_attr "prefix" "orig,orig,orig,vex")
13055 (set_attr "mode" "<MODE>")])
13057 (define_insn "*rcpsf2_sse"
13058 [(set (match_operand:SF 0 "register_operand" "=x")
13059 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13062 "%vrcpss\t{%1, %d0|%d0, %1}"
13063 [(set_attr "type" "sse")
13064 (set_attr "atom_sse_attr" "rcp")
13065 (set_attr "prefix" "maybe_vex")
13066 (set_attr "mode" "SF")])
13068 (define_insn "*fop_<mode>_1_sse"
13069 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13070 (match_operator:MODEF 3 "binary_fp_operator"
13071 [(match_operand:MODEF 1 "register_operand" "0,x")
13072 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13074 && !COMMUTATIVE_ARITH_P (operands[3])"
13075 "* return output_387_binary_op (insn, operands);"
13076 [(set (attr "type")
13077 (cond [(match_operand:MODEF 3 "mult_operator" "")
13078 (const_string "ssemul")
13079 (match_operand:MODEF 3 "div_operator" "")
13080 (const_string "ssediv")
13082 (const_string "sseadd")))
13083 (set_attr "isa" "noavx,avx")
13084 (set_attr "prefix" "orig,vex")
13085 (set_attr "mode" "<MODE>")])
13087 ;; This pattern is not fully shadowed by the pattern above.
13088 (define_insn "*fop_<mode>_1_i387"
13089 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13090 (match_operator:MODEF 3 "binary_fp_operator"
13091 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13092 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13093 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13094 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13095 && !COMMUTATIVE_ARITH_P (operands[3])
13096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13097 "* return output_387_binary_op (insn, operands);"
13098 [(set (attr "type")
13099 (cond [(match_operand:MODEF 3 "mult_operator" "")
13100 (const_string "fmul")
13101 (match_operand:MODEF 3 "div_operator" "")
13102 (const_string "fdiv")
13104 (const_string "fop")))
13105 (set_attr "mode" "<MODE>")])
13107 ;; ??? Add SSE splitters for these!
13108 (define_insn "*fop_<MODEF:mode>_2_i387"
13109 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13110 (match_operator:MODEF 3 "binary_fp_operator"
13112 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13113 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13114 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13115 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13116 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13117 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13118 [(set (attr "type")
13119 (cond [(match_operand:MODEF 3 "mult_operator" "")
13120 (const_string "fmul")
13121 (match_operand:MODEF 3 "div_operator" "")
13122 (const_string "fdiv")
13124 (const_string "fop")))
13125 (set_attr "fp_int_src" "true")
13126 (set_attr "mode" "<SWI24:MODE>")])
13128 (define_insn "*fop_<MODEF:mode>_3_i387"
13129 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13130 (match_operator:MODEF 3 "binary_fp_operator"
13131 [(match_operand:MODEF 1 "register_operand" "0,0")
13133 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13134 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13135 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13136 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13137 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13138 [(set (attr "type")
13139 (cond [(match_operand:MODEF 3 "mult_operator" "")
13140 (const_string "fmul")
13141 (match_operand:MODEF 3 "div_operator" "")
13142 (const_string "fdiv")
13144 (const_string "fop")))
13145 (set_attr "fp_int_src" "true")
13146 (set_attr "mode" "<MODE>")])
13148 (define_insn "*fop_df_4_i387"
13149 [(set (match_operand:DF 0 "register_operand" "=f,f")
13150 (match_operator:DF 3 "binary_fp_operator"
13152 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13153 (match_operand:DF 2 "register_operand" "0,f")]))]
13154 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13155 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13156 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13157 "* return output_387_binary_op (insn, operands);"
13158 [(set (attr "type")
13159 (cond [(match_operand:DF 3 "mult_operator" "")
13160 (const_string "fmul")
13161 (match_operand:DF 3 "div_operator" "")
13162 (const_string "fdiv")
13164 (const_string "fop")))
13165 (set_attr "mode" "SF")])
13167 (define_insn "*fop_df_5_i387"
13168 [(set (match_operand:DF 0 "register_operand" "=f,f")
13169 (match_operator:DF 3 "binary_fp_operator"
13170 [(match_operand:DF 1 "register_operand" "0,f")
13172 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13173 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13174 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13175 "* return output_387_binary_op (insn, operands);"
13176 [(set (attr "type")
13177 (cond [(match_operand:DF 3 "mult_operator" "")
13178 (const_string "fmul")
13179 (match_operand:DF 3 "div_operator" "")
13180 (const_string "fdiv")
13182 (const_string "fop")))
13183 (set_attr "mode" "SF")])
13185 (define_insn "*fop_df_6_i387"
13186 [(set (match_operand:DF 0 "register_operand" "=f,f")
13187 (match_operator:DF 3 "binary_fp_operator"
13189 (match_operand:SF 1 "register_operand" "0,f"))
13191 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13192 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13193 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13194 "* return output_387_binary_op (insn, operands);"
13195 [(set (attr "type")
13196 (cond [(match_operand:DF 3 "mult_operator" "")
13197 (const_string "fmul")
13198 (match_operand:DF 3 "div_operator" "")
13199 (const_string "fdiv")
13201 (const_string "fop")))
13202 (set_attr "mode" "SF")])
13204 (define_insn "*fop_xf_comm_i387"
13205 [(set (match_operand:XF 0 "register_operand" "=f")
13206 (match_operator:XF 3 "binary_fp_operator"
13207 [(match_operand:XF 1 "register_operand" "%0")
13208 (match_operand:XF 2 "register_operand" "f")]))]
13210 && COMMUTATIVE_ARITH_P (operands[3])"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (if_then_else (match_operand:XF 3 "mult_operator" "")
13214 (const_string "fmul")
13215 (const_string "fop")))
13216 (set_attr "mode" "XF")])
13218 (define_insn "*fop_xf_1_i387"
13219 [(set (match_operand:XF 0 "register_operand" "=f,f")
13220 (match_operator:XF 3 "binary_fp_operator"
13221 [(match_operand:XF 1 "register_operand" "0,f")
13222 (match_operand:XF 2 "register_operand" "f,0")]))]
13224 && !COMMUTATIVE_ARITH_P (operands[3])"
13225 "* return output_387_binary_op (insn, operands);"
13226 [(set (attr "type")
13227 (cond [(match_operand:XF 3 "mult_operator" "")
13228 (const_string "fmul")
13229 (match_operand:XF 3 "div_operator" "")
13230 (const_string "fdiv")
13232 (const_string "fop")))
13233 (set_attr "mode" "XF")])
13235 (define_insn "*fop_xf_2_i387"
13236 [(set (match_operand:XF 0 "register_operand" "=f,f")
13237 (match_operator:XF 3 "binary_fp_operator"
13239 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13240 (match_operand:XF 2 "register_operand" "0,0")]))]
13241 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13242 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13243 [(set (attr "type")
13244 (cond [(match_operand:XF 3 "mult_operator" "")
13245 (const_string "fmul")
13246 (match_operand:XF 3 "div_operator" "")
13247 (const_string "fdiv")
13249 (const_string "fop")))
13250 (set_attr "fp_int_src" "true")
13251 (set_attr "mode" "<MODE>")])
13253 (define_insn "*fop_xf_3_i387"
13254 [(set (match_operand:XF 0 "register_operand" "=f,f")
13255 (match_operator:XF 3 "binary_fp_operator"
13256 [(match_operand:XF 1 "register_operand" "0,0")
13258 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13259 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13260 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13261 [(set (attr "type")
13262 (cond [(match_operand:XF 3 "mult_operator" "")
13263 (const_string "fmul")
13264 (match_operand:XF 3 "div_operator" "")
13265 (const_string "fdiv")
13267 (const_string "fop")))
13268 (set_attr "fp_int_src" "true")
13269 (set_attr "mode" "<MODE>")])
13271 (define_insn "*fop_xf_4_i387"
13272 [(set (match_operand:XF 0 "register_operand" "=f,f")
13273 (match_operator:XF 3 "binary_fp_operator"
13275 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13276 (match_operand:XF 2 "register_operand" "0,f")]))]
13278 "* return output_387_binary_op (insn, operands);"
13279 [(set (attr "type")
13280 (cond [(match_operand:XF 3 "mult_operator" "")
13281 (const_string "fmul")
13282 (match_operand:XF 3 "div_operator" "")
13283 (const_string "fdiv")
13285 (const_string "fop")))
13286 (set_attr "mode" "<MODE>")])
13288 (define_insn "*fop_xf_5_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f,f")
13290 (match_operator:XF 3 "binary_fp_operator"
13291 [(match_operand:XF 1 "register_operand" "0,f")
13293 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (cond [(match_operand:XF 3 "mult_operator" "")
13298 (const_string "fmul")
13299 (match_operand:XF 3 "div_operator" "")
13300 (const_string "fdiv")
13302 (const_string "fop")))
13303 (set_attr "mode" "<MODE>")])
13305 (define_insn "*fop_xf_6_i387"
13306 [(set (match_operand:XF 0 "register_operand" "=f,f")
13307 (match_operator:XF 3 "binary_fp_operator"
13309 (match_operand:MODEF 1 "register_operand" "0,f"))
13311 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13313 "* return output_387_binary_op (insn, operands);"
13314 [(set (attr "type")
13315 (cond [(match_operand:XF 3 "mult_operator" "")
13316 (const_string "fmul")
13317 (match_operand:XF 3 "div_operator" "")
13318 (const_string "fdiv")
13320 (const_string "fop")))
13321 (set_attr "mode" "<MODE>")])
13324 [(set (match_operand 0 "register_operand" "")
13325 (match_operator 3 "binary_fp_operator"
13326 [(float (match_operand:SWI24 1 "register_operand" ""))
13327 (match_operand 2 "register_operand" "")]))]
13329 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13330 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13333 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13334 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13335 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13336 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13337 GET_MODE (operands[3]),
13340 ix86_free_from_memory (GET_MODE (operands[1]));
13345 [(set (match_operand 0 "register_operand" "")
13346 (match_operator 3 "binary_fp_operator"
13347 [(match_operand 1 "register_operand" "")
13348 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13350 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13351 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13354 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13355 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13356 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13357 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13358 GET_MODE (operands[3]),
13361 ix86_free_from_memory (GET_MODE (operands[2]));
13365 ;; FPU special functions.
13367 ;; This pattern implements a no-op XFmode truncation for
13368 ;; all fancy i386 XFmode math functions.
13370 (define_insn "truncxf<mode>2_i387_noop_unspec"
13371 [(set (match_operand:MODEF 0 "register_operand" "=f")
13372 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13373 UNSPEC_TRUNC_NOOP))]
13374 "TARGET_USE_FANCY_MATH_387"
13375 "* return output_387_reg_move (insn, operands);"
13376 [(set_attr "type" "fmov")
13377 (set_attr "mode" "<MODE>")])
13379 (define_insn "sqrtxf2"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13381 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13382 "TARGET_USE_FANCY_MATH_387"
13384 [(set_attr "type" "fpspc")
13385 (set_attr "mode" "XF")
13386 (set_attr "athlon_decode" "direct")
13387 (set_attr "amdfam10_decode" "direct")
13388 (set_attr "bdver1_decode" "direct")])
13390 (define_insn "sqrt_extend<mode>xf2_i387"
13391 [(set (match_operand:XF 0 "register_operand" "=f")
13394 (match_operand:MODEF 1 "register_operand" "0"))))]
13395 "TARGET_USE_FANCY_MATH_387"
13397 [(set_attr "type" "fpspc")
13398 (set_attr "mode" "XF")
13399 (set_attr "athlon_decode" "direct")
13400 (set_attr "amdfam10_decode" "direct")
13401 (set_attr "bdver1_decode" "direct")])
13403 (define_insn "*rsqrtsf2_sse"
13404 [(set (match_operand:SF 0 "register_operand" "=x")
13405 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13408 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13409 [(set_attr "type" "sse")
13410 (set_attr "atom_sse_attr" "rcp")
13411 (set_attr "prefix" "maybe_vex")
13412 (set_attr "mode" "SF")])
13414 (define_expand "rsqrtsf2"
13415 [(set (match_operand:SF 0 "register_operand" "")
13416 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13420 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13424 (define_insn "*sqrt<mode>2_sse"
13425 [(set (match_operand:MODEF 0 "register_operand" "=x")
13427 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13429 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13430 [(set_attr "type" "sse")
13431 (set_attr "atom_sse_attr" "sqrt")
13432 (set_attr "prefix" "maybe_vex")
13433 (set_attr "mode" "<MODE>")
13434 (set_attr "athlon_decode" "*")
13435 (set_attr "amdfam10_decode" "*")
13436 (set_attr "bdver1_decode" "*")])
13438 (define_expand "sqrt<mode>2"
13439 [(set (match_operand:MODEF 0 "register_operand" "")
13441 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13442 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13445 if (<MODE>mode == SFmode
13447 && TARGET_RECIP_SQRT
13448 && !optimize_function_for_size_p (cfun)
13449 && flag_finite_math_only && !flag_trapping_math
13450 && flag_unsafe_math_optimizations)
13452 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13456 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13458 rtx op0 = gen_reg_rtx (XFmode);
13459 rtx op1 = force_reg (<MODE>mode, operands[1]);
13461 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13462 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13467 (define_insn "fpremxf4_i387"
13468 [(set (match_operand:XF 0 "register_operand" "=f")
13469 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13470 (match_operand:XF 3 "register_operand" "1")]
13472 (set (match_operand:XF 1 "register_operand" "=u")
13473 (unspec:XF [(match_dup 2) (match_dup 3)]
13475 (set (reg:CCFP FPSR_REG)
13476 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13478 "TARGET_USE_FANCY_MATH_387"
13480 [(set_attr "type" "fpspc")
13481 (set_attr "mode" "XF")])
13483 (define_expand "fmodxf3"
13484 [(use (match_operand:XF 0 "register_operand" ""))
13485 (use (match_operand:XF 1 "general_operand" ""))
13486 (use (match_operand:XF 2 "general_operand" ""))]
13487 "TARGET_USE_FANCY_MATH_387"
13489 rtx label = gen_label_rtx ();
13491 rtx op1 = gen_reg_rtx (XFmode);
13492 rtx op2 = gen_reg_rtx (XFmode);
13494 emit_move_insn (op2, operands[2]);
13495 emit_move_insn (op1, operands[1]);
13497 emit_label (label);
13498 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13499 ix86_emit_fp_unordered_jump (label);
13500 LABEL_NUSES (label) = 1;
13502 emit_move_insn (operands[0], op1);
13506 (define_expand "fmod<mode>3"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "general_operand" ""))
13509 (use (match_operand:MODEF 2 "general_operand" ""))]
13510 "TARGET_USE_FANCY_MATH_387"
13512 rtx (*gen_truncxf) (rtx, rtx);
13514 rtx label = gen_label_rtx ();
13516 rtx op1 = gen_reg_rtx (XFmode);
13517 rtx op2 = gen_reg_rtx (XFmode);
13519 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13522 emit_label (label);
13523 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13524 ix86_emit_fp_unordered_jump (label);
13525 LABEL_NUSES (label) = 1;
13527 /* Truncate the result properly for strict SSE math. */
13528 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13529 && !TARGET_MIX_SSE_I387)
13530 gen_truncxf = gen_truncxf<mode>2;
13532 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13534 emit_insn (gen_truncxf (operands[0], op1));
13538 (define_insn "fprem1xf4_i387"
13539 [(set (match_operand:XF 0 "register_operand" "=f")
13540 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13541 (match_operand:XF 3 "register_operand" "1")]
13543 (set (match_operand:XF 1 "register_operand" "=u")
13544 (unspec:XF [(match_dup 2) (match_dup 3)]
13546 (set (reg:CCFP FPSR_REG)
13547 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13549 "TARGET_USE_FANCY_MATH_387"
13551 [(set_attr "type" "fpspc")
13552 (set_attr "mode" "XF")])
13554 (define_expand "remainderxf3"
13555 [(use (match_operand:XF 0 "register_operand" ""))
13556 (use (match_operand:XF 1 "general_operand" ""))
13557 (use (match_operand:XF 2 "general_operand" ""))]
13558 "TARGET_USE_FANCY_MATH_387"
13560 rtx label = gen_label_rtx ();
13562 rtx op1 = gen_reg_rtx (XFmode);
13563 rtx op2 = gen_reg_rtx (XFmode);
13565 emit_move_insn (op2, operands[2]);
13566 emit_move_insn (op1, operands[1]);
13568 emit_label (label);
13569 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13570 ix86_emit_fp_unordered_jump (label);
13571 LABEL_NUSES (label) = 1;
13573 emit_move_insn (operands[0], op1);
13577 (define_expand "remainder<mode>3"
13578 [(use (match_operand:MODEF 0 "register_operand" ""))
13579 (use (match_operand:MODEF 1 "general_operand" ""))
13580 (use (match_operand:MODEF 2 "general_operand" ""))]
13581 "TARGET_USE_FANCY_MATH_387"
13583 rtx (*gen_truncxf) (rtx, rtx);
13585 rtx label = gen_label_rtx ();
13587 rtx op1 = gen_reg_rtx (XFmode);
13588 rtx op2 = gen_reg_rtx (XFmode);
13590 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13591 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13593 emit_label (label);
13595 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13596 ix86_emit_fp_unordered_jump (label);
13597 LABEL_NUSES (label) = 1;
13599 /* Truncate the result properly for strict SSE math. */
13600 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13601 && !TARGET_MIX_SSE_I387)
13602 gen_truncxf = gen_truncxf<mode>2;
13604 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13606 emit_insn (gen_truncxf (operands[0], op1));
13610 (define_insn "*sinxf2_i387"
13611 [(set (match_operand:XF 0 "register_operand" "=f")
13612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && flag_unsafe_math_optimizations"
13616 [(set_attr "type" "fpspc")
13617 (set_attr "mode" "XF")])
13619 (define_insn "*sin_extend<mode>xf2_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(float_extend:XF
13622 (match_operand:MODEF 1 "register_operand" "0"))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13626 || TARGET_MIX_SSE_I387)
13627 && flag_unsafe_math_optimizations"
13629 [(set_attr "type" "fpspc")
13630 (set_attr "mode" "XF")])
13632 (define_insn "*cosxf2_i387"
13633 [(set (match_operand:XF 0 "register_operand" "=f")
13634 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && flag_unsafe_math_optimizations"
13638 [(set_attr "type" "fpspc")
13639 (set_attr "mode" "XF")])
13641 (define_insn "*cos_extend<mode>xf2_i387"
13642 [(set (match_operand:XF 0 "register_operand" "=f")
13643 (unspec:XF [(float_extend:XF
13644 (match_operand:MODEF 1 "register_operand" "0"))]
13646 "TARGET_USE_FANCY_MATH_387
13647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13648 || TARGET_MIX_SSE_I387)
13649 && flag_unsafe_math_optimizations"
13651 [(set_attr "type" "fpspc")
13652 (set_attr "mode" "XF")])
13654 ;; When sincos pattern is defined, sin and cos builtin functions will be
13655 ;; expanded to sincos pattern with one of its outputs left unused.
13656 ;; CSE pass will figure out if two sincos patterns can be combined,
13657 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13658 ;; depending on the unused output.
13660 (define_insn "sincosxf3"
13661 [(set (match_operand:XF 0 "register_operand" "=f")
13662 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13663 UNSPEC_SINCOS_COS))
13664 (set (match_operand:XF 1 "register_operand" "=u")
13665 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13666 "TARGET_USE_FANCY_MATH_387
13667 && flag_unsafe_math_optimizations"
13669 [(set_attr "type" "fpspc")
13670 (set_attr "mode" "XF")])
13673 [(set (match_operand:XF 0 "register_operand" "")
13674 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13675 UNSPEC_SINCOS_COS))
13676 (set (match_operand:XF 1 "register_operand" "")
13677 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13678 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13679 && can_create_pseudo_p ()"
13680 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13683 [(set (match_operand:XF 0 "register_operand" "")
13684 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13685 UNSPEC_SINCOS_COS))
13686 (set (match_operand:XF 1 "register_operand" "")
13687 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13688 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13689 && can_create_pseudo_p ()"
13690 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13692 (define_insn "sincos_extend<mode>xf3_i387"
13693 [(set (match_operand:XF 0 "register_operand" "=f")
13694 (unspec:XF [(float_extend:XF
13695 (match_operand:MODEF 2 "register_operand" "0"))]
13696 UNSPEC_SINCOS_COS))
13697 (set (match_operand:XF 1 "register_operand" "=u")
13698 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13699 "TARGET_USE_FANCY_MATH_387
13700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13701 || TARGET_MIX_SSE_I387)
13702 && flag_unsafe_math_optimizations"
13704 [(set_attr "type" "fpspc")
13705 (set_attr "mode" "XF")])
13708 [(set (match_operand:XF 0 "register_operand" "")
13709 (unspec:XF [(float_extend:XF
13710 (match_operand:MODEF 2 "register_operand" ""))]
13711 UNSPEC_SINCOS_COS))
13712 (set (match_operand:XF 1 "register_operand" "")
13713 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13714 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13715 && can_create_pseudo_p ()"
13716 [(set (match_dup 1)
13717 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13720 [(set (match_operand:XF 0 "register_operand" "")
13721 (unspec:XF [(float_extend:XF
13722 (match_operand:MODEF 2 "register_operand" ""))]
13723 UNSPEC_SINCOS_COS))
13724 (set (match_operand:XF 1 "register_operand" "")
13725 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13726 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13727 && can_create_pseudo_p ()"
13728 [(set (match_dup 0)
13729 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13731 (define_expand "sincos<mode>3"
13732 [(use (match_operand:MODEF 0 "register_operand" ""))
13733 (use (match_operand:MODEF 1 "register_operand" ""))
13734 (use (match_operand:MODEF 2 "register_operand" ""))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13740 rtx op0 = gen_reg_rtx (XFmode);
13741 rtx op1 = gen_reg_rtx (XFmode);
13743 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13749 (define_insn "fptanxf4_i387"
13750 [(set (match_operand:XF 0 "register_operand" "=f")
13751 (match_operand:XF 3 "const_double_operand" "F"))
13752 (set (match_operand:XF 1 "register_operand" "=u")
13753 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13755 "TARGET_USE_FANCY_MATH_387
13756 && flag_unsafe_math_optimizations
13757 && standard_80387_constant_p (operands[3]) == 2"
13759 [(set_attr "type" "fpspc")
13760 (set_attr "mode" "XF")])
13762 (define_insn "fptan_extend<mode>xf4_i387"
13763 [(set (match_operand:MODEF 0 "register_operand" "=f")
13764 (match_operand:MODEF 3 "const_double_operand" "F"))
13765 (set (match_operand:XF 1 "register_operand" "=u")
13766 (unspec:XF [(float_extend:XF
13767 (match_operand:MODEF 2 "register_operand" "0"))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations
13773 && standard_80387_constant_p (operands[3]) == 2"
13775 [(set_attr "type" "fpspc")
13776 (set_attr "mode" "XF")])
13778 (define_expand "tanxf2"
13779 [(use (match_operand:XF 0 "register_operand" ""))
13780 (use (match_operand:XF 1 "register_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && flag_unsafe_math_optimizations"
13784 rtx one = gen_reg_rtx (XFmode);
13785 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13787 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13791 (define_expand "tan<mode>2"
13792 [(use (match_operand:MODEF 0 "register_operand" ""))
13793 (use (match_operand:MODEF 1 "register_operand" ""))]
13794 "TARGET_USE_FANCY_MATH_387
13795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13796 || TARGET_MIX_SSE_I387)
13797 && flag_unsafe_math_optimizations"
13799 rtx op0 = gen_reg_rtx (XFmode);
13801 rtx one = gen_reg_rtx (<MODE>mode);
13802 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13804 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13805 operands[1], op2));
13806 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13810 (define_insn "*fpatanxf3_i387"
13811 [(set (match_operand:XF 0 "register_operand" "=f")
13812 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13813 (match_operand:XF 2 "register_operand" "u")]
13815 (clobber (match_scratch:XF 3 "=2"))]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations"
13819 [(set_attr "type" "fpspc")
13820 (set_attr "mode" "XF")])
13822 (define_insn "fpatan_extend<mode>xf3_i387"
13823 [(set (match_operand:XF 0 "register_operand" "=f")
13824 (unspec:XF [(float_extend:XF
13825 (match_operand:MODEF 1 "register_operand" "0"))
13827 (match_operand:MODEF 2 "register_operand" "u"))]
13829 (clobber (match_scratch:XF 3 "=2"))]
13830 "TARGET_USE_FANCY_MATH_387
13831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13832 || TARGET_MIX_SSE_I387)
13833 && flag_unsafe_math_optimizations"
13835 [(set_attr "type" "fpspc")
13836 (set_attr "mode" "XF")])
13838 (define_expand "atan2xf3"
13839 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13840 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13841 (match_operand:XF 1 "register_operand" "")]
13843 (clobber (match_scratch:XF 3 ""))])]
13844 "TARGET_USE_FANCY_MATH_387
13845 && flag_unsafe_math_optimizations")
13847 (define_expand "atan2<mode>3"
13848 [(use (match_operand:MODEF 0 "register_operand" ""))
13849 (use (match_operand:MODEF 1 "register_operand" ""))
13850 (use (match_operand:MODEF 2 "register_operand" ""))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853 || TARGET_MIX_SSE_I387)
13854 && flag_unsafe_math_optimizations"
13856 rtx op0 = gen_reg_rtx (XFmode);
13858 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13863 (define_expand "atanxf2"
13864 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13865 (unspec:XF [(match_dup 2)
13866 (match_operand:XF 1 "register_operand" "")]
13868 (clobber (match_scratch:XF 3 ""))])]
13869 "TARGET_USE_FANCY_MATH_387
13870 && flag_unsafe_math_optimizations"
13872 operands[2] = gen_reg_rtx (XFmode);
13873 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13876 (define_expand "atan<mode>2"
13877 [(use (match_operand:MODEF 0 "register_operand" ""))
13878 (use (match_operand:MODEF 1 "register_operand" ""))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13881 || TARGET_MIX_SSE_I387)
13882 && flag_unsafe_math_optimizations"
13884 rtx op0 = gen_reg_rtx (XFmode);
13886 rtx op2 = gen_reg_rtx (<MODE>mode);
13887 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13889 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13894 (define_expand "asinxf2"
13895 [(set (match_dup 2)
13896 (mult:XF (match_operand:XF 1 "register_operand" "")
13898 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13899 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13900 (parallel [(set (match_operand:XF 0 "register_operand" "")
13901 (unspec:XF [(match_dup 5) (match_dup 1)]
13903 (clobber (match_scratch:XF 6 ""))])]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13909 if (optimize_insn_for_size_p ())
13912 for (i = 2; i < 6; i++)
13913 operands[i] = gen_reg_rtx (XFmode);
13915 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13918 (define_expand "asin<mode>2"
13919 [(use (match_operand:MODEF 0 "register_operand" ""))
13920 (use (match_operand:MODEF 1 "general_operand" ""))]
13921 "TARGET_USE_FANCY_MATH_387
13922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13923 || TARGET_MIX_SSE_I387)
13924 && flag_unsafe_math_optimizations"
13926 rtx op0 = gen_reg_rtx (XFmode);
13927 rtx op1 = gen_reg_rtx (XFmode);
13929 if (optimize_insn_for_size_p ())
13932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13933 emit_insn (gen_asinxf2 (op0, op1));
13934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13938 (define_expand "acosxf2"
13939 [(set (match_dup 2)
13940 (mult:XF (match_operand:XF 1 "register_operand" "")
13942 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13943 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13944 (parallel [(set (match_operand:XF 0 "register_operand" "")
13945 (unspec:XF [(match_dup 1) (match_dup 5)]
13947 (clobber (match_scratch:XF 6 ""))])]
13948 "TARGET_USE_FANCY_MATH_387
13949 && flag_unsafe_math_optimizations"
13953 if (optimize_insn_for_size_p ())
13956 for (i = 2; i < 6; i++)
13957 operands[i] = gen_reg_rtx (XFmode);
13959 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13962 (define_expand "acos<mode>2"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "general_operand" ""))]
13965 "TARGET_USE_FANCY_MATH_387
13966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967 || TARGET_MIX_SSE_I387)
13968 && flag_unsafe_math_optimizations"
13970 rtx op0 = gen_reg_rtx (XFmode);
13971 rtx op1 = gen_reg_rtx (XFmode);
13973 if (optimize_insn_for_size_p ())
13976 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13977 emit_insn (gen_acosxf2 (op0, op1));
13978 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13982 (define_insn "fyl2xxf3_i387"
13983 [(set (match_operand:XF 0 "register_operand" "=f")
13984 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13985 (match_operand:XF 2 "register_operand" "u")]
13987 (clobber (match_scratch:XF 3 "=2"))]
13988 "TARGET_USE_FANCY_MATH_387
13989 && flag_unsafe_math_optimizations"
13991 [(set_attr "type" "fpspc")
13992 (set_attr "mode" "XF")])
13994 (define_insn "fyl2x_extend<mode>xf3_i387"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (unspec:XF [(float_extend:XF
13997 (match_operand:MODEF 1 "register_operand" "0"))
13998 (match_operand:XF 2 "register_operand" "u")]
14000 (clobber (match_scratch:XF 3 "=2"))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003 || TARGET_MIX_SSE_I387)
14004 && flag_unsafe_math_optimizations"
14006 [(set_attr "type" "fpspc")
14007 (set_attr "mode" "XF")])
14009 (define_expand "logxf2"
14010 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14011 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14012 (match_dup 2)] UNSPEC_FYL2X))
14013 (clobber (match_scratch:XF 3 ""))])]
14014 "TARGET_USE_FANCY_MATH_387
14015 && flag_unsafe_math_optimizations"
14017 operands[2] = gen_reg_rtx (XFmode);
14018 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14021 (define_expand "log<mode>2"
14022 [(use (match_operand:MODEF 0 "register_operand" ""))
14023 (use (match_operand:MODEF 1 "register_operand" ""))]
14024 "TARGET_USE_FANCY_MATH_387
14025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14026 || TARGET_MIX_SSE_I387)
14027 && flag_unsafe_math_optimizations"
14029 rtx op0 = gen_reg_rtx (XFmode);
14031 rtx op2 = gen_reg_rtx (XFmode);
14032 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14034 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14035 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039 (define_expand "log10xf2"
14040 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14041 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14042 (match_dup 2)] UNSPEC_FYL2X))
14043 (clobber (match_scratch:XF 3 ""))])]
14044 "TARGET_USE_FANCY_MATH_387
14045 && flag_unsafe_math_optimizations"
14047 operands[2] = gen_reg_rtx (XFmode);
14048 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14051 (define_expand "log10<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand" ""))
14053 (use (match_operand:MODEF 1 "register_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14059 rtx op0 = gen_reg_rtx (XFmode);
14061 rtx op2 = gen_reg_rtx (XFmode);
14062 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14064 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14069 (define_expand "log2xf2"
14070 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14071 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14072 (match_dup 2)] UNSPEC_FYL2X))
14073 (clobber (match_scratch:XF 3 ""))])]
14074 "TARGET_USE_FANCY_MATH_387
14075 && flag_unsafe_math_optimizations"
14077 operands[2] = gen_reg_rtx (XFmode);
14078 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14081 (define_expand "log2<mode>2"
14082 [(use (match_operand:MODEF 0 "register_operand" ""))
14083 (use (match_operand:MODEF 1 "register_operand" ""))]
14084 "TARGET_USE_FANCY_MATH_387
14085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14086 || TARGET_MIX_SSE_I387)
14087 && flag_unsafe_math_optimizations"
14089 rtx op0 = gen_reg_rtx (XFmode);
14091 rtx op2 = gen_reg_rtx (XFmode);
14092 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14094 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099 (define_insn "fyl2xp1xf3_i387"
14100 [(set (match_operand:XF 0 "register_operand" "=f")
14101 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14102 (match_operand:XF 2 "register_operand" "u")]
14104 (clobber (match_scratch:XF 3 "=2"))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && flag_unsafe_math_optimizations"
14108 [(set_attr "type" "fpspc")
14109 (set_attr "mode" "XF")])
14111 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14112 [(set (match_operand:XF 0 "register_operand" "=f")
14113 (unspec:XF [(float_extend:XF
14114 (match_operand:MODEF 1 "register_operand" "0"))
14115 (match_operand:XF 2 "register_operand" "u")]
14117 (clobber (match_scratch:XF 3 "=2"))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14120 || TARGET_MIX_SSE_I387)
14121 && flag_unsafe_math_optimizations"
14123 [(set_attr "type" "fpspc")
14124 (set_attr "mode" "XF")])
14126 (define_expand "log1pxf2"
14127 [(use (match_operand:XF 0 "register_operand" ""))
14128 (use (match_operand:XF 1 "register_operand" ""))]
14129 "TARGET_USE_FANCY_MATH_387
14130 && flag_unsafe_math_optimizations"
14132 if (optimize_insn_for_size_p ())
14135 ix86_emit_i387_log1p (operands[0], operands[1]);
14139 (define_expand "log1p<mode>2"
14140 [(use (match_operand:MODEF 0 "register_operand" ""))
14141 (use (match_operand:MODEF 1 "register_operand" ""))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144 || TARGET_MIX_SSE_I387)
14145 && flag_unsafe_math_optimizations"
14149 if (optimize_insn_for_size_p ())
14152 op0 = gen_reg_rtx (XFmode);
14154 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14156 ix86_emit_i387_log1p (op0, operands[1]);
14157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14161 (define_insn "fxtractxf3_i387"
14162 [(set (match_operand:XF 0 "register_operand" "=f")
14163 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14164 UNSPEC_XTRACT_FRACT))
14165 (set (match_operand:XF 1 "register_operand" "=u")
14166 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14170 [(set_attr "type" "fpspc")
14171 (set_attr "mode" "XF")])
14173 (define_insn "fxtract_extend<mode>xf3_i387"
14174 [(set (match_operand:XF 0 "register_operand" "=f")
14175 (unspec:XF [(float_extend:XF
14176 (match_operand:MODEF 2 "register_operand" "0"))]
14177 UNSPEC_XTRACT_FRACT))
14178 (set (match_operand:XF 1 "register_operand" "=u")
14179 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14180 "TARGET_USE_FANCY_MATH_387
14181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14182 || TARGET_MIX_SSE_I387)
14183 && flag_unsafe_math_optimizations"
14185 [(set_attr "type" "fpspc")
14186 (set_attr "mode" "XF")])
14188 (define_expand "logbxf2"
14189 [(parallel [(set (match_dup 2)
14190 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14191 UNSPEC_XTRACT_FRACT))
14192 (set (match_operand:XF 0 "register_operand" "")
14193 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14196 "operands[2] = gen_reg_rtx (XFmode);")
14198 (define_expand "logb<mode>2"
14199 [(use (match_operand:MODEF 0 "register_operand" ""))
14200 (use (match_operand:MODEF 1 "register_operand" ""))]
14201 "TARGET_USE_FANCY_MATH_387
14202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203 || TARGET_MIX_SSE_I387)
14204 && flag_unsafe_math_optimizations"
14206 rtx op0 = gen_reg_rtx (XFmode);
14207 rtx op1 = gen_reg_rtx (XFmode);
14209 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14210 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14214 (define_expand "ilogbxf2"
14215 [(use (match_operand:SI 0 "register_operand" ""))
14216 (use (match_operand:XF 1 "register_operand" ""))]
14217 "TARGET_USE_FANCY_MATH_387
14218 && flag_unsafe_math_optimizations"
14222 if (optimize_insn_for_size_p ())
14225 op0 = gen_reg_rtx (XFmode);
14226 op1 = gen_reg_rtx (XFmode);
14228 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14229 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14233 (define_expand "ilogb<mode>2"
14234 [(use (match_operand:SI 0 "register_operand" ""))
14235 (use (match_operand:MODEF 1 "register_operand" ""))]
14236 "TARGET_USE_FANCY_MATH_387
14237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14238 || TARGET_MIX_SSE_I387)
14239 && flag_unsafe_math_optimizations"
14243 if (optimize_insn_for_size_p ())
14246 op0 = gen_reg_rtx (XFmode);
14247 op1 = gen_reg_rtx (XFmode);
14249 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14250 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14254 (define_insn "*f2xm1xf2_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14261 [(set_attr "type" "fpspc")
14262 (set_attr "mode" "XF")])
14264 (define_insn "*fscalexf4_i387"
14265 [(set (match_operand:XF 0 "register_operand" "=f")
14266 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14267 (match_operand:XF 3 "register_operand" "1")]
14268 UNSPEC_FSCALE_FRACT))
14269 (set (match_operand:XF 1 "register_operand" "=u")
14270 (unspec:XF [(match_dup 2) (match_dup 3)]
14271 UNSPEC_FSCALE_EXP))]
14272 "TARGET_USE_FANCY_MATH_387
14273 && flag_unsafe_math_optimizations"
14275 [(set_attr "type" "fpspc")
14276 (set_attr "mode" "XF")])
14278 (define_expand "expNcorexf3"
14279 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14280 (match_operand:XF 2 "register_operand" "")))
14281 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14282 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14283 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14284 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14285 (parallel [(set (match_operand:XF 0 "register_operand" "")
14286 (unspec:XF [(match_dup 8) (match_dup 4)]
14287 UNSPEC_FSCALE_FRACT))
14289 (unspec:XF [(match_dup 8) (match_dup 4)]
14290 UNSPEC_FSCALE_EXP))])]
14291 "TARGET_USE_FANCY_MATH_387
14292 && flag_unsafe_math_optimizations"
14296 if (optimize_insn_for_size_p ())
14299 for (i = 3; i < 10; i++)
14300 operands[i] = gen_reg_rtx (XFmode);
14302 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14305 (define_expand "expxf2"
14306 [(use (match_operand:XF 0 "register_operand" ""))
14307 (use (match_operand:XF 1 "register_operand" ""))]
14308 "TARGET_USE_FANCY_MATH_387
14309 && flag_unsafe_math_optimizations"
14313 if (optimize_insn_for_size_p ())
14316 op2 = gen_reg_rtx (XFmode);
14317 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14319 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14323 (define_expand "exp<mode>2"
14324 [(use (match_operand:MODEF 0 "register_operand" ""))
14325 (use (match_operand:MODEF 1 "general_operand" ""))]
14326 "TARGET_USE_FANCY_MATH_387
14327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14328 || TARGET_MIX_SSE_I387)
14329 && flag_unsafe_math_optimizations"
14333 if (optimize_insn_for_size_p ())
14336 op0 = gen_reg_rtx (XFmode);
14337 op1 = gen_reg_rtx (XFmode);
14339 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14340 emit_insn (gen_expxf2 (op0, op1));
14341 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14345 (define_expand "exp10xf2"
14346 [(use (match_operand:XF 0 "register_operand" ""))
14347 (use (match_operand:XF 1 "register_operand" ""))]
14348 "TARGET_USE_FANCY_MATH_387
14349 && flag_unsafe_math_optimizations"
14353 if (optimize_insn_for_size_p ())
14356 op2 = gen_reg_rtx (XFmode);
14357 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14359 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14363 (define_expand "exp10<mode>2"
14364 [(use (match_operand:MODEF 0 "register_operand" ""))
14365 (use (match_operand:MODEF 1 "general_operand" ""))]
14366 "TARGET_USE_FANCY_MATH_387
14367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14368 || TARGET_MIX_SSE_I387)
14369 && flag_unsafe_math_optimizations"
14373 if (optimize_insn_for_size_p ())
14376 op0 = gen_reg_rtx (XFmode);
14377 op1 = gen_reg_rtx (XFmode);
14379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14380 emit_insn (gen_exp10xf2 (op0, op1));
14381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14385 (define_expand "exp2xf2"
14386 [(use (match_operand:XF 0 "register_operand" ""))
14387 (use (match_operand:XF 1 "register_operand" ""))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && flag_unsafe_math_optimizations"
14393 if (optimize_insn_for_size_p ())
14396 op2 = gen_reg_rtx (XFmode);
14397 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14399 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14403 (define_expand "exp2<mode>2"
14404 [(use (match_operand:MODEF 0 "register_operand" ""))
14405 (use (match_operand:MODEF 1 "general_operand" ""))]
14406 "TARGET_USE_FANCY_MATH_387
14407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14408 || TARGET_MIX_SSE_I387)
14409 && flag_unsafe_math_optimizations"
14413 if (optimize_insn_for_size_p ())
14416 op0 = gen_reg_rtx (XFmode);
14417 op1 = gen_reg_rtx (XFmode);
14419 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14420 emit_insn (gen_exp2xf2 (op0, op1));
14421 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14425 (define_expand "expm1xf2"
14426 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14428 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14429 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14430 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14431 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14432 (parallel [(set (match_dup 7)
14433 (unspec:XF [(match_dup 6) (match_dup 4)]
14434 UNSPEC_FSCALE_FRACT))
14436 (unspec:XF [(match_dup 6) (match_dup 4)]
14437 UNSPEC_FSCALE_EXP))])
14438 (parallel [(set (match_dup 10)
14439 (unspec:XF [(match_dup 9) (match_dup 8)]
14440 UNSPEC_FSCALE_FRACT))
14441 (set (match_dup 11)
14442 (unspec:XF [(match_dup 9) (match_dup 8)]
14443 UNSPEC_FSCALE_EXP))])
14444 (set (match_dup 12) (minus:XF (match_dup 10)
14445 (float_extend:XF (match_dup 13))))
14446 (set (match_operand:XF 0 "register_operand" "")
14447 (plus:XF (match_dup 12) (match_dup 7)))]
14448 "TARGET_USE_FANCY_MATH_387
14449 && flag_unsafe_math_optimizations"
14453 if (optimize_insn_for_size_p ())
14456 for (i = 2; i < 13; i++)
14457 operands[i] = gen_reg_rtx (XFmode);
14460 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14462 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14465 (define_expand "expm1<mode>2"
14466 [(use (match_operand:MODEF 0 "register_operand" ""))
14467 (use (match_operand:MODEF 1 "general_operand" ""))]
14468 "TARGET_USE_FANCY_MATH_387
14469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14470 || TARGET_MIX_SSE_I387)
14471 && flag_unsafe_math_optimizations"
14475 if (optimize_insn_for_size_p ())
14478 op0 = gen_reg_rtx (XFmode);
14479 op1 = gen_reg_rtx (XFmode);
14481 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14482 emit_insn (gen_expm1xf2 (op0, op1));
14483 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14487 (define_expand "ldexpxf3"
14488 [(set (match_dup 3)
14489 (float:XF (match_operand:SI 2 "register_operand" "")))
14490 (parallel [(set (match_operand:XF 0 " register_operand" "")
14491 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14493 UNSPEC_FSCALE_FRACT))
14495 (unspec:XF [(match_dup 1) (match_dup 3)]
14496 UNSPEC_FSCALE_EXP))])]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14500 if (optimize_insn_for_size_p ())
14503 operands[3] = gen_reg_rtx (XFmode);
14504 operands[4] = gen_reg_rtx (XFmode);
14507 (define_expand "ldexp<mode>3"
14508 [(use (match_operand:MODEF 0 "register_operand" ""))
14509 (use (match_operand:MODEF 1 "general_operand" ""))
14510 (use (match_operand:SI 2 "register_operand" ""))]
14511 "TARGET_USE_FANCY_MATH_387
14512 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14513 || TARGET_MIX_SSE_I387)
14514 && flag_unsafe_math_optimizations"
14518 if (optimize_insn_for_size_p ())
14521 op0 = gen_reg_rtx (XFmode);
14522 op1 = gen_reg_rtx (XFmode);
14524 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14525 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14530 (define_expand "scalbxf3"
14531 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14532 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14533 (match_operand:XF 2 "register_operand" "")]
14534 UNSPEC_FSCALE_FRACT))
14536 (unspec:XF [(match_dup 1) (match_dup 2)]
14537 UNSPEC_FSCALE_EXP))])]
14538 "TARGET_USE_FANCY_MATH_387
14539 && flag_unsafe_math_optimizations"
14541 if (optimize_insn_for_size_p ())
14544 operands[3] = gen_reg_rtx (XFmode);
14547 (define_expand "scalb<mode>3"
14548 [(use (match_operand:MODEF 0 "register_operand" ""))
14549 (use (match_operand:MODEF 1 "general_operand" ""))
14550 (use (match_operand:MODEF 2 "general_operand" ""))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553 || TARGET_MIX_SSE_I387)
14554 && flag_unsafe_math_optimizations"
14558 if (optimize_insn_for_size_p ())
14561 op0 = gen_reg_rtx (XFmode);
14562 op1 = gen_reg_rtx (XFmode);
14563 op2 = gen_reg_rtx (XFmode);
14565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14567 emit_insn (gen_scalbxf3 (op0, op1, op2));
14568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14572 (define_expand "significandxf2"
14573 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14574 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14575 UNSPEC_XTRACT_FRACT))
14577 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14578 "TARGET_USE_FANCY_MATH_387
14579 && flag_unsafe_math_optimizations"
14580 "operands[2] = gen_reg_rtx (XFmode);")
14582 (define_expand "significand<mode>2"
14583 [(use (match_operand:MODEF 0 "register_operand" ""))
14584 (use (match_operand:MODEF 1 "register_operand" ""))]
14585 "TARGET_USE_FANCY_MATH_387
14586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14587 || TARGET_MIX_SSE_I387)
14588 && flag_unsafe_math_optimizations"
14590 rtx op0 = gen_reg_rtx (XFmode);
14591 rtx op1 = gen_reg_rtx (XFmode);
14593 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14594 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14599 (define_insn "sse4_1_round<mode>2"
14600 [(set (match_operand:MODEF 0 "register_operand" "=x")
14601 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14602 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14605 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14606 [(set_attr "type" "ssecvt")
14607 (set_attr "prefix_extra" "1")
14608 (set_attr "prefix" "maybe_vex")
14609 (set_attr "mode" "<MODE>")])
14611 (define_insn "rintxf2"
14612 [(set (match_operand:XF 0 "register_operand" "=f")
14613 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14615 "TARGET_USE_FANCY_MATH_387
14616 && flag_unsafe_math_optimizations"
14618 [(set_attr "type" "fpspc")
14619 (set_attr "mode" "XF")])
14621 (define_expand "rint<mode>2"
14622 [(use (match_operand:MODEF 0 "register_operand" ""))
14623 (use (match_operand:MODEF 1 "register_operand" ""))]
14624 "(TARGET_USE_FANCY_MATH_387
14625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14626 || TARGET_MIX_SSE_I387)
14627 && flag_unsafe_math_optimizations)
14628 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14629 && !flag_trapping_math)"
14631 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14632 && !flag_trapping_math)
14635 emit_insn (gen_sse4_1_round<mode>2
14636 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14637 else if (optimize_insn_for_size_p ())
14640 ix86_expand_rint (operand0, operand1);
14644 rtx op0 = gen_reg_rtx (XFmode);
14645 rtx op1 = gen_reg_rtx (XFmode);
14647 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14648 emit_insn (gen_rintxf2 (op0, op1));
14650 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14655 (define_expand "round<mode>2"
14656 [(match_operand:X87MODEF 0 "register_operand" "")
14657 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14658 "(TARGET_USE_FANCY_MATH_387
14659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14660 || TARGET_MIX_SSE_I387)
14661 && flag_unsafe_math_optimizations)
14662 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14663 && !flag_trapping_math && !flag_rounding_math)"
14665 if (optimize_insn_for_size_p ())
14668 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14669 && !flag_trapping_math && !flag_rounding_math)
14673 operands[1] = force_reg (<MODE>mode, operands[1]);
14674 ix86_expand_round_sse4 (operands[0], operands[1]);
14676 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14677 ix86_expand_round (operands[0], operands[1]);
14679 ix86_expand_rounddf_32 (operands[0], operands[1]);
14683 operands[1] = force_reg (<MODE>mode, operands[1]);
14684 ix86_emit_i387_round (operands[0], operands[1]);
14689 (define_insn_and_split "*fistdi2_1"
14690 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14693 "TARGET_USE_FANCY_MATH_387
14694 && can_create_pseudo_p ()"
14699 if (memory_operand (operands[0], VOIDmode))
14700 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14703 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14704 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14709 [(set_attr "type" "fpspc")
14710 (set_attr "mode" "DI")])
14712 (define_insn "fistdi2"
14713 [(set (match_operand:DI 0 "memory_operand" "=m")
14714 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14716 (clobber (match_scratch:XF 2 "=&1f"))]
14717 "TARGET_USE_FANCY_MATH_387"
14718 "* return output_fix_trunc (insn, operands, false);"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "DI")])
14722 (define_insn "fistdi2_with_temp"
14723 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14726 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14727 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14728 "TARGET_USE_FANCY_MATH_387"
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "DI")])
14734 [(set (match_operand:DI 0 "register_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14737 (clobber (match_operand:DI 2 "memory_operand" ""))
14738 (clobber (match_scratch 3 ""))]
14740 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741 (clobber (match_dup 3))])
14742 (set (match_dup 0) (match_dup 2))])
14745 [(set (match_operand:DI 0 "memory_operand" "")
14746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14748 (clobber (match_operand:DI 2 "memory_operand" ""))
14749 (clobber (match_scratch 3 ""))]
14751 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14752 (clobber (match_dup 3))])])
14754 (define_insn_and_split "*fist<mode>2_1"
14755 [(set (match_operand:SWI24 0 "register_operand" "")
14756 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14758 "TARGET_USE_FANCY_MATH_387
14759 && can_create_pseudo_p ()"
14764 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14765 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "<MODE>")])
14772 (define_insn "fist<mode>2"
14773 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14776 "TARGET_USE_FANCY_MATH_387"
14777 "* return output_fix_trunc (insn, operands, false);"
14778 [(set_attr "type" "fpspc")
14779 (set_attr "mode" "<MODE>")])
14781 (define_insn "fist<mode>2_with_temp"
14782 [(set (match_operand:SWI24 0 "register_operand" "=r")
14783 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14785 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14786 "TARGET_USE_FANCY_MATH_387"
14788 [(set_attr "type" "fpspc")
14789 (set_attr "mode" "<MODE>")])
14792 [(set (match_operand:SWI24 0 "register_operand" "")
14793 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14795 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14797 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14798 (set (match_dup 0) (match_dup 2))])
14801 [(set (match_operand:SWI24 0 "memory_operand" "")
14802 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14804 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14806 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14808 (define_expand "lrintxf<mode>2"
14809 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14810 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14812 "TARGET_USE_FANCY_MATH_387")
14814 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14815 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14816 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14817 UNSPEC_FIX_NOTRUNC))]
14818 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14819 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14821 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14822 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14823 (match_operand:X87MODEF 1 "register_operand" "")]
14824 "(TARGET_USE_FANCY_MATH_387
14825 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14826 || TARGET_MIX_SSE_I387)
14827 && flag_unsafe_math_optimizations)
14828 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14829 && <SWI248x:MODE>mode != HImode
14830 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14831 && !flag_trapping_math && !flag_rounding_math)"
14833 if (optimize_insn_for_size_p ())
14836 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14837 && <SWI248x:MODE>mode != HImode
14838 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14839 && !flag_trapping_math && !flag_rounding_math)
14840 ix86_expand_lround (operand0, operand1);
14842 ix86_emit_i387_round (operands[0], operands[1]);
14846 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14847 (define_insn_and_split "frndintxf2_floor"
14848 [(set (match_operand:XF 0 "register_operand" "")
14849 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14850 UNSPEC_FRNDINT_FLOOR))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_USE_FANCY_MATH_387
14853 && flag_unsafe_math_optimizations
14854 && can_create_pseudo_p ()"
14859 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14861 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14862 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14864 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14865 operands[2], operands[3]));
14868 [(set_attr "type" "frndint")
14869 (set_attr "i387_cw" "floor")
14870 (set_attr "mode" "XF")])
14872 (define_insn "frndintxf2_floor_i387"
14873 [(set (match_operand:XF 0 "register_operand" "=f")
14874 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14875 UNSPEC_FRNDINT_FLOOR))
14876 (use (match_operand:HI 2 "memory_operand" "m"))
14877 (use (match_operand:HI 3 "memory_operand" "m"))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && flag_unsafe_math_optimizations"
14880 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14881 [(set_attr "type" "frndint")
14882 (set_attr "i387_cw" "floor")
14883 (set_attr "mode" "XF")])
14885 (define_expand "floorxf2"
14886 [(use (match_operand:XF 0 "register_operand" ""))
14887 (use (match_operand:XF 1 "register_operand" ""))]
14888 "TARGET_USE_FANCY_MATH_387
14889 && flag_unsafe_math_optimizations"
14891 if (optimize_insn_for_size_p ())
14893 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14897 (define_expand "floor<mode>2"
14898 [(use (match_operand:MODEF 0 "register_operand" ""))
14899 (use (match_operand:MODEF 1 "register_operand" ""))]
14900 "(TARGET_USE_FANCY_MATH_387
14901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14902 || TARGET_MIX_SSE_I387)
14903 && flag_unsafe_math_optimizations)
14904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && !flag_trapping_math)"
14907 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14908 && !flag_trapping_math)
14911 emit_insn (gen_sse4_1_round<mode>2
14912 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14913 else if (optimize_insn_for_size_p ())
14915 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14916 ix86_expand_floorceil (operand0, operand1, true);
14918 ix86_expand_floorceildf_32 (operand0, operand1, true);
14924 if (optimize_insn_for_size_p ())
14927 op0 = gen_reg_rtx (XFmode);
14928 op1 = gen_reg_rtx (XFmode);
14929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14930 emit_insn (gen_frndintxf2_floor (op0, op1));
14932 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14937 (define_insn_and_split "*fist<mode>2_floor_1"
14938 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14939 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14940 UNSPEC_FIST_FLOOR))
14941 (clobber (reg:CC FLAGS_REG))]
14942 "TARGET_USE_FANCY_MATH_387
14943 && flag_unsafe_math_optimizations
14944 && can_create_pseudo_p ()"
14949 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14951 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14952 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14953 if (memory_operand (operands[0], VOIDmode))
14954 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14955 operands[2], operands[3]));
14958 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14959 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14960 operands[2], operands[3],
14965 [(set_attr "type" "fistp")
14966 (set_attr "i387_cw" "floor")
14967 (set_attr "mode" "<MODE>")])
14969 (define_insn "fistdi2_floor"
14970 [(set (match_operand:DI 0 "memory_operand" "=m")
14971 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14972 UNSPEC_FIST_FLOOR))
14973 (use (match_operand:HI 2 "memory_operand" "m"))
14974 (use (match_operand:HI 3 "memory_operand" "m"))
14975 (clobber (match_scratch:XF 4 "=&1f"))]
14976 "TARGET_USE_FANCY_MATH_387
14977 && flag_unsafe_math_optimizations"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "DI")])
14983 (define_insn "fistdi2_floor_with_temp"
14984 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14985 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" "m,m"))
14988 (use (match_operand:HI 3 "memory_operand" "m,m"))
14989 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14990 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations"
14994 [(set_attr "type" "fistp")
14995 (set_attr "i387_cw" "floor")
14996 (set_attr "mode" "DI")])
14999 [(set (match_operand:DI 0 "register_operand" "")
15000 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15001 UNSPEC_FIST_FLOOR))
15002 (use (match_operand:HI 2 "memory_operand" ""))
15003 (use (match_operand:HI 3 "memory_operand" ""))
15004 (clobber (match_operand:DI 4 "memory_operand" ""))
15005 (clobber (match_scratch 5 ""))]
15007 [(parallel [(set (match_dup 4)
15008 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15009 (use (match_dup 2))
15010 (use (match_dup 3))
15011 (clobber (match_dup 5))])
15012 (set (match_dup 0) (match_dup 4))])
15015 [(set (match_operand:DI 0 "memory_operand" "")
15016 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15017 UNSPEC_FIST_FLOOR))
15018 (use (match_operand:HI 2 "memory_operand" ""))
15019 (use (match_operand:HI 3 "memory_operand" ""))
15020 (clobber (match_operand:DI 4 "memory_operand" ""))
15021 (clobber (match_scratch 5 ""))]
15023 [(parallel [(set (match_dup 0)
15024 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15025 (use (match_dup 2))
15026 (use (match_dup 3))
15027 (clobber (match_dup 5))])])
15029 (define_insn "fist<mode>2_floor"
15030 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15031 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15032 UNSPEC_FIST_FLOOR))
15033 (use (match_operand:HI 2 "memory_operand" "m"))
15034 (use (match_operand:HI 3 "memory_operand" "m"))]
15035 "TARGET_USE_FANCY_MATH_387
15036 && flag_unsafe_math_optimizations"
15037 "* return output_fix_trunc (insn, operands, false);"
15038 [(set_attr "type" "fistp")
15039 (set_attr "i387_cw" "floor")
15040 (set_attr "mode" "<MODE>")])
15042 (define_insn "fist<mode>2_floor_with_temp"
15043 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15044 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15045 UNSPEC_FIST_FLOOR))
15046 (use (match_operand:HI 2 "memory_operand" "m,m"))
15047 (use (match_operand:HI 3 "memory_operand" "m,m"))
15048 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && flag_unsafe_math_optimizations"
15052 [(set_attr "type" "fistp")
15053 (set_attr "i387_cw" "floor")
15054 (set_attr "mode" "<MODE>")])
15057 [(set (match_operand:SWI24 0 "register_operand" "")
15058 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15059 UNSPEC_FIST_FLOOR))
15060 (use (match_operand:HI 2 "memory_operand" ""))
15061 (use (match_operand:HI 3 "memory_operand" ""))
15062 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15064 [(parallel [(set (match_dup 4)
15065 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15066 (use (match_dup 2))
15067 (use (match_dup 3))])
15068 (set (match_dup 0) (match_dup 4))])
15071 [(set (match_operand:SWI24 0 "memory_operand" "")
15072 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15073 UNSPEC_FIST_FLOOR))
15074 (use (match_operand:HI 2 "memory_operand" ""))
15075 (use (match_operand:HI 3 "memory_operand" ""))
15076 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15078 [(parallel [(set (match_dup 0)
15079 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15080 (use (match_dup 2))
15081 (use (match_dup 3))])])
15083 (define_expand "lfloorxf<mode>2"
15084 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15085 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15086 UNSPEC_FIST_FLOOR))
15087 (clobber (reg:CC FLAGS_REG))])]
15088 "TARGET_USE_FANCY_MATH_387
15089 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15090 && flag_unsafe_math_optimizations")
15092 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15093 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15094 (match_operand:MODEF 1 "register_operand" "")]
15095 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15096 && !flag_trapping_math"
15098 if (TARGET_64BIT && optimize_insn_for_size_p ())
15100 ix86_expand_lfloorceil (operand0, operand1, true);
15104 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15105 (define_insn_and_split "frndintxf2_ceil"
15106 [(set (match_operand:XF 0 "register_operand" "")
15107 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15108 UNSPEC_FRNDINT_CEIL))
15109 (clobber (reg:CC FLAGS_REG))]
15110 "TARGET_USE_FANCY_MATH_387
15111 && flag_unsafe_math_optimizations
15112 && can_create_pseudo_p ()"
15117 ix86_optimize_mode_switching[I387_CEIL] = 1;
15119 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15120 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15122 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15123 operands[2], operands[3]));
15126 [(set_attr "type" "frndint")
15127 (set_attr "i387_cw" "ceil")
15128 (set_attr "mode" "XF")])
15130 (define_insn "frndintxf2_ceil_i387"
15131 [(set (match_operand:XF 0 "register_operand" "=f")
15132 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15133 UNSPEC_FRNDINT_CEIL))
15134 (use (match_operand:HI 2 "memory_operand" "m"))
15135 (use (match_operand:HI 3 "memory_operand" "m"))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations"
15138 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15139 [(set_attr "type" "frndint")
15140 (set_attr "i387_cw" "ceil")
15141 (set_attr "mode" "XF")])
15143 (define_expand "ceilxf2"
15144 [(use (match_operand:XF 0 "register_operand" ""))
15145 (use (match_operand:XF 1 "register_operand" ""))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && flag_unsafe_math_optimizations"
15149 if (optimize_insn_for_size_p ())
15151 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15155 (define_expand "ceil<mode>2"
15156 [(use (match_operand:MODEF 0 "register_operand" ""))
15157 (use (match_operand:MODEF 1 "register_operand" ""))]
15158 "(TARGET_USE_FANCY_MATH_387
15159 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15160 || TARGET_MIX_SSE_I387)
15161 && flag_unsafe_math_optimizations)
15162 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15163 && !flag_trapping_math)"
15165 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15166 && !flag_trapping_math)
15169 emit_insn (gen_sse4_1_round<mode>2
15170 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15171 else if (optimize_insn_for_size_p ())
15173 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15174 ix86_expand_floorceil (operand0, operand1, false);
15176 ix86_expand_floorceildf_32 (operand0, operand1, false);
15182 if (optimize_insn_for_size_p ())
15185 op0 = gen_reg_rtx (XFmode);
15186 op1 = gen_reg_rtx (XFmode);
15187 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15188 emit_insn (gen_frndintxf2_ceil (op0, op1));
15190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15195 (define_insn_and_split "*fist<mode>2_ceil_1"
15196 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15197 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15199 (clobber (reg:CC FLAGS_REG))]
15200 "TARGET_USE_FANCY_MATH_387
15201 && flag_unsafe_math_optimizations
15202 && can_create_pseudo_p ()"
15207 ix86_optimize_mode_switching[I387_CEIL] = 1;
15209 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15210 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15211 if (memory_operand (operands[0], VOIDmode))
15212 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15213 operands[2], operands[3]));
15216 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15217 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15218 operands[2], operands[3],
15223 [(set_attr "type" "fistp")
15224 (set_attr "i387_cw" "ceil")
15225 (set_attr "mode" "<MODE>")])
15227 (define_insn "fistdi2_ceil"
15228 [(set (match_operand:DI 0 "memory_operand" "=m")
15229 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15231 (use (match_operand:HI 2 "memory_operand" "m"))
15232 (use (match_operand:HI 3 "memory_operand" "m"))
15233 (clobber (match_scratch:XF 4 "=&1f"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15236 "* return output_fix_trunc (insn, operands, false);"
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "DI")])
15241 (define_insn "fistdi2_ceil_with_temp"
15242 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15243 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15245 (use (match_operand:HI 2 "memory_operand" "m,m"))
15246 (use (match_operand:HI 3 "memory_operand" "m,m"))
15247 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15248 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15249 "TARGET_USE_FANCY_MATH_387
15250 && flag_unsafe_math_optimizations"
15252 [(set_attr "type" "fistp")
15253 (set_attr "i387_cw" "ceil")
15254 (set_attr "mode" "DI")])
15257 [(set (match_operand:DI 0 "register_operand" "")
15258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15260 (use (match_operand:HI 2 "memory_operand" ""))
15261 (use (match_operand:HI 3 "memory_operand" ""))
15262 (clobber (match_operand:DI 4 "memory_operand" ""))
15263 (clobber (match_scratch 5 ""))]
15265 [(parallel [(set (match_dup 4)
15266 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15267 (use (match_dup 2))
15268 (use (match_dup 3))
15269 (clobber (match_dup 5))])
15270 (set (match_dup 0) (match_dup 4))])
15273 [(set (match_operand:DI 0 "memory_operand" "")
15274 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15276 (use (match_operand:HI 2 "memory_operand" ""))
15277 (use (match_operand:HI 3 "memory_operand" ""))
15278 (clobber (match_operand:DI 4 "memory_operand" ""))
15279 (clobber (match_scratch 5 ""))]
15281 [(parallel [(set (match_dup 0)
15282 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15283 (use (match_dup 2))
15284 (use (match_dup 3))
15285 (clobber (match_dup 5))])])
15287 (define_insn "fist<mode>2_ceil"
15288 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15289 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15291 (use (match_operand:HI 2 "memory_operand" "m"))
15292 (use (match_operand:HI 3 "memory_operand" "m"))]
15293 "TARGET_USE_FANCY_MATH_387
15294 && flag_unsafe_math_optimizations"
15295 "* return output_fix_trunc (insn, operands, false);"
15296 [(set_attr "type" "fistp")
15297 (set_attr "i387_cw" "ceil")
15298 (set_attr "mode" "<MODE>")])
15300 (define_insn "fist<mode>2_ceil_with_temp"
15301 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15302 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15304 (use (match_operand:HI 2 "memory_operand" "m,m"))
15305 (use (match_operand:HI 3 "memory_operand" "m,m"))
15306 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15310 [(set_attr "type" "fistp")
15311 (set_attr "i387_cw" "ceil")
15312 (set_attr "mode" "<MODE>")])
15315 [(set (match_operand:SWI24 0 "register_operand" "")
15316 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15318 (use (match_operand:HI 2 "memory_operand" ""))
15319 (use (match_operand:HI 3 "memory_operand" ""))
15320 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15322 [(parallel [(set (match_dup 4)
15323 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15324 (use (match_dup 2))
15325 (use (match_dup 3))])
15326 (set (match_dup 0) (match_dup 4))])
15329 [(set (match_operand:SWI24 0 "memory_operand" "")
15330 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15332 (use (match_operand:HI 2 "memory_operand" ""))
15333 (use (match_operand:HI 3 "memory_operand" ""))
15334 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15336 [(parallel [(set (match_dup 0)
15337 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15338 (use (match_dup 2))
15339 (use (match_dup 3))])])
15341 (define_expand "lceilxf<mode>2"
15342 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15343 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15345 (clobber (reg:CC FLAGS_REG))])]
15346 "TARGET_USE_FANCY_MATH_387
15347 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15348 && flag_unsafe_math_optimizations")
15350 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15351 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15352 (match_operand:MODEF 1 "register_operand" "")]
15353 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15354 && !flag_trapping_math"
15356 ix86_expand_lfloorceil (operand0, operand1, false);
15360 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15361 (define_insn_and_split "frndintxf2_trunc"
15362 [(set (match_operand:XF 0 "register_operand" "")
15363 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15364 UNSPEC_FRNDINT_TRUNC))
15365 (clobber (reg:CC FLAGS_REG))]
15366 "TARGET_USE_FANCY_MATH_387
15367 && flag_unsafe_math_optimizations
15368 && can_create_pseudo_p ()"
15373 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15375 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15376 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15378 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15379 operands[2], operands[3]));
15382 [(set_attr "type" "frndint")
15383 (set_attr "i387_cw" "trunc")
15384 (set_attr "mode" "XF")])
15386 (define_insn "frndintxf2_trunc_i387"
15387 [(set (match_operand:XF 0 "register_operand" "=f")
15388 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15389 UNSPEC_FRNDINT_TRUNC))
15390 (use (match_operand:HI 2 "memory_operand" "m"))
15391 (use (match_operand:HI 3 "memory_operand" "m"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_unsafe_math_optimizations"
15394 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15395 [(set_attr "type" "frndint")
15396 (set_attr "i387_cw" "trunc")
15397 (set_attr "mode" "XF")])
15399 (define_expand "btruncxf2"
15400 [(use (match_operand:XF 0 "register_operand" ""))
15401 (use (match_operand:XF 1 "register_operand" ""))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_unsafe_math_optimizations"
15405 if (optimize_insn_for_size_p ())
15407 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15411 (define_expand "btrunc<mode>2"
15412 [(use (match_operand:MODEF 0 "register_operand" ""))
15413 (use (match_operand:MODEF 1 "register_operand" ""))]
15414 "(TARGET_USE_FANCY_MATH_387
15415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15416 || TARGET_MIX_SSE_I387)
15417 && flag_unsafe_math_optimizations)
15418 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15419 && !flag_trapping_math)"
15421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15422 && !flag_trapping_math)
15425 emit_insn (gen_sse4_1_round<mode>2
15426 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15427 else if (optimize_insn_for_size_p ())
15429 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15430 ix86_expand_trunc (operand0, operand1);
15432 ix86_expand_truncdf_32 (operand0, operand1);
15438 if (optimize_insn_for_size_p ())
15441 op0 = gen_reg_rtx (XFmode);
15442 op1 = gen_reg_rtx (XFmode);
15443 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15444 emit_insn (gen_frndintxf2_trunc (op0, op1));
15446 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15451 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15452 (define_insn_and_split "frndintxf2_mask_pm"
15453 [(set (match_operand:XF 0 "register_operand" "")
15454 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15455 UNSPEC_FRNDINT_MASK_PM))
15456 (clobber (reg:CC FLAGS_REG))]
15457 "TARGET_USE_FANCY_MATH_387
15458 && flag_unsafe_math_optimizations
15459 && can_create_pseudo_p ()"
15464 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15466 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15467 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15469 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15470 operands[2], operands[3]));
15473 [(set_attr "type" "frndint")
15474 (set_attr "i387_cw" "mask_pm")
15475 (set_attr "mode" "XF")])
15477 (define_insn "frndintxf2_mask_pm_i387"
15478 [(set (match_operand:XF 0 "register_operand" "=f")
15479 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15480 UNSPEC_FRNDINT_MASK_PM))
15481 (use (match_operand:HI 2 "memory_operand" "m"))
15482 (use (match_operand:HI 3 "memory_operand" "m"))]
15483 "TARGET_USE_FANCY_MATH_387
15484 && flag_unsafe_math_optimizations"
15485 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15486 [(set_attr "type" "frndint")
15487 (set_attr "i387_cw" "mask_pm")
15488 (set_attr "mode" "XF")])
15490 (define_expand "nearbyintxf2"
15491 [(use (match_operand:XF 0 "register_operand" ""))
15492 (use (match_operand:XF 1 "register_operand" ""))]
15493 "TARGET_USE_FANCY_MATH_387
15494 && flag_unsafe_math_optimizations"
15496 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15500 (define_expand "nearbyint<mode>2"
15501 [(use (match_operand:MODEF 0 "register_operand" ""))
15502 (use (match_operand:MODEF 1 "register_operand" ""))]
15503 "TARGET_USE_FANCY_MATH_387
15504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15505 || TARGET_MIX_SSE_I387)
15506 && flag_unsafe_math_optimizations"
15508 rtx op0 = gen_reg_rtx (XFmode);
15509 rtx op1 = gen_reg_rtx (XFmode);
15511 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15512 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15518 (define_insn "fxam<mode>2_i387"
15519 [(set (match_operand:HI 0 "register_operand" "=a")
15521 [(match_operand:X87MODEF 1 "register_operand" "f")]
15523 "TARGET_USE_FANCY_MATH_387"
15524 "fxam\n\tfnstsw\t%0"
15525 [(set_attr "type" "multi")
15526 (set_attr "length" "4")
15527 (set_attr "unit" "i387")
15528 (set_attr "mode" "<MODE>")])
15530 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15531 [(set (match_operand:HI 0 "register_operand" "")
15533 [(match_operand:MODEF 1 "memory_operand" "")]
15535 "TARGET_USE_FANCY_MATH_387
15536 && can_create_pseudo_p ()"
15539 [(set (match_dup 2)(match_dup 1))
15541 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15543 operands[2] = gen_reg_rtx (<MODE>mode);
15545 MEM_VOLATILE_P (operands[1]) = 1;
15547 [(set_attr "type" "multi")
15548 (set_attr "unit" "i387")
15549 (set_attr "mode" "<MODE>")])
15551 (define_expand "isinfxf2"
15552 [(use (match_operand:SI 0 "register_operand" ""))
15553 (use (match_operand:XF 1 "register_operand" ""))]
15554 "TARGET_USE_FANCY_MATH_387
15555 && TARGET_C99_FUNCTIONS"
15557 rtx mask = GEN_INT (0x45);
15558 rtx val = GEN_INT (0x05);
15562 rtx scratch = gen_reg_rtx (HImode);
15563 rtx res = gen_reg_rtx (QImode);
15565 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15567 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15568 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15569 cond = gen_rtx_fmt_ee (EQ, QImode,
15570 gen_rtx_REG (CCmode, FLAGS_REG),
15572 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15573 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15577 (define_expand "isinf<mode>2"
15578 [(use (match_operand:SI 0 "register_operand" ""))
15579 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && TARGET_C99_FUNCTIONS
15582 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15584 rtx mask = GEN_INT (0x45);
15585 rtx val = GEN_INT (0x05);
15589 rtx scratch = gen_reg_rtx (HImode);
15590 rtx res = gen_reg_rtx (QImode);
15592 /* Remove excess precision by forcing value through memory. */
15593 if (memory_operand (operands[1], VOIDmode))
15594 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15597 enum ix86_stack_slot slot = (virtuals_instantiated
15600 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15602 emit_move_insn (temp, operands[1]);
15603 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15606 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15607 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15608 cond = gen_rtx_fmt_ee (EQ, QImode,
15609 gen_rtx_REG (CCmode, FLAGS_REG),
15611 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15612 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15616 (define_expand "signbitxf2"
15617 [(use (match_operand:SI 0 "register_operand" ""))
15618 (use (match_operand:XF 1 "register_operand" ""))]
15619 "TARGET_USE_FANCY_MATH_387"
15621 rtx scratch = gen_reg_rtx (HImode);
15623 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15624 emit_insn (gen_andsi3 (operands[0],
15625 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15629 (define_insn "movmsk_df"
15630 [(set (match_operand:SI 0 "register_operand" "=r")
15632 [(match_operand:DF 1 "register_operand" "x")]
15634 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15635 "%vmovmskpd\t{%1, %0|%0, %1}"
15636 [(set_attr "type" "ssemov")
15637 (set_attr "prefix" "maybe_vex")
15638 (set_attr "mode" "DF")])
15640 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15641 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15642 (define_expand "signbitdf2"
15643 [(use (match_operand:SI 0 "register_operand" ""))
15644 (use (match_operand:DF 1 "register_operand" ""))]
15645 "TARGET_USE_FANCY_MATH_387
15646 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15648 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15650 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15651 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15655 rtx scratch = gen_reg_rtx (HImode);
15657 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15658 emit_insn (gen_andsi3 (operands[0],
15659 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15664 (define_expand "signbitsf2"
15665 [(use (match_operand:SI 0 "register_operand" ""))
15666 (use (match_operand:SF 1 "register_operand" ""))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15670 rtx scratch = gen_reg_rtx (HImode);
15672 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15673 emit_insn (gen_andsi3 (operands[0],
15674 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15678 ;; Block operation instructions
15681 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15684 [(set_attr "length" "1")
15685 (set_attr "length_immediate" "0")
15686 (set_attr "modrm" "0")])
15688 (define_expand "movmem<mode>"
15689 [(use (match_operand:BLK 0 "memory_operand" ""))
15690 (use (match_operand:BLK 1 "memory_operand" ""))
15691 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15692 (use (match_operand:SWI48 3 "const_int_operand" ""))
15693 (use (match_operand:SI 4 "const_int_operand" ""))
15694 (use (match_operand:SI 5 "const_int_operand" ""))]
15697 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15698 operands[4], operands[5]))
15704 ;; Most CPUs don't like single string operations
15705 ;; Handle this case here to simplify previous expander.
15707 (define_expand "strmov"
15708 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15709 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15710 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15711 (clobber (reg:CC FLAGS_REG))])
15712 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15713 (clobber (reg:CC FLAGS_REG))])]
15716 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15718 /* If .md ever supports :P for Pmode, these can be directly
15719 in the pattern above. */
15720 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15721 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15723 /* Can't use this if the user has appropriated esi or edi. */
15724 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15727 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15728 operands[2], operands[3],
15729 operands[5], operands[6]));
15733 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15736 (define_expand "strmov_singleop"
15737 [(parallel [(set (match_operand 1 "memory_operand" "")
15738 (match_operand 3 "memory_operand" ""))
15739 (set (match_operand 0 "register_operand" "")
15740 (match_operand 4 "" ""))
15741 (set (match_operand 2 "register_operand" "")
15742 (match_operand 5 "" ""))])]
15744 "ix86_current_function_needs_cld = 1;")
15746 (define_insn "*strmovdi_rex_1"
15747 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15748 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15749 (set (match_operand:DI 0 "register_operand" "=D")
15750 (plus:DI (match_dup 2)
15752 (set (match_operand:DI 1 "register_operand" "=S")
15753 (plus:DI (match_dup 3)
15756 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set_attr "mode" "DI")])
15762 (define_insn "*strmovsi_1"
15763 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15764 (mem:SI (match_operand:P 3 "register_operand" "1")))
15765 (set (match_operand:P 0 "register_operand" "=D")
15766 (plus:P (match_dup 2)
15768 (set (match_operand:P 1 "register_operand" "=S")
15769 (plus:P (match_dup 3)
15771 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773 [(set_attr "type" "str")
15774 (set_attr "memory" "both")
15775 (set_attr "mode" "SI")])
15777 (define_insn "*strmovhi_1"
15778 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15779 (mem:HI (match_operand:P 3 "register_operand" "1")))
15780 (set (match_operand:P 0 "register_operand" "=D")
15781 (plus:P (match_dup 2)
15783 (set (match_operand:P 1 "register_operand" "=S")
15784 (plus:P (match_dup 3)
15786 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15788 [(set_attr "type" "str")
15789 (set_attr "memory" "both")
15790 (set_attr "mode" "HI")])
15792 (define_insn "*strmovqi_1"
15793 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15794 (mem:QI (match_operand:P 3 "register_operand" "1")))
15795 (set (match_operand:P 0 "register_operand" "=D")
15796 (plus:P (match_dup 2)
15798 (set (match_operand:P 1 "register_operand" "=S")
15799 (plus:P (match_dup 3)
15801 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15803 [(set_attr "type" "str")
15804 (set_attr "memory" "both")
15805 (set (attr "prefix_rex")
15807 (match_test "<P:MODE>mode == DImode")
15809 (const_string "*")))
15810 (set_attr "mode" "QI")])
15812 (define_expand "rep_mov"
15813 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15814 (set (match_operand 0 "register_operand" "")
15815 (match_operand 5 "" ""))
15816 (set (match_operand 2 "register_operand" "")
15817 (match_operand 6 "" ""))
15818 (set (match_operand 1 "memory_operand" "")
15819 (match_operand 3 "memory_operand" ""))
15820 (use (match_dup 4))])]
15822 "ix86_current_function_needs_cld = 1;")
15824 (define_insn "*rep_movdi_rex64"
15825 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15826 (set (match_operand:DI 0 "register_operand" "=D")
15827 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15829 (match_operand:DI 3 "register_operand" "0")))
15830 (set (match_operand:DI 1 "register_operand" "=S")
15831 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15832 (match_operand:DI 4 "register_operand" "1")))
15833 (set (mem:BLK (match_dup 3))
15834 (mem:BLK (match_dup 4)))
15835 (use (match_dup 5))]
15837 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15839 [(set_attr "type" "str")
15840 (set_attr "prefix_rep" "1")
15841 (set_attr "memory" "both")
15842 (set_attr "mode" "DI")])
15844 (define_insn "*rep_movsi"
15845 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15846 (set (match_operand:P 0 "register_operand" "=D")
15847 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15849 (match_operand:P 3 "register_operand" "0")))
15850 (set (match_operand:P 1 "register_operand" "=S")
15851 (plus:P (ashift:P (match_dup 5) (const_int 2))
15852 (match_operand:P 4 "register_operand" "1")))
15853 (set (mem:BLK (match_dup 3))
15854 (mem:BLK (match_dup 4)))
15855 (use (match_dup 5))]
15856 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15857 "rep{%;} movs{l|d}"
15858 [(set_attr "type" "str")
15859 (set_attr "prefix_rep" "1")
15860 (set_attr "memory" "both")
15861 (set_attr "mode" "SI")])
15863 (define_insn "*rep_movqi"
15864 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15865 (set (match_operand:P 0 "register_operand" "=D")
15866 (plus:P (match_operand:P 3 "register_operand" "0")
15867 (match_operand:P 5 "register_operand" "2")))
15868 (set (match_operand:P 1 "register_operand" "=S")
15869 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15870 (set (mem:BLK (match_dup 3))
15871 (mem:BLK (match_dup 4)))
15872 (use (match_dup 5))]
15873 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15875 [(set_attr "type" "str")
15876 (set_attr "prefix_rep" "1")
15877 (set_attr "memory" "both")
15878 (set_attr "mode" "QI")])
15880 (define_expand "setmem<mode>"
15881 [(use (match_operand:BLK 0 "memory_operand" ""))
15882 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15883 (use (match_operand:QI 2 "nonmemory_operand" ""))
15884 (use (match_operand 3 "const_int_operand" ""))
15885 (use (match_operand:SI 4 "const_int_operand" ""))
15886 (use (match_operand:SI 5 "const_int_operand" ""))]
15889 if (ix86_expand_setmem (operands[0], operands[1],
15890 operands[2], operands[3],
15891 operands[4], operands[5]))
15897 ;; Most CPUs don't like single string operations
15898 ;; Handle this case here to simplify previous expander.
15900 (define_expand "strset"
15901 [(set (match_operand 1 "memory_operand" "")
15902 (match_operand 2 "register_operand" ""))
15903 (parallel [(set (match_operand 0 "register_operand" "")
15905 (clobber (reg:CC FLAGS_REG))])]
15908 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15909 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15911 /* If .md ever supports :P for Pmode, this can be directly
15912 in the pattern above. */
15913 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15914 GEN_INT (GET_MODE_SIZE (GET_MODE
15916 /* Can't use this if the user has appropriated eax or edi. */
15917 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15918 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15920 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15926 (define_expand "strset_singleop"
15927 [(parallel [(set (match_operand 1 "memory_operand" "")
15928 (match_operand 2 "register_operand" ""))
15929 (set (match_operand 0 "register_operand" "")
15930 (match_operand 3 "" ""))])]
15932 "ix86_current_function_needs_cld = 1;")
15934 (define_insn "*strsetdi_rex_1"
15935 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15936 (match_operand:DI 2 "register_operand" "a"))
15937 (set (match_operand:DI 0 "register_operand" "=D")
15938 (plus:DI (match_dup 1)
15941 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943 [(set_attr "type" "str")
15944 (set_attr "memory" "store")
15945 (set_attr "mode" "DI")])
15947 (define_insn "*strsetsi_1"
15948 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15949 (match_operand:SI 2 "register_operand" "a"))
15950 (set (match_operand:P 0 "register_operand" "=D")
15951 (plus:P (match_dup 1)
15953 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15955 [(set_attr "type" "str")
15956 (set_attr "memory" "store")
15957 (set_attr "mode" "SI")])
15959 (define_insn "*strsethi_1"
15960 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15961 (match_operand:HI 2 "register_operand" "a"))
15962 (set (match_operand:P 0 "register_operand" "=D")
15963 (plus:P (match_dup 1)
15965 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15967 [(set_attr "type" "str")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "HI")])
15971 (define_insn "*strsetqi_1"
15972 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15973 (match_operand:QI 2 "register_operand" "a"))
15974 (set (match_operand:P 0 "register_operand" "=D")
15975 (plus:P (match_dup 1)
15977 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15979 [(set_attr "type" "str")
15980 (set_attr "memory" "store")
15981 (set (attr "prefix_rex")
15983 (match_test "<P:MODE>mode == DImode")
15985 (const_string "*")))
15986 (set_attr "mode" "QI")])
15988 (define_expand "rep_stos"
15989 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15990 (set (match_operand 0 "register_operand" "")
15991 (match_operand 4 "" ""))
15992 (set (match_operand 2 "memory_operand" "") (const_int 0))
15993 (use (match_operand 3 "register_operand" ""))
15994 (use (match_dup 1))])]
15996 "ix86_current_function_needs_cld = 1;")
15998 (define_insn "*rep_stosdi_rex64"
15999 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16000 (set (match_operand:DI 0 "register_operand" "=D")
16001 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16003 (match_operand:DI 3 "register_operand" "0")))
16004 (set (mem:BLK (match_dup 3))
16006 (use (match_operand:DI 2 "register_operand" "a"))
16007 (use (match_dup 4))]
16009 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16011 [(set_attr "type" "str")
16012 (set_attr "prefix_rep" "1")
16013 (set_attr "memory" "store")
16014 (set_attr "mode" "DI")])
16016 (define_insn "*rep_stossi"
16017 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16018 (set (match_operand:P 0 "register_operand" "=D")
16019 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16021 (match_operand:P 3 "register_operand" "0")))
16022 (set (mem:BLK (match_dup 3))
16024 (use (match_operand:SI 2 "register_operand" "a"))
16025 (use (match_dup 4))]
16026 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16027 "rep{%;} stos{l|d}"
16028 [(set_attr "type" "str")
16029 (set_attr "prefix_rep" "1")
16030 (set_attr "memory" "store")
16031 (set_attr "mode" "SI")])
16033 (define_insn "*rep_stosqi"
16034 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16035 (set (match_operand:P 0 "register_operand" "=D")
16036 (plus:P (match_operand:P 3 "register_operand" "0")
16037 (match_operand:P 4 "register_operand" "1")))
16038 (set (mem:BLK (match_dup 3))
16040 (use (match_operand:QI 2 "register_operand" "a"))
16041 (use (match_dup 4))]
16042 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16044 [(set_attr "type" "str")
16045 (set_attr "prefix_rep" "1")
16046 (set_attr "memory" "store")
16047 (set (attr "prefix_rex")
16049 (match_test "<P:MODE>mode == DImode")
16051 (const_string "*")))
16052 (set_attr "mode" "QI")])
16054 (define_expand "cmpstrnsi"
16055 [(set (match_operand:SI 0 "register_operand" "")
16056 (compare:SI (match_operand:BLK 1 "general_operand" "")
16057 (match_operand:BLK 2 "general_operand" "")))
16058 (use (match_operand 3 "general_operand" ""))
16059 (use (match_operand 4 "immediate_operand" ""))]
16062 rtx addr1, addr2, out, outlow, count, countreg, align;
16064 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16067 /* Can't use this if the user has appropriated ecx, esi or edi. */
16068 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16073 out = gen_reg_rtx (SImode);
16075 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16076 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16077 if (addr1 != XEXP (operands[1], 0))
16078 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16079 if (addr2 != XEXP (operands[2], 0))
16080 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16082 count = operands[3];
16083 countreg = ix86_zero_extend_to_Pmode (count);
16085 /* %%% Iff we are testing strict equality, we can use known alignment
16086 to good advantage. This may be possible with combine, particularly
16087 once cc0 is dead. */
16088 align = operands[4];
16090 if (CONST_INT_P (count))
16092 if (INTVAL (count) == 0)
16094 emit_move_insn (operands[0], const0_rtx);
16097 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16098 operands[1], operands[2]));
16102 rtx (*gen_cmp) (rtx, rtx);
16104 gen_cmp = (TARGET_64BIT
16105 ? gen_cmpdi_1 : gen_cmpsi_1);
16107 emit_insn (gen_cmp (countreg, countreg));
16108 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16109 operands[1], operands[2]));
16112 outlow = gen_lowpart (QImode, out);
16113 emit_insn (gen_cmpintqi (outlow));
16114 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16116 if (operands[0] != out)
16117 emit_move_insn (operands[0], out);
16122 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16124 (define_expand "cmpintqi"
16125 [(set (match_dup 1)
16126 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16128 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16129 (parallel [(set (match_operand:QI 0 "register_operand" "")
16130 (minus:QI (match_dup 1)
16132 (clobber (reg:CC FLAGS_REG))])]
16135 operands[1] = gen_reg_rtx (QImode);
16136 operands[2] = gen_reg_rtx (QImode);
16139 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16140 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16142 (define_expand "cmpstrnqi_nz_1"
16143 [(parallel [(set (reg:CC FLAGS_REG)
16144 (compare:CC (match_operand 4 "memory_operand" "")
16145 (match_operand 5 "memory_operand" "")))
16146 (use (match_operand 2 "register_operand" ""))
16147 (use (match_operand:SI 3 "immediate_operand" ""))
16148 (clobber (match_operand 0 "register_operand" ""))
16149 (clobber (match_operand 1 "register_operand" ""))
16150 (clobber (match_dup 2))])]
16152 "ix86_current_function_needs_cld = 1;")
16154 (define_insn "*cmpstrnqi_nz_1"
16155 [(set (reg:CC FLAGS_REG)
16156 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16157 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16158 (use (match_operand:P 6 "register_operand" "2"))
16159 (use (match_operand:SI 3 "immediate_operand" "i"))
16160 (clobber (match_operand:P 0 "register_operand" "=S"))
16161 (clobber (match_operand:P 1 "register_operand" "=D"))
16162 (clobber (match_operand:P 2 "register_operand" "=c"))]
16163 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16165 [(set_attr "type" "str")
16166 (set_attr "mode" "QI")
16167 (set (attr "prefix_rex")
16169 (match_test "<P:MODE>mode == DImode")
16171 (const_string "*")))
16172 (set_attr "prefix_rep" "1")])
16174 ;; The same, but the count is not known to not be zero.
16176 (define_expand "cmpstrnqi_1"
16177 [(parallel [(set (reg:CC FLAGS_REG)
16178 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16180 (compare:CC (match_operand 4 "memory_operand" "")
16181 (match_operand 5 "memory_operand" ""))
16183 (use (match_operand:SI 3 "immediate_operand" ""))
16184 (use (reg:CC FLAGS_REG))
16185 (clobber (match_operand 0 "register_operand" ""))
16186 (clobber (match_operand 1 "register_operand" ""))
16187 (clobber (match_dup 2))])]
16189 "ix86_current_function_needs_cld = 1;")
16191 (define_insn "*cmpstrnqi_1"
16192 [(set (reg:CC FLAGS_REG)
16193 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16195 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16196 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16198 (use (match_operand:SI 3 "immediate_operand" "i"))
16199 (use (reg:CC FLAGS_REG))
16200 (clobber (match_operand:P 0 "register_operand" "=S"))
16201 (clobber (match_operand:P 1 "register_operand" "=D"))
16202 (clobber (match_operand:P 2 "register_operand" "=c"))]
16203 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16205 [(set_attr "type" "str")
16206 (set_attr "mode" "QI")
16207 (set (attr "prefix_rex")
16209 (match_test "<P:MODE>mode == DImode")
16211 (const_string "*")))
16212 (set_attr "prefix_rep" "1")])
16214 (define_expand "strlen<mode>"
16215 [(set (match_operand:P 0 "register_operand" "")
16216 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16217 (match_operand:QI 2 "immediate_operand" "")
16218 (match_operand 3 "immediate_operand" "")]
16222 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16228 (define_expand "strlenqi_1"
16229 [(parallel [(set (match_operand 0 "register_operand" "")
16230 (match_operand 2 "" ""))
16231 (clobber (match_operand 1 "register_operand" ""))
16232 (clobber (reg:CC FLAGS_REG))])]
16234 "ix86_current_function_needs_cld = 1;")
16236 (define_insn "*strlenqi_1"
16237 [(set (match_operand:P 0 "register_operand" "=&c")
16238 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16239 (match_operand:QI 2 "register_operand" "a")
16240 (match_operand:P 3 "immediate_operand" "i")
16241 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16242 (clobber (match_operand:P 1 "register_operand" "=D"))
16243 (clobber (reg:CC FLAGS_REG))]
16244 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16246 [(set_attr "type" "str")
16247 (set_attr "mode" "QI")
16248 (set (attr "prefix_rex")
16250 (match_test "<P:MODE>mode == DImode")
16252 (const_string "*")))
16253 (set_attr "prefix_rep" "1")])
16255 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16256 ;; handled in combine, but it is not currently up to the task.
16257 ;; When used for their truth value, the cmpstrn* expanders generate
16266 ;; The intermediate three instructions are unnecessary.
16268 ;; This one handles cmpstrn*_nz_1...
16271 (set (reg:CC FLAGS_REG)
16272 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16273 (mem:BLK (match_operand 5 "register_operand" ""))))
16274 (use (match_operand 6 "register_operand" ""))
16275 (use (match_operand:SI 3 "immediate_operand" ""))
16276 (clobber (match_operand 0 "register_operand" ""))
16277 (clobber (match_operand 1 "register_operand" ""))
16278 (clobber (match_operand 2 "register_operand" ""))])
16279 (set (match_operand:QI 7 "register_operand" "")
16280 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16281 (set (match_operand:QI 8 "register_operand" "")
16282 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (reg FLAGS_REG)
16284 (compare (match_dup 7) (match_dup 8)))
16286 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16288 (set (reg:CC FLAGS_REG)
16289 (compare:CC (mem:BLK (match_dup 4))
16290 (mem:BLK (match_dup 5))))
16291 (use (match_dup 6))
16292 (use (match_dup 3))
16293 (clobber (match_dup 0))
16294 (clobber (match_dup 1))
16295 (clobber (match_dup 2))])])
16297 ;; ...and this one handles cmpstrn*_1.
16300 (set (reg:CC FLAGS_REG)
16301 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16303 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16304 (mem:BLK (match_operand 5 "register_operand" "")))
16306 (use (match_operand:SI 3 "immediate_operand" ""))
16307 (use (reg:CC FLAGS_REG))
16308 (clobber (match_operand 0 "register_operand" ""))
16309 (clobber (match_operand 1 "register_operand" ""))
16310 (clobber (match_operand 2 "register_operand" ""))])
16311 (set (match_operand:QI 7 "register_operand" "")
16312 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16313 (set (match_operand:QI 8 "register_operand" "")
16314 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (reg FLAGS_REG)
16316 (compare (match_dup 7) (match_dup 8)))
16318 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16320 (set (reg:CC FLAGS_REG)
16321 (if_then_else:CC (ne (match_dup 6)
16323 (compare:CC (mem:BLK (match_dup 4))
16324 (mem:BLK (match_dup 5)))
16326 (use (match_dup 3))
16327 (use (reg:CC FLAGS_REG))
16328 (clobber (match_dup 0))
16329 (clobber (match_dup 1))
16330 (clobber (match_dup 2))])])
16332 ;; Conditional move instructions.
16334 (define_expand "mov<mode>cc"
16335 [(set (match_operand:SWIM 0 "register_operand" "")
16336 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16337 (match_operand:SWIM 2 "<general_operand>" "")
16338 (match_operand:SWIM 3 "<general_operand>" "")))]
16340 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16342 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16343 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16344 ;; So just document what we're doing explicitly.
16346 (define_expand "x86_mov<mode>cc_0_m1"
16348 [(set (match_operand:SWI48 0 "register_operand" "")
16349 (if_then_else:SWI48
16350 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16351 [(match_operand 1 "flags_reg_operand" "")
16355 (clobber (reg:CC FLAGS_REG))])])
16357 (define_insn "*x86_mov<mode>cc_0_m1"
16358 [(set (match_operand:SWI48 0 "register_operand" "=r")
16359 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16360 [(reg FLAGS_REG) (const_int 0)])
16363 (clobber (reg:CC FLAGS_REG))]
16365 "sbb{<imodesuffix>}\t%0, %0"
16366 ; Since we don't have the proper number of operands for an alu insn,
16367 ; fill in all the blanks.
16368 [(set_attr "type" "alu")
16369 (set_attr "use_carry" "1")
16370 (set_attr "pent_pair" "pu")
16371 (set_attr "memory" "none")
16372 (set_attr "imm_disp" "false")
16373 (set_attr "mode" "<MODE>")
16374 (set_attr "length_immediate" "0")])
16376 (define_insn "*x86_mov<mode>cc_0_m1_se"
16377 [(set (match_operand:SWI48 0 "register_operand" "=r")
16378 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16379 [(reg FLAGS_REG) (const_int 0)])
16382 (clobber (reg:CC FLAGS_REG))]
16384 "sbb{<imodesuffix>}\t%0, %0"
16385 [(set_attr "type" "alu")
16386 (set_attr "use_carry" "1")
16387 (set_attr "pent_pair" "pu")
16388 (set_attr "memory" "none")
16389 (set_attr "imm_disp" "false")
16390 (set_attr "mode" "<MODE>")
16391 (set_attr "length_immediate" "0")])
16393 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16394 [(set (match_operand:SWI48 0 "register_operand" "=r")
16395 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16396 [(reg FLAGS_REG) (const_int 0)])))]
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16407 (define_insn "*mov<mode>cc_noc"
16408 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16409 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16410 [(reg FLAGS_REG) (const_int 0)])
16411 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16412 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16413 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16415 cmov%O2%C1\t{%2, %0|%0, %2}
16416 cmov%O2%c1\t{%3, %0|%0, %3}"
16417 [(set_attr "type" "icmov")
16418 (set_attr "mode" "<MODE>")])
16420 (define_insn_and_split "*movqicc_noc"
16421 [(set (match_operand:QI 0 "register_operand" "=r,r")
16422 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16423 [(match_operand 4 "flags_reg_operand" "")
16425 (match_operand:QI 2 "register_operand" "r,0")
16426 (match_operand:QI 3 "register_operand" "0,r")))]
16427 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16429 "&& reload_completed"
16430 [(set (match_dup 0)
16431 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16434 "operands[0] = gen_lowpart (SImode, operands[0]);
16435 operands[2] = gen_lowpart (SImode, operands[2]);
16436 operands[3] = gen_lowpart (SImode, operands[3]);"
16437 [(set_attr "type" "icmov")
16438 (set_attr "mode" "SI")])
16440 (define_expand "mov<mode>cc"
16441 [(set (match_operand:X87MODEF 0 "register_operand" "")
16442 (if_then_else:X87MODEF
16443 (match_operand 1 "ix86_fp_comparison_operator" "")
16444 (match_operand:X87MODEF 2 "register_operand" "")
16445 (match_operand:X87MODEF 3 "register_operand" "")))]
16446 "(TARGET_80387 && TARGET_CMOVE)
16447 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16448 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16450 (define_insn "*movxfcc_1"
16451 [(set (match_operand:XF 0 "register_operand" "=f,f")
16452 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16453 [(reg FLAGS_REG) (const_int 0)])
16454 (match_operand:XF 2 "register_operand" "f,0")
16455 (match_operand:XF 3 "register_operand" "0,f")))]
16456 "TARGET_80387 && TARGET_CMOVE"
16458 fcmov%F1\t{%2, %0|%0, %2}
16459 fcmov%f1\t{%3, %0|%0, %3}"
16460 [(set_attr "type" "fcmov")
16461 (set_attr "mode" "XF")])
16463 (define_insn "*movdfcc_1_rex64"
16464 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16465 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16466 [(reg FLAGS_REG) (const_int 0)])
16467 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16468 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16469 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16470 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16472 fcmov%F1\t{%2, %0|%0, %2}
16473 fcmov%f1\t{%3, %0|%0, %3}
16474 cmov%O2%C1\t{%2, %0|%0, %2}
16475 cmov%O2%c1\t{%3, %0|%0, %3}"
16476 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16477 (set_attr "mode" "DF,DF,DI,DI")])
16479 (define_insn "*movdfcc_1"
16480 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16481 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16484 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16485 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16486 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16488 fcmov%F1\t{%2, %0|%0, %2}
16489 fcmov%f1\t{%3, %0|%0, %3}
16492 [(set_attr "type" "fcmov,fcmov,multi,multi")
16493 (set_attr "mode" "DF,DF,DI,DI")])
16496 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16497 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16498 [(match_operand 4 "flags_reg_operand" "")
16500 (match_operand:DF 2 "nonimmediate_operand" "")
16501 (match_operand:DF 3 "nonimmediate_operand" "")))]
16502 "!TARGET_64BIT && reload_completed"
16503 [(set (match_dup 2)
16504 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16508 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16512 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16513 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16516 (define_insn "*movsfcc_1_387"
16517 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16518 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16519 [(reg FLAGS_REG) (const_int 0)])
16520 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16521 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16522 "TARGET_80387 && TARGET_CMOVE
16523 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16525 fcmov%F1\t{%2, %0|%0, %2}
16526 fcmov%f1\t{%3, %0|%0, %3}
16527 cmov%O2%C1\t{%2, %0|%0, %2}
16528 cmov%O2%c1\t{%3, %0|%0, %3}"
16529 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16530 (set_attr "mode" "SF,SF,SI,SI")])
16532 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16533 ;; the scalar versions to have only XMM registers as operands.
16535 ;; XOP conditional move
16536 (define_insn "*xop_pcmov_<mode>"
16537 [(set (match_operand:MODEF 0 "register_operand" "=x")
16538 (if_then_else:MODEF
16539 (match_operand:MODEF 1 "register_operand" "x")
16540 (match_operand:MODEF 2 "register_operand" "x")
16541 (match_operand:MODEF 3 "register_operand" "x")))]
16543 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16544 [(set_attr "type" "sse4arg")])
16546 ;; These versions of the min/max patterns are intentionally ignorant of
16547 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16548 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16549 ;; are undefined in this condition, we're certain this is correct.
16551 (define_insn "<code><mode>3"
16552 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16554 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16555 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16556 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16558 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16559 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16560 [(set_attr "isa" "noavx,avx")
16561 (set_attr "prefix" "orig,vex")
16562 (set_attr "type" "sseadd")
16563 (set_attr "mode" "<MODE>")])
16565 ;; These versions of the min/max patterns implement exactly the operations
16566 ;; min = (op1 < op2 ? op1 : op2)
16567 ;; max = (!(op1 < op2) ? op1 : op2)
16568 ;; Their operands are not commutative, and thus they may be used in the
16569 ;; presence of -0.0 and NaN.
16571 (define_insn "*ieee_smin<mode>3"
16572 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16574 [(match_operand:MODEF 1 "register_operand" "0,x")
16575 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16577 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16579 min<ssemodesuffix>\t{%2, %0|%0, %2}
16580 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16581 [(set_attr "isa" "noavx,avx")
16582 (set_attr "prefix" "orig,vex")
16583 (set_attr "type" "sseadd")
16584 (set_attr "mode" "<MODE>")])
16586 (define_insn "*ieee_smax<mode>3"
16587 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16589 [(match_operand:MODEF 1 "register_operand" "0,x")
16590 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16594 max<ssemodesuffix>\t{%2, %0|%0, %2}
16595 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16596 [(set_attr "isa" "noavx,avx")
16597 (set_attr "prefix" "orig,vex")
16598 (set_attr "type" "sseadd")
16599 (set_attr "mode" "<MODE>")])
16601 ;; Make two stack loads independent:
16603 ;; fld %st(0) -> fld bb
16604 ;; fmul bb fmul %st(1), %st
16606 ;; Actually we only match the last two instructions for simplicity.
16608 [(set (match_operand 0 "fp_register_operand" "")
16609 (match_operand 1 "fp_register_operand" ""))
16611 (match_operator 2 "binary_fp_operator"
16613 (match_operand 3 "memory_operand" "")]))]
16614 "REGNO (operands[0]) != REGNO (operands[1])"
16615 [(set (match_dup 0) (match_dup 3))
16616 (set (match_dup 0) (match_dup 4))]
16618 ;; The % modifier is not operational anymore in peephole2's, so we have to
16619 ;; swap the operands manually in the case of addition and multiplication.
16620 "if (COMMUTATIVE_ARITH_P (operands[2]))
16621 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16622 GET_MODE (operands[2]),
16623 operands[0], operands[1]);
16625 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16626 GET_MODE (operands[2]),
16627 operands[1], operands[0]);")
16629 ;; Conditional addition patterns
16630 (define_expand "add<mode>cc"
16631 [(match_operand:SWI 0 "register_operand" "")
16632 (match_operand 1 "ordered_comparison_operator" "")
16633 (match_operand:SWI 2 "register_operand" "")
16634 (match_operand:SWI 3 "const_int_operand" "")]
16636 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16638 ;; Misc patterns (?)
16640 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641 ;; Otherwise there will be nothing to keep
16643 ;; [(set (reg ebp) (reg esp))]
16644 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645 ;; (clobber (eflags)]
16646 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16648 ;; in proper program order.
16650 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651 [(set (match_operand:P 0 "register_operand" "=r,r")
16652 (plus:P (match_operand:P 1 "register_operand" "0,r")
16653 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654 (clobber (reg:CC FLAGS_REG))
16655 (clobber (mem:BLK (scratch)))]
16658 switch (get_attr_type (insn))
16661 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16671 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16675 [(set (attr "type")
16676 (cond [(and (eq_attr "alternative" "0")
16677 (not (match_test "TARGET_OPT_AGU")))
16678 (const_string "alu")
16679 (match_operand:<MODE> 2 "const0_operand" "")
16680 (const_string "imov")
16682 (const_string "lea")))
16683 (set (attr "length_immediate")
16684 (cond [(eq_attr "type" "imov")
16686 (and (eq_attr "type" "alu")
16687 (match_operand 2 "const128_operand" ""))
16690 (const_string "*")))
16691 (set_attr "mode" "<MODE>")])
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694 [(set (match_operand:P 0 "register_operand" "=r")
16695 (minus:P (match_operand:P 1 "register_operand" "0")
16696 (match_operand:P 2 "register_operand" "r")))
16697 (clobber (reg:CC FLAGS_REG))
16698 (clobber (mem:BLK (scratch)))]
16700 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701 [(set_attr "type" "alu")
16702 (set_attr "mode" "<MODE>")])
16704 (define_insn "allocate_stack_worker_probe_<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=a")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_STACK_PROBE))
16708 (clobber (reg:CC FLAGS_REG))]
16709 "ix86_target_stack_probe ()"
16710 "call\t___chkstk_ms"
16711 [(set_attr "type" "multi")
16712 (set_attr "length" "5")])
16714 (define_expand "allocate_stack"
16715 [(match_operand 0 "register_operand" "")
16716 (match_operand 1 "general_operand" "")]
16717 "ix86_target_stack_probe ()"
16721 #ifndef CHECK_STACK_LIMIT
16722 #define CHECK_STACK_LIMIT 0
16725 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16728 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729 stack_pointer_rtx, 0, OPTAB_DIRECT);
16730 if (x != stack_pointer_rtx)
16731 emit_move_insn (stack_pointer_rtx, x);
16735 x = copy_to_mode_reg (Pmode, operands[1]);
16737 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16739 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741 stack_pointer_rtx, 0, OPTAB_DIRECT);
16742 if (x != stack_pointer_rtx)
16743 emit_move_insn (stack_pointer_rtx, x);
16746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16750 ;; Use IOR for stack probes, this is shorter.
16751 (define_expand "probe_stack"
16752 [(match_operand 0 "memory_operand" "")]
16755 rtx (*gen_ior3) (rtx, rtx, rtx);
16757 gen_ior3 = (GET_MODE (operands[0]) == DImode
16758 ? gen_iordi3 : gen_iorsi3);
16760 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16764 (define_insn "adjust_stack_and_probe<mode>"
16765 [(set (match_operand:P 0 "register_operand" "=r")
16766 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767 UNSPECV_PROBE_STACK_RANGE))
16768 (set (reg:P SP_REG)
16769 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770 (clobber (reg:CC FLAGS_REG))
16771 (clobber (mem:BLK (scratch)))]
16773 "* return output_adjust_stack_and_probe (operands[0]);"
16774 [(set_attr "type" "multi")])
16776 (define_insn "probe_stack_range<mode>"
16777 [(set (match_operand:P 0 "register_operand" "=r")
16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779 (match_operand:P 2 "const_int_operand" "n")]
16780 UNSPECV_PROBE_STACK_RANGE))
16781 (clobber (reg:CC FLAGS_REG))]
16783 "* return output_probe_stack_range (operands[0], operands[2]);"
16784 [(set_attr "type" "multi")])
16786 (define_expand "builtin_setjmp_receiver"
16787 [(label_ref (match_operand 0 "" ""))]
16788 "!TARGET_64BIT && flag_pic"
16794 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795 rtx label_rtx = gen_label_rtx ();
16796 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797 xops[0] = xops[1] = picreg;
16798 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799 ix86_expand_binary_operator (MINUS, SImode, xops);
16803 emit_insn (gen_set_got (pic_offset_table_rtx));
16807 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16810 [(set (match_operand 0 "register_operand" "")
16811 (match_operator 3 "promotable_binary_operator"
16812 [(match_operand 1 "register_operand" "")
16813 (match_operand 2 "aligned_operand" "")]))
16814 (clobber (reg:CC FLAGS_REG))]
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && ((GET_MODE (operands[0]) == HImode
16817 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16818 /* ??? next two lines just !satisfies_constraint_K (...) */
16819 || !CONST_INT_P (operands[2])
16820 || satisfies_constraint_K (operands[2])))
16821 || (GET_MODE (operands[0]) == QImode
16822 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16823 [(parallel [(set (match_dup 0)
16824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16825 (clobber (reg:CC FLAGS_REG))])]
16826 "operands[0] = gen_lowpart (SImode, operands[0]);
16827 operands[1] = gen_lowpart (SImode, operands[1]);
16828 if (GET_CODE (operands[3]) != ASHIFT)
16829 operands[2] = gen_lowpart (SImode, operands[2]);
16830 PUT_MODE (operands[3], SImode);")
16832 ; Promote the QImode tests, as i386 has encoding of the AND
16833 ; instruction with 32-bit sign-extended immediate and thus the
16834 ; instruction size is unchanged, except in the %eax case for
16835 ; which it is increased by one byte, hence the ! optimize_size.
16837 [(set (match_operand 0 "flags_reg_operand" "")
16838 (match_operator 2 "compare_operator"
16839 [(and (match_operand 3 "aligned_operand" "")
16840 (match_operand 4 "const_int_operand" ""))
16842 (set (match_operand 1 "register_operand" "")
16843 (and (match_dup 3) (match_dup 4)))]
16844 "! TARGET_PARTIAL_REG_STALL && reload_completed
16845 && optimize_insn_for_speed_p ()
16846 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16847 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16848 /* Ensure that the operand will remain sign-extended immediate. */
16849 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16850 [(parallel [(set (match_dup 0)
16851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16854 (and:SI (match_dup 3) (match_dup 4)))])]
16857 = gen_int_mode (INTVAL (operands[4])
16858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16859 operands[1] = gen_lowpart (SImode, operands[1]);
16860 operands[3] = gen_lowpart (SImode, operands[3]);
16863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16864 ; the TEST instruction with 32-bit sign-extended immediate and thus
16865 ; the instruction size would at least double, which is not what we
16866 ; want even with ! optimize_size.
16868 [(set (match_operand 0 "flags_reg_operand" "")
16869 (match_operator 1 "compare_operator"
16870 [(and (match_operand:HI 2 "aligned_operand" "")
16871 (match_operand:HI 3 "const_int_operand" ""))
16873 "! TARGET_PARTIAL_REG_STALL && reload_completed
16874 && ! TARGET_FAST_PREFIX
16875 && optimize_insn_for_speed_p ()
16876 /* Ensure that the operand will remain sign-extended immediate. */
16877 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16878 [(set (match_dup 0)
16879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16883 = gen_int_mode (INTVAL (operands[3])
16884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16885 operands[2] = gen_lowpart (SImode, operands[2]);
16889 [(set (match_operand 0 "register_operand" "")
16890 (neg (match_operand 1 "register_operand" "")))
16891 (clobber (reg:CC FLAGS_REG))]
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && (GET_MODE (operands[0]) == HImode
16894 || (GET_MODE (operands[0]) == QImode
16895 && (TARGET_PROMOTE_QImode
16896 || optimize_insn_for_size_p ())))"
16897 [(parallel [(set (match_dup 0)
16898 (neg:SI (match_dup 1)))
16899 (clobber (reg:CC FLAGS_REG))])]
16900 "operands[0] = gen_lowpart (SImode, operands[0]);
16901 operands[1] = gen_lowpart (SImode, operands[1]);")
16904 [(set (match_operand 0 "register_operand" "")
16905 (not (match_operand 1 "register_operand" "")))]
16906 "! TARGET_PARTIAL_REG_STALL && reload_completed
16907 && (GET_MODE (operands[0]) == HImode
16908 || (GET_MODE (operands[0]) == QImode
16909 && (TARGET_PROMOTE_QImode
16910 || optimize_insn_for_size_p ())))"
16911 [(set (match_dup 0)
16912 (not:SI (match_dup 1)))]
16913 "operands[0] = gen_lowpart (SImode, operands[0]);
16914 operands[1] = gen_lowpart (SImode, operands[1]);")
16917 [(set (match_operand 0 "register_operand" "")
16918 (if_then_else (match_operator 1 "ordered_comparison_operator"
16919 [(reg FLAGS_REG) (const_int 0)])
16920 (match_operand 2 "register_operand" "")
16921 (match_operand 3 "register_operand" "")))]
16922 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16923 && (GET_MODE (operands[0]) == HImode
16924 || (GET_MODE (operands[0]) == QImode
16925 && (TARGET_PROMOTE_QImode
16926 || optimize_insn_for_size_p ())))"
16927 [(set (match_dup 0)
16928 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16929 "operands[0] = gen_lowpart (SImode, operands[0]);
16930 operands[2] = gen_lowpart (SImode, operands[2]);
16931 operands[3] = gen_lowpart (SImode, operands[3]);")
16933 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16934 ;; transform a complex memory operation into two memory to register operations.
16936 ;; Don't push memory operands
16938 [(set (match_operand:SWI 0 "push_operand" "")
16939 (match_operand:SWI 1 "memory_operand" ""))
16940 (match_scratch:SWI 2 "<r>")]
16941 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16942 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16943 [(set (match_dup 2) (match_dup 1))
16944 (set (match_dup 0) (match_dup 2))])
16946 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16949 [(set (match_operand:SF 0 "push_operand" "")
16950 (match_operand:SF 1 "memory_operand" ""))
16951 (match_scratch:SF 2 "r")]
16952 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16953 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16954 [(set (match_dup 2) (match_dup 1))
16955 (set (match_dup 0) (match_dup 2))])
16957 ;; Don't move an immediate directly to memory when the instruction
16960 [(match_scratch:SWI124 1 "<r>")
16961 (set (match_operand:SWI124 0 "memory_operand" "")
16963 "optimize_insn_for_speed_p ()
16964 && !TARGET_USE_MOV0
16965 && TARGET_SPLIT_LONG_MOVES
16966 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16967 && peep2_regno_dead_p (0, FLAGS_REG)"
16968 [(parallel [(set (match_dup 2) (const_int 0))
16969 (clobber (reg:CC FLAGS_REG))])
16970 (set (match_dup 0) (match_dup 1))]
16971 "operands[2] = gen_lowpart (SImode, operands[1]);")
16974 [(match_scratch:SWI124 2 "<r>")
16975 (set (match_operand:SWI124 0 "memory_operand" "")
16976 (match_operand:SWI124 1 "immediate_operand" ""))]
16977 "optimize_insn_for_speed_p ()
16978 && TARGET_SPLIT_LONG_MOVES
16979 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16980 [(set (match_dup 2) (match_dup 1))
16981 (set (match_dup 0) (match_dup 2))])
16983 ;; Don't compare memory with zero, load and use a test instead.
16985 [(set (match_operand 0 "flags_reg_operand" "")
16986 (match_operator 1 "compare_operator"
16987 [(match_operand:SI 2 "memory_operand" "")
16989 (match_scratch:SI 3 "r")]
16990 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16991 [(set (match_dup 3) (match_dup 2))
16992 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16994 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16995 ;; Don't split NOTs with a displacement operand, because resulting XOR
16996 ;; will not be pairable anyway.
16998 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16999 ;; represented using a modRM byte. The XOR replacement is long decoded,
17000 ;; so this split helps here as well.
17002 ;; Note: Can't do this as a regular split because we can't get proper
17003 ;; lifetime information then.
17006 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17007 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17008 "optimize_insn_for_speed_p ()
17009 && ((TARGET_NOT_UNPAIRABLE
17010 && (!MEM_P (operands[0])
17011 || !memory_displacement_operand (operands[0], <MODE>mode)))
17012 || (TARGET_NOT_VECTORMODE
17013 && long_memory_operand (operands[0], <MODE>mode)))
17014 && peep2_regno_dead_p (0, FLAGS_REG)"
17015 [(parallel [(set (match_dup 0)
17016 (xor:SWI124 (match_dup 1) (const_int -1)))
17017 (clobber (reg:CC FLAGS_REG))])])
17019 ;; Non pairable "test imm, reg" instructions can be translated to
17020 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17021 ;; byte opcode instead of two, have a short form for byte operands),
17022 ;; so do it for other CPUs as well. Given that the value was dead,
17023 ;; this should not create any new dependencies. Pass on the sub-word
17024 ;; versions if we're concerned about partial register stalls.
17027 [(set (match_operand 0 "flags_reg_operand" "")
17028 (match_operator 1 "compare_operator"
17029 [(and:SI (match_operand:SI 2 "register_operand" "")
17030 (match_operand:SI 3 "immediate_operand" ""))
17032 "ix86_match_ccmode (insn, CCNOmode)
17033 && (true_regnum (operands[2]) != AX_REG
17034 || satisfies_constraint_K (operands[3]))
17035 && peep2_reg_dead_p (1, operands[2])"
17037 [(set (match_dup 0)
17038 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17041 (and:SI (match_dup 2) (match_dup 3)))])])
17043 ;; We don't need to handle HImode case, because it will be promoted to SImode
17044 ;; on ! TARGET_PARTIAL_REG_STALL
17047 [(set (match_operand 0 "flags_reg_operand" "")
17048 (match_operator 1 "compare_operator"
17049 [(and:QI (match_operand:QI 2 "register_operand" "")
17050 (match_operand:QI 3 "immediate_operand" ""))
17052 "! TARGET_PARTIAL_REG_STALL
17053 && ix86_match_ccmode (insn, CCNOmode)
17054 && true_regnum (operands[2]) != AX_REG
17055 && peep2_reg_dead_p (1, operands[2])"
17057 [(set (match_dup 0)
17058 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17061 (and:QI (match_dup 2) (match_dup 3)))])])
17064 [(set (match_operand 0 "flags_reg_operand" "")
17065 (match_operator 1 "compare_operator"
17068 (match_operand 2 "ext_register_operand" "")
17071 (match_operand 3 "const_int_operand" ""))
17073 "! TARGET_PARTIAL_REG_STALL
17074 && ix86_match_ccmode (insn, CCNOmode)
17075 && true_regnum (operands[2]) != AX_REG
17076 && peep2_reg_dead_p (1, operands[2])"
17077 [(parallel [(set (match_dup 0)
17086 (set (zero_extract:SI (match_dup 2)
17094 (match_dup 3)))])])
17096 ;; Don't do logical operations with memory inputs.
17098 [(match_scratch:SI 2 "r")
17099 (parallel [(set (match_operand:SI 0 "register_operand" "")
17100 (match_operator:SI 3 "arith_or_logical_operator"
17102 (match_operand:SI 1 "memory_operand" "")]))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17105 [(set (match_dup 2) (match_dup 1))
17106 (parallel [(set (match_dup 0)
17107 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17108 (clobber (reg:CC FLAGS_REG))])])
17111 [(match_scratch:SI 2 "r")
17112 (parallel [(set (match_operand:SI 0 "register_operand" "")
17113 (match_operator:SI 3 "arith_or_logical_operator"
17114 [(match_operand:SI 1 "memory_operand" "")
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17118 [(set (match_dup 2) (match_dup 1))
17119 (parallel [(set (match_dup 0)
17120 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17121 (clobber (reg:CC FLAGS_REG))])])
17123 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17124 ;; refers to the destination of the load!
17127 [(set (match_operand:SI 0 "register_operand" "")
17128 (match_operand:SI 1 "register_operand" ""))
17129 (parallel [(set (match_dup 0)
17130 (match_operator:SI 3 "commutative_operator"
17132 (match_operand:SI 2 "memory_operand" "")]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "REGNO (operands[0]) != REGNO (operands[1])
17135 && GENERAL_REGNO_P (REGNO (operands[0]))
17136 && GENERAL_REGNO_P (REGNO (operands[1]))"
17137 [(set (match_dup 0) (match_dup 4))
17138 (parallel [(set (match_dup 0)
17139 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17140 (clobber (reg:CC FLAGS_REG))])]
17141 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17144 [(set (match_operand 0 "register_operand" "")
17145 (match_operand 1 "register_operand" ""))
17147 (match_operator 3 "commutative_operator"
17149 (match_operand 2 "memory_operand" "")]))]
17150 "REGNO (operands[0]) != REGNO (operands[1])
17151 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17152 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17153 [(set (match_dup 0) (match_dup 2))
17155 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17157 ; Don't do logical operations with memory outputs
17159 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17160 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17161 ; the same decoder scheduling characteristics as the original.
17164 [(match_scratch:SI 2 "r")
17165 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17166 (match_operator:SI 3 "arith_or_logical_operator"
17168 (match_operand:SI 1 "nonmemory_operand" "")]))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17171 /* Do not split stack checking probes. */
17172 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17173 [(set (match_dup 2) (match_dup 0))
17174 (parallel [(set (match_dup 2)
17175 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17176 (clobber (reg:CC FLAGS_REG))])
17177 (set (match_dup 0) (match_dup 2))])
17180 [(match_scratch:SI 2 "r")
17181 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17182 (match_operator:SI 3 "arith_or_logical_operator"
17183 [(match_operand:SI 1 "nonmemory_operand" "")
17185 (clobber (reg:CC FLAGS_REG))])]
17186 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17187 /* Do not split stack checking probes. */
17188 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17189 [(set (match_dup 2) (match_dup 0))
17190 (parallel [(set (match_dup 2)
17191 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17192 (clobber (reg:CC FLAGS_REG))])
17193 (set (match_dup 0) (match_dup 2))])
17195 ;; Attempt to use arith or logical operations with memory outputs with
17196 ;; setting of flags.
17198 [(set (match_operand:SWI 0 "register_operand" "")
17199 (match_operand:SWI 1 "memory_operand" ""))
17200 (parallel [(set (match_dup 0)
17201 (match_operator:SWI 3 "plusminuslogic_operator"
17203 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17204 (clobber (reg:CC FLAGS_REG))])
17205 (set (match_dup 1) (match_dup 0))
17206 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17207 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17208 && peep2_reg_dead_p (4, operands[0])
17209 && !reg_overlap_mentioned_p (operands[0], operands[1])
17210 && ix86_match_ccmode (peep2_next_insn (3),
17211 (GET_CODE (operands[3]) == PLUS
17212 || GET_CODE (operands[3]) == MINUS)
17213 ? CCGOCmode : CCNOmode)"
17214 [(parallel [(set (match_dup 4) (match_dup 5))
17215 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17216 (match_dup 2)]))])]
17217 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17218 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17219 copy_rtx (operands[1]),
17220 copy_rtx (operands[2]));
17221 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17222 operands[5], const0_rtx);")
17225 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17226 (match_operator:SWI 2 "plusminuslogic_operator"
17228 (match_operand:SWI 1 "memory_operand" "")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && GET_CODE (operands[2]) != MINUS
17234 && peep2_reg_dead_p (3, operands[0])
17235 && !reg_overlap_mentioned_p (operands[0], operands[1])
17236 && ix86_match_ccmode (peep2_next_insn (2),
17237 GET_CODE (operands[2]) == PLUS
17238 ? CCGOCmode : CCNOmode)"
17239 [(parallel [(set (match_dup 3) (match_dup 4))
17240 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17241 (match_dup 0)]))])]
17242 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17243 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17244 copy_rtx (operands[1]),
17245 copy_rtx (operands[0]));
17246 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17247 operands[4], const0_rtx);")
17250 [(set (match_operand:SWI12 0 "register_operand" "")
17251 (match_operand:SWI12 1 "memory_operand" ""))
17252 (parallel [(set (match_operand:SI 4 "register_operand" "")
17253 (match_operator:SI 3 "plusminuslogic_operator"
17255 (match_operand:SI 2 "nonmemory_operand" "")]))
17256 (clobber (reg:CC FLAGS_REG))])
17257 (set (match_dup 1) (match_dup 0))
17258 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17259 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17260 && REG_P (operands[0]) && REG_P (operands[4])
17261 && REGNO (operands[0]) == REGNO (operands[4])
17262 && peep2_reg_dead_p (4, operands[0])
17263 && !reg_overlap_mentioned_p (operands[0], operands[1])
17264 && ix86_match_ccmode (peep2_next_insn (3),
17265 (GET_CODE (operands[3]) == PLUS
17266 || GET_CODE (operands[3]) == MINUS)
17267 ? CCGOCmode : CCNOmode)"
17268 [(parallel [(set (match_dup 4) (match_dup 5))
17269 (set (match_dup 1) (match_dup 6))])]
17270 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17271 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17272 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]), operands[2]);
17274 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17275 operands[5], const0_rtx);
17276 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17277 copy_rtx (operands[1]),
17278 copy_rtx (operands[2]));")
17280 ;; Attempt to always use XOR for zeroing registers.
17282 [(set (match_operand 0 "register_operand" "")
17283 (match_operand 1 "const0_operand" ""))]
17284 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17285 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17286 && GENERAL_REG_P (operands[0])
17287 && peep2_regno_dead_p (0, FLAGS_REG)"
17288 [(parallel [(set (match_dup 0) (const_int 0))
17289 (clobber (reg:CC FLAGS_REG))])]
17290 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17293 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17295 "(GET_MODE (operands[0]) == QImode
17296 || GET_MODE (operands[0]) == HImode)
17297 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17298 && peep2_regno_dead_p (0, FLAGS_REG)"
17299 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17300 (clobber (reg:CC FLAGS_REG))])])
17302 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17304 [(set (match_operand:SWI248 0 "register_operand" "")
17306 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17307 && peep2_regno_dead_p (0, FLAGS_REG)"
17308 [(parallel [(set (match_dup 0) (const_int -1))
17309 (clobber (reg:CC FLAGS_REG))])]
17311 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17312 operands[0] = gen_lowpart (SImode, operands[0]);
17315 ;; Attempt to convert simple lea to add/shift.
17316 ;; These can be created by move expanders.
17319 [(set (match_operand:SWI48 0 "register_operand" "")
17320 (plus:SWI48 (match_dup 0)
17321 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17322 "peep2_regno_dead_p (0, FLAGS_REG)"
17323 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17324 (clobber (reg:CC FLAGS_REG))])])
17327 [(set (match_operand:SI 0 "register_operand" "")
17328 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17329 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17331 && peep2_regno_dead_p (0, FLAGS_REG)
17332 && REGNO (operands[0]) == REGNO (operands[1])"
17333 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = gen_lowpart (SImode, operands[2]);")
17338 [(set (match_operand:SWI48 0 "register_operand" "")
17339 (mult:SWI48 (match_dup 0)
17340 (match_operand:SWI48 1 "const_int_operand" "")))]
17341 "exact_log2 (INTVAL (operands[1])) >= 0
17342 && peep2_regno_dead_p (0, FLAGS_REG)"
17343 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17344 (clobber (reg:CC FLAGS_REG))])]
17345 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17348 [(set (match_operand:SI 0 "register_operand" "")
17349 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17350 (match_operand:DI 2 "const_int_operand" "")) 0))]
17352 && exact_log2 (INTVAL (operands[2])) >= 0
17353 && REGNO (operands[0]) == REGNO (operands[1])
17354 && peep2_regno_dead_p (0, FLAGS_REG)"
17355 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17359 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17360 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17361 ;; On many CPUs it is also faster, since special hardware to avoid esp
17362 ;; dependencies is present.
17364 ;; While some of these conversions may be done using splitters, we use
17365 ;; peepholes in order to allow combine_stack_adjustments pass to see
17366 ;; nonobfuscated RTL.
17368 ;; Convert prologue esp subtractions to push.
17369 ;; We need register to push. In order to keep verify_flow_info happy we have
17371 ;; - use scratch and clobber it in order to avoid dependencies
17372 ;; - use already live register
17373 ;; We can't use the second way right now, since there is no reliable way how to
17374 ;; verify that given register is live. First choice will also most likely in
17375 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17376 ;; call clobbered registers are dead. We may want to use base pointer as an
17377 ;; alternative when no register is available later.
17380 [(match_scratch:P 1 "r")
17381 (parallel [(set (reg:P SP_REG)
17382 (plus:P (reg:P SP_REG)
17383 (match_operand:P 0 "const_int_operand" "")))
17384 (clobber (reg:CC FLAGS_REG))
17385 (clobber (mem:BLK (scratch)))])]
17386 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17387 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17388 [(clobber (match_dup 1))
17389 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17390 (clobber (mem:BLK (scratch)))])])
17393 [(match_scratch:P 1 "r")
17394 (parallel [(set (reg:P SP_REG)
17395 (plus:P (reg:P SP_REG)
17396 (match_operand:P 0 "const_int_operand" "")))
17397 (clobber (reg:CC FLAGS_REG))
17398 (clobber (mem:BLK (scratch)))])]
17399 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17400 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17401 [(clobber (match_dup 1))
17402 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17403 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (clobber (mem:BLK (scratch)))])])
17406 ;; Convert esp subtractions to push.
17408 [(match_scratch:P 1 "r")
17409 (parallel [(set (reg:P SP_REG)
17410 (plus:P (reg:P SP_REG)
17411 (match_operand:P 0 "const_int_operand" "")))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17414 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17415 [(clobber (match_dup 1))
17416 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17419 [(match_scratch:P 1 "r")
17420 (parallel [(set (reg:P SP_REG)
17421 (plus:P (reg:P SP_REG)
17422 (match_operand:P 0 "const_int_operand" "")))
17423 (clobber (reg:CC FLAGS_REG))])]
17424 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17425 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17426 [(clobber (match_dup 1))
17427 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17428 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17430 ;; Convert epilogue deallocator to pop.
17432 [(match_scratch:P 1 "r")
17433 (parallel [(set (reg:P SP_REG)
17434 (plus:P (reg:P SP_REG)
17435 (match_operand:P 0 "const_int_operand" "")))
17436 (clobber (reg:CC FLAGS_REG))
17437 (clobber (mem:BLK (scratch)))])]
17438 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17439 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17440 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17441 (clobber (mem:BLK (scratch)))])])
17443 ;; Two pops case is tricky, since pop causes dependency
17444 ;; on destination register. We use two registers if available.
17446 [(match_scratch:P 1 "r")
17447 (match_scratch:P 2 "r")
17448 (parallel [(set (reg:P SP_REG)
17449 (plus:P (reg:P SP_REG)
17450 (match_operand:P 0 "const_int_operand" "")))
17451 (clobber (reg:CC FLAGS_REG))
17452 (clobber (mem:BLK (scratch)))])]
17453 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17454 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17455 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17456 (clobber (mem:BLK (scratch)))])
17457 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17460 [(match_scratch:P 1 "r")
17461 (parallel [(set (reg:P SP_REG)
17462 (plus:P (reg:P SP_REG)
17463 (match_operand:P 0 "const_int_operand" "")))
17464 (clobber (reg:CC FLAGS_REG))
17465 (clobber (mem:BLK (scratch)))])]
17466 "optimize_insn_for_size_p ()
17467 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17468 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17469 (clobber (mem:BLK (scratch)))])
17470 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17472 ;; Convert esp additions to pop.
17474 [(match_scratch:P 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand" "")))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17480 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17482 ;; Two pops case is tricky, since pop causes dependency
17483 ;; on destination register. We use two registers if available.
17485 [(match_scratch:P 1 "r")
17486 (match_scratch:P 2 "r")
17487 (parallel [(set (reg:P SP_REG)
17488 (plus:P (reg:P SP_REG)
17489 (match_operand:P 0 "const_int_operand" "")))
17490 (clobber (reg:CC FLAGS_REG))])]
17491 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17492 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17493 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17496 [(match_scratch:P 1 "r")
17497 (parallel [(set (reg:P SP_REG)
17498 (plus:P (reg:P SP_REG)
17499 (match_operand:P 0 "const_int_operand" "")))
17500 (clobber (reg:CC FLAGS_REG))])]
17501 "optimize_insn_for_size_p ()
17502 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17503 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17504 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17506 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17507 ;; required and register dies. Similarly for 128 to -128.
17509 [(set (match_operand 0 "flags_reg_operand" "")
17510 (match_operator 1 "compare_operator"
17511 [(match_operand 2 "register_operand" "")
17512 (match_operand 3 "const_int_operand" "")]))]
17513 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17514 && incdec_operand (operands[3], GET_MODE (operands[3])))
17515 || (!TARGET_FUSE_CMP_AND_BRANCH
17516 && INTVAL (operands[3]) == 128))
17517 && ix86_match_ccmode (insn, CCGCmode)
17518 && peep2_reg_dead_p (1, operands[2])"
17519 [(parallel [(set (match_dup 0)
17520 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17521 (clobber (match_dup 2))])])
17523 ;; Convert imul by three, five and nine into lea
17526 [(set (match_operand:SWI48 0 "register_operand" "")
17527 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17528 (match_operand:SWI48 2 "const359_operand" "")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "!TARGET_PARTIAL_REG_STALL
17531 || <MODE>mode == SImode
17532 || optimize_function_for_size_p (cfun)"
17533 [(set (match_dup 0)
17534 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17536 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17540 [(set (match_operand:SWI48 0 "register_operand" "")
17541 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17542 (match_operand:SWI48 2 "const359_operand" "")))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "optimize_insn_for_speed_p ()
17545 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17546 [(set (match_dup 0) (match_dup 1))
17548 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17550 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17552 ;; imul $32bit_imm, mem, reg is vector decoded, while
17553 ;; imul $32bit_imm, reg, reg is direct decoded.
17555 [(match_scratch:SWI48 3 "r")
17556 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17557 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17558 (match_operand:SWI48 2 "immediate_operand" "")))
17559 (clobber (reg:CC FLAGS_REG))])]
17560 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17561 && !satisfies_constraint_K (operands[2])"
17562 [(set (match_dup 3) (match_dup 1))
17563 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17564 (clobber (reg:CC FLAGS_REG))])])
17567 [(match_scratch:SI 3 "r")
17568 (parallel [(set (match_operand:DI 0 "register_operand" "")
17570 (mult:SI (match_operand:SI 1 "memory_operand" "")
17571 (match_operand:SI 2 "immediate_operand" ""))))
17572 (clobber (reg:CC FLAGS_REG))])]
17574 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17575 && !satisfies_constraint_K (operands[2])"
17576 [(set (match_dup 3) (match_dup 1))
17577 (parallel [(set (match_dup 0)
17578 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17579 (clobber (reg:CC FLAGS_REG))])])
17581 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17582 ;; Convert it into imul reg, reg
17583 ;; It would be better to force assembler to encode instruction using long
17584 ;; immediate, but there is apparently no way to do so.
17586 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17588 (match_operand:SWI248 1 "nonimmediate_operand" "")
17589 (match_operand:SWI248 2 "const_int_operand" "")))
17590 (clobber (reg:CC FLAGS_REG))])
17591 (match_scratch:SWI248 3 "r")]
17592 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17593 && satisfies_constraint_K (operands[2])"
17594 [(set (match_dup 3) (match_dup 2))
17595 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17596 (clobber (reg:CC FLAGS_REG))])]
17598 if (!rtx_equal_p (operands[0], operands[1]))
17599 emit_move_insn (operands[0], operands[1]);
17602 ;; After splitting up read-modify operations, array accesses with memory
17603 ;; operands might end up in form:
17605 ;; movl 4(%esp), %edx
17607 ;; instead of pre-splitting:
17609 ;; addl 4(%esp), %eax
17611 ;; movl 4(%esp), %edx
17612 ;; leal (%edx,%eax,4), %eax
17615 [(match_scratch:P 5 "r")
17616 (parallel [(set (match_operand 0 "register_operand" "")
17617 (ashift (match_operand 1 "register_operand" "")
17618 (match_operand 2 "const_int_operand" "")))
17619 (clobber (reg:CC FLAGS_REG))])
17620 (parallel [(set (match_operand 3 "register_operand" "")
17621 (plus (match_dup 0)
17622 (match_operand 4 "x86_64_general_operand" "")))
17623 (clobber (reg:CC FLAGS_REG))])]
17624 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17625 /* Validate MODE for lea. */
17626 && ((!TARGET_PARTIAL_REG_STALL
17627 && (GET_MODE (operands[0]) == QImode
17628 || GET_MODE (operands[0]) == HImode))
17629 || GET_MODE (operands[0]) == SImode
17630 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17631 && (rtx_equal_p (operands[0], operands[3])
17632 || peep2_reg_dead_p (2, operands[0]))
17633 /* We reorder load and the shift. */
17634 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17635 [(set (match_dup 5) (match_dup 4))
17636 (set (match_dup 0) (match_dup 1))]
17638 enum machine_mode op1mode = GET_MODE (operands[1]);
17639 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17640 int scale = 1 << INTVAL (operands[2]);
17641 rtx index = gen_lowpart (Pmode, operands[1]);
17642 rtx base = gen_lowpart (Pmode, operands[5]);
17643 rtx dest = gen_lowpart (mode, operands[3]);
17645 operands[1] = gen_rtx_PLUS (Pmode, base,
17646 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17647 operands[5] = base;
17649 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17650 if (op1mode != Pmode)
17651 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17652 operands[0] = dest;
17655 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17656 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17657 ;; caught for use by garbage collectors and the like. Using an insn that
17658 ;; maps to SIGILL makes it more likely the program will rightfully die.
17659 ;; Keeping with tradition, "6" is in honor of #UD.
17660 (define_insn "trap"
17661 [(trap_if (const_int 1) (const_int 6))]
17663 { return ASM_SHORT "0x0b0f"; }
17664 [(set_attr "length" "2")])
17666 (define_expand "prefetch"
17667 [(prefetch (match_operand 0 "address_operand" "")
17668 (match_operand:SI 1 "const_int_operand" "")
17669 (match_operand:SI 2 "const_int_operand" ""))]
17670 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17672 int rw = INTVAL (operands[1]);
17673 int locality = INTVAL (operands[2]);
17675 gcc_assert (rw == 0 || rw == 1);
17676 gcc_assert (locality >= 0 && locality <= 3);
17677 gcc_assert (GET_MODE (operands[0]) == Pmode
17678 || GET_MODE (operands[0]) == VOIDmode);
17680 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17681 supported by SSE counterpart or the SSE prefetch is not available
17682 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17684 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17685 operands[2] = GEN_INT (3);
17687 operands[1] = const0_rtx;
17690 (define_insn "*prefetch_sse_<mode>"
17691 [(prefetch (match_operand:P 0 "address_operand" "p")
17693 (match_operand:SI 1 "const_int_operand" ""))]
17694 "TARGET_PREFETCH_SSE"
17696 static const char * const patterns[4] = {
17697 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17700 int locality = INTVAL (operands[1]);
17701 gcc_assert (locality >= 0 && locality <= 3);
17703 return patterns[locality];
17705 [(set_attr "type" "sse")
17706 (set_attr "atom_sse_attr" "prefetch")
17707 (set (attr "length_address")
17708 (symbol_ref "memory_address_length (operands[0])"))
17709 (set_attr "memory" "none")])
17711 (define_insn "*prefetch_3dnow_<mode>"
17712 [(prefetch (match_operand:P 0 "address_operand" "p")
17713 (match_operand:SI 1 "const_int_operand" "n")
17717 if (INTVAL (operands[1]) == 0)
17718 return "prefetch\t%a0";
17720 return "prefetchw\t%a0";
17722 [(set_attr "type" "mmx")
17723 (set (attr "length_address")
17724 (symbol_ref "memory_address_length (operands[0])"))
17725 (set_attr "memory" "none")])
17727 (define_expand "stack_protect_set"
17728 [(match_operand 0 "memory_operand" "")
17729 (match_operand 1 "memory_operand" "")]
17732 rtx (*insn)(rtx, rtx);
17734 #ifdef TARGET_THREAD_SSP_OFFSET
17735 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17736 insn = (TARGET_LP64
17737 ? gen_stack_tls_protect_set_di
17738 : gen_stack_tls_protect_set_si);
17740 insn = (TARGET_LP64
17741 ? gen_stack_protect_set_di
17742 : gen_stack_protect_set_si);
17745 emit_insn (insn (operands[0], operands[1]));
17749 (define_insn "stack_protect_set_<mode>"
17750 [(set (match_operand:PTR 0 "memory_operand" "=m")
17751 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17753 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17754 (clobber (reg:CC FLAGS_REG))]
17756 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17757 [(set_attr "type" "multi")])
17759 (define_insn "stack_tls_protect_set_<mode>"
17760 [(set (match_operand:PTR 0 "memory_operand" "=m")
17761 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17762 UNSPEC_SP_TLS_SET))
17763 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17764 (clobber (reg:CC FLAGS_REG))]
17766 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17767 [(set_attr "type" "multi")])
17769 (define_expand "stack_protect_test"
17770 [(match_operand 0 "memory_operand" "")
17771 (match_operand 1 "memory_operand" "")
17772 (match_operand 2 "" "")]
17775 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17777 rtx (*insn)(rtx, rtx, rtx);
17779 #ifdef TARGET_THREAD_SSP_OFFSET
17780 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17781 insn = (TARGET_LP64
17782 ? gen_stack_tls_protect_test_di
17783 : gen_stack_tls_protect_test_si);
17785 insn = (TARGET_LP64
17786 ? gen_stack_protect_test_di
17787 : gen_stack_protect_test_si);
17790 emit_insn (insn (flags, operands[0], operands[1]));
17792 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17793 flags, const0_rtx, operands[2]));
17797 (define_insn "stack_protect_test_<mode>"
17798 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17799 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17800 (match_operand:PTR 2 "memory_operand" "m")]
17802 (clobber (match_scratch:PTR 3 "=&r"))]
17804 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17805 [(set_attr "type" "multi")])
17807 (define_insn "stack_tls_protect_test_<mode>"
17808 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17809 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17810 (match_operand:PTR 2 "const_int_operand" "i")]
17811 UNSPEC_SP_TLS_TEST))
17812 (clobber (match_scratch:PTR 3 "=r"))]
17814 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17815 [(set_attr "type" "multi")])
17817 (define_insn "sse4_2_crc32<mode>"
17818 [(set (match_operand:SI 0 "register_operand" "=r")
17820 [(match_operand:SI 1 "register_operand" "0")
17821 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17823 "TARGET_SSE4_2 || TARGET_CRC32"
17824 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17825 [(set_attr "type" "sselog1")
17826 (set_attr "prefix_rep" "1")
17827 (set_attr "prefix_extra" "1")
17828 (set (attr "prefix_data16")
17829 (if_then_else (match_operand:HI 2 "" "")
17831 (const_string "*")))
17832 (set (attr "prefix_rex")
17833 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17835 (const_string "*")))
17836 (set_attr "mode" "SI")])
17838 (define_insn "sse4_2_crc32di"
17839 [(set (match_operand:DI 0 "register_operand" "=r")
17841 [(match_operand:DI 1 "register_operand" "0")
17842 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17844 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17845 "crc32{q}\t{%2, %0|%0, %2}"
17846 [(set_attr "type" "sselog1")
17847 (set_attr "prefix_rep" "1")
17848 (set_attr "prefix_extra" "1")
17849 (set_attr "mode" "DI")])
17851 (define_expand "rdpmc"
17852 [(match_operand:DI 0 "register_operand" "")
17853 (match_operand:SI 1 "register_operand" "")]
17856 rtx reg = gen_reg_rtx (DImode);
17859 /* Force operand 1 into ECX. */
17860 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17861 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17862 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17867 rtvec vec = rtvec_alloc (2);
17868 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17869 rtx upper = gen_reg_rtx (DImode);
17870 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17871 gen_rtvec (1, const0_rtx),
17873 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17874 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17876 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17877 NULL, 1, OPTAB_DIRECT);
17878 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17882 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17883 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17887 (define_insn "*rdpmc"
17888 [(set (match_operand:DI 0 "register_operand" "=A")
17889 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17893 [(set_attr "type" "other")
17894 (set_attr "length" "2")])
17896 (define_insn "*rdpmc_rex64"
17897 [(set (match_operand:DI 0 "register_operand" "=a")
17898 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17900 (set (match_operand:DI 1 "register_operand" "=d")
17901 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17904 [(set_attr "type" "other")
17905 (set_attr "length" "2")])
17907 (define_expand "rdtsc"
17908 [(set (match_operand:DI 0 "register_operand" "")
17909 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17914 rtvec vec = rtvec_alloc (2);
17915 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17916 rtx upper = gen_reg_rtx (DImode);
17917 rtx lower = gen_reg_rtx (DImode);
17918 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17919 gen_rtvec (1, const0_rtx),
17921 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17922 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17924 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17925 NULL, 1, OPTAB_DIRECT);
17926 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17928 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17933 (define_insn "*rdtsc"
17934 [(set (match_operand:DI 0 "register_operand" "=A")
17935 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17938 [(set_attr "type" "other")
17939 (set_attr "length" "2")])
17941 (define_insn "*rdtsc_rex64"
17942 [(set (match_operand:DI 0 "register_operand" "=a")
17943 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17944 (set (match_operand:DI 1 "register_operand" "=d")
17945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17948 [(set_attr "type" "other")
17949 (set_attr "length" "2")])
17951 (define_expand "rdtscp"
17952 [(match_operand:DI 0 "register_operand" "")
17953 (match_operand:SI 1 "memory_operand" "")]
17956 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17957 gen_rtvec (1, const0_rtx),
17959 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17960 gen_rtvec (1, const0_rtx),
17962 rtx reg = gen_reg_rtx (DImode);
17963 rtx tmp = gen_reg_rtx (SImode);
17967 rtvec vec = rtvec_alloc (3);
17968 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17969 rtx upper = gen_reg_rtx (DImode);
17970 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17971 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17972 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17974 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17975 NULL, 1, OPTAB_DIRECT);
17976 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17981 rtvec vec = rtvec_alloc (2);
17982 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17983 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17984 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17987 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17988 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17992 (define_insn "*rdtscp"
17993 [(set (match_operand:DI 0 "register_operand" "=A")
17994 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17995 (set (match_operand:SI 1 "register_operand" "=c")
17996 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17999 [(set_attr "type" "other")
18000 (set_attr "length" "3")])
18002 (define_insn "*rdtscp_rex64"
18003 [(set (match_operand:DI 0 "register_operand" "=a")
18004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18005 (set (match_operand:DI 1 "register_operand" "=d")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18007 (set (match_operand:SI 2 "register_operand" "=c")
18008 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18011 [(set_attr "type" "other")
18012 (set_attr "length" "3")])
18014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18016 ;; LWP instructions
18018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18020 (define_expand "lwp_llwpcb"
18021 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18022 UNSPECV_LLWP_INTRINSIC)]
18025 (define_insn "*lwp_llwpcb<mode>1"
18026 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18027 UNSPECV_LLWP_INTRINSIC)]
18030 [(set_attr "type" "lwp")
18031 (set_attr "mode" "<MODE>")
18032 (set_attr "length" "5")])
18034 (define_expand "lwp_slwpcb"
18035 [(set (match_operand 0 "register_operand" "=r")
18036 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18041 insn = (TARGET_64BIT
18043 : gen_lwp_slwpcbsi);
18045 emit_insn (insn (operands[0]));
18049 (define_insn "lwp_slwpcb<mode>"
18050 [(set (match_operand:P 0 "register_operand" "=r")
18051 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18054 [(set_attr "type" "lwp")
18055 (set_attr "mode" "<MODE>")
18056 (set_attr "length" "5")])
18058 (define_expand "lwp_lwpval<mode>3"
18059 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18060 (match_operand:SI 2 "nonimmediate_operand" "rm")
18061 (match_operand:SI 3 "const_int_operand" "i")]
18062 UNSPECV_LWPVAL_INTRINSIC)]
18064 "/* Avoid unused variable warning. */
18067 (define_insn "*lwp_lwpval<mode>3_1"
18068 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18069 (match_operand:SI 1 "nonimmediate_operand" "rm")
18070 (match_operand:SI 2 "const_int_operand" "i")]
18071 UNSPECV_LWPVAL_INTRINSIC)]
18073 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18074 [(set_attr "type" "lwp")
18075 (set_attr "mode" "<MODE>")
18076 (set (attr "length")
18077 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18079 (define_expand "lwp_lwpins<mode>3"
18080 [(set (reg:CCC FLAGS_REG)
18081 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18082 (match_operand:SI 2 "nonimmediate_operand" "rm")
18083 (match_operand:SI 3 "const_int_operand" "i")]
18084 UNSPECV_LWPINS_INTRINSIC))
18085 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18086 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18089 (define_insn "*lwp_lwpins<mode>3_1"
18090 [(set (reg:CCC FLAGS_REG)
18091 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18092 (match_operand:SI 1 "nonimmediate_operand" "rm")
18093 (match_operand:SI 2 "const_int_operand" "i")]
18094 UNSPECV_LWPINS_INTRINSIC))]
18096 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18097 [(set_attr "type" "lwp")
18098 (set_attr "mode" "<MODE>")
18099 (set (attr "length")
18100 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18102 (define_insn "rdfsbase<mode>"
18103 [(set (match_operand:SWI48 0 "register_operand" "=r")
18104 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18105 "TARGET_64BIT && TARGET_FSGSBASE"
18107 [(set_attr "type" "other")
18108 (set_attr "prefix_extra" "2")])
18110 (define_insn "rdgsbase<mode>"
18111 [(set (match_operand:SWI48 0 "register_operand" "=r")
18112 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18113 "TARGET_64BIT && TARGET_FSGSBASE"
18115 [(set_attr "type" "other")
18116 (set_attr "prefix_extra" "2")])
18118 (define_insn "wrfsbase<mode>"
18119 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18121 "TARGET_64BIT && TARGET_FSGSBASE"
18123 [(set_attr "type" "other")
18124 (set_attr "prefix_extra" "2")])
18126 (define_insn "wrgsbase<mode>"
18127 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18129 "TARGET_64BIT && TARGET_FSGSBASE"
18131 [(set_attr "type" "other")
18132 (set_attr "prefix_extra" "2")])
18134 (define_insn "rdrand<mode>_1"
18135 [(set (match_operand:SWI248 0 "register_operand" "=r")
18136 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18137 (set (reg:CCC FLAGS_REG)
18138 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18141 [(set_attr "type" "other")
18142 (set_attr "prefix_extra" "1")])
18144 (define_expand "pause"
18145 [(set (match_dup 0)
18146 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18149 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18150 MEM_VOLATILE_P (operands[0]) = 1;
18153 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18154 ;; They have the same encoding.
18155 (define_insn "*pause"
18156 [(set (match_operand:BLK 0 "" "")
18157 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18160 [(set_attr "length" "2")
18161 (set_attr "memory" "unknown")])
18165 (include "sync.md")