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
245 ;; For RDRAND support
253 (define_c_enum "unspecv" [
256 UNSPECV_PROBE_STACK_RANGE
276 UNSPECV_LLWP_INTRINSIC
277 UNSPECV_SLWP_INTRINSIC
278 UNSPECV_LWPVAL_INTRINSIC
279 UNSPECV_LWPINS_INTRINSIC
284 UNSPECV_SPLIT_STACK_RETURN
287 ;; Constants to represent rounding modes in the ROUND instruction
296 ;; Constants to represent pcomtrue/pcomfalse variants
306 ;; Constants used in the XOP pperm instruction
308 [(PPERM_SRC 0x00) /* copy source */
309 (PPERM_INVERT 0x20) /* invert source */
310 (PPERM_REVERSE 0x40) /* bit reverse source */
311 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
312 (PPERM_ZERO 0x80) /* all 0's */
313 (PPERM_ONES 0xa0) /* all 1's */
314 (PPERM_SIGN 0xc0) /* propagate sign bit */
315 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
316 (PPERM_SRC1 0x00) /* use first source byte */
317 (PPERM_SRC2 0x10) /* use second source byte */
320 ;; Registers by name.
373 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
376 ;; In C guard expressions, put expressions which may be compile-time
377 ;; constants first. This allows for better optimization. For
378 ;; example, write "TARGET_64BIT && reload_completed", not
379 ;; "reload_completed && TARGET_64BIT".
383 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
384 atom,generic64,amdfam10,bdver1,bdver2,btver1"
385 (const (symbol_ref "ix86_schedule")))
387 ;; A basic instruction type. Refinements due to arguments to be
388 ;; provided in other attributes.
391 alu,alu1,negnot,imov,imovx,lea,
392 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
393 icmp,test,ibr,setcc,icmov,
394 push,pop,call,callv,leave,
396 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
397 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
398 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
399 ssemuladd,sse4arg,lwp,
400 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
401 (const_string "other"))
403 ;; Main data type used by the insn
405 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
406 (const_string "unknown"))
408 ;; The CPU unit operations uses.
409 (define_attr "unit" "integer,i387,sse,mmx,unknown"
410 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
411 (const_string "i387")
412 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
413 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
414 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
416 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
418 (eq_attr "type" "other")
419 (const_string "unknown")]
420 (const_string "integer")))
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
427 (eq_attr "unit" "i387,sse,mmx")
429 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430 rotate,rotatex,rotate1,imul,icmp,push,pop")
431 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432 (eq_attr "type" "imov,test")
433 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434 (eq_attr "type" "call")
435 (if_then_else (match_operand 0 "constant_call_address_operand" "")
438 (eq_attr "type" "callv")
439 (if_then_else (match_operand 1 "constant_call_address_operand" "")
442 ;; We don't know the size before shorten_branches. Expect
443 ;; the instruction to fit for better scheduling.
444 (eq_attr "type" "ibr")
447 (symbol_ref "/* Update immediate_length and other attributes! */
448 gcc_unreachable (),1")))
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452 (cond [(eq_attr "type" "str,other,multi,fxch")
454 (and (eq_attr "type" "call")
455 (match_operand 0 "constant_call_address_operand" ""))
457 (and (eq_attr "type" "callv")
458 (match_operand 1 "constant_call_address_operand" ""))
461 (symbol_ref "ix86_attr_length_address_default (insn)")))
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
467 (eq_attr "mode" "HI")
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
478 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
486 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
487 (eq_attr "unit" "sse,mmx"))
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493 (cond [(not (match_test "TARGET_64BIT"))
495 (and (eq_attr "mode" "DI")
496 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497 (eq_attr "unit" "!mmx")))
499 (and (eq_attr "mode" "QI")
500 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
502 (match_test "x86_extended_reg_mentioned_p (insn)")
504 (and (eq_attr "type" "imovx")
505 (match_operand:QI 1 "ext_QIreg_operand" ""))
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg")
517 (eq_attr "type" "sseiadd1,ssecvt1")
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex"
524 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
526 (const_string "orig")))
528 ;; VEX W bit is used.
529 (define_attr "prefix_vex_w" "" (const_int 0))
531 ;; The length of VEX prefix
532 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
533 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
534 ;; still prefix_0f 1, with prefix_extra 1.
535 (define_attr "length_vex" ""
536 (if_then_else (and (eq_attr "prefix_0f" "1")
537 (eq_attr "prefix_extra" "0"))
538 (if_then_else (eq_attr "prefix_vex_w" "1")
539 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
540 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
541 (if_then_else (eq_attr "prefix_vex_w" "1")
542 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
543 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
545 ;; Set when modrm byte is used.
546 (define_attr "modrm" ""
547 (cond [(eq_attr "type" "str,leave")
549 (eq_attr "unit" "i387")
551 (and (eq_attr "type" "incdec")
552 (and (not (match_test "TARGET_64BIT"))
553 (ior (match_operand:SI 1 "register_operand" "")
554 (match_operand:HI 1 "register_operand" ""))))
556 (and (eq_attr "type" "push")
557 (not (match_operand 1 "memory_operand" "")))
559 (and (eq_attr "type" "pop")
560 (not (match_operand 0 "memory_operand" "")))
562 (and (eq_attr "type" "imov")
563 (and (not (eq_attr "mode" "DI"))
564 (ior (and (match_operand 0 "register_operand" "")
565 (match_operand 1 "immediate_operand" ""))
566 (ior (and (match_operand 0 "ax_reg_operand" "")
567 (match_operand 1 "memory_displacement_only_operand" ""))
568 (and (match_operand 0 "memory_displacement_only_operand" "")
569 (match_operand 1 "ax_reg_operand" ""))))))
571 (and (eq_attr "type" "call")
572 (match_operand 0 "constant_call_address_operand" ""))
574 (and (eq_attr "type" "callv")
575 (match_operand 1 "constant_call_address_operand" ""))
577 (and (eq_attr "type" "alu,alu1,icmp,test")
578 (match_operand 0 "ax_reg_operand" ""))
579 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
583 ;; The (bounding maximum) length of an instruction in bytes.
584 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
585 ;; Later we may want to split them and compute proper length as for
587 (define_attr "length" ""
588 (cond [(eq_attr "type" "other,multi,fistp,frndint")
590 (eq_attr "type" "fcmp")
592 (eq_attr "unit" "i387")
594 (plus (attr "prefix_data16")
595 (attr "length_address")))
596 (ior (eq_attr "prefix" "vex")
597 (and (eq_attr "prefix" "maybe_vex")
598 (match_test "TARGET_AVX")))
599 (plus (attr "length_vex")
600 (plus (attr "length_immediate")
602 (attr "length_address"))))]
603 (plus (plus (attr "modrm")
604 (plus (attr "prefix_0f")
605 (plus (attr "prefix_rex")
606 (plus (attr "prefix_extra")
608 (plus (attr "prefix_rep")
609 (plus (attr "prefix_data16")
610 (plus (attr "length_immediate")
611 (attr "length_address")))))))
613 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
614 ;; `store' if there is a simple memory reference therein, or `unknown'
615 ;; if the instruction is complex.
617 (define_attr "memory" "none,load,store,both,unknown"
618 (cond [(eq_attr "type" "other,multi,str,lwp")
619 (const_string "unknown")
620 (eq_attr "type" "lea,fcmov,fpspc")
621 (const_string "none")
622 (eq_attr "type" "fistp,leave")
623 (const_string "both")
624 (eq_attr "type" "frndint")
625 (const_string "load")
626 (eq_attr "type" "push")
627 (if_then_else (match_operand 1 "memory_operand" "")
628 (const_string "both")
629 (const_string "store"))
630 (eq_attr "type" "pop")
631 (if_then_else (match_operand 0 "memory_operand" "")
632 (const_string "both")
633 (const_string "load"))
634 (eq_attr "type" "setcc")
635 (if_then_else (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (const_string "none"))
638 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
639 (if_then_else (ior (match_operand 0 "memory_operand" "")
640 (match_operand 1 "memory_operand" ""))
641 (const_string "load")
642 (const_string "none"))
643 (eq_attr "type" "ibr")
644 (if_then_else (match_operand 0 "memory_operand" "")
645 (const_string "load")
646 (const_string "none"))
647 (eq_attr "type" "call")
648 (if_then_else (match_operand 0 "constant_call_address_operand" "")
649 (const_string "none")
650 (const_string "load"))
651 (eq_attr "type" "callv")
652 (if_then_else (match_operand 1 "constant_call_address_operand" "")
653 (const_string "none")
654 (const_string "load"))
655 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
656 (match_operand 1 "memory_operand" ""))
657 (const_string "both")
658 (and (match_operand 0 "memory_operand" "")
659 (match_operand 1 "memory_operand" ""))
660 (const_string "both")
661 (match_operand 0 "memory_operand" "")
662 (const_string "store")
663 (match_operand 1 "memory_operand" "")
664 (const_string "load")
666 "!alu1,negnot,ishift1,
667 imov,imovx,icmp,test,bitmanip,
669 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
670 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
671 (match_operand 2 "memory_operand" ""))
672 (const_string "load")
673 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
674 (match_operand 3 "memory_operand" ""))
675 (const_string "load")
677 (const_string "none")))
679 ;; Indicates if an instruction has both an immediate and a displacement.
681 (define_attr "imm_disp" "false,true,unknown"
682 (cond [(eq_attr "type" "other,multi")
683 (const_string "unknown")
684 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
685 (and (match_operand 0 "memory_displacement_operand" "")
686 (match_operand 1 "immediate_operand" "")))
687 (const_string "true")
688 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
689 (and (match_operand 0 "memory_displacement_operand" "")
690 (match_operand 2 "immediate_operand" "")))
691 (const_string "true")
693 (const_string "false")))
695 ;; Indicates if an FP operation has an integer source.
697 (define_attr "fp_int_src" "false,true"
698 (const_string "false"))
700 ;; Defines rounding mode of an FP operation.
702 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
703 (const_string "any"))
705 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
706 (define_attr "use_carry" "0,1" (const_string "0"))
708 ;; Define attribute to indicate unaligned ssemov insns
709 (define_attr "movu" "0,1" (const_string "0"))
711 ;; Used to control the "enabled" attribute on a per-instruction basis.
712 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
713 (const_string "base"))
715 (define_attr "enabled" ""
716 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
717 (eq_attr "isa" "sse2_noavx")
718 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
719 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
720 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
721 (eq_attr "isa" "sse4_noavx")
722 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
723 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
724 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
725 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
729 ;; Describe a user's asm statement.
730 (define_asm_attributes
731 [(set_attr "length" "128")
732 (set_attr "type" "multi")])
734 (define_code_iterator plusminus [plus minus])
736 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
738 ;; Base name for define_insn
739 (define_code_attr plusminus_insn
740 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
741 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr plusminus_mnemonic
745 [(plus "add") (ss_plus "adds") (us_plus "addus")
746 (minus "sub") (ss_minus "subs") (us_minus "subus")])
747 (define_code_attr plusminus_carry_mnemonic
748 [(plus "adc") (minus "sbb")])
750 ;; Mark commutative operators as such in constraints.
751 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
752 (minus "") (ss_minus "") (us_minus "")])
754 ;; Mapping of max and min
755 (define_code_iterator maxmin [smax smin umax umin])
757 ;; Mapping of signed max and min
758 (define_code_iterator smaxmin [smax smin])
760 ;; Mapping of unsigned max and min
761 (define_code_iterator umaxmin [umax umin])
763 ;; Base name for integer and FP insn mnemonic
764 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
765 (umax "maxu") (umin "minu")])
766 (define_code_attr maxmin_float [(smax "max") (smin "min")])
768 ;; Mapping of logic operators
769 (define_code_iterator any_logic [and ior xor])
770 (define_code_iterator any_or [ior xor])
772 ;; Base name for insn mnemonic.
773 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
775 ;; Mapping of shift-right operators
776 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
778 ;; Base name for define_insn
779 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
781 ;; Base name for insn mnemonic.
782 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
784 ;; Mapping of rotate operators
785 (define_code_iterator any_rotate [rotate rotatert])
787 ;; Base name for define_insn
788 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
790 ;; Base name for insn mnemonic.
791 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
793 ;; Mapping of abs neg operators
794 (define_code_iterator absneg [abs neg])
796 ;; Base name for x87 insn mnemonic.
797 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
799 ;; Used in signed and unsigned widening multiplications.
800 (define_code_iterator any_extend [sign_extend zero_extend])
802 ;; Prefix for insn menmonic.
803 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
805 ;; Prefix for define_insn
806 (define_code_attr u [(sign_extend "") (zero_extend "u")])
807 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
809 ;; All integer modes.
810 (define_mode_iterator SWI1248x [QI HI SI DI])
812 ;; All integer modes without QImode.
813 (define_mode_iterator SWI248x [HI SI DI])
815 ;; All integer modes without QImode and HImode.
816 (define_mode_iterator SWI48x [SI DI])
818 ;; All integer modes without SImode and DImode.
819 (define_mode_iterator SWI12 [QI HI])
821 ;; All integer modes without DImode.
822 (define_mode_iterator SWI124 [QI HI SI])
824 ;; All integer modes without QImode and DImode.
825 (define_mode_iterator SWI24 [HI SI])
827 ;; Single word integer modes.
828 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
830 ;; Single word integer modes without QImode.
831 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
833 ;; Single word integer modes without QImode and HImode.
834 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
836 ;; All math-dependant single and double word integer modes.
837 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
838 (HI "TARGET_HIMODE_MATH")
839 SI DI (TI "TARGET_64BIT")])
841 ;; Math-dependant single word integer modes.
842 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
843 (HI "TARGET_HIMODE_MATH")
844 SI (DI "TARGET_64BIT")])
846 ;; Math-dependant integer modes without DImode.
847 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
848 (HI "TARGET_HIMODE_MATH")
851 ;; Math-dependant single word integer modes without QImode.
852 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
853 SI (DI "TARGET_64BIT")])
855 ;; Double word integer modes.
856 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
857 (TI "TARGET_64BIT")])
859 ;; Double word integer modes as mode attribute.
860 (define_mode_attr DWI [(SI "DI") (DI "TI")])
861 (define_mode_attr dwi [(SI "di") (DI "ti")])
863 ;; Half mode for double word integer modes.
864 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
865 (DI "TARGET_64BIT")])
867 ;; Instruction suffix for integer modes.
868 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
870 ;; Pointer size prefix for integer modes (Intel asm dialect)
871 (define_mode_attr iptrsize [(QI "BYTE")
876 ;; Register class for integer modes.
877 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
879 ;; Immediate operand constraint for integer modes.
880 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
882 ;; General operand constraint for word modes.
883 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
885 ;; Immediate operand constraint for double integer modes.
886 (define_mode_attr di [(SI "nF") (DI "e")])
888 ;; Immediate operand constraint for shifts.
889 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
891 ;; General operand predicate for integer modes.
892 (define_mode_attr general_operand
893 [(QI "general_operand")
894 (HI "general_operand")
895 (SI "x86_64_general_operand")
896 (DI "x86_64_general_operand")
897 (TI "x86_64_general_operand")])
899 ;; General sign/zero extend operand predicate for integer modes.
900 (define_mode_attr general_szext_operand
901 [(QI "general_operand")
902 (HI "general_operand")
903 (SI "x86_64_szext_general_operand")
904 (DI "x86_64_szext_general_operand")])
906 ;; Immediate operand predicate for integer modes.
907 (define_mode_attr immediate_operand
908 [(QI "immediate_operand")
909 (HI "immediate_operand")
910 (SI "x86_64_immediate_operand")
911 (DI "x86_64_immediate_operand")])
913 ;; Nonmemory operand predicate for integer modes.
914 (define_mode_attr nonmemory_operand
915 [(QI "nonmemory_operand")
916 (HI "nonmemory_operand")
917 (SI "x86_64_nonmemory_operand")
918 (DI "x86_64_nonmemory_operand")])
920 ;; Operand predicate for shifts.
921 (define_mode_attr shift_operand
922 [(QI "nonimmediate_operand")
923 (HI "nonimmediate_operand")
924 (SI "nonimmediate_operand")
925 (DI "shiftdi_operand")
926 (TI "register_operand")])
928 ;; Operand predicate for shift argument.
929 (define_mode_attr shift_immediate_operand
930 [(QI "const_1_to_31_operand")
931 (HI "const_1_to_31_operand")
932 (SI "const_1_to_31_operand")
933 (DI "const_1_to_63_operand")])
935 ;; Input operand predicate for arithmetic left shifts.
936 (define_mode_attr ashl_input_operand
937 [(QI "nonimmediate_operand")
938 (HI "nonimmediate_operand")
939 (SI "nonimmediate_operand")
940 (DI "ashldi_input_operand")
941 (TI "reg_or_pm1_operand")])
943 ;; SSE and x87 SFmode and DFmode floating point modes
944 (define_mode_iterator MODEF [SF DF])
946 ;; All x87 floating point modes
947 (define_mode_iterator X87MODEF [SF DF XF])
949 ;; SSE instruction suffix for various modes
950 (define_mode_attr ssemodesuffix
952 (V8SF "ps") (V4DF "pd")
953 (V4SF "ps") (V2DF "pd")
954 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
955 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
957 ;; SSE vector suffix for floating point modes
958 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
960 ;; SSE vector mode corresponding to a scalar mode
961 (define_mode_attr ssevecmode
962 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
964 ;; Instruction suffix for REX 64bit operators.
965 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
967 ;; This mode iterator allows :P to be used for patterns that operate on
968 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
969 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
971 ;; This mode iterator allows :PTR to be used for patterns that operate on
972 ;; ptr_mode sized quantities.
973 (define_mode_iterator PTR
974 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
976 ;; Scheduling descriptions
978 (include "pentium.md")
981 (include "athlon.md")
982 (include "bdver1.md")
988 ;; Operand and operator predicates and constraints
990 (include "predicates.md")
991 (include "constraints.md")
994 ;; Compare and branch/compare and store instructions.
996 (define_expand "cbranch<mode>4"
997 [(set (reg:CC FLAGS_REG)
998 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
999 (match_operand:SDWIM 2 "<general_operand>" "")))
1000 (set (pc) (if_then_else
1001 (match_operator 0 "ordered_comparison_operator"
1002 [(reg:CC FLAGS_REG) (const_int 0)])
1003 (label_ref (match_operand 3 "" ""))
1007 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1008 operands[1] = force_reg (<MODE>mode, operands[1]);
1009 ix86_expand_branch (GET_CODE (operands[0]),
1010 operands[1], operands[2], operands[3]);
1014 (define_expand "cstore<mode>4"
1015 [(set (reg:CC FLAGS_REG)
1016 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1017 (match_operand:SWIM 3 "<general_operand>" "")))
1018 (set (match_operand:QI 0 "register_operand" "")
1019 (match_operator 1 "ordered_comparison_operator"
1020 [(reg:CC FLAGS_REG) (const_int 0)]))]
1023 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1024 operands[2] = force_reg (<MODE>mode, operands[2]);
1025 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1026 operands[2], operands[3]);
1030 (define_expand "cmp<mode>_1"
1031 [(set (reg:CC FLAGS_REG)
1032 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1033 (match_operand:SWI48 1 "<general_operand>" "")))])
1035 (define_insn "*cmp<mode>_ccno_1"
1036 [(set (reg FLAGS_REG)
1037 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1038 (match_operand:SWI 1 "const0_operand" "")))]
1039 "ix86_match_ccmode (insn, CCNOmode)"
1041 test{<imodesuffix>}\t%0, %0
1042 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "test,icmp")
1044 (set_attr "length_immediate" "0,1")
1045 (set_attr "mode" "<MODE>")])
1047 (define_insn "*cmp<mode>_1"
1048 [(set (reg FLAGS_REG)
1049 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1050 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1051 "ix86_match_ccmode (insn, CCmode)"
1052 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1053 [(set_attr "type" "icmp")
1054 (set_attr "mode" "<MODE>")])
1056 (define_insn "*cmp<mode>_minus_1"
1057 [(set (reg FLAGS_REG)
1059 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1060 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1062 "ix86_match_ccmode (insn, CCGOCmode)"
1063 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "<MODE>")])
1067 (define_insn "*cmpqi_ext_1"
1068 [(set (reg FLAGS_REG)
1070 (match_operand:QI 0 "general_operand" "Qm")
1073 (match_operand 1 "ext_register_operand" "Q")
1075 (const_int 8)) 0)))]
1076 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1077 "cmp{b}\t{%h1, %0|%0, %h1}"
1078 [(set_attr "type" "icmp")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_1_rex64"
1082 [(set (reg FLAGS_REG)
1084 (match_operand:QI 0 "register_operand" "Q")
1087 (match_operand 1 "ext_register_operand" "Q")
1089 (const_int 8)) 0)))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%h1, %0|%0, %h1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "mode" "QI")])
1095 (define_insn "*cmpqi_ext_2"
1096 [(set (reg FLAGS_REG)
1100 (match_operand 0 "ext_register_operand" "Q")
1103 (match_operand:QI 1 "const0_operand" "")))]
1104 "ix86_match_ccmode (insn, CCNOmode)"
1106 [(set_attr "type" "test")
1107 (set_attr "length_immediate" "0")
1108 (set_attr "mode" "QI")])
1110 (define_expand "cmpqi_ext_3"
1111 [(set (reg:CC FLAGS_REG)
1115 (match_operand 0 "ext_register_operand" "")
1118 (match_operand:QI 1 "immediate_operand" "")))])
1120 (define_insn "*cmpqi_ext_3_insn"
1121 [(set (reg FLAGS_REG)
1125 (match_operand 0 "ext_register_operand" "Q")
1128 (match_operand:QI 1 "general_operand" "Qmn")))]
1129 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1130 "cmp{b}\t{%1, %h0|%h0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "modrm" "1")
1133 (set_attr "mode" "QI")])
1135 (define_insn "*cmpqi_ext_3_insn_rex64"
1136 [(set (reg FLAGS_REG)
1140 (match_operand 0 "ext_register_operand" "Q")
1143 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1144 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1145 "cmp{b}\t{%1, %h0|%h0, %1}"
1146 [(set_attr "type" "icmp")
1147 (set_attr "modrm" "1")
1148 (set_attr "mode" "QI")])
1150 (define_insn "*cmpqi_ext_4"
1151 [(set (reg FLAGS_REG)
1155 (match_operand 0 "ext_register_operand" "Q")
1160 (match_operand 1 "ext_register_operand" "Q")
1162 (const_int 8)) 0)))]
1163 "ix86_match_ccmode (insn, CCmode)"
1164 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1165 [(set_attr "type" "icmp")
1166 (set_attr "mode" "QI")])
1168 ;; These implement float point compares.
1169 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1170 ;; which would allow mix and match FP modes on the compares. Which is what
1171 ;; the old patterns did, but with many more of them.
1173 (define_expand "cbranchxf4"
1174 [(set (reg:CC FLAGS_REG)
1175 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1176 (match_operand:XF 2 "nonmemory_operand" "")))
1177 (set (pc) (if_then_else
1178 (match_operator 0 "ix86_fp_comparison_operator"
1181 (label_ref (match_operand 3 "" ""))
1185 ix86_expand_branch (GET_CODE (operands[0]),
1186 operands[1], operands[2], operands[3]);
1190 (define_expand "cstorexf4"
1191 [(set (reg:CC FLAGS_REG)
1192 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1193 (match_operand:XF 3 "nonmemory_operand" "")))
1194 (set (match_operand:QI 0 "register_operand" "")
1195 (match_operator 1 "ix86_fp_comparison_operator"
1200 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1201 operands[2], operands[3]);
1205 (define_expand "cbranch<mode>4"
1206 [(set (reg:CC FLAGS_REG)
1207 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1208 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1209 (set (pc) (if_then_else
1210 (match_operator 0 "ix86_fp_comparison_operator"
1213 (label_ref (match_operand 3 "" ""))
1215 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1217 ix86_expand_branch (GET_CODE (operands[0]),
1218 operands[1], operands[2], operands[3]);
1222 (define_expand "cstore<mode>4"
1223 [(set (reg:CC FLAGS_REG)
1224 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1225 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1226 (set (match_operand:QI 0 "register_operand" "")
1227 (match_operator 1 "ix86_fp_comparison_operator"
1230 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1232 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1233 operands[2], operands[3]);
1237 (define_expand "cbranchcc4"
1238 [(set (pc) (if_then_else
1239 (match_operator 0 "comparison_operator"
1240 [(match_operand 1 "flags_reg_operand" "")
1241 (match_operand 2 "const0_operand" "")])
1242 (label_ref (match_operand 3 "" ""))
1246 ix86_expand_branch (GET_CODE (operands[0]),
1247 operands[1], operands[2], operands[3]);
1251 (define_expand "cstorecc4"
1252 [(set (match_operand:QI 0 "register_operand" "")
1253 (match_operator 1 "comparison_operator"
1254 [(match_operand 2 "flags_reg_operand" "")
1255 (match_operand 3 "const0_operand" "")]))]
1258 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1259 operands[2], operands[3]);
1264 ;; FP compares, step 1:
1265 ;; Set the FP condition codes.
1267 ;; CCFPmode compare with exceptions
1268 ;; CCFPUmode compare with no exceptions
1270 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1271 ;; used to manage the reg stack popping would not be preserved.
1273 (define_insn "*cmpfp_0"
1274 [(set (match_operand:HI 0 "register_operand" "=a")
1277 (match_operand 1 "register_operand" "f")
1278 (match_operand 2 "const0_operand" ""))]
1280 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1281 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282 "* return output_fp_compare (insn, operands, false, false);"
1283 [(set_attr "type" "multi")
1284 (set_attr "unit" "i387")
1286 (cond [(match_operand:SF 1 "" "")
1288 (match_operand:DF 1 "" "")
1291 (const_string "XF")))])
1293 (define_insn_and_split "*cmpfp_0_cc"
1294 [(set (reg:CCFP FLAGS_REG)
1296 (match_operand 1 "register_operand" "f")
1297 (match_operand 2 "const0_operand" "")))
1298 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1300 && TARGET_SAHF && !TARGET_CMOVE
1301 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1303 "&& reload_completed"
1306 [(compare:CCFP (match_dup 1)(match_dup 2))]
1308 (set (reg:CC FLAGS_REG)
1309 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311 [(set_attr "type" "multi")
1312 (set_attr "unit" "i387")
1314 (cond [(match_operand:SF 1 "" "")
1316 (match_operand:DF 1 "" "")
1319 (const_string "XF")))])
1321 (define_insn "*cmpfp_xf"
1322 [(set (match_operand:HI 0 "register_operand" "=a")
1325 (match_operand:XF 1 "register_operand" "f")
1326 (match_operand:XF 2 "register_operand" "f"))]
1329 "* return output_fp_compare (insn, operands, false, false);"
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1334 (define_insn_and_split "*cmpfp_xf_cc"
1335 [(set (reg:CCFP FLAGS_REG)
1337 (match_operand:XF 1 "register_operand" "f")
1338 (match_operand:XF 2 "register_operand" "f")))
1339 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341 && TARGET_SAHF && !TARGET_CMOVE"
1343 "&& reload_completed"
1346 [(compare:CCFP (match_dup 1)(match_dup 2))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set_attr "mode" "XF")])
1355 (define_insn "*cmpfp_<mode>"
1356 [(set (match_operand:HI 0 "register_operand" "=a")
1359 (match_operand:MODEF 1 "register_operand" "f")
1360 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1363 "* return output_fp_compare (insn, operands, false, false);"
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn_and_split "*cmpfp_<mode>_cc"
1369 [(set (reg:CCFP FLAGS_REG)
1371 (match_operand:MODEF 1 "register_operand" "f")
1372 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1373 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1375 && TARGET_SAHF && !TARGET_CMOVE"
1377 "&& reload_completed"
1380 [(compare:CCFP (match_dup 1)(match_dup 2))]
1382 (set (reg:CC FLAGS_REG)
1383 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1385 [(set_attr "type" "multi")
1386 (set_attr "unit" "i387")
1387 (set_attr "mode" "<MODE>")])
1389 (define_insn "*cmpfp_u"
1390 [(set (match_operand:HI 0 "register_operand" "=a")
1393 (match_operand 1 "register_operand" "f")
1394 (match_operand 2 "register_operand" "f"))]
1396 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1397 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398 "* return output_fp_compare (insn, operands, false, true);"
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1402 (cond [(match_operand:SF 1 "" "")
1404 (match_operand:DF 1 "" "")
1407 (const_string "XF")))])
1409 (define_insn_and_split "*cmpfp_u_cc"
1410 [(set (reg:CCFPU FLAGS_REG)
1412 (match_operand 1 "register_operand" "f")
1413 (match_operand 2 "register_operand" "f")))
1414 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1415 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1416 && TARGET_SAHF && !TARGET_CMOVE
1417 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1419 "&& reload_completed"
1422 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1424 (set (reg:CC FLAGS_REG)
1425 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1427 [(set_attr "type" "multi")
1428 (set_attr "unit" "i387")
1430 (cond [(match_operand:SF 1 "" "")
1432 (match_operand:DF 1 "" "")
1435 (const_string "XF")))])
1437 (define_insn "*cmpfp_<mode>"
1438 [(set (match_operand:HI 0 "register_operand" "=a")
1441 (match_operand 1 "register_operand" "f")
1442 (match_operator 3 "float_operator"
1443 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1446 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448 "* return output_fp_compare (insn, operands, false, false);"
1449 [(set_attr "type" "multi")
1450 (set_attr "unit" "i387")
1451 (set_attr "fp_int_src" "true")
1452 (set_attr "mode" "<MODE>")])
1454 (define_insn_and_split "*cmpfp_<mode>_cc"
1455 [(set (reg:CCFP FLAGS_REG)
1457 (match_operand 1 "register_operand" "f")
1458 (match_operator 3 "float_operator"
1459 [(match_operand:SWI24 2 "memory_operand" "m")])))
1460 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1461 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1462 && TARGET_SAHF && !TARGET_CMOVE
1463 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1464 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1466 "&& reload_completed"
1471 (match_op_dup 3 [(match_dup 2)]))]
1473 (set (reg:CC FLAGS_REG)
1474 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1476 [(set_attr "type" "multi")
1477 (set_attr "unit" "i387")
1478 (set_attr "fp_int_src" "true")
1479 (set_attr "mode" "<MODE>")])
1481 ;; FP compares, step 2
1482 ;; Move the fpsw to ax.
1484 (define_insn "x86_fnstsw_1"
1485 [(set (match_operand:HI 0 "register_operand" "=a")
1486 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1489 [(set (attr "length")
1490 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1491 (set_attr "mode" "SI")
1492 (set_attr "unit" "i387")])
1494 ;; FP compares, step 3
1495 ;; Get ax into flags, general case.
1497 (define_insn "x86_sahf_1"
1498 [(set (reg:CC FLAGS_REG)
1499 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1503 #ifndef HAVE_AS_IX86_SAHF
1505 return ASM_BYTE "0x9e";
1510 [(set_attr "length" "1")
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "direct")
1514 (set_attr "mode" "SI")])
1516 ;; Pentium Pro can do steps 1 through 3 in one go.
1517 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1518 ;; (these i387 instructions set flags directly)
1519 (define_insn "*cmpfp_i_mixed"
1520 [(set (reg:CCFP FLAGS_REG)
1521 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1522 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523 "TARGET_MIX_SSE_I387
1524 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, true, false);"
1527 [(set_attr "type" "fcmp,ssecomi")
1528 (set_attr "prefix" "orig,maybe_vex")
1530 (if_then_else (match_operand:SF 1 "" "")
1532 (const_string "DF")))
1533 (set (attr "prefix_rep")
1534 (if_then_else (eq_attr "type" "ssecomi")
1536 (const_string "*")))
1537 (set (attr "prefix_data16")
1538 (cond [(eq_attr "type" "fcmp")
1540 (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_i_sse"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "x")
1551 (match_operand 1 "nonimmediate_operand" "xm")))]
1553 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555 "* return output_fp_compare (insn, operands, true, false);"
1556 [(set_attr "type" "ssecomi")
1557 (set_attr "prefix" "maybe_vex")
1559 (if_then_else (match_operand:SF 1 "" "")
1561 (const_string "DF")))
1562 (set_attr "prefix_rep" "0")
1563 (set (attr "prefix_data16")
1564 (if_then_else (eq_attr "mode" "DF")
1566 (const_string "0")))
1567 (set_attr "athlon_decode" "vector")
1568 (set_attr "amdfam10_decode" "direct")
1569 (set_attr "bdver1_decode" "double")])
1571 (define_insn "*cmpfp_i_i387"
1572 [(set (reg:CCFP FLAGS_REG)
1573 (compare:CCFP (match_operand 0 "register_operand" "f")
1574 (match_operand 1 "register_operand" "f")))]
1575 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1577 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579 "* return output_fp_compare (insn, operands, true, false);"
1580 [(set_attr "type" "fcmp")
1582 (cond [(match_operand:SF 1 "" "")
1584 (match_operand:DF 1 "" "")
1587 (const_string "XF")))
1588 (set_attr "athlon_decode" "vector")
1589 (set_attr "amdfam10_decode" "direct")
1590 (set_attr "bdver1_decode" "double")])
1592 (define_insn "*cmpfp_iu_mixed"
1593 [(set (reg:CCFPU FLAGS_REG)
1594 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1595 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1596 "TARGET_MIX_SSE_I387
1597 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1598 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1599 "* return output_fp_compare (insn, operands, true, true);"
1600 [(set_attr "type" "fcmp,ssecomi")
1601 (set_attr "prefix" "orig,maybe_vex")
1603 (if_then_else (match_operand:SF 1 "" "")
1605 (const_string "DF")))
1606 (set (attr "prefix_rep")
1607 (if_then_else (eq_attr "type" "ssecomi")
1609 (const_string "*")))
1610 (set (attr "prefix_data16")
1611 (cond [(eq_attr "type" "fcmp")
1613 (eq_attr "mode" "DF")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1621 (define_insn "*cmpfp_iu_sse"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "x")
1624 (match_operand 1 "nonimmediate_operand" "xm")))]
1626 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1627 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1628 "* return output_fp_compare (insn, operands, true, true);"
1629 [(set_attr "type" "ssecomi")
1630 (set_attr "prefix" "maybe_vex")
1632 (if_then_else (match_operand:SF 1 "" "")
1634 (const_string "DF")))
1635 (set_attr "prefix_rep" "0")
1636 (set (attr "prefix_data16")
1637 (if_then_else (eq_attr "mode" "DF")
1639 (const_string "0")))
1640 (set_attr "athlon_decode" "vector")
1641 (set_attr "amdfam10_decode" "direct")
1642 (set_attr "bdver1_decode" "double")])
1644 (define_insn "*cmpfp_iu_387"
1645 [(set (reg:CCFPU FLAGS_REG)
1646 (compare:CCFPU (match_operand 0 "register_operand" "f")
1647 (match_operand 1 "register_operand" "f")))]
1648 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1650 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1651 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1652 "* return output_fp_compare (insn, operands, true, true);"
1653 [(set_attr "type" "fcmp")
1655 (cond [(match_operand:SF 1 "" "")
1657 (match_operand:DF 1 "" "")
1660 (const_string "XF")))
1661 (set_attr "athlon_decode" "vector")
1662 (set_attr "amdfam10_decode" "direct")
1663 (set_attr "bdver1_decode" "direct")])
1665 ;; Push/pop instructions.
1667 (define_insn "*push<mode>2"
1668 [(set (match_operand:DWI 0 "push_operand" "=<")
1669 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1672 [(set_attr "type" "multi")
1673 (set_attr "mode" "<MODE>")])
1676 [(set (match_operand:TI 0 "push_operand" "")
1677 (match_operand:TI 1 "general_operand" ""))]
1678 "TARGET_64BIT && reload_completed
1679 && !SSE_REG_P (operands[1])"
1681 "ix86_split_long_move (operands); DONE;")
1683 (define_insn "*pushdi2_rex64"
1684 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1685 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1690 [(set_attr "type" "push,multi")
1691 (set_attr "mode" "DI")])
1693 ;; Convert impossible pushes of immediate to existing instructions.
1694 ;; First try to get scratch register and go through it. In case this
1695 ;; fails, push sign extended lower part first and then overwrite
1696 ;; upper part by 32bit move.
1698 [(match_scratch:DI 2 "r")
1699 (set (match_operand:DI 0 "push_operand" "")
1700 (match_operand:DI 1 "immediate_operand" ""))]
1701 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1702 && !x86_64_immediate_operand (operands[1], DImode)"
1703 [(set (match_dup 2) (match_dup 1))
1704 (set (match_dup 0) (match_dup 2))])
1706 ;; We need to define this as both peepholer and splitter for case
1707 ;; peephole2 pass is not run.
1708 ;; "&& 1" is needed to keep it from matching the previous pattern.
1710 [(set (match_operand:DI 0 "push_operand" "")
1711 (match_operand:DI 1 "immediate_operand" ""))]
1712 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1713 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1714 [(set (match_dup 0) (match_dup 1))
1715 (set (match_dup 2) (match_dup 3))]
1717 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1719 operands[1] = gen_lowpart (DImode, operands[2]);
1720 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1725 [(set (match_operand:DI 0 "push_operand" "")
1726 (match_operand:DI 1 "immediate_operand" ""))]
1727 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1728 ? epilogue_completed : reload_completed)
1729 && !symbolic_operand (operands[1], DImode)
1730 && !x86_64_immediate_operand (operands[1], DImode)"
1731 [(set (match_dup 0) (match_dup 1))
1732 (set (match_dup 2) (match_dup 3))]
1734 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1736 operands[1] = gen_lowpart (DImode, operands[2]);
1737 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1742 [(set (match_operand:DI 0 "push_operand" "")
1743 (match_operand:DI 1 "general_operand" ""))]
1744 "!TARGET_64BIT && reload_completed
1745 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1747 "ix86_split_long_move (operands); DONE;")
1749 (define_insn "*pushsi2"
1750 [(set (match_operand:SI 0 "push_operand" "=<")
1751 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1758 ;; "push a byte/word". But actually we use pushl, which has the effect
1759 ;; of rounding the amount pushed up to a word.
1761 ;; For TARGET_64BIT we always round up to 8 bytes.
1762 (define_insn "*push<mode>2_rex64"
1763 [(set (match_operand:SWI124 0 "push_operand" "=X")
1764 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1767 [(set_attr "type" "push")
1768 (set_attr "mode" "DI")])
1770 (define_insn "*push<mode>2"
1771 [(set (match_operand:SWI12 0 "push_operand" "=X")
1772 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1775 [(set_attr "type" "push")
1776 (set_attr "mode" "SI")])
1778 (define_insn "*push<mode>2_prologue"
1779 [(set (match_operand:P 0 "push_operand" "=<")
1780 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1781 (clobber (mem:BLK (scratch)))]
1783 "push{<imodesuffix>}\t%1"
1784 [(set_attr "type" "push")
1785 (set_attr "mode" "<MODE>")])
1787 (define_insn "*pop<mode>1"
1788 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1789 (match_operand:P 1 "pop_operand" ">"))]
1791 "pop{<imodesuffix>}\t%0"
1792 [(set_attr "type" "pop")
1793 (set_attr "mode" "<MODE>")])
1795 (define_insn "*pop<mode>1_epilogue"
1796 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1797 (match_operand:P 1 "pop_operand" ">"))
1798 (clobber (mem:BLK (scratch)))]
1800 "pop{<imodesuffix>}\t%0"
1801 [(set_attr "type" "pop")
1802 (set_attr "mode" "<MODE>")])
1804 ;; Move instructions.
1806 (define_expand "movoi"
1807 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1808 (match_operand:OI 1 "general_operand" ""))]
1810 "ix86_expand_move (OImode, operands); DONE;")
1812 (define_expand "movti"
1813 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1814 (match_operand:TI 1 "nonimmediate_operand" ""))]
1815 "TARGET_64BIT || TARGET_SSE"
1818 ix86_expand_move (TImode, operands);
1819 else if (push_operand (operands[0], TImode))
1820 ix86_expand_push (TImode, operands[1]);
1822 ix86_expand_vector_move (TImode, operands);
1826 ;; This expands to what emit_move_complex would generate if we didn't
1827 ;; have a movti pattern. Having this avoids problems with reload on
1828 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1829 ;; to have around all the time.
1830 (define_expand "movcdi"
1831 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1832 (match_operand:CDI 1 "general_operand" ""))]
1835 if (push_operand (operands[0], CDImode))
1836 emit_move_complex_push (CDImode, operands[0], operands[1]);
1838 emit_move_complex_parts (operands[0], operands[1]);
1842 (define_expand "mov<mode>"
1843 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1844 (match_operand:SWI1248x 1 "general_operand" ""))]
1846 "ix86_expand_move (<MODE>mode, operands); DONE;")
1848 (define_insn "*mov<mode>_xor"
1849 [(set (match_operand:SWI48 0 "register_operand" "=r")
1850 (match_operand:SWI48 1 "const0_operand" ""))
1851 (clobber (reg:CC FLAGS_REG))]
1854 [(set_attr "type" "alu1")
1855 (set_attr "mode" "SI")
1856 (set_attr "length_immediate" "0")])
1858 (define_insn "*mov<mode>_or"
1859 [(set (match_operand:SWI48 0 "register_operand" "=r")
1860 (match_operand:SWI48 1 "const_int_operand" ""))
1861 (clobber (reg:CC FLAGS_REG))]
1863 && operands[1] == constm1_rtx"
1864 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1865 [(set_attr "type" "alu1")
1866 (set_attr "mode" "<MODE>")
1867 (set_attr "length_immediate" "1")])
1869 (define_insn "*movoi_internal_avx"
1870 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1871 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1872 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1874 switch (which_alternative)
1877 return standard_sse_constant_opcode (insn, operands[1]);
1880 if (misaligned_operand (operands[0], OImode)
1881 || misaligned_operand (operands[1], OImode))
1882 return "vmovdqu\t{%1, %0|%0, %1}";
1884 return "vmovdqa\t{%1, %0|%0, %1}";
1889 [(set_attr "type" "sselog1,ssemov,ssemov")
1890 (set_attr "prefix" "vex")
1891 (set_attr "mode" "OI")])
1893 (define_insn "*movti_internal_rex64"
1894 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1895 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1896 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1898 switch (which_alternative)
1904 return standard_sse_constant_opcode (insn, operands[1]);
1907 /* TDmode values are passed as TImode on the stack. Moving them
1908 to stack may result in unaligned memory access. */
1909 if (misaligned_operand (operands[0], TImode)
1910 || misaligned_operand (operands[1], TImode))
1912 if (get_attr_mode (insn) == MODE_V4SF)
1913 return "%vmovups\t{%1, %0|%0, %1}";
1915 return "%vmovdqu\t{%1, %0|%0, %1}";
1919 if (get_attr_mode (insn) == MODE_V4SF)
1920 return "%vmovaps\t{%1, %0|%0, %1}";
1922 return "%vmovdqa\t{%1, %0|%0, %1}";
1928 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1929 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1931 (cond [(eq_attr "alternative" "2,3")
1933 (match_test "optimize_function_for_size_p (cfun)")
1934 (const_string "V4SF")
1935 (const_string "TI"))
1936 (eq_attr "alternative" "4")
1938 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1939 (match_test "optimize_function_for_size_p (cfun)"))
1940 (const_string "V4SF")
1941 (const_string "TI"))]
1942 (const_string "DI")))])
1945 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1946 (match_operand:TI 1 "general_operand" ""))]
1948 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1950 "ix86_split_long_move (operands); DONE;")
1952 (define_insn "*movti_internal_sse"
1953 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1954 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1955 "TARGET_SSE && !TARGET_64BIT
1956 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958 switch (which_alternative)
1961 return standard_sse_constant_opcode (insn, operands[1]);
1964 /* TDmode values are passed as TImode on the stack. Moving them
1965 to stack may result in unaligned memory access. */
1966 if (misaligned_operand (operands[0], TImode)
1967 || misaligned_operand (operands[1], TImode))
1969 if (get_attr_mode (insn) == MODE_V4SF)
1970 return "%vmovups\t{%1, %0|%0, %1}";
1972 return "%vmovdqu\t{%1, %0|%0, %1}";
1976 if (get_attr_mode (insn) == MODE_V4SF)
1977 return "%vmovaps\t{%1, %0|%0, %1}";
1979 return "%vmovdqa\t{%1, %0|%0, %1}";
1985 [(set_attr "type" "sselog1,ssemov,ssemov")
1986 (set_attr "prefix" "maybe_vex")
1988 (cond [(ior (not (match_test "TARGET_SSE2"))
1989 (match_test "optimize_function_for_size_p (cfun)"))
1990 (const_string "V4SF")
1991 (and (eq_attr "alternative" "2")
1992 (match_test "TARGET_SSE_TYPELESS_STORES"))
1993 (const_string "V4SF")]
1994 (const_string "TI")))])
1996 (define_insn "*movdi_internal_rex64"
1997 [(set (match_operand:DI 0 "nonimmediate_operand"
1998 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1999 (match_operand:DI 1 "general_operand"
2000 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2001 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003 switch (get_attr_type (insn))
2006 if (SSE_REG_P (operands[0]))
2007 return "movq2dq\t{%1, %0|%0, %1}";
2009 return "movdq2q\t{%1, %0|%0, %1}";
2012 if (get_attr_mode (insn) == MODE_TI)
2013 return "%vmovdqa\t{%1, %0|%0, %1}";
2014 /* Handle broken assemblers that require movd instead of movq. */
2015 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2016 return "%vmovd\t{%1, %0|%0, %1}";
2018 return "%vmovq\t{%1, %0|%0, %1}";
2021 /* Handle broken assemblers that require movd instead of movq. */
2022 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2023 return "movd\t{%1, %0|%0, %1}";
2025 return "movq\t{%1, %0|%0, %1}";
2028 return standard_sse_constant_opcode (insn, operands[1]);
2031 return "pxor\t%0, %0";
2037 return "lea{q}\t{%a1, %0|%0, %a1}";
2040 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2041 if (get_attr_mode (insn) == MODE_SI)
2042 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2043 else if (which_alternative == 2)
2044 return "movabs{q}\t{%1, %0|%0, %1}";
2046 return "mov{q}\t{%1, %0|%0, %1}";
2050 (cond [(eq_attr "alternative" "4")
2051 (const_string "multi")
2052 (eq_attr "alternative" "5")
2053 (const_string "mmx")
2054 (eq_attr "alternative" "6,7,8,9")
2055 (const_string "mmxmov")
2056 (eq_attr "alternative" "10")
2057 (const_string "sselog1")
2058 (eq_attr "alternative" "11,12,13,14,15")
2059 (const_string "ssemov")
2060 (eq_attr "alternative" "16,17")
2061 (const_string "ssecvt")
2062 (match_operand 1 "pic_32bit_operand" "")
2063 (const_string "lea")
2065 (const_string "imov")))
2068 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2070 (const_string "*")))
2071 (set (attr "length_immediate")
2073 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2075 (const_string "*")))
2076 (set (attr "prefix_rex")
2077 (if_then_else (eq_attr "alternative" "8,9")
2079 (const_string "*")))
2080 (set (attr "prefix_data16")
2081 (if_then_else (eq_attr "alternative" "11")
2083 (const_string "*")))
2084 (set (attr "prefix")
2085 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2086 (const_string "maybe_vex")
2087 (const_string "orig")))
2088 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2090 ;; Reload patterns to support multi-word load/store
2091 ;; with non-offsetable address.
2092 (define_expand "reload_noff_store"
2093 [(parallel [(match_operand 0 "memory_operand" "=m")
2094 (match_operand 1 "register_operand" "r")
2095 (match_operand:DI 2 "register_operand" "=&r")])]
2098 rtx mem = operands[0];
2099 rtx addr = XEXP (mem, 0);
2101 emit_move_insn (operands[2], addr);
2102 mem = replace_equiv_address_nv (mem, operands[2]);
2104 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2108 (define_expand "reload_noff_load"
2109 [(parallel [(match_operand 0 "register_operand" "=r")
2110 (match_operand 1 "memory_operand" "m")
2111 (match_operand:DI 2 "register_operand" "=r")])]
2114 rtx mem = operands[1];
2115 rtx addr = XEXP (mem, 0);
2117 emit_move_insn (operands[2], addr);
2118 mem = replace_equiv_address_nv (mem, operands[2]);
2120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2124 ;; Convert impossible stores of immediate to existing instructions.
2125 ;; First try to get scratch register and go through it. In case this
2126 ;; fails, move by 32bit parts.
2128 [(match_scratch:DI 2 "r")
2129 (set (match_operand:DI 0 "memory_operand" "")
2130 (match_operand:DI 1 "immediate_operand" ""))]
2131 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2132 && !x86_64_immediate_operand (operands[1], DImode)"
2133 [(set (match_dup 2) (match_dup 1))
2134 (set (match_dup 0) (match_dup 2))])
2136 ;; We need to define this as both peepholer and splitter for case
2137 ;; peephole2 pass is not run.
2138 ;; "&& 1" is needed to keep it from matching the previous pattern.
2140 [(set (match_operand:DI 0 "memory_operand" "")
2141 (match_operand:DI 1 "immediate_operand" ""))]
2142 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2143 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2144 [(set (match_dup 2) (match_dup 3))
2145 (set (match_dup 4) (match_dup 5))]
2146 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2149 [(set (match_operand:DI 0 "memory_operand" "")
2150 (match_operand:DI 1 "immediate_operand" ""))]
2151 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2152 ? epilogue_completed : reload_completed)
2153 && !symbolic_operand (operands[1], DImode)
2154 && !x86_64_immediate_operand (operands[1], DImode)"
2155 [(set (match_dup 2) (match_dup 3))
2156 (set (match_dup 4) (match_dup 5))]
2157 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2159 (define_insn "*movdi_internal"
2160 [(set (match_operand:DI 0 "nonimmediate_operand"
2161 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2162 (match_operand:DI 1 "general_operand"
2163 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2164 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2166 switch (get_attr_type (insn))
2169 if (SSE_REG_P (operands[0]))
2170 return "movq2dq\t{%1, %0|%0, %1}";
2172 return "movdq2q\t{%1, %0|%0, %1}";
2175 switch (get_attr_mode (insn))
2178 return "%vmovdqa\t{%1, %0|%0, %1}";
2180 return "%vmovq\t{%1, %0|%0, %1}";
2182 return "movaps\t{%1, %0|%0, %1}";
2184 return "movlps\t{%1, %0|%0, %1}";
2190 return "movq\t{%1, %0|%0, %1}";
2193 return standard_sse_constant_opcode (insn, operands[1]);
2196 return "pxor\t%0, %0";
2206 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2207 (const_string "sse2")
2208 (eq_attr "alternative" "9,10,11,12")
2209 (const_string "noavx")
2211 (const_string "*")))
2213 (cond [(eq_attr "alternative" "0,1")
2214 (const_string "multi")
2215 (eq_attr "alternative" "2")
2216 (const_string "mmx")
2217 (eq_attr "alternative" "3,4")
2218 (const_string "mmxmov")
2219 (eq_attr "alternative" "5,9")
2220 (const_string "sselog1")
2221 (eq_attr "alternative" "13,14")
2222 (const_string "ssecvt")
2224 (const_string "ssemov")))
2225 (set (attr "prefix")
2226 (if_then_else (eq_attr "alternative" "5,6,7,8")
2227 (const_string "maybe_vex")
2228 (const_string "orig")))
2229 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2232 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2233 (match_operand:DI 1 "general_operand" ""))]
2234 "!TARGET_64BIT && reload_completed
2235 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2236 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2238 "ix86_split_long_move (operands); DONE;")
2240 (define_insn "*movsi_internal"
2241 [(set (match_operand:SI 0 "nonimmediate_operand"
2242 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2243 (match_operand:SI 1 "general_operand"
2244 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 switch (get_attr_type (insn))
2250 return standard_sse_constant_opcode (insn, operands[1]);
2253 switch (get_attr_mode (insn))
2256 return "%vmovdqa\t{%1, %0|%0, %1}";
2258 return "%vmovaps\t{%1, %0|%0, %1}";
2260 return "%vmovd\t{%1, %0|%0, %1}";
2262 return "%vmovss\t{%1, %0|%0, %1}";
2268 return "pxor\t%0, %0";
2271 if (get_attr_mode (insn) == MODE_DI)
2272 return "movq\t{%1, %0|%0, %1}";
2273 return "movd\t{%1, %0|%0, %1}";
2276 return "lea{l}\t{%a1, %0|%0, %a1}";
2279 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280 return "mov{l}\t{%1, %0|%0, %1}";
2284 (cond [(eq_attr "alternative" "2")
2285 (const_string "mmx")
2286 (eq_attr "alternative" "3,4,5")
2287 (const_string "mmxmov")
2288 (eq_attr "alternative" "6")
2289 (const_string "sselog1")
2290 (eq_attr "alternative" "7,8,9,10,11")
2291 (const_string "ssemov")
2292 (match_operand 1 "pic_32bit_operand" "")
2293 (const_string "lea")
2295 (const_string "imov")))
2296 (set (attr "prefix")
2297 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2298 (const_string "orig")
2299 (const_string "maybe_vex")))
2300 (set (attr "prefix_data16")
2301 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2303 (const_string "*")))
2305 (cond [(eq_attr "alternative" "2,3")
2307 (eq_attr "alternative" "6,7")
2309 (not (match_test "TARGET_SSE2"))
2310 (const_string "V4SF")
2311 (const_string "TI"))
2312 (and (eq_attr "alternative" "8,9,10,11")
2313 (not (match_test "TARGET_SSE2")))
2316 (const_string "SI")))])
2318 (define_insn "*movhi_internal"
2319 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2320 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2321 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2323 switch (get_attr_type (insn))
2326 /* movzwl is faster than movw on p2 due to partial word stalls,
2327 though not as fast as an aligned movl. */
2328 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2330 if (get_attr_mode (insn) == MODE_SI)
2331 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2333 return "mov{w}\t{%1, %0|%0, %1}";
2337 (cond [(match_test "optimize_function_for_size_p (cfun)")
2338 (const_string "imov")
2339 (and (eq_attr "alternative" "0")
2340 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2341 (not (match_test "TARGET_HIMODE_MATH"))))
2342 (const_string "imov")
2343 (and (eq_attr "alternative" "1,2")
2344 (match_operand:HI 1 "aligned_operand" ""))
2345 (const_string "imov")
2346 (and (match_test "TARGET_MOVX")
2347 (eq_attr "alternative" "0,2"))
2348 (const_string "imovx")
2350 (const_string "imov")))
2352 (cond [(eq_attr "type" "imovx")
2354 (and (eq_attr "alternative" "1,2")
2355 (match_operand:HI 1 "aligned_operand" ""))
2357 (and (eq_attr "alternative" "0")
2358 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2359 (not (match_test "TARGET_HIMODE_MATH"))))
2362 (const_string "HI")))])
2364 ;; Situation is quite tricky about when to choose full sized (SImode) move
2365 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2366 ;; partial register dependency machines (such as AMD Athlon), where QImode
2367 ;; moves issue extra dependency and for partial register stalls machines
2368 ;; that don't use QImode patterns (and QImode move cause stall on the next
2371 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2372 ;; register stall machines with, where we use QImode instructions, since
2373 ;; partial register stall can be caused there. Then we use movzx.
2374 (define_insn "*movqi_internal"
2375 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2376 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2377 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2379 switch (get_attr_type (insn))
2382 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2383 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2385 if (get_attr_mode (insn) == MODE_SI)
2386 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2388 return "mov{b}\t{%1, %0|%0, %1}";
2392 (cond [(and (eq_attr "alternative" "5")
2393 (not (match_operand:QI 1 "aligned_operand" "")))
2394 (const_string "imovx")
2395 (match_test "optimize_function_for_size_p (cfun)")
2396 (const_string "imov")
2397 (and (eq_attr "alternative" "3")
2398 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2399 (not (match_test "TARGET_QIMODE_MATH"))))
2400 (const_string "imov")
2401 (eq_attr "alternative" "3,5")
2402 (const_string "imovx")
2403 (and (match_test "TARGET_MOVX")
2404 (eq_attr "alternative" "2"))
2405 (const_string "imovx")
2407 (const_string "imov")))
2409 (cond [(eq_attr "alternative" "3,4,5")
2411 (eq_attr "alternative" "6")
2413 (eq_attr "type" "imovx")
2415 (and (eq_attr "type" "imov")
2416 (and (eq_attr "alternative" "0,1")
2417 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2418 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2419 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2421 ;; Avoid partial register stalls when not using QImode arithmetic
2422 (and (eq_attr "type" "imov")
2423 (and (eq_attr "alternative" "0,1")
2424 (and (match_test "TARGET_PARTIAL_REG_STALL")
2425 (not (match_test "TARGET_QIMODE_MATH")))))
2428 (const_string "QI")))])
2430 ;; Stores and loads of ax to arbitrary constant address.
2431 ;; We fake an second form of instruction to force reload to load address
2432 ;; into register when rax is not available
2433 (define_insn "*movabs<mode>_1"
2434 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2435 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2436 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2438 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2439 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2440 [(set_attr "type" "imov")
2441 (set_attr "modrm" "0,*")
2442 (set_attr "length_address" "8,0")
2443 (set_attr "length_immediate" "0,*")
2444 (set_attr "memory" "store")
2445 (set_attr "mode" "<MODE>")])
2447 (define_insn "*movabs<mode>_2"
2448 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2449 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2450 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2452 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2453 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "modrm" "0,*")
2456 (set_attr "length_address" "8,0")
2457 (set_attr "length_immediate" "0")
2458 (set_attr "memory" "load")
2459 (set_attr "mode" "<MODE>")])
2461 (define_insn "*swap<mode>"
2462 [(set (match_operand:SWI48 0 "register_operand" "+r")
2463 (match_operand:SWI48 1 "register_operand" "+r"))
2467 "xchg{<imodesuffix>}\t%1, %0"
2468 [(set_attr "type" "imov")
2469 (set_attr "mode" "<MODE>")
2470 (set_attr "pent_pair" "np")
2471 (set_attr "athlon_decode" "vector")
2472 (set_attr "amdfam10_decode" "double")
2473 (set_attr "bdver1_decode" "double")])
2475 (define_insn "*swap<mode>_1"
2476 [(set (match_operand:SWI12 0 "register_operand" "+r")
2477 (match_operand:SWI12 1 "register_operand" "+r"))
2480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2482 [(set_attr "type" "imov")
2483 (set_attr "mode" "SI")
2484 (set_attr "pent_pair" "np")
2485 (set_attr "athlon_decode" "vector")
2486 (set_attr "amdfam10_decode" "double")
2487 (set_attr "bdver1_decode" "double")])
2489 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2490 ;; is disabled for AMDFAM10
2491 (define_insn "*swap<mode>_2"
2492 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2493 (match_operand:SWI12 1 "register_operand" "+<r>"))
2496 "TARGET_PARTIAL_REG_STALL"
2497 "xchg{<imodesuffix>}\t%1, %0"
2498 [(set_attr "type" "imov")
2499 (set_attr "mode" "<MODE>")
2500 (set_attr "pent_pair" "np")
2501 (set_attr "athlon_decode" "vector")])
2503 (define_expand "movstrict<mode>"
2504 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2505 (match_operand:SWI12 1 "general_operand" ""))]
2508 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2510 if (GET_CODE (operands[0]) == SUBREG
2511 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2513 /* Don't generate memory->memory moves, go through a register */
2514 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2515 operands[1] = force_reg (<MODE>mode, operands[1]);
2518 (define_insn "*movstrict<mode>_1"
2519 [(set (strict_low_part
2520 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2521 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2522 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2524 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2525 [(set_attr "type" "imov")
2526 (set_attr "mode" "<MODE>")])
2528 (define_insn "*movstrict<mode>_xor"
2529 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2530 (match_operand:SWI12 1 "const0_operand" ""))
2531 (clobber (reg:CC FLAGS_REG))]
2533 "xor{<imodesuffix>}\t%0, %0"
2534 [(set_attr "type" "alu1")
2535 (set_attr "mode" "<MODE>")
2536 (set_attr "length_immediate" "0")])
2538 (define_insn "*mov<mode>_extv_1"
2539 [(set (match_operand:SWI24 0 "register_operand" "=R")
2540 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2544 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2545 [(set_attr "type" "imovx")
2546 (set_attr "mode" "SI")])
2548 (define_insn "*movqi_extv_1_rex64"
2549 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2550 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2555 switch (get_attr_type (insn))
2558 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2560 return "mov{b}\t{%h1, %0|%0, %h1}";
2564 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2565 (match_test "TARGET_MOVX"))
2566 (const_string "imovx")
2567 (const_string "imov")))
2569 (if_then_else (eq_attr "type" "imovx")
2571 (const_string "QI")))])
2573 (define_insn "*movqi_extv_1"
2574 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2575 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2580 switch (get_attr_type (insn))
2583 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2585 return "mov{b}\t{%h1, %0|%0, %h1}";
2589 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2590 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2591 (match_test "TARGET_MOVX")))
2592 (const_string "imovx")
2593 (const_string "imov")))
2595 (if_then_else (eq_attr "type" "imovx")
2597 (const_string "QI")))])
2599 (define_insn "*mov<mode>_extzv_1"
2600 [(set (match_operand:SWI48 0 "register_operand" "=R")
2601 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2605 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2606 [(set_attr "type" "imovx")
2607 (set_attr "mode" "SI")])
2609 (define_insn "*movqi_extzv_2_rex64"
2610 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2612 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2617 switch (get_attr_type (insn))
2620 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2622 return "mov{b}\t{%h1, %0|%0, %h1}";
2626 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2627 (match_test "TARGET_MOVX"))
2628 (const_string "imovx")
2629 (const_string "imov")))
2631 (if_then_else (eq_attr "type" "imovx")
2633 (const_string "QI")))])
2635 (define_insn "*movqi_extzv_2"
2636 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2638 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2643 switch (get_attr_type (insn))
2646 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2648 return "mov{b}\t{%h1, %0|%0, %h1}";
2652 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2653 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2654 (match_test "TARGET_MOVX")))
2655 (const_string "imovx")
2656 (const_string "imov")))
2658 (if_then_else (eq_attr "type" "imovx")
2660 (const_string "QI")))])
2662 (define_expand "mov<mode>_insv_1"
2663 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2666 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2668 (define_insn "*mov<mode>_insv_1_rex64"
2669 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2672 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2674 "mov{b}\t{%b1, %h0|%h0, %b1}"
2675 [(set_attr "type" "imov")
2676 (set_attr "mode" "QI")])
2678 (define_insn "*movsi_insv_1"
2679 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2682 (match_operand:SI 1 "general_operand" "Qmn"))]
2684 "mov{b}\t{%b1, %h0|%h0, %b1}"
2685 [(set_attr "type" "imov")
2686 (set_attr "mode" "QI")])
2688 (define_insn "*movqi_insv_2"
2689 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2692 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2695 "mov{b}\t{%h1, %h0|%h0, %h1}"
2696 [(set_attr "type" "imov")
2697 (set_attr "mode" "QI")])
2699 ;; Floating point push instructions.
2701 (define_insn "*pushtf"
2702 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2703 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2706 /* This insn should be already split before reg-stack. */
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "sse,*,*")
2711 (set_attr "mode" "TF,SI,SI")])
2713 ;; %%% Kill this when call knows how to work this out.
2715 [(set (match_operand:TF 0 "push_operand" "")
2716 (match_operand:TF 1 "sse_reg_operand" ""))]
2717 "TARGET_SSE2 && reload_completed"
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2719 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2721 (define_insn "*pushxf"
2722 [(set (match_operand:XF 0 "push_operand" "=<,<")
2723 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2724 "optimize_function_for_speed_p (cfun)"
2726 /* This insn should be already split before reg-stack. */
2729 [(set_attr "type" "multi")
2730 (set_attr "unit" "i387,*")
2731 (set_attr "mode" "XF,SI")])
2733 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references (assuming that any given constant is pushed
2737 ;; only once, but this ought to be handled elsewhere).
2739 (define_insn "*pushxf_nointeger"
2740 [(set (match_operand:XF 0 "push_operand" "=<,<")
2741 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2742 "optimize_function_for_size_p (cfun)"
2744 /* This insn should be already split before reg-stack. */
2747 [(set_attr "type" "multi")
2748 (set_attr "unit" "i387,*")
2749 (set_attr "mode" "XF,SI")])
2751 ;; %%% Kill this when call knows how to work this out.
2753 [(set (match_operand:XF 0 "push_operand" "")
2754 (match_operand:XF 1 "fp_register_operand" ""))]
2756 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2757 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2758 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2760 (define_insn "*pushdf_rex64"
2761 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2762 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2765 /* This insn should be already split before reg-stack. */
2768 [(set_attr "type" "multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "DF,DI,DF")])
2772 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2773 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2774 ;; On the average, pushdf using integers can be still shorter.
2776 (define_insn "*pushdf"
2777 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2778 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2781 /* This insn should be already split before reg-stack. */
2784 [(set_attr "isa" "*,*,sse2")
2785 (set_attr "type" "multi")
2786 (set_attr "unit" "i387,*,*")
2787 (set_attr "mode" "DF,DI,DF")])
2789 ;; %%% Kill this when call knows how to work this out.
2791 [(set (match_operand:DF 0 "push_operand" "")
2792 (match_operand:DF 1 "any_fp_register_operand" ""))]
2794 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2795 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2797 (define_insn "*pushsf_rex64"
2798 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2799 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2802 /* Anything else should be already split before reg-stack. */
2803 gcc_assert (which_alternative == 1);
2804 return "push{q}\t%q1";
2806 [(set_attr "type" "multi,push,multi")
2807 (set_attr "unit" "i387,*,*")
2808 (set_attr "mode" "SF,DI,SF")])
2810 (define_insn "*pushsf"
2811 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2812 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2815 /* Anything else should be already split before reg-stack. */
2816 gcc_assert (which_alternative == 1);
2817 return "push{l}\t%1";
2819 [(set_attr "type" "multi,push,multi")
2820 (set_attr "unit" "i387,*,*")
2821 (set_attr "mode" "SF,SI,SF")])
2823 ;; %%% Kill this when call knows how to work this out.
2825 [(set (match_operand:SF 0 "push_operand" "")
2826 (match_operand:SF 1 "any_fp_register_operand" ""))]
2828 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2829 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2830 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2833 [(set (match_operand:SF 0 "push_operand" "")
2834 (match_operand:SF 1 "memory_operand" ""))]
2836 && (operands[2] = find_constant_src (insn))"
2837 [(set (match_dup 0) (match_dup 2))])
2840 [(set (match_operand 0 "push_operand" "")
2841 (match_operand 1 "general_operand" ""))]
2843 && (GET_MODE (operands[0]) == TFmode
2844 || GET_MODE (operands[0]) == XFmode
2845 || GET_MODE (operands[0]) == DFmode)
2846 && !ANY_FP_REG_P (operands[1])"
2848 "ix86_split_long_move (operands); DONE;")
2850 ;; Floating point move instructions.
2852 (define_expand "movtf"
2853 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2854 (match_operand:TF 1 "nonimmediate_operand" ""))]
2857 ix86_expand_move (TFmode, operands);
2861 (define_expand "mov<mode>"
2862 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2863 (match_operand:X87MODEF 1 "general_operand" ""))]
2865 "ix86_expand_move (<MODE>mode, operands); DONE;")
2867 (define_insn "*movtf_internal"
2868 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2869 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2871 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2872 && (!can_create_pseudo_p ()
2873 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2874 || GET_CODE (operands[1]) != CONST_DOUBLE
2875 || (optimize_function_for_size_p (cfun)
2876 && standard_sse_constant_p (operands[1])
2877 && !memory_operand (operands[0], TFmode))
2878 || (!TARGET_MEMORY_MISMATCH_STALL
2879 && memory_operand (operands[0], TFmode)))"
2881 switch (which_alternative)
2885 /* Handle misaligned load/store since we
2886 don't have movmisaligntf pattern. */
2887 if (misaligned_operand (operands[0], TFmode)
2888 || misaligned_operand (operands[1], TFmode))
2890 if (get_attr_mode (insn) == MODE_V4SF)
2891 return "%vmovups\t{%1, %0|%0, %1}";
2893 return "%vmovdqu\t{%1, %0|%0, %1}";
2897 if (get_attr_mode (insn) == MODE_V4SF)
2898 return "%vmovaps\t{%1, %0|%0, %1}";
2900 return "%vmovdqa\t{%1, %0|%0, %1}";
2904 return standard_sse_constant_opcode (insn, operands[1]);
2914 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2915 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2917 (cond [(eq_attr "alternative" "0,2")
2919 (match_test "optimize_function_for_size_p (cfun)")
2920 (const_string "V4SF")
2921 (const_string "TI"))
2922 (eq_attr "alternative" "1")
2924 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2925 (match_test "optimize_function_for_size_p (cfun)"))
2926 (const_string "V4SF")
2927 (const_string "TI"))]
2928 (const_string "DI")))])
2930 ;; Possible store forwarding (partial memory) stall in alternative 4.
2931 (define_insn "*movxf_internal"
2932 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2933 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2934 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2935 && (!can_create_pseudo_p ()
2936 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2937 || GET_CODE (operands[1]) != CONST_DOUBLE
2938 || (optimize_function_for_size_p (cfun)
2939 && standard_80387_constant_p (operands[1]) > 0
2940 && !memory_operand (operands[0], XFmode))
2941 || (!TARGET_MEMORY_MISMATCH_STALL
2942 && memory_operand (operands[0], XFmode)))"
2944 switch (which_alternative)
2948 return output_387_reg_move (insn, operands);
2951 return standard_80387_constant_opcode (operands[1]);
2961 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2962 (set_attr "mode" "XF,XF,XF,SI,SI")])
2964 (define_insn "*movdf_internal_rex64"
2965 [(set (match_operand:DF 0 "nonimmediate_operand"
2966 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2967 (match_operand:DF 1 "general_operand"
2968 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2969 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2970 && (!can_create_pseudo_p ()
2971 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2972 || GET_CODE (operands[1]) != CONST_DOUBLE
2973 || (optimize_function_for_size_p (cfun)
2974 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2975 && standard_80387_constant_p (operands[1]) > 0)
2976 || (TARGET_SSE2 && TARGET_SSE_MATH
2977 && standard_sse_constant_p (operands[1]))))
2978 || memory_operand (operands[0], DFmode))"
2980 switch (which_alternative)
2984 return output_387_reg_move (insn, operands);
2987 return standard_80387_constant_opcode (operands[1]);
2991 return "mov{q}\t{%1, %0|%0, %1}";
2994 return "movabs{q}\t{%1, %0|%0, %1}";
3000 return standard_sse_constant_opcode (insn, operands[1]);
3005 switch (get_attr_mode (insn))
3008 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3009 return "%vmovapd\t{%1, %0|%0, %1}";
3011 return "%vmovaps\t{%1, %0|%0, %1}";
3014 return "%vmovq\t{%1, %0|%0, %1}";
3016 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3017 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3018 return "%vmovsd\t{%1, %0|%0, %1}";
3020 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3022 return "%vmovlps\t{%1, %d0|%d0, %1}";
3029 /* Handle broken assemblers that require movd instead of movq. */
3030 return "%vmovd\t{%1, %0|%0, %1}";
3037 (cond [(eq_attr "alternative" "0,1,2")
3038 (const_string "fmov")
3039 (eq_attr "alternative" "3,4,5")
3040 (const_string "imov")
3041 (eq_attr "alternative" "6")
3042 (const_string "multi")
3043 (eq_attr "alternative" "7")
3044 (const_string "sselog1")
3046 (const_string "ssemov")))
3049 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3051 (const_string "*")))
3052 (set (attr "length_immediate")
3054 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3056 (const_string "*")))
3057 (set (attr "prefix")
3058 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3059 (const_string "orig")
3060 (const_string "maybe_vex")))
3061 (set (attr "prefix_data16")
3062 (if_then_else (eq_attr "mode" "V1DF")
3064 (const_string "*")))
3066 (cond [(eq_attr "alternative" "0,1,2")
3068 (eq_attr "alternative" "3,4,5,6,11,12")
3071 /* xorps is one byte shorter. */
3072 (eq_attr "alternative" "7")
3073 (cond [(match_test "optimize_function_for_size_p (cfun)")
3074 (const_string "V4SF")
3075 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3078 (const_string "V2DF"))
3080 /* For architectures resolving dependencies on
3081 whole SSE registers use APD move to break dependency
3082 chains, otherwise use short move to avoid extra work.
3084 movaps encodes one byte shorter. */
3085 (eq_attr "alternative" "8")
3087 [(match_test "optimize_function_for_size_p (cfun)")
3088 (const_string "V4SF")
3089 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3090 (const_string "V2DF")
3092 (const_string "DF"))
3093 /* For architectures resolving dependencies on register
3094 parts we may avoid extra work to zero out upper part
3096 (eq_attr "alternative" "9")
3098 (match_test "TARGET_SSE_SPLIT_REGS")
3099 (const_string "V1DF")
3100 (const_string "DF"))
3102 (const_string "DF")))])
3104 ;; Possible store forwarding (partial memory) stall in alternative 4.
3105 (define_insn "*movdf_internal"
3106 [(set (match_operand:DF 0 "nonimmediate_operand"
3107 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3108 (match_operand:DF 1 "general_operand"
3109 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3111 && (!can_create_pseudo_p ()
3112 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3113 || GET_CODE (operands[1]) != CONST_DOUBLE
3114 || (optimize_function_for_size_p (cfun)
3115 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3116 && standard_80387_constant_p (operands[1]) > 0)
3117 || (TARGET_SSE2 && TARGET_SSE_MATH
3118 && standard_sse_constant_p (operands[1])))
3119 && !memory_operand (operands[0], DFmode))
3120 || (!TARGET_MEMORY_MISMATCH_STALL
3121 && memory_operand (operands[0], DFmode)))"
3123 switch (which_alternative)
3127 return output_387_reg_move (insn, operands);
3130 return standard_80387_constant_opcode (operands[1]);
3138 return standard_sse_constant_opcode (insn, operands[1]);
3146 switch (get_attr_mode (insn))
3149 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3150 return "%vmovapd\t{%1, %0|%0, %1}";
3152 return "%vmovaps\t{%1, %0|%0, %1}";
3155 return "%vmovq\t{%1, %0|%0, %1}";
3157 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3158 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3159 return "%vmovsd\t{%1, %0|%0, %1}";
3161 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3163 return "%vmovlps\t{%1, %d0|%d0, %1}";
3173 (if_then_else (eq_attr "alternative" "5,6,7,8")
3174 (const_string "sse2")
3175 (const_string "*")))
3177 (cond [(eq_attr "alternative" "0,1,2")
3178 (const_string "fmov")
3179 (eq_attr "alternative" "3,4")
3180 (const_string "multi")
3181 (eq_attr "alternative" "5,9")
3182 (const_string "sselog1")
3184 (const_string "ssemov")))
3185 (set (attr "prefix")
3186 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3187 (const_string "orig")
3188 (const_string "maybe_vex")))
3189 (set (attr "prefix_data16")
3190 (if_then_else (eq_attr "mode" "V1DF")
3192 (const_string "*")))
3194 (cond [(eq_attr "alternative" "0,1,2")
3196 (eq_attr "alternative" "3,4")
3199 /* For SSE1, we have many fewer alternatives. */
3200 (not (match_test "TARGET_SSE2"))
3202 (eq_attr "alternative" "5,6,9,10")
3203 (const_string "V4SF")
3204 (const_string "V2SF"))
3206 /* xorps is one byte shorter. */
3207 (eq_attr "alternative" "5,9")
3208 (cond [(match_test "optimize_function_for_size_p (cfun)")
3209 (const_string "V4SF")
3210 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3213 (const_string "V2DF"))
3215 /* For architectures resolving dependencies on
3216 whole SSE registers use APD move to break dependency
3217 chains, otherwise use short move to avoid extra work.
3219 movaps encodes one byte shorter. */
3220 (eq_attr "alternative" "6,10")
3222 [(match_test "optimize_function_for_size_p (cfun)")
3223 (const_string "V4SF")
3224 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3225 (const_string "V2DF")
3227 (const_string "DF"))
3228 /* For architectures resolving dependencies on register
3229 parts we may avoid extra work to zero out upper part
3231 (eq_attr "alternative" "7,11")
3233 (match_test "TARGET_SSE_SPLIT_REGS")
3234 (const_string "V1DF")
3235 (const_string "DF"))
3237 (const_string "DF")))])
3239 (define_insn "*movsf_internal"
3240 [(set (match_operand:SF 0 "nonimmediate_operand"
3241 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3242 (match_operand:SF 1 "general_operand"
3243 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3244 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3245 && (!can_create_pseudo_p ()
3246 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3247 || GET_CODE (operands[1]) != CONST_DOUBLE
3248 || (optimize_function_for_size_p (cfun)
3249 && ((!TARGET_SSE_MATH
3250 && standard_80387_constant_p (operands[1]) > 0)
3252 && standard_sse_constant_p (operands[1]))))
3253 || memory_operand (operands[0], SFmode))"
3255 switch (which_alternative)
3259 return output_387_reg_move (insn, operands);
3262 return standard_80387_constant_opcode (operands[1]);
3266 return "mov{l}\t{%1, %0|%0, %1}";
3269 return standard_sse_constant_opcode (insn, operands[1]);
3272 if (get_attr_mode (insn) == MODE_V4SF)
3273 return "%vmovaps\t{%1, %0|%0, %1}";
3275 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3279 return "%vmovss\t{%1, %0|%0, %1}";
3285 return "movd\t{%1, %0|%0, %1}";
3288 return "movq\t{%1, %0|%0, %1}";
3292 return "%vmovd\t{%1, %0|%0, %1}";
3299 (cond [(eq_attr "alternative" "0,1,2")
3300 (const_string "fmov")
3301 (eq_attr "alternative" "3,4")
3302 (const_string "multi")
3303 (eq_attr "alternative" "5")
3304 (const_string "sselog1")
3305 (eq_attr "alternative" "9,10,11,14,15")
3306 (const_string "mmxmov")
3308 (const_string "ssemov")))
3309 (set (attr "prefix")
3310 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3311 (const_string "maybe_vex")
3312 (const_string "orig")))
3314 (cond [(eq_attr "alternative" "3,4,9,10")
3316 (eq_attr "alternative" "5")
3318 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3319 (match_test "TARGET_SSE2"))
3320 (not (match_test "optimize_function_for_size_p (cfun)")))
3322 (const_string "V4SF"))
3323 /* For architectures resolving dependencies on
3324 whole SSE registers use APS move to break dependency
3325 chains, otherwise use short move to avoid extra work.
3327 Do the same for architectures resolving dependencies on
3328 the parts. While in DF mode it is better to always handle
3329 just register parts, the SF mode is different due to lack
3330 of instructions to load just part of the register. It is
3331 better to maintain the whole registers in single format
3332 to avoid problems on using packed logical operations. */
3333 (eq_attr "alternative" "6")
3335 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3336 (match_test "TARGET_SSE_SPLIT_REGS"))
3337 (const_string "V4SF")
3338 (const_string "SF"))
3339 (eq_attr "alternative" "11")
3340 (const_string "DI")]
3341 (const_string "SF")))])
3344 [(set (match_operand 0 "any_fp_register_operand" "")
3345 (match_operand 1 "memory_operand" ""))]
3347 && (GET_MODE (operands[0]) == TFmode
3348 || GET_MODE (operands[0]) == XFmode
3349 || GET_MODE (operands[0]) == DFmode
3350 || GET_MODE (operands[0]) == SFmode)
3351 && (operands[2] = find_constant_src (insn))"
3352 [(set (match_dup 0) (match_dup 2))]
3354 rtx c = operands[2];
3355 int r = REGNO (operands[0]);
3357 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3358 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3363 [(set (match_operand 0 "any_fp_register_operand" "")
3364 (float_extend (match_operand 1 "memory_operand" "")))]
3366 && (GET_MODE (operands[0]) == TFmode
3367 || GET_MODE (operands[0]) == XFmode
3368 || GET_MODE (operands[0]) == DFmode)
3369 && (operands[2] = find_constant_src (insn))"
3370 [(set (match_dup 0) (match_dup 2))]
3372 rtx c = operands[2];
3373 int r = REGNO (operands[0]);
3375 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3376 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3380 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3382 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3383 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3385 && (standard_80387_constant_p (operands[1]) == 8
3386 || standard_80387_constant_p (operands[1]) == 9)"
3387 [(set (match_dup 0)(match_dup 1))
3389 (neg:X87MODEF (match_dup 0)))]
3393 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3394 if (real_isnegzero (&r))
3395 operands[1] = CONST0_RTX (<MODE>mode);
3397 operands[1] = CONST1_RTX (<MODE>mode);
3401 [(set (match_operand 0 "nonimmediate_operand" "")
3402 (match_operand 1 "general_operand" ""))]
3404 && (GET_MODE (operands[0]) == TFmode
3405 || GET_MODE (operands[0]) == XFmode
3406 || GET_MODE (operands[0]) == DFmode)
3407 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3409 "ix86_split_long_move (operands); DONE;")
3411 (define_insn "swapxf"
3412 [(set (match_operand:XF 0 "register_operand" "+f")
3413 (match_operand:XF 1 "register_operand" "+f"))
3418 if (STACK_TOP_P (operands[0]))
3423 [(set_attr "type" "fxch")
3424 (set_attr "mode" "XF")])
3426 (define_insn "*swap<mode>"
3427 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3428 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3431 "TARGET_80387 || reload_completed"
3433 if (STACK_TOP_P (operands[0]))
3438 [(set_attr "type" "fxch")
3439 (set_attr "mode" "<MODE>")])
3441 ;; Zero extension instructions
3443 (define_expand "zero_extendsidi2"
3444 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3445 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3450 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3455 (define_insn "*zero_extendsidi2_rex64"
3456 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3458 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3461 mov\t{%k1, %k0|%k0, %k1}
3463 movd\t{%1, %0|%0, %1}
3464 movd\t{%1, %0|%0, %1}
3465 %vmovd\t{%1, %0|%0, %1}
3466 %vmovd\t{%1, %0|%0, %1}"
3467 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3468 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3469 (set_attr "prefix_0f" "0,*,*,*,*,*")
3470 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3473 [(set (match_operand:DI 0 "memory_operand" "")
3474 (zero_extend:DI (match_dup 0)))]
3476 [(set (match_dup 4) (const_int 0))]
3477 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3479 ;; %%% Kill me once multi-word ops are sane.
3480 (define_insn "zero_extendsidi2_1"
3481 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3483 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3484 (clobber (reg:CC FLAGS_REG))]
3490 movd\t{%1, %0|%0, %1}
3491 movd\t{%1, %0|%0, %1}
3492 %vmovd\t{%1, %0|%0, %1}
3493 %vmovd\t{%1, %0|%0, %1}"
3494 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3495 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3496 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3497 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3500 [(set (match_operand:DI 0 "register_operand" "")
3501 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3502 (clobber (reg:CC FLAGS_REG))]
3503 "!TARGET_64BIT && reload_completed
3504 && true_regnum (operands[0]) == true_regnum (operands[1])"
3505 [(set (match_dup 4) (const_int 0))]
3506 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3509 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3510 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3512 "!TARGET_64BIT && reload_completed
3513 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3514 [(set (match_dup 3) (match_dup 1))
3515 (set (match_dup 4) (const_int 0))]
3516 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3518 (define_insn "zero_extend<mode>di2"
3519 [(set (match_operand:DI 0 "register_operand" "=r")
3521 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3523 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "SI")])
3527 (define_expand "zero_extendhisi2"
3528 [(set (match_operand:SI 0 "register_operand" "")
3529 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3532 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3534 operands[1] = force_reg (HImode, operands[1]);
3535 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3540 (define_insn_and_split "zero_extendhisi2_and"
3541 [(set (match_operand:SI 0 "register_operand" "=r")
3542 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3543 (clobber (reg:CC FLAGS_REG))]
3544 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3546 "&& reload_completed"
3547 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3548 (clobber (reg:CC FLAGS_REG))])]
3550 [(set_attr "type" "alu1")
3551 (set_attr "mode" "SI")])
3553 (define_insn "*zero_extendhisi2_movzwl"
3554 [(set (match_operand:SI 0 "register_operand" "=r")
3555 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3556 "!TARGET_ZERO_EXTEND_WITH_AND
3557 || optimize_function_for_size_p (cfun)"
3558 "movz{wl|x}\t{%1, %0|%0, %1}"
3559 [(set_attr "type" "imovx")
3560 (set_attr "mode" "SI")])
3562 (define_expand "zero_extendqi<mode>2"
3564 [(set (match_operand:SWI24 0 "register_operand" "")
3565 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3566 (clobber (reg:CC FLAGS_REG))])])
3568 (define_insn "*zero_extendqi<mode>2_and"
3569 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3570 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3571 (clobber (reg:CC FLAGS_REG))]
3572 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3574 [(set_attr "type" "alu1")
3575 (set_attr "mode" "<MODE>")])
3577 ;; When source and destination does not overlap, clear destination
3578 ;; first and then do the movb
3580 [(set (match_operand:SWI24 0 "register_operand" "")
3581 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3582 (clobber (reg:CC FLAGS_REG))]
3584 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3585 && ANY_QI_REG_P (operands[0])
3586 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3587 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3588 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3590 operands[2] = gen_lowpart (QImode, operands[0]);
3591 ix86_expand_clear (operands[0]);
3594 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3595 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3596 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3597 (clobber (reg:CC FLAGS_REG))]
3598 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3600 [(set_attr "type" "imovx,alu1")
3601 (set_attr "mode" "<MODE>")])
3603 ;; For the movzbl case strip only the clobber
3605 [(set (match_operand:SWI24 0 "register_operand" "")
3606 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3607 (clobber (reg:CC FLAGS_REG))]
3609 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3610 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3612 (zero_extend:SWI24 (match_dup 1)))])
3614 ; zero extend to SImode to avoid partial register stalls
3615 (define_insn "*zero_extendqi<mode>2_movzbl"
3616 [(set (match_operand:SWI24 0 "register_operand" "=r")
3617 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3619 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3620 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3621 [(set_attr "type" "imovx")
3622 (set_attr "mode" "SI")])
3624 ;; Rest is handled by single and.
3626 [(set (match_operand:SWI24 0 "register_operand" "")
3627 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3628 (clobber (reg:CC FLAGS_REG))]
3630 && true_regnum (operands[0]) == true_regnum (operands[1])"
3631 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3632 (clobber (reg:CC FLAGS_REG))])])
3634 ;; Sign extension instructions
3636 (define_expand "extendsidi2"
3637 [(set (match_operand:DI 0 "register_operand" "")
3638 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3643 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3648 (define_insn "*extendsidi2_rex64"
3649 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3650 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3654 movs{lq|x}\t{%1, %0|%0, %1}"
3655 [(set_attr "type" "imovx")
3656 (set_attr "mode" "DI")
3657 (set_attr "prefix_0f" "0")
3658 (set_attr "modrm" "0,1")])
3660 (define_insn "extendsidi2_1"
3661 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3662 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3663 (clobber (reg:CC FLAGS_REG))
3664 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3668 ;; Extend to memory case when source register does die.
3670 [(set (match_operand:DI 0 "memory_operand" "")
3671 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3672 (clobber (reg:CC FLAGS_REG))
3673 (clobber (match_operand:SI 2 "register_operand" ""))]
3675 && dead_or_set_p (insn, operands[1])
3676 && !reg_mentioned_p (operands[1], operands[0]))"
3677 [(set (match_dup 3) (match_dup 1))
3678 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3679 (clobber (reg:CC FLAGS_REG))])
3680 (set (match_dup 4) (match_dup 1))]
3681 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3683 ;; Extend to memory case when source register does not die.
3685 [(set (match_operand:DI 0 "memory_operand" "")
3686 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))
3688 (clobber (match_operand:SI 2 "register_operand" ""))]
3692 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3694 emit_move_insn (operands[3], operands[1]);
3696 /* Generate a cltd if possible and doing so it profitable. */
3697 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3698 && true_regnum (operands[1]) == AX_REG
3699 && true_regnum (operands[2]) == DX_REG)
3701 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3705 emit_move_insn (operands[2], operands[1]);
3706 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3708 emit_move_insn (operands[4], operands[2]);
3712 ;; Extend to register case. Optimize case where source and destination
3713 ;; registers match and cases where we can use cltd.
3715 [(set (match_operand:DI 0 "register_operand" "")
3716 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3717 (clobber (reg:CC FLAGS_REG))
3718 (clobber (match_scratch:SI 2 ""))]
3722 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3724 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3725 emit_move_insn (operands[3], operands[1]);
3727 /* Generate a cltd if possible and doing so it profitable. */
3728 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3729 && true_regnum (operands[3]) == AX_REG
3730 && true_regnum (operands[4]) == DX_REG)
3732 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3736 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3737 emit_move_insn (operands[4], operands[1]);
3739 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3743 (define_insn "extend<mode>di2"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3748 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "DI")])
3752 (define_insn "extendhisi2"
3753 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3754 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3757 switch (get_attr_prefix_0f (insn))
3760 return "{cwtl|cwde}";
3762 return "movs{wl|x}\t{%1, %0|%0, %1}";
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "SI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3772 (const_string "1")))
3774 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "1")))])
3778 (define_insn "*extendhisi2_zext"
3779 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3782 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3785 switch (get_attr_prefix_0f (insn))
3788 return "{cwtl|cwde}";
3790 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3793 [(set_attr "type" "imovx")
3794 (set_attr "mode" "SI")
3795 (set (attr "prefix_0f")
3796 ;; movsx is short decodable while cwtl is vector decoded.
3797 (if_then_else (and (eq_attr "cpu" "!k6")
3798 (eq_attr "alternative" "0"))
3800 (const_string "1")))
3802 (if_then_else (eq_attr "prefix_0f" "0")
3804 (const_string "1")))])
3806 (define_insn "extendqisi2"
3807 [(set (match_operand:SI 0 "register_operand" "=r")
3808 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3810 "movs{bl|x}\t{%1, %0|%0, %1}"
3811 [(set_attr "type" "imovx")
3812 (set_attr "mode" "SI")])
3814 (define_insn "*extendqisi2_zext"
3815 [(set (match_operand:DI 0 "register_operand" "=r")
3817 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3819 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3820 [(set_attr "type" "imovx")
3821 (set_attr "mode" "SI")])
3823 (define_insn "extendqihi2"
3824 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3825 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3828 switch (get_attr_prefix_0f (insn))
3831 return "{cbtw|cbw}";
3833 return "movs{bw|x}\t{%1, %0|%0, %1}";
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "HI")
3838 (set (attr "prefix_0f")
3839 ;; movsx is short decodable while cwtl is vector decoded.
3840 (if_then_else (and (eq_attr "cpu" "!k6")
3841 (eq_attr "alternative" "0"))
3843 (const_string "1")))
3845 (if_then_else (eq_attr "prefix_0f" "0")
3847 (const_string "1")))])
3849 ;; Conversions between float and double.
3851 ;; These are all no-ops in the model used for the 80387.
3852 ;; So just emit moves.
3854 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3856 [(set (match_operand:DF 0 "push_operand" "")
3857 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3859 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3860 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3863 [(set (match_operand:XF 0 "push_operand" "")
3864 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3866 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3867 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3868 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3870 (define_expand "extendsfdf2"
3871 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3872 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3873 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3875 /* ??? Needed for compress_float_constant since all fp constants
3876 are TARGET_LEGITIMATE_CONSTANT_P. */
3877 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3879 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3880 && standard_80387_constant_p (operands[1]) > 0)
3882 operands[1] = simplify_const_unary_operation
3883 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3884 emit_move_insn_1 (operands[0], operands[1]);
3887 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3891 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3893 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3895 We do the conversion post reload to avoid producing of 128bit spills
3896 that might lead to ICE on 32bit target. The sequence unlikely combine
3899 [(set (match_operand:DF 0 "register_operand" "")
3901 (match_operand:SF 1 "nonimmediate_operand" "")))]
3902 "TARGET_USE_VECTOR_FP_CONVERTS
3903 && optimize_insn_for_speed_p ()
3904 && reload_completed && SSE_REG_P (operands[0])"
3909 (parallel [(const_int 0) (const_int 1)]))))]
3911 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3912 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3913 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3914 Try to avoid move when unpacking can be done in source. */
3915 if (REG_P (operands[1]))
3917 /* If it is unsafe to overwrite upper half of source, we need
3918 to move to destination and unpack there. */
3919 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3920 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3921 && true_regnum (operands[0]) != true_regnum (operands[1]))
3923 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3924 emit_move_insn (tmp, operands[1]);
3927 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3928 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3932 emit_insn (gen_vec_setv4sf_0 (operands[3],
3933 CONST0_RTX (V4SFmode), operands[1]));
3936 (define_insn "*extendsfdf2_mixed"
3937 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3939 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3940 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3942 switch (which_alternative)
3946 return output_387_reg_move (insn, operands);
3949 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3955 [(set_attr "type" "fmov,fmov,ssecvt")
3956 (set_attr "prefix" "orig,orig,maybe_vex")
3957 (set_attr "mode" "SF,XF,DF")])
3959 (define_insn "*extendsfdf2_sse"
3960 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3961 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3962 "TARGET_SSE2 && TARGET_SSE_MATH"
3963 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3964 [(set_attr "type" "ssecvt")
3965 (set_attr "prefix" "maybe_vex")
3966 (set_attr "mode" "DF")])
3968 (define_insn "*extendsfdf2_i387"
3969 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3970 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3972 "* return output_387_reg_move (insn, operands);"
3973 [(set_attr "type" "fmov")
3974 (set_attr "mode" "SF,XF")])
3976 (define_expand "extend<mode>xf2"
3977 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3978 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3981 /* ??? Needed for compress_float_constant since all fp constants
3982 are TARGET_LEGITIMATE_CONSTANT_P. */
3983 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3985 if (standard_80387_constant_p (operands[1]) > 0)
3987 operands[1] = simplify_const_unary_operation
3988 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3989 emit_move_insn_1 (operands[0], operands[1]);
3992 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3996 (define_insn "*extend<mode>xf2_i387"
3997 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3999 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4001 "* return output_387_reg_move (insn, operands);"
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "<MODE>,XF")])
4005 ;; %%% This seems bad bad news.
4006 ;; This cannot output into an f-reg because there is no way to be sure
4007 ;; of truncating in that case. Otherwise this is just like a simple move
4008 ;; insn. So we pretend we can output to a reg in order to get better
4009 ;; register preferencing, but we really use a stack slot.
4011 ;; Conversion from DFmode to SFmode.
4013 (define_expand "truncdfsf2"
4014 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4016 (match_operand:DF 1 "nonimmediate_operand" "")))]
4017 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4019 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4021 else if (flag_unsafe_math_optimizations)
4025 enum ix86_stack_slot slot = (virtuals_instantiated
4028 rtx temp = assign_386_stack_local (SFmode, slot);
4029 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4034 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4036 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4038 We do the conversion post reload to avoid producing of 128bit spills
4039 that might lead to ICE on 32bit target. The sequence unlikely combine
4042 [(set (match_operand:SF 0 "register_operand" "")
4044 (match_operand:DF 1 "nonimmediate_operand" "")))]
4045 "TARGET_USE_VECTOR_FP_CONVERTS
4046 && optimize_insn_for_speed_p ()
4047 && reload_completed && SSE_REG_P (operands[0])"
4050 (float_truncate:V2SF
4054 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4055 operands[3] = CONST0_RTX (V2SFmode);
4056 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4057 /* Use movsd for loading from memory, unpcklpd for registers.
4058 Try to avoid move when unpacking can be done in source, or SSE3
4059 movddup is available. */
4060 if (REG_P (operands[1]))
4063 && true_regnum (operands[0]) != true_regnum (operands[1])
4064 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4065 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4067 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4068 emit_move_insn (tmp, operands[1]);
4071 else if (!TARGET_SSE3)
4072 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4073 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4076 emit_insn (gen_sse2_loadlpd (operands[4],
4077 CONST0_RTX (V2DFmode), operands[1]));
4080 (define_expand "truncdfsf2_with_temp"
4081 [(parallel [(set (match_operand:SF 0 "" "")
4082 (float_truncate:SF (match_operand:DF 1 "" "")))
4083 (clobber (match_operand:SF 2 "" ""))])])
4085 (define_insn "*truncdfsf_fast_mixed"
4086 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4088 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4089 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4091 switch (which_alternative)
4094 return output_387_reg_move (insn, operands);
4096 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4101 [(set_attr "type" "fmov,ssecvt")
4102 (set_attr "prefix" "orig,maybe_vex")
4103 (set_attr "mode" "SF")])
4105 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4106 ;; because nothing we do here is unsafe.
4107 (define_insn "*truncdfsf_fast_sse"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4110 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4111 "TARGET_SSE2 && TARGET_SSE_MATH"
4112 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4113 [(set_attr "type" "ssecvt")
4114 (set_attr "prefix" "maybe_vex")
4115 (set_attr "mode" "SF")])
4117 (define_insn "*truncdfsf_fast_i387"
4118 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4120 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4121 "TARGET_80387 && flag_unsafe_math_optimizations"
4122 "* return output_387_reg_move (insn, operands);"
4123 [(set_attr "type" "fmov")
4124 (set_attr "mode" "SF")])
4126 (define_insn "*truncdfsf_mixed"
4127 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4129 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4130 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4131 "TARGET_MIX_SSE_I387"
4133 switch (which_alternative)
4136 return output_387_reg_move (insn, operands);
4138 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4144 [(set_attr "isa" "*,sse2,*,*,*")
4145 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4146 (set_attr "unit" "*,*,i387,i387,i387")
4147 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4148 (set_attr "mode" "SF")])
4150 (define_insn "*truncdfsf_i387"
4151 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4153 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4154 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4157 switch (which_alternative)
4160 return output_387_reg_move (insn, operands);
4166 [(set_attr "type" "fmov,multi,multi,multi")
4167 (set_attr "unit" "*,i387,i387,i387")
4168 (set_attr "mode" "SF")])
4170 (define_insn "*truncdfsf2_i387_1"
4171 [(set (match_operand:SF 0 "memory_operand" "=m")
4173 (match_operand:DF 1 "register_operand" "f")))]
4175 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4176 && !TARGET_MIX_SSE_I387"
4177 "* return output_387_reg_move (insn, operands);"
4178 [(set_attr "type" "fmov")
4179 (set_attr "mode" "SF")])
4182 [(set (match_operand:SF 0 "register_operand" "")
4184 (match_operand:DF 1 "fp_register_operand" "")))
4185 (clobber (match_operand 2 "" ""))]
4187 [(set (match_dup 2) (match_dup 1))
4188 (set (match_dup 0) (match_dup 2))]
4189 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4191 ;; Conversion from XFmode to {SF,DF}mode
4193 (define_expand "truncxf<mode>2"
4194 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "")))
4197 (clobber (match_dup 2))])]
4200 if (flag_unsafe_math_optimizations)
4202 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4203 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4204 if (reg != operands[0])
4205 emit_move_insn (operands[0], reg);
4210 enum ix86_stack_slot slot = (virtuals_instantiated
4213 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4217 (define_insn "*truncxfsf2_mixed"
4218 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4220 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4221 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4224 gcc_assert (!which_alternative);
4225 return output_387_reg_move (insn, operands);
4227 [(set_attr "type" "fmov,multi,multi,multi")
4228 (set_attr "unit" "*,i387,i387,i387")
4229 (set_attr "mode" "SF")])
4231 (define_insn "*truncxfdf2_mixed"
4232 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4234 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4235 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4238 gcc_assert (!which_alternative);
4239 return output_387_reg_move (insn, operands);
4241 [(set_attr "isa" "*,*,sse2,*")
4242 (set_attr "type" "fmov,multi,multi,multi")
4243 (set_attr "unit" "*,i387,i387,i387")
4244 (set_attr "mode" "DF")])
4246 (define_insn "truncxf<mode>2_i387_noop"
4247 [(set (match_operand:MODEF 0 "register_operand" "=f")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "f")))]
4250 "TARGET_80387 && flag_unsafe_math_optimizations"
4251 "* return output_387_reg_move (insn, operands);"
4252 [(set_attr "type" "fmov")
4253 (set_attr "mode" "<MODE>")])
4255 (define_insn "*truncxf<mode>2_i387"
4256 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4257 (float_truncate:MODEF
4258 (match_operand:XF 1 "register_operand" "f")))]
4260 "* return output_387_reg_move (insn, operands);"
4261 [(set_attr "type" "fmov")
4262 (set_attr "mode" "<MODE>")])
4265 [(set (match_operand:MODEF 0 "register_operand" "")
4266 (float_truncate:MODEF
4267 (match_operand:XF 1 "register_operand" "")))
4268 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4269 "TARGET_80387 && reload_completed"
4270 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4271 (set (match_dup 0) (match_dup 2))])
4274 [(set (match_operand:MODEF 0 "memory_operand" "")
4275 (float_truncate:MODEF
4276 (match_operand:XF 1 "register_operand" "")))
4277 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4279 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4281 ;; Signed conversion to DImode.
4283 (define_expand "fix_truncxfdi2"
4284 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4285 (fix:DI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>di2"
4297 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4298 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4303 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4311 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to SImode.
4320 (define_expand "fix_truncxfsi2"
4321 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4322 (fix:SI (match_operand:XF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4328 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4333 (define_expand "fix_trunc<mode>si2"
4334 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4335 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4336 (clobber (reg:CC FLAGS_REG))])]
4337 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4340 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4342 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4345 if (SSE_FLOAT_MODE_P (<MODE>mode))
4347 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4348 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4349 if (out != operands[0])
4350 emit_move_insn (operands[0], out);
4355 ;; Signed conversion to HImode.
4357 (define_expand "fix_trunc<mode>hi2"
4358 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4359 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4360 (clobber (reg:CC FLAGS_REG))])]
4362 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4366 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4371 ;; Unsigned conversion to SImode.
4373 (define_expand "fixuns_trunc<mode>si2"
4375 [(set (match_operand:SI 0 "register_operand" "")
4377 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4379 (clobber (match_scratch:<ssevecmode> 3 ""))
4380 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4381 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4383 enum machine_mode mode = <MODE>mode;
4384 enum machine_mode vecmode = <ssevecmode>mode;
4385 REAL_VALUE_TYPE TWO31r;
4388 if (optimize_insn_for_size_p ())
4391 real_ldexp (&TWO31r, &dconst1, 31);
4392 two31 = const_double_from_real_value (TWO31r, mode);
4393 two31 = ix86_build_const_vector (vecmode, true, two31);
4394 operands[2] = force_reg (vecmode, two31);
4397 (define_insn_and_split "*fixuns_trunc<mode>_1"
4398 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4400 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4401 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4402 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4403 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4404 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4405 && optimize_function_for_speed_p (cfun)"
4407 "&& reload_completed"
4410 ix86_split_convert_uns_si_sse (operands);
4414 ;; Unsigned conversion to HImode.
4415 ;; Without these patterns, we'll try the unsigned SI conversion which
4416 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4418 (define_expand "fixuns_trunc<mode>hi2"
4420 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4421 (set (match_operand:HI 0 "nonimmediate_operand" "")
4422 (subreg:HI (match_dup 2) 0))]
4423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4424 "operands[2] = gen_reg_rtx (SImode);")
4426 ;; When SSE is available, it is always faster to use it!
4427 (define_insn "fix_trunc<mode>di_sse"
4428 [(set (match_operand:DI 0 "register_operand" "=r,r")
4429 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4430 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4431 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4432 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4433 [(set_attr "type" "sseicvt")
4434 (set_attr "prefix" "maybe_vex")
4435 (set_attr "prefix_rex" "1")
4436 (set_attr "mode" "<MODE>")
4437 (set_attr "athlon_decode" "double,vector")
4438 (set_attr "amdfam10_decode" "double,double")
4439 (set_attr "bdver1_decode" "double,double")])
4441 (define_insn "fix_trunc<mode>si_sse"
4442 [(set (match_operand:SI 0 "register_operand" "=r,r")
4443 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4444 "SSE_FLOAT_MODE_P (<MODE>mode)
4445 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4446 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4447 [(set_attr "type" "sseicvt")
4448 (set_attr "prefix" "maybe_vex")
4449 (set_attr "mode" "<MODE>")
4450 (set_attr "athlon_decode" "double,vector")
4451 (set_attr "amdfam10_decode" "double,double")
4452 (set_attr "bdver1_decode" "double,double")])
4454 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4456 [(set (match_operand:MODEF 0 "register_operand" "")
4457 (match_operand:MODEF 1 "memory_operand" ""))
4458 (set (match_operand:SWI48x 2 "register_operand" "")
4459 (fix:SWI48x (match_dup 0)))]
4460 "TARGET_SHORTEN_X87_SSE
4461 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4462 && peep2_reg_dead_p (2, operands[0])"
4463 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4465 ;; Avoid vector decoded forms of the instruction.
4467 [(match_scratch:DF 2 "x")
4468 (set (match_operand:SWI48x 0 "register_operand" "")
4469 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4470 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4471 [(set (match_dup 2) (match_dup 1))
4472 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4475 [(match_scratch:SF 2 "x")
4476 (set (match_operand:SWI48x 0 "register_operand" "")
4477 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4478 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4479 [(set (match_dup 2) (match_dup 1))
4480 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4482 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4483 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4484 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (TARGET_64BIT || <MODE>mode != DImode))
4490 && can_create_pseudo_p ()"
4495 if (memory_operand (operands[0], VOIDmode))
4496 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4499 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4500 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4506 [(set_attr "type" "fisttp")
4507 (set_attr "mode" "<MODE>")])
4509 (define_insn "fix_trunc<mode>_i387_fisttp"
4510 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4511 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4512 (clobber (match_scratch:XF 2 "=&1f"))]
4513 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && (TARGET_64BIT || <MODE>mode != DImode))
4517 && TARGET_SSE_MATH)"
4518 "* return output_fix_trunc (insn, operands, true);"
4519 [(set_attr "type" "fisttp")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4523 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4524 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4525 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4526 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && (TARGET_64BIT || <MODE>mode != DImode))
4531 && TARGET_SSE_MATH)"
4533 [(set_attr "type" "fisttp")
4534 (set_attr "mode" "<MODE>")])
4537 [(set (match_operand:SWI248x 0 "register_operand" "")
4538 (fix:SWI248x (match_operand 1 "register_operand" "")))
4539 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4540 (clobber (match_scratch 3 ""))]
4542 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4543 (clobber (match_dup 3))])
4544 (set (match_dup 0) (match_dup 2))])
4547 [(set (match_operand:SWI248x 0 "memory_operand" "")
4548 (fix:SWI248x (match_operand 1 "register_operand" "")))
4549 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4550 (clobber (match_scratch 3 ""))]
4552 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4553 (clobber (match_dup 3))])])
4555 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4556 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4557 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4558 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4559 ;; function in i386.c.
4560 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4561 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4562 (fix:SWI248x (match_operand 1 "register_operand" "")))
4563 (clobber (reg:CC FLAGS_REG))]
4564 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4567 && (TARGET_64BIT || <MODE>mode != DImode))
4568 && can_create_pseudo_p ()"
4573 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4577 if (memory_operand (operands[0], VOIDmode))
4578 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4579 operands[2], operands[3]));
4582 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4583 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4584 operands[2], operands[3],
4589 [(set_attr "type" "fistp")
4590 (set_attr "i387_cw" "trunc")
4591 (set_attr "mode" "<MODE>")])
4593 (define_insn "fix_truncdi_i387"
4594 [(set (match_operand:DI 0 "memory_operand" "=m")
4595 (fix:DI (match_operand 1 "register_operand" "f")))
4596 (use (match_operand:HI 2 "memory_operand" "m"))
4597 (use (match_operand:HI 3 "memory_operand" "m"))
4598 (clobber (match_scratch:XF 4 "=&1f"))]
4599 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602 "* return output_fix_trunc (insn, operands, false);"
4603 [(set_attr "type" "fistp")
4604 (set_attr "i387_cw" "trunc")
4605 (set_attr "mode" "DI")])
4607 (define_insn "fix_truncdi_i387_with_temp"
4608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:DI (match_operand 1 "register_operand" "f,f")))
4610 (use (match_operand:HI 2 "memory_operand" "m,m"))
4611 (use (match_operand:HI 3 "memory_operand" "m,m"))
4612 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4613 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "DI")])
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (fix:DI (match_operand 1 "register_operand" "")))
4625 (use (match_operand:HI 2 "memory_operand" ""))
4626 (use (match_operand:HI 3 "memory_operand" ""))
4627 (clobber (match_operand:DI 4 "memory_operand" ""))
4628 (clobber (match_scratch 5 ""))]
4630 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4633 (clobber (match_dup 5))])
4634 (set (match_dup 0) (match_dup 4))])
4637 [(set (match_operand:DI 0 "memory_operand" "")
4638 (fix:DI (match_operand 1 "register_operand" "")))
4639 (use (match_operand:HI 2 "memory_operand" ""))
4640 (use (match_operand:HI 3 "memory_operand" ""))
4641 (clobber (match_operand:DI 4 "memory_operand" ""))
4642 (clobber (match_scratch 5 ""))]
4644 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4647 (clobber (match_dup 5))])])
4649 (define_insn "fix_trunc<mode>_i387"
4650 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4651 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4652 (use (match_operand:HI 2 "memory_operand" "m"))
4653 (use (match_operand:HI 3 "memory_operand" "m"))]
4654 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4657 "* return output_fix_trunc (insn, operands, false);"
4658 [(set_attr "type" "fistp")
4659 (set_attr "i387_cw" "trunc")
4660 (set_attr "mode" "<MODE>")])
4662 (define_insn "fix_trunc<mode>_i387_with_temp"
4663 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4664 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4665 (use (match_operand:HI 2 "memory_operand" "m,m"))
4666 (use (match_operand:HI 3 "memory_operand" "m,m"))
4667 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4668 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4670 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4672 [(set_attr "type" "fistp")
4673 (set_attr "i387_cw" "trunc")
4674 (set_attr "mode" "<MODE>")])
4677 [(set (match_operand:SWI24 0 "register_operand" "")
4678 (fix:SWI24 (match_operand 1 "register_operand" "")))
4679 (use (match_operand:HI 2 "memory_operand" ""))
4680 (use (match_operand:HI 3 "memory_operand" ""))
4681 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4683 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4685 (use (match_dup 3))])
4686 (set (match_dup 0) (match_dup 4))])
4689 [(set (match_operand:SWI24 0 "memory_operand" "")
4690 (fix:SWI24 (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4695 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4697 (use (match_dup 3))])])
4699 (define_insn "x86_fnstcw_1"
4700 [(set (match_operand:HI 0 "memory_operand" "=m")
4701 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4704 [(set (attr "length")
4705 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4706 (set_attr "mode" "HI")
4707 (set_attr "unit" "i387")
4708 (set_attr "bdver1_decode" "vector")])
4710 (define_insn "x86_fldcw_1"
4711 [(set (reg:HI FPCR_REG)
4712 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4715 [(set (attr "length")
4716 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4717 (set_attr "mode" "HI")
4718 (set_attr "unit" "i387")
4719 (set_attr "athlon_decode" "vector")
4720 (set_attr "amdfam10_decode" "vector")
4721 (set_attr "bdver1_decode" "vector")])
4723 ;; Conversion between fixed point and floating point.
4725 ;; Even though we only accept memory inputs, the backend _really_
4726 ;; wants to be able to do this between registers.
4728 (define_expand "floathi<mode>2"
4729 [(set (match_operand:X87MODEF 0 "register_operand" "")
4730 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4733 || TARGET_MIX_SSE_I387)")
4735 ;; Pre-reload splitter to add memory clobber to the pattern.
4736 (define_insn_and_split "*floathi<mode>2_1"
4737 [(set (match_operand:X87MODEF 0 "register_operand" "")
4738 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741 || TARGET_MIX_SSE_I387)
4742 && can_create_pseudo_p ()"
4745 [(parallel [(set (match_dup 0)
4746 (float:X87MODEF (match_dup 1)))
4747 (clobber (match_dup 2))])]
4748 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4750 (define_insn "*floathi<mode>2_i387_with_temp"
4751 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4752 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4753 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4755 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4756 || TARGET_MIX_SSE_I387)"
4758 [(set_attr "type" "fmov,multi")
4759 (set_attr "mode" "<MODE>")
4760 (set_attr "unit" "*,i387")
4761 (set_attr "fp_int_src" "true")])
4763 (define_insn "*floathi<mode>2_i387"
4764 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4765 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4768 || TARGET_MIX_SSE_I387)"
4770 [(set_attr "type" "fmov")
4771 (set_attr "mode" "<MODE>")
4772 (set_attr "fp_int_src" "true")])
4775 [(set (match_operand:X87MODEF 0 "register_operand" "")
4776 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4777 (clobber (match_operand:HI 2 "memory_operand" ""))]
4779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4780 || TARGET_MIX_SSE_I387)
4781 && reload_completed"
4782 [(set (match_dup 2) (match_dup 1))
4783 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4786 [(set (match_operand:X87MODEF 0 "register_operand" "")
4787 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4788 (clobber (match_operand:HI 2 "memory_operand" ""))]
4790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791 || TARGET_MIX_SSE_I387)
4792 && reload_completed"
4793 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4795 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4796 [(set (match_operand:X87MODEF 0 "register_operand" "")
4798 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4800 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4801 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4803 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4805 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4807 rtx reg = gen_reg_rtx (XFmode);
4808 rtx (*insn)(rtx, rtx);
4810 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4812 if (<X87MODEF:MODE>mode == SFmode)
4813 insn = gen_truncxfsf2;
4814 else if (<X87MODEF:MODE>mode == DFmode)
4815 insn = gen_truncxfdf2;
4819 emit_insn (insn (operands[0], reg));
4824 ;; Pre-reload splitter to add memory clobber to the pattern.
4825 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4826 [(set (match_operand:X87MODEF 0 "register_operand" "")
4827 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4829 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4830 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4831 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4832 || TARGET_MIX_SSE_I387))
4833 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4835 && ((<SWI48x:MODE>mode == SImode
4836 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4837 && optimize_function_for_speed_p (cfun)
4838 && flag_trapping_math)
4839 || !(TARGET_INTER_UNIT_CONVERSIONS
4840 || optimize_function_for_size_p (cfun)))))
4841 && can_create_pseudo_p ()"
4844 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4845 (clobber (match_dup 2))])]
4847 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4849 /* Avoid store forwarding (partial memory) stall penalty
4850 by passing DImode value through XMM registers. */
4851 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4852 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4853 && optimize_function_for_speed_p (cfun))
4855 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4862 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4863 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4865 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4866 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4867 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4868 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4870 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4871 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4872 (set_attr "unit" "*,i387,*,*,*")
4873 (set_attr "athlon_decode" "*,*,double,direct,double")
4874 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4875 (set_attr "bdver1_decode" "*,*,double,direct,double")
4876 (set_attr "fp_int_src" "true")])
4878 (define_insn "*floatsi<mode>2_vector_mixed"
4879 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4880 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4881 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4882 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4886 [(set_attr "type" "fmov,sseicvt")
4887 (set_attr "mode" "<MODE>,<ssevecmode>")
4888 (set_attr "unit" "i387,*")
4889 (set_attr "athlon_decode" "*,direct")
4890 (set_attr "amdfam10_decode" "*,double")
4891 (set_attr "bdver1_decode" "*,direct")
4892 (set_attr "fp_int_src" "true")])
4894 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4895 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4897 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4898 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4899 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4902 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set_attr "unit" "*,i387,*,*")
4905 (set_attr "athlon_decode" "*,*,double,direct")
4906 (set_attr "amdfam10_decode" "*,*,vector,double")
4907 (set_attr "bdver1_decode" "*,*,double,direct")
4908 (set_attr "fp_int_src" "true")])
4911 [(set (match_operand:MODEF 0 "register_operand" "")
4912 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4913 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4914 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4915 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916 && TARGET_INTER_UNIT_CONVERSIONS
4918 && (SSE_REG_P (operands[0])
4919 || (GET_CODE (operands[0]) == SUBREG
4920 && SSE_REG_P (operands[0])))"
4921 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4924 [(set (match_operand:MODEF 0 "register_operand" "")
4925 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4926 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4927 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4928 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4929 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4931 && (SSE_REG_P (operands[0])
4932 || (GET_CODE (operands[0]) == SUBREG
4933 && SSE_REG_P (operands[0])))"
4934 [(set (match_dup 2) (match_dup 1))
4935 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4937 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4938 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4940 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4941 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4942 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4943 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4946 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4947 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4948 [(set_attr "type" "fmov,sseicvt,sseicvt")
4949 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4950 (set_attr "mode" "<MODEF:MODE>")
4951 (set (attr "prefix_rex")
4953 (and (eq_attr "prefix" "maybe_vex")
4954 (match_test "<SWI48x:MODE>mode == DImode"))
4956 (const_string "*")))
4957 (set_attr "unit" "i387,*,*")
4958 (set_attr "athlon_decode" "*,double,direct")
4959 (set_attr "amdfam10_decode" "*,vector,double")
4960 (set_attr "bdver1_decode" "*,double,direct")
4961 (set_attr "fp_int_src" "true")])
4963 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4964 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4966 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4967 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4968 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4969 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4972 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4973 [(set_attr "type" "fmov,sseicvt")
4974 (set_attr "prefix" "orig,maybe_vex")
4975 (set_attr "mode" "<MODEF:MODE>")
4976 (set (attr "prefix_rex")
4978 (and (eq_attr "prefix" "maybe_vex")
4979 (match_test "<SWI48x:MODE>mode == DImode"))
4981 (const_string "*")))
4982 (set_attr "athlon_decode" "*,direct")
4983 (set_attr "amdfam10_decode" "*,double")
4984 (set_attr "bdver1_decode" "*,direct")
4985 (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4988 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4990 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4991 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4992 "TARGET_SSE2 && TARGET_SSE_MATH
4993 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4995 [(set_attr "type" "sseicvt")
4996 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4997 (set_attr "athlon_decode" "double,direct,double")
4998 (set_attr "amdfam10_decode" "vector,double,double")
4999 (set_attr "bdver1_decode" "double,direct,double")
5000 (set_attr "fp_int_src" "true")])
5002 (define_insn "*floatsi<mode>2_vector_sse"
5003 [(set (match_operand:MODEF 0 "register_operand" "=x")
5004 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5005 "TARGET_SSE2 && TARGET_SSE_MATH
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5008 [(set_attr "type" "sseicvt")
5009 (set_attr "mode" "<MODE>")
5010 (set_attr "athlon_decode" "direct")
5011 (set_attr "amdfam10_decode" "double")
5012 (set_attr "bdver1_decode" "direct")
5013 (set_attr "fp_int_src" "true")])
5016 [(set (match_operand:MODEF 0 "register_operand" "")
5017 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5018 (clobber (match_operand:SI 2 "memory_operand" ""))]
5019 "TARGET_SSE2 && TARGET_SSE_MATH
5020 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5022 && (SSE_REG_P (operands[0])
5023 || (GET_CODE (operands[0]) == SUBREG
5024 && SSE_REG_P (operands[0])))"
5027 rtx op1 = operands[1];
5029 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5031 if (GET_CODE (op1) == SUBREG)
5032 op1 = SUBREG_REG (op1);
5034 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5036 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5037 emit_insn (gen_sse2_loadld (operands[4],
5038 CONST0_RTX (V4SImode), operands[1]));
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047 emit_move_insn (operands[2], operands[1]);
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[2]));
5052 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5057 [(set (match_operand:MODEF 0 "register_operand" "")
5058 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5059 (clobber (match_operand:SI 2 "memory_operand" ""))]
5060 "TARGET_SSE2 && TARGET_SSE_MATH
5061 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5063 && (SSE_REG_P (operands[0])
5064 || (GET_CODE (operands[0]) == SUBREG
5065 && SSE_REG_P (operands[0])))"
5068 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5070 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5072 emit_insn (gen_sse2_loadld (operands[4],
5073 CONST0_RTX (V4SImode), operands[1]));
5075 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5080 [(set (match_operand:MODEF 0 "register_operand" "")
5081 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5082 "TARGET_SSE2 && TARGET_SSE_MATH
5083 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5085 && (SSE_REG_P (operands[0])
5086 || (GET_CODE (operands[0]) == SUBREG
5087 && SSE_REG_P (operands[0])))"
5090 rtx op1 = operands[1];
5092 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5094 if (GET_CODE (op1) == SUBREG)
5095 op1 = SUBREG_REG (op1);
5097 if (GENERAL_REG_P (op1))
5099 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5100 if (TARGET_INTER_UNIT_MOVES)
5101 emit_insn (gen_sse2_loadld (operands[4],
5102 CONST0_RTX (V4SImode), operands[1]));
5105 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5107 emit_insn (gen_sse2_loadld (operands[4],
5108 CONST0_RTX (V4SImode), operands[5]));
5109 ix86_free_from_memory (GET_MODE (operands[1]));
5112 /* We can ignore possible trapping value in the
5113 high part of SSE register for non-trapping math. */
5114 else if (SSE_REG_P (op1) && !flag_trapping_math)
5115 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5119 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5124 [(set (match_operand:MODEF 0 "register_operand" "")
5125 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5126 "TARGET_SSE2 && TARGET_SSE_MATH
5127 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5129 && (SSE_REG_P (operands[0])
5130 || (GET_CODE (operands[0]) == SUBREG
5131 && SSE_REG_P (operands[0])))"
5134 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5136 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5138 emit_insn (gen_sse2_loadld (operands[4],
5139 CONST0_RTX (V4SImode), operands[1]));
5141 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5145 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5146 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5148 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5149 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5150 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5151 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5153 [(set_attr "type" "sseicvt")
5154 (set_attr "mode" "<MODEF:MODE>")
5155 (set_attr "athlon_decode" "double,direct")
5156 (set_attr "amdfam10_decode" "vector,double")
5157 (set_attr "bdver1_decode" "double,direct")
5158 (set_attr "fp_int_src" "true")])
5160 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5161 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5163 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5164 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5165 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5167 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5168 [(set_attr "type" "sseicvt")
5169 (set_attr "prefix" "maybe_vex")
5170 (set_attr "mode" "<MODEF:MODE>")
5171 (set (attr "prefix_rex")
5173 (and (eq_attr "prefix" "maybe_vex")
5174 (match_test "<SWI48x:MODE>mode == DImode"))
5176 (const_string "*")))
5177 (set_attr "athlon_decode" "double,direct")
5178 (set_attr "amdfam10_decode" "vector,double")
5179 (set_attr "bdver1_decode" "double,direct")
5180 (set_attr "fp_int_src" "true")])
5183 [(set (match_operand:MODEF 0 "register_operand" "")
5184 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5185 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5186 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5187 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5188 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5190 && (SSE_REG_P (operands[0])
5191 || (GET_CODE (operands[0]) == SUBREG
5192 && SSE_REG_P (operands[0])))"
5193 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5195 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5196 [(set (match_operand:MODEF 0 "register_operand" "=x")
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5199 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5201 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5202 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5203 [(set_attr "type" "sseicvt")
5204 (set_attr "prefix" "maybe_vex")
5205 (set_attr "mode" "<MODEF:MODE>")
5206 (set (attr "prefix_rex")
5208 (and (eq_attr "prefix" "maybe_vex")
5209 (match_test "<SWI48x:MODE>mode == DImode"))
5211 (const_string "*")))
5212 (set_attr "athlon_decode" "direct")
5213 (set_attr "amdfam10_decode" "double")
5214 (set_attr "bdver1_decode" "direct")
5215 (set_attr "fp_int_src" "true")])
5218 [(set (match_operand:MODEF 0 "register_operand" "")
5219 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5220 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5222 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5223 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5225 && (SSE_REG_P (operands[0])
5226 || (GET_CODE (operands[0]) == SUBREG
5227 && SSE_REG_P (operands[0])))"
5228 [(set (match_dup 2) (match_dup 1))
5229 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5232 [(set (match_operand:MODEF 0 "register_operand" "")
5233 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5234 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5235 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5236 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5238 && (SSE_REG_P (operands[0])
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && SSE_REG_P (operands[0])))"
5241 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5243 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5244 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5246 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5247 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5249 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5253 [(set_attr "type" "fmov,multi")
5254 (set_attr "mode" "<X87MODEF:MODE>")
5255 (set_attr "unit" "*,i387")
5256 (set_attr "fp_int_src" "true")])
5258 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5259 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5261 (match_operand:SWI48x 1 "memory_operand" "m")))]
5263 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5265 [(set_attr "type" "fmov")
5266 (set_attr "mode" "<X87MODEF:MODE>")
5267 (set_attr "fp_int_src" "true")])
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5272 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5275 && reload_completed"
5276 [(set (match_dup 2) (match_dup 1))
5277 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5280 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5281 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5282 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5284 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5285 && reload_completed"
5286 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5288 ;; Avoid store forwarding (partial memory) stall penalty
5289 ;; by passing DImode value through XMM registers. */
5291 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5292 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5294 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5295 (clobber (match_scratch:V4SI 3 "=X,x"))
5296 (clobber (match_scratch:V4SI 4 "=X,x"))
5297 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5298 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5300 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5302 [(set_attr "type" "multi")
5303 (set_attr "mode" "<X87MODEF:MODE>")
5304 (set_attr "unit" "i387")
5305 (set_attr "fp_int_src" "true")])
5308 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5309 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5310 (clobber (match_scratch:V4SI 3 ""))
5311 (clobber (match_scratch:V4SI 4 ""))
5312 (clobber (match_operand:DI 2 "memory_operand" ""))]
5313 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5315 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5316 && reload_completed"
5317 [(set (match_dup 2) (match_dup 3))
5318 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5320 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5321 Assemble the 64-bit DImode value in an xmm register. */
5322 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5323 gen_rtx_SUBREG (SImode, operands[1], 0)));
5324 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5325 gen_rtx_SUBREG (SImode, operands[1], 4)));
5326 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5329 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5333 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5334 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5335 (clobber (match_scratch:V4SI 3 ""))
5336 (clobber (match_scratch:V4SI 4 ""))
5337 (clobber (match_operand:DI 2 "memory_operand" ""))]
5338 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5339 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5340 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5341 && reload_completed"
5342 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5344 ;; Avoid store forwarding (partial memory) stall penalty by extending
5345 ;; SImode value to DImode through XMM register instead of pushing two
5346 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5347 ;; targets benefit from this optimization. Also note that fild
5348 ;; loads from memory only.
5350 (define_insn "*floatunssi<mode>2_1"
5351 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5352 (unsigned_float:X87MODEF
5353 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5354 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5355 (clobber (match_scratch:SI 3 "=X,x"))]
5357 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5360 [(set_attr "type" "multi")
5361 (set_attr "mode" "<MODE>")])
5364 [(set (match_operand:X87MODEF 0 "register_operand" "")
5365 (unsigned_float:X87MODEF
5366 (match_operand:SI 1 "register_operand" "")))
5367 (clobber (match_operand:DI 2 "memory_operand" ""))
5368 (clobber (match_scratch:SI 3 ""))]
5370 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5372 && reload_completed"
5373 [(set (match_dup 2) (match_dup 1))
5375 (float:X87MODEF (match_dup 2)))]
5376 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5379 [(set (match_operand:X87MODEF 0 "register_operand" "")
5380 (unsigned_float:X87MODEF
5381 (match_operand:SI 1 "memory_operand" "")))
5382 (clobber (match_operand:DI 2 "memory_operand" ""))
5383 (clobber (match_scratch:SI 3 ""))]
5385 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5387 && reload_completed"
5388 [(set (match_dup 2) (match_dup 3))
5390 (float:X87MODEF (match_dup 2)))]
5392 emit_move_insn (operands[3], operands[1]);
5393 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5396 (define_expand "floatunssi<mode>2"
5398 [(set (match_operand:X87MODEF 0 "register_operand" "")
5399 (unsigned_float:X87MODEF
5400 (match_operand:SI 1 "nonimmediate_operand" "")))
5401 (clobber (match_dup 2))
5402 (clobber (match_scratch:SI 3 ""))])]
5404 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5406 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5408 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5410 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5415 enum ix86_stack_slot slot = (virtuals_instantiated
5418 operands[2] = assign_386_stack_local (DImode, slot);
5422 (define_expand "floatunsdisf2"
5423 [(use (match_operand:SF 0 "register_operand" ""))
5424 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5425 "TARGET_64BIT && TARGET_SSE_MATH"
5426 "x86_emit_floatuns (operands); DONE;")
5428 (define_expand "floatunsdidf2"
5429 [(use (match_operand:DF 0 "register_operand" ""))
5430 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5431 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5432 && TARGET_SSE2 && TARGET_SSE_MATH"
5435 x86_emit_floatuns (operands);
5437 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5443 (define_expand "add<mode>3"
5444 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5445 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5446 (match_operand:SDWIM 2 "<general_operand>" "")))]
5448 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5450 (define_insn_and_split "*add<dwi>3_doubleword"
5451 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5453 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5454 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5455 (clobber (reg:CC FLAGS_REG))]
5456 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5459 [(parallel [(set (reg:CC FLAGS_REG)
5460 (unspec:CC [(match_dup 1) (match_dup 2)]
5463 (plus:DWIH (match_dup 1) (match_dup 2)))])
5464 (parallel [(set (match_dup 3)
5468 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5470 (clobber (reg:CC FLAGS_REG))])]
5471 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5473 (define_insn "*add<mode>3_cc"
5474 [(set (reg:CC FLAGS_REG)
5476 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5477 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5479 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5480 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5481 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5482 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5483 [(set_attr "type" "alu")
5484 (set_attr "mode" "<MODE>")])
5486 (define_insn "addqi3_cc"
5487 [(set (reg:CC FLAGS_REG)
5489 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5490 (match_operand:QI 2 "general_operand" "qn,qm")]
5492 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5493 (plus:QI (match_dup 1) (match_dup 2)))]
5494 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5495 "add{b}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "mode" "QI")])
5499 (define_insn_and_split "*lea_1"
5500 [(set (match_operand:SI 0 "register_operand" "=r")
5501 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5503 "lea{l}\t{%a1, %0|%0, %a1}"
5504 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5507 ix86_split_lea_for_addr (operands, SImode);
5510 [(set_attr "type" "lea")
5511 (set_attr "mode" "SI")])
5513 (define_insn_and_split "*lea<mode>_2"
5514 [(set (match_operand:SWI48 0 "register_operand" "=r")
5515 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5517 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5518 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5521 ix86_split_lea_for_addr (operands, <MODE>mode);
5524 [(set_attr "type" "lea")
5525 (set_attr "mode" "<MODE>")])
5527 (define_insn "*lea_3_zext"
5528 [(set (match_operand:DI 0 "register_operand" "=r")
5530 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5532 "lea{l}\t{%a1, %k0|%k0, %a1}"
5533 [(set_attr "type" "lea")
5534 (set_attr "mode" "SI")])
5536 (define_insn "*lea_4_zext"
5537 [(set (match_operand:DI 0 "register_operand" "=r")
5539 (match_operand:SI 1 "lea_address_operand" "p")))]
5541 "lea{l}\t{%a1, %k0|%k0, %a1}"
5542 [(set_attr "type" "lea")
5543 (set_attr "mode" "SI")])
5545 (define_insn "*lea_5_zext"
5546 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5549 (match_operand:DI 2 "const_32bit_mask" "n")))]
5551 "lea{l}\t{%a1, %k0|%k0, %a1}"
5552 [(set_attr "type" "lea")
5553 (set_attr "mode" "SI")])
5555 (define_insn "*lea_6_zext"
5556 [(set (match_operand:DI 0 "register_operand" "=r")
5558 (match_operand:DI 1 "lea_address_operand" "p")
5559 (match_operand:DI 2 "const_32bit_mask" "n")))]
5561 "lea{l}\t{%a1, %k0|%k0, %a1}"
5562 [(set_attr "type" "lea")
5563 (set_attr "mode" "SI")])
5565 (define_insn "*add<mode>_1"
5566 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5568 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5569 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5570 (clobber (reg:CC FLAGS_REG))]
5571 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5573 switch (get_attr_type (insn))
5579 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5580 if (operands[2] == const1_rtx)
5581 return "inc{<imodesuffix>}\t%0";
5584 gcc_assert (operands[2] == constm1_rtx);
5585 return "dec{<imodesuffix>}\t%0";
5589 /* For most processors, ADD is faster than LEA. This alternative
5590 was added to use ADD as much as possible. */
5591 if (which_alternative == 2)
5594 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5597 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5599 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5601 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5605 (cond [(eq_attr "alternative" "3")
5606 (const_string "lea")
5607 (match_operand:SWI48 2 "incdec_operand" "")
5608 (const_string "incdec")
5610 (const_string "alu")))
5611 (set (attr "length_immediate")
5613 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5615 (const_string "*")))
5616 (set_attr "mode" "<MODE>")])
5618 ;; It may seem that nonimmediate operand is proper one for operand 1.
5619 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5620 ;; we take care in ix86_binary_operator_ok to not allow two memory
5621 ;; operands so proper swapping will be done in reload. This allow
5622 ;; patterns constructed from addsi_1 to match.
5624 (define_insn "addsi_1_zext"
5625 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5627 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5628 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5629 (clobber (reg:CC FLAGS_REG))]
5630 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5632 switch (get_attr_type (insn))
5638 if (operands[2] == const1_rtx)
5639 return "inc{l}\t%k0";
5642 gcc_assert (operands[2] == constm1_rtx);
5643 return "dec{l}\t%k0";
5647 /* For most processors, ADD is faster than LEA. This alternative
5648 was added to use ADD as much as possible. */
5649 if (which_alternative == 1)
5652 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5655 if (x86_maybe_negate_const_int (&operands[2], SImode))
5656 return "sub{l}\t{%2, %k0|%k0, %2}";
5658 return "add{l}\t{%2, %k0|%k0, %2}";
5662 (cond [(eq_attr "alternative" "2")
5663 (const_string "lea")
5664 (match_operand:SI 2 "incdec_operand" "")
5665 (const_string "incdec")
5667 (const_string "alu")))
5668 (set (attr "length_immediate")
5670 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5672 (const_string "*")))
5673 (set_attr "mode" "SI")])
5675 (define_insn "*addhi_1"
5676 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5677 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5678 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5679 (clobber (reg:CC FLAGS_REG))]
5680 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5682 switch (get_attr_type (insn))
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 if (operands[2] == const1_rtx)
5690 return "inc{w}\t%0";
5693 gcc_assert (operands[2] == constm1_rtx);
5694 return "dec{w}\t%0";
5698 /* For most processors, ADD is faster than LEA. This alternative
5699 was added to use ADD as much as possible. */
5700 if (which_alternative == 2)
5703 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 if (x86_maybe_negate_const_int (&operands[2], HImode))
5708 return "sub{w}\t{%2, %0|%0, %2}";
5710 return "add{w}\t{%2, %0|%0, %2}";
5714 (cond [(eq_attr "alternative" "3")
5715 (const_string "lea")
5716 (match_operand:HI 2 "incdec_operand" "")
5717 (const_string "incdec")
5719 (const_string "alu")))
5720 (set (attr "length_immediate")
5722 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5724 (const_string "*")))
5725 (set_attr "mode" "HI,HI,HI,SI")])
5727 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5728 (define_insn "*addqi_1"
5729 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5730 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5731 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5732 (clobber (reg:CC FLAGS_REG))]
5733 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5735 bool widen = (which_alternative == 3 || which_alternative == 4);
5737 switch (get_attr_type (insn))
5743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744 if (operands[2] == const1_rtx)
5745 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5748 gcc_assert (operands[2] == constm1_rtx);
5749 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5753 /* For most processors, ADD is faster than LEA. These alternatives
5754 were added to use ADD as much as possible. */
5755 if (which_alternative == 2 || which_alternative == 4)
5758 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5762 if (x86_maybe_negate_const_int (&operands[2], QImode))
5765 return "sub{l}\t{%2, %k0|%k0, %2}";
5767 return "sub{b}\t{%2, %0|%0, %2}";
5770 return "add{l}\t{%k2, %k0|%k0, %k2}";
5772 return "add{b}\t{%2, %0|%0, %2}";
5776 (cond [(eq_attr "alternative" "5")
5777 (const_string "lea")
5778 (match_operand:QI 2 "incdec_operand" "")
5779 (const_string "incdec")
5781 (const_string "alu")))
5782 (set (attr "length_immediate")
5784 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5786 (const_string "*")))
5787 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5789 (define_insn "*addqi_1_slp"
5790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5791 (plus:QI (match_dup 0)
5792 (match_operand:QI 1 "general_operand" "qn,qm")))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5797 switch (get_attr_type (insn))
5800 if (operands[1] == const1_rtx)
5801 return "inc{b}\t%0";
5804 gcc_assert (operands[1] == constm1_rtx);
5805 return "dec{b}\t%0";
5809 if (x86_maybe_negate_const_int (&operands[1], QImode))
5810 return "sub{b}\t{%1, %0|%0, %1}";
5812 return "add{b}\t{%1, %0|%0, %1}";
5816 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5817 (const_string "incdec")
5818 (const_string "alu1")))
5819 (set (attr "memory")
5820 (if_then_else (match_operand 1 "memory_operand" "")
5821 (const_string "load")
5822 (const_string "none")))
5823 (set_attr "mode" "QI")])
5825 ;; Split non destructive adds if we cannot use lea.
5827 [(set (match_operand:SWI48 0 "register_operand" "")
5828 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5829 (match_operand:SWI48 2 "nonmemory_operand" "")))
5830 (clobber (reg:CC FLAGS_REG))]
5831 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5832 [(set (match_dup 0) (match_dup 1))
5833 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5834 (clobber (reg:CC FLAGS_REG))])])
5836 ;; Convert add to the lea pattern to avoid flags dependency.
5838 [(set (match_operand:SWI 0 "register_operand" "")
5839 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5840 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5841 (clobber (reg:CC FLAGS_REG))]
5842 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5845 enum machine_mode mode = <MODE>mode;
5848 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5851 operands[0] = gen_lowpart (mode, operands[0]);
5852 operands[1] = gen_lowpart (mode, operands[1]);
5853 operands[2] = gen_lowpart (mode, operands[2]);
5856 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5858 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5862 ;; Convert add to the lea pattern to avoid flags dependency.
5864 [(set (match_operand:DI 0 "register_operand" "")
5866 (plus:SI (match_operand:SI 1 "register_operand" "")
5867 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5868 (clobber (reg:CC FLAGS_REG))]
5869 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5871 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5873 (define_insn "*add<mode>_2"
5874 [(set (reg FLAGS_REG)
5877 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5878 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5880 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5881 (plus:SWI (match_dup 1) (match_dup 2)))]
5882 "ix86_match_ccmode (insn, CCGOCmode)
5883 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5885 switch (get_attr_type (insn))
5888 if (operands[2] == const1_rtx)
5889 return "inc{<imodesuffix>}\t%0";
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return "dec{<imodesuffix>}\t%0";
5897 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5898 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5900 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5904 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu")))
5907 (set (attr "length_immediate")
5909 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5911 (const_string "*")))
5912 (set_attr "mode" "<MODE>")])
5914 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5915 (define_insn "*addsi_2_zext"
5916 [(set (reg FLAGS_REG)
5918 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5919 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5921 (set (match_operand:DI 0 "register_operand" "=r")
5922 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5923 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5924 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5926 switch (get_attr_type (insn))
5929 if (operands[2] == const1_rtx)
5930 return "inc{l}\t%k0";
5933 gcc_assert (operands[2] == constm1_rtx);
5934 return "dec{l}\t%k0";
5938 if (x86_maybe_negate_const_int (&operands[2], SImode))
5939 return "sub{l}\t{%2, %k0|%k0, %2}";
5941 return "add{l}\t{%2, %k0|%k0, %2}";
5945 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set (attr "length_immediate")
5950 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5952 (const_string "*")))
5953 (set_attr "mode" "SI")])
5955 (define_insn "*add<mode>_3"
5956 [(set (reg FLAGS_REG)
5958 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5959 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5960 (clobber (match_scratch:SWI 0 "=<r>"))]
5961 "ix86_match_ccmode (insn, CCZmode)
5962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5964 switch (get_attr_type (insn))
5967 if (operands[2] == const1_rtx)
5968 return "inc{<imodesuffix>}\t%0";
5971 gcc_assert (operands[2] == constm1_rtx);
5972 return "dec{<imodesuffix>}\t%0";
5976 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5977 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5979 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5983 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu")))
5986 (set (attr "length_immediate")
5988 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5990 (const_string "*")))
5991 (set_attr "mode" "<MODE>")])
5993 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5994 (define_insn "*addsi_3_zext"
5995 [(set (reg FLAGS_REG)
5997 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5998 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5999 (set (match_operand:DI 0 "register_operand" "=r")
6000 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6001 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6002 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6004 switch (get_attr_type (insn))
6007 if (operands[2] == const1_rtx)
6008 return "inc{l}\t%k0";
6011 gcc_assert (operands[2] == constm1_rtx);
6012 return "dec{l}\t%k0";
6016 if (x86_maybe_negate_const_int (&operands[2], SImode))
6017 return "sub{l}\t{%2, %k0|%k0, %2}";
6019 return "add{l}\t{%2, %k0|%k0, %2}";
6023 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set (attr "length_immediate")
6028 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6030 (const_string "*")))
6031 (set_attr "mode" "SI")])
6033 ; For comparisons against 1, -1 and 128, we may generate better code
6034 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6035 ; is matched then. We can't accept general immediate, because for
6036 ; case of overflows, the result is messed up.
6037 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6038 ; only for comparisons not depending on it.
6040 (define_insn "*adddi_4"
6041 [(set (reg FLAGS_REG)
6043 (match_operand:DI 1 "nonimmediate_operand" "0")
6044 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6045 (clobber (match_scratch:DI 0 "=rm"))]
6047 && ix86_match_ccmode (insn, CCGCmode)"
6049 switch (get_attr_type (insn))
6052 if (operands[2] == constm1_rtx)
6053 return "inc{q}\t%0";
6056 gcc_assert (operands[2] == const1_rtx);
6057 return "dec{q}\t%0";
6061 if (x86_maybe_negate_const_int (&operands[2], DImode))
6062 return "add{q}\t{%2, %0|%0, %2}";
6064 return "sub{q}\t{%2, %0|%0, %2}";
6068 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6069 (const_string "incdec")
6070 (const_string "alu")))
6071 (set (attr "length_immediate")
6073 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6075 (const_string "*")))
6076 (set_attr "mode" "DI")])
6078 ; For comparisons against 1, -1 and 128, we may generate better code
6079 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6080 ; is matched then. We can't accept general immediate, because for
6081 ; case of overflows, the result is messed up.
6082 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6083 ; only for comparisons not depending on it.
6085 (define_insn "*add<mode>_4"
6086 [(set (reg FLAGS_REG)
6088 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6089 (match_operand:SWI124 2 "const_int_operand" "n")))
6090 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6091 "ix86_match_ccmode (insn, CCGCmode)"
6093 switch (get_attr_type (insn))
6096 if (operands[2] == constm1_rtx)
6097 return "inc{<imodesuffix>}\t%0";
6100 gcc_assert (operands[2] == const1_rtx);
6101 return "dec{<imodesuffix>}\t%0";
6105 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6106 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6108 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6112 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6113 (const_string "incdec")
6114 (const_string "alu")))
6115 (set (attr "length_immediate")
6117 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6119 (const_string "*")))
6120 (set_attr "mode" "<MODE>")])
6122 (define_insn "*add<mode>_5"
6123 [(set (reg FLAGS_REG)
6126 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6127 (match_operand:SWI 2 "<general_operand>" "<g>"))
6129 (clobber (match_scratch:SWI 0 "=<r>"))]
6130 "ix86_match_ccmode (insn, CCGOCmode)
6131 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6133 switch (get_attr_type (insn))
6136 if (operands[2] == const1_rtx)
6137 return "inc{<imodesuffix>}\t%0";
6140 gcc_assert (operands[2] == constm1_rtx);
6141 return "dec{<imodesuffix>}\t%0";
6145 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6146 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6148 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6152 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set (attr "length_immediate")
6157 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6159 (const_string "*")))
6160 (set_attr "mode" "<MODE>")])
6162 (define_insn "*addqi_ext_1_rex64"
6163 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6168 (match_operand 1 "ext_register_operand" "0")
6171 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6172 (clobber (reg:CC FLAGS_REG))]
6175 switch (get_attr_type (insn))
6178 if (operands[2] == const1_rtx)
6179 return "inc{b}\t%h0";
6182 gcc_assert (operands[2] == constm1_rtx);
6183 return "dec{b}\t%h0";
6187 return "add{b}\t{%2, %h0|%h0, %2}";
6191 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6192 (const_string "incdec")
6193 (const_string "alu")))
6194 (set_attr "modrm" "1")
6195 (set_attr "mode" "QI")])
6197 (define_insn "addqi_ext_1"
6198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6203 (match_operand 1 "ext_register_operand" "0")
6206 (match_operand:QI 2 "general_operand" "Qmn")))
6207 (clobber (reg:CC FLAGS_REG))]
6210 switch (get_attr_type (insn))
6213 if (operands[2] == const1_rtx)
6214 return "inc{b}\t%h0";
6217 gcc_assert (operands[2] == constm1_rtx);
6218 return "dec{b}\t%h0";
6222 return "add{b}\t{%2, %h0|%h0, %2}";
6226 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6227 (const_string "incdec")
6228 (const_string "alu")))
6229 (set_attr "modrm" "1")
6230 (set_attr "mode" "QI")])
6232 (define_insn "*addqi_ext_2"
6233 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6238 (match_operand 1 "ext_register_operand" "%0")
6242 (match_operand 2 "ext_register_operand" "Q")
6245 (clobber (reg:CC FLAGS_REG))]
6247 "add{b}\t{%h2, %h0|%h0, %h2}"
6248 [(set_attr "type" "alu")
6249 (set_attr "mode" "QI")])
6251 ;; The lea patterns for modes less than 32 bits need to be matched by
6252 ;; several insns converted to real lea by splitters.
6254 (define_insn_and_split "*lea_general_1"
6255 [(set (match_operand 0 "register_operand" "=r")
6256 (plus (plus (match_operand 1 "index_register_operand" "l")
6257 (match_operand 2 "register_operand" "r"))
6258 (match_operand 3 "immediate_operand" "i")))]
6259 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6260 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6261 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6262 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6263 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6264 || GET_MODE (operands[3]) == VOIDmode)"
6266 "&& reload_completed"
6269 enum machine_mode mode = SImode;
6272 operands[0] = gen_lowpart (mode, operands[0]);
6273 operands[1] = gen_lowpart (mode, operands[1]);
6274 operands[2] = gen_lowpart (mode, operands[2]);
6275 operands[3] = gen_lowpart (mode, operands[3]);
6277 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_2"
6287 [(set (match_operand 0 "register_operand" "=r")
6288 (plus (mult (match_operand 1 "index_register_operand" "l")
6289 (match_operand 2 "const248_operand" "n"))
6290 (match_operand 3 "nonmemory_operand" "ri")))]
6291 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6292 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6293 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6294 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6295 || GET_MODE (operands[3]) == VOIDmode)"
6297 "&& reload_completed"
6300 enum machine_mode mode = SImode;
6303 operands[0] = gen_lowpart (mode, operands[0]);
6304 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[3] = gen_lowpart (mode, operands[3]);
6307 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6310 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6313 [(set_attr "type" "lea")
6314 (set_attr "mode" "SI")])
6316 (define_insn_and_split "*lea_general_3"
6317 [(set (match_operand 0 "register_operand" "=r")
6318 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6319 (match_operand 2 "const248_operand" "n"))
6320 (match_operand 3 "register_operand" "r"))
6321 (match_operand 4 "immediate_operand" "i")))]
6322 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6323 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6324 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6325 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6327 "&& reload_completed"
6330 enum machine_mode mode = SImode;
6333 operands[0] = gen_lowpart (mode, operands[0]);
6334 operands[1] = gen_lowpart (mode, operands[1]);
6335 operands[3] = gen_lowpart (mode, operands[3]);
6336 operands[4] = gen_lowpart (mode, operands[4]);
6338 pat = gen_rtx_PLUS (mode,
6340 gen_rtx_MULT (mode, operands[1],
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6348 [(set_attr "type" "lea")
6349 (set_attr "mode" "SI")])
6351 (define_insn_and_split "*lea_general_4"
6352 [(set (match_operand 0 "register_operand" "=r")
6354 (match_operand 1 "index_register_operand" "l")
6355 (match_operand 2 "const_int_operand" "n"))
6356 (match_operand 3 "const_int_operand" "n")))]
6357 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6359 || GET_MODE (operands[0]) == SImode
6360 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6361 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6362 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6363 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6364 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6366 "&& reload_completed"
6369 enum machine_mode mode = GET_MODE (operands[0]);
6372 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6375 operands[0] = gen_lowpart (mode, operands[0]);
6376 operands[1] = gen_lowpart (mode, operands[1]);
6379 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6381 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6382 INTVAL (operands[3]));
6384 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6387 [(set_attr "type" "lea")
6389 (if_then_else (match_operand:DI 0 "" "")
6391 (const_string "SI")))])
6393 ;; Subtract instructions
6395 (define_expand "sub<mode>3"
6396 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6397 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6398 (match_operand:SDWIM 2 "<general_operand>" "")))]
6400 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6402 (define_insn_and_split "*sub<dwi>3_doubleword"
6403 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6405 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6406 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6407 (clobber (reg:CC FLAGS_REG))]
6408 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6411 [(parallel [(set (reg:CC FLAGS_REG)
6412 (compare:CC (match_dup 1) (match_dup 2)))
6414 (minus:DWIH (match_dup 1) (match_dup 2)))])
6415 (parallel [(set (match_dup 3)
6419 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6421 (clobber (reg:CC FLAGS_REG))])]
6422 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6424 (define_insn "*sub<mode>_1"
6425 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6427 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6428 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6431 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "<MODE>")])
6435 (define_insn "*subsi_1_zext"
6436 [(set (match_operand:DI 0 "register_operand" "=r")
6438 (minus:SI (match_operand:SI 1 "register_operand" "0")
6439 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6440 (clobber (reg:CC FLAGS_REG))]
6441 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6442 "sub{l}\t{%2, %k0|%k0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "SI")])
6446 (define_insn "*subqi_1_slp"
6447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6448 (minus:QI (match_dup 0)
6449 (match_operand:QI 1 "general_operand" "qn,qm")))
6450 (clobber (reg:CC FLAGS_REG))]
6451 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6453 "sub{b}\t{%1, %0|%0, %1}"
6454 [(set_attr "type" "alu1")
6455 (set_attr "mode" "QI")])
6457 (define_insn "*sub<mode>_2"
6458 [(set (reg FLAGS_REG)
6461 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6462 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6464 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6465 (minus:SWI (match_dup 1) (match_dup 2)))]
6466 "ix86_match_ccmode (insn, CCGOCmode)
6467 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "<MODE>")])
6472 (define_insn "*subsi_2_zext"
6473 [(set (reg FLAGS_REG)
6475 (minus:SI (match_operand:SI 1 "register_operand" "0")
6476 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6478 (set (match_operand:DI 0 "register_operand" "=r")
6480 (minus:SI (match_dup 1)
6482 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6483 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6484 "sub{l}\t{%2, %k0|%k0, %2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "mode" "SI")])
6488 (define_insn "*sub<mode>_3"
6489 [(set (reg FLAGS_REG)
6490 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6491 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6492 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6493 (minus:SWI (match_dup 1) (match_dup 2)))]
6494 "ix86_match_ccmode (insn, CCmode)
6495 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6496 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6497 [(set_attr "type" "alu")
6498 (set_attr "mode" "<MODE>")])
6500 (define_insn "*subsi_3_zext"
6501 [(set (reg FLAGS_REG)
6502 (compare (match_operand:SI 1 "register_operand" "0")
6503 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6504 (set (match_operand:DI 0 "register_operand" "=r")
6506 (minus:SI (match_dup 1)
6508 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6509 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6510 "sub{l}\t{%2, %1|%1, %2}"
6511 [(set_attr "type" "alu")
6512 (set_attr "mode" "SI")])
6514 ;; Add with carry and subtract with borrow
6516 (define_expand "<plusminus_insn><mode>3_carry"
6518 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6520 (match_operand:SWI 1 "nonimmediate_operand" "")
6521 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6522 [(match_operand 3 "flags_reg_operand" "")
6524 (match_operand:SWI 2 "<general_operand>" ""))))
6525 (clobber (reg:CC FLAGS_REG))])]
6526 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6528 (define_insn "*<plusminus_insn><mode>3_carry"
6529 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6531 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6533 (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6538 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "use_carry" "1")
6541 (set_attr "pent_pair" "pu")
6542 (set_attr "mode" "<MODE>")])
6544 (define_insn "*addsi3_carry_zext"
6545 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6548 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6549 [(reg FLAGS_REG) (const_int 0)])
6550 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6553 "adc{l}\t{%2, %k0|%k0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "use_carry" "1")
6556 (set_attr "pent_pair" "pu")
6557 (set_attr "mode" "SI")])
6559 (define_insn "*subsi3_carry_zext"
6560 [(set (match_operand:DI 0 "register_operand" "=r")
6562 (minus:SI (match_operand:SI 1 "register_operand" "0")
6563 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6564 [(reg FLAGS_REG) (const_int 0)])
6565 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6566 (clobber (reg:CC FLAGS_REG))]
6567 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6568 "sbb{l}\t{%2, %k0|%k0, %2}"
6569 [(set_attr "type" "alu")
6570 (set_attr "pent_pair" "pu")
6571 (set_attr "mode" "SI")])
6573 ;; Overflow setting add and subtract instructions
6575 (define_insn "*add<mode>3_cconly_overflow"
6576 [(set (reg:CCC FLAGS_REG)
6579 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6580 (match_operand:SWI 2 "<general_operand>" "<g>"))
6582 (clobber (match_scratch:SWI 0 "=<r>"))]
6583 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6584 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "mode" "<MODE>")])
6588 (define_insn "*sub<mode>3_cconly_overflow"
6589 [(set (reg:CCC FLAGS_REG)
6592 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6593 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6596 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6597 [(set_attr "type" "icmp")
6598 (set_attr "mode" "<MODE>")])
6600 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6601 [(set (reg:CCC FLAGS_REG)
6604 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6605 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6607 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6609 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6610 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "mode" "<MODE>")])
6614 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6615 [(set (reg:CCC FLAGS_REG)
6618 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6619 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6621 (set (match_operand:DI 0 "register_operand" "=r")
6622 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6623 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6624 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "SI")])
6628 ;; The patterns that match these are at the end of this file.
6630 (define_expand "<plusminus_insn>xf3"
6631 [(set (match_operand:XF 0 "register_operand" "")
6633 (match_operand:XF 1 "register_operand" "")
6634 (match_operand:XF 2 "register_operand" "")))]
6637 (define_expand "<plusminus_insn><mode>3"
6638 [(set (match_operand:MODEF 0 "register_operand" "")
6640 (match_operand:MODEF 1 "register_operand" "")
6641 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6642 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6643 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6645 ;; Multiply instructions
6647 (define_expand "mul<mode>3"
6648 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6650 (match_operand:SWIM248 1 "register_operand" "")
6651 (match_operand:SWIM248 2 "<general_operand>" "")))
6652 (clobber (reg:CC FLAGS_REG))])])
6654 (define_expand "mulqi3"
6655 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6657 (match_operand:QI 1 "register_operand" "")
6658 (match_operand:QI 2 "nonimmediate_operand" "")))
6659 (clobber (reg:CC FLAGS_REG))])]
6660 "TARGET_QIMODE_MATH")
6663 ;; IMUL reg32/64, reg32/64, imm8 Direct
6664 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6665 ;; IMUL reg32/64, reg32/64, imm32 Direct
6666 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6667 ;; IMUL reg32/64, reg32/64 Direct
6668 ;; IMUL reg32/64, mem32/64 Direct
6670 ;; On BDVER1, all above IMULs use DirectPath
6672 (define_insn "*mul<mode>3_1"
6673 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6675 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6676 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6677 (clobber (reg:CC FLAGS_REG))]
6678 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6680 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6681 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6682 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6683 [(set_attr "type" "imul")
6684 (set_attr "prefix_0f" "0,0,1")
6685 (set (attr "athlon_decode")
6686 (cond [(eq_attr "cpu" "athlon")
6687 (const_string "vector")
6688 (eq_attr "alternative" "1")
6689 (const_string "vector")
6690 (and (eq_attr "alternative" "2")
6691 (match_operand 1 "memory_operand" ""))
6692 (const_string "vector")]
6693 (const_string "direct")))
6694 (set (attr "amdfam10_decode")
6695 (cond [(and (eq_attr "alternative" "0,1")
6696 (match_operand 1 "memory_operand" ""))
6697 (const_string "vector")]
6698 (const_string "direct")))
6699 (set_attr "bdver1_decode" "direct")
6700 (set_attr "mode" "<MODE>")])
6702 (define_insn "*mulsi3_1_zext"
6703 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6705 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6706 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6707 (clobber (reg:CC FLAGS_REG))]
6709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6711 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6713 imul{l}\t{%2, %k0|%k0, %2}"
6714 [(set_attr "type" "imul")
6715 (set_attr "prefix_0f" "0,0,1")
6716 (set (attr "athlon_decode")
6717 (cond [(eq_attr "cpu" "athlon")
6718 (const_string "vector")
6719 (eq_attr "alternative" "1")
6720 (const_string "vector")
6721 (and (eq_attr "alternative" "2")
6722 (match_operand 1 "memory_operand" ""))
6723 (const_string "vector")]
6724 (const_string "direct")))
6725 (set (attr "amdfam10_decode")
6726 (cond [(and (eq_attr "alternative" "0,1")
6727 (match_operand 1 "memory_operand" ""))
6728 (const_string "vector")]
6729 (const_string "direct")))
6730 (set_attr "bdver1_decode" "direct")
6731 (set_attr "mode" "SI")])
6734 ;; IMUL reg16, reg16, imm8 VectorPath
6735 ;; IMUL reg16, mem16, imm8 VectorPath
6736 ;; IMUL reg16, reg16, imm16 VectorPath
6737 ;; IMUL reg16, mem16, imm16 VectorPath
6738 ;; IMUL reg16, reg16 Direct
6739 ;; IMUL reg16, mem16 Direct
6741 ;; On BDVER1, all HI MULs use DoublePath
6743 (define_insn "*mulhi3_1"
6744 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6745 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6746 (match_operand:HI 2 "general_operand" "K,n,mr")))
6747 (clobber (reg:CC FLAGS_REG))]
6749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 imul{w}\t{%2, %1, %0|%0, %1, %2}
6752 imul{w}\t{%2, %1, %0|%0, %1, %2}
6753 imul{w}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "imul")
6755 (set_attr "prefix_0f" "0,0,1")
6756 (set (attr "athlon_decode")
6757 (cond [(eq_attr "cpu" "athlon")
6758 (const_string "vector")
6759 (eq_attr "alternative" "1,2")
6760 (const_string "vector")]
6761 (const_string "direct")))
6762 (set (attr "amdfam10_decode")
6763 (cond [(eq_attr "alternative" "0,1")
6764 (const_string "vector")]
6765 (const_string "direct")))
6766 (set_attr "bdver1_decode" "double")
6767 (set_attr "mode" "HI")])
6769 ;;On AMDFAM10 and BDVER1
6773 (define_insn "*mulqi3_1"
6774 [(set (match_operand:QI 0 "register_operand" "=a")
6775 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6776 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6777 (clobber (reg:CC FLAGS_REG))]
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781 [(set_attr "type" "imul")
6782 (set_attr "length_immediate" "0")
6783 (set (attr "athlon_decode")
6784 (if_then_else (eq_attr "cpu" "athlon")
6785 (const_string "vector")
6786 (const_string "direct")))
6787 (set_attr "amdfam10_decode" "direct")
6788 (set_attr "bdver1_decode" "direct")
6789 (set_attr "mode" "QI")])
6791 (define_expand "<u>mul<mode><dwi>3"
6792 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6795 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6797 (match_operand:DWIH 2 "register_operand" ""))))
6798 (clobber (reg:CC FLAGS_REG))])])
6800 (define_expand "<u>mulqihi3"
6801 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6804 (match_operand:QI 1 "nonimmediate_operand" ""))
6806 (match_operand:QI 2 "register_operand" ""))))
6807 (clobber (reg:CC FLAGS_REG))])]
6808 "TARGET_QIMODE_MATH")
6810 (define_insn "*bmi2_umulditi3_1"
6811 [(set (match_operand:DI 0 "register_operand" "=r")
6813 (match_operand:DI 2 "nonimmediate_operand" "%d")
6814 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6815 (set (match_operand:DI 1 "register_operand" "=r")
6818 (mult:TI (zero_extend:TI (match_dup 2))
6819 (zero_extend:TI (match_dup 3)))
6821 "TARGET_64BIT && TARGET_BMI2
6822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823 "mulx\t{%3, %0, %1|%1, %0, %3}"
6824 [(set_attr "type" "imulx")
6825 (set_attr "prefix" "vex")
6826 (set_attr "mode" "DI")])
6828 (define_insn "*bmi2_umulsidi3_1"
6829 [(set (match_operand:SI 0 "register_operand" "=r")
6831 (match_operand:SI 2 "nonimmediate_operand" "%d")
6832 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6833 (set (match_operand:SI 1 "register_operand" "=r")
6836 (mult:DI (zero_extend:DI (match_dup 2))
6837 (zero_extend:DI (match_dup 3)))
6839 "!TARGET_64BIT && TARGET_BMI2
6840 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 "mulx\t{%3, %0, %1|%1, %0, %3}"
6842 [(set_attr "type" "imulx")
6843 (set_attr "prefix" "vex")
6844 (set_attr "mode" "SI")])
6846 (define_insn "*umul<mode><dwi>3_1"
6847 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6850 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6852 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6853 (clobber (reg:CC FLAGS_REG))]
6854 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 mul{<imodesuffix>}\t%2
6858 [(set_attr "isa" "*,bmi2")
6859 (set_attr "type" "imul,imulx")
6860 (set_attr "length_immediate" "0,*")
6861 (set (attr "athlon_decode")
6862 (cond [(eq_attr "alternative" "0")
6863 (if_then_else (eq_attr "cpu" "athlon")
6864 (const_string "vector")
6865 (const_string "double"))]
6866 (const_string "*")))
6867 (set_attr "amdfam10_decode" "double,*")
6868 (set_attr "bdver1_decode" "direct,*")
6869 (set_attr "prefix" "orig,vex")
6870 (set_attr "mode" "<MODE>")])
6872 ;; Convert mul to the mulx pattern to avoid flags dependency.
6874 [(set (match_operand:<DWI> 0 "register_operand" "")
6877 (match_operand:DWIH 1 "register_operand" ""))
6879 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6880 (clobber (reg:CC FLAGS_REG))]
6881 "TARGET_BMI2 && reload_completed
6882 && true_regnum (operands[1]) == DX_REG"
6883 [(parallel [(set (match_dup 3)
6884 (mult:DWIH (match_dup 1) (match_dup 2)))
6888 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6889 (zero_extend:<DWI> (match_dup 2)))
6892 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6894 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6897 (define_insn "*mul<mode><dwi>3_1"
6898 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6901 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6903 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6904 (clobber (reg:CC FLAGS_REG))]
6905 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906 "imul{<imodesuffix>}\t%2"
6907 [(set_attr "type" "imul")
6908 (set_attr "length_immediate" "0")
6909 (set (attr "athlon_decode")
6910 (if_then_else (eq_attr "cpu" "athlon")
6911 (const_string "vector")
6912 (const_string "double")))
6913 (set_attr "amdfam10_decode" "double")
6914 (set_attr "bdver1_decode" "direct")
6915 (set_attr "mode" "<MODE>")])
6917 (define_insn "*<u>mulqihi3_1"
6918 [(set (match_operand:HI 0 "register_operand" "=a")
6921 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6923 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6924 (clobber (reg:CC FLAGS_REG))]
6926 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6927 "<sgnprefix>mul{b}\t%2"
6928 [(set_attr "type" "imul")
6929 (set_attr "length_immediate" "0")
6930 (set (attr "athlon_decode")
6931 (if_then_else (eq_attr "cpu" "athlon")
6932 (const_string "vector")
6933 (const_string "direct")))
6934 (set_attr "amdfam10_decode" "direct")
6935 (set_attr "bdver1_decode" "direct")
6936 (set_attr "mode" "QI")])
6938 (define_expand "<s>mul<mode>3_highpart"
6939 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6944 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6946 (match_operand:SWI48 2 "register_operand" "")))
6948 (clobber (match_scratch:SWI48 3 ""))
6949 (clobber (reg:CC FLAGS_REG))])]
6951 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6953 (define_insn "*<s>muldi3_highpart_1"
6954 [(set (match_operand:DI 0 "register_operand" "=d")
6959 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6961 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6963 (clobber (match_scratch:DI 3 "=1"))
6964 (clobber (reg:CC FLAGS_REG))]
6966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 "<sgnprefix>mul{q}\t%2"
6968 [(set_attr "type" "imul")
6969 (set_attr "length_immediate" "0")
6970 (set (attr "athlon_decode")
6971 (if_then_else (eq_attr "cpu" "athlon")
6972 (const_string "vector")
6973 (const_string "double")))
6974 (set_attr "amdfam10_decode" "double")
6975 (set_attr "bdver1_decode" "direct")
6976 (set_attr "mode" "DI")])
6978 (define_insn "*<s>mulsi3_highpart_1"
6979 [(set (match_operand:SI 0 "register_operand" "=d")
6984 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6986 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6988 (clobber (match_scratch:SI 3 "=1"))
6989 (clobber (reg:CC FLAGS_REG))]
6990 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991 "<sgnprefix>mul{l}\t%2"
6992 [(set_attr "type" "imul")
6993 (set_attr "length_immediate" "0")
6994 (set (attr "athlon_decode")
6995 (if_then_else (eq_attr "cpu" "athlon")
6996 (const_string "vector")
6997 (const_string "double")))
6998 (set_attr "amdfam10_decode" "double")
6999 (set_attr "bdver1_decode" "direct")
7000 (set_attr "mode" "SI")])
7002 (define_insn "*<s>mulsi3_highpart_zext"
7003 [(set (match_operand:DI 0 "register_operand" "=d")
7004 (zero_extend:DI (truncate:SI
7006 (mult:DI (any_extend:DI
7007 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7009 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7011 (clobber (match_scratch:SI 3 "=1"))
7012 (clobber (reg:CC FLAGS_REG))]
7014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7015 "<sgnprefix>mul{l}\t%2"
7016 [(set_attr "type" "imul")
7017 (set_attr "length_immediate" "0")
7018 (set (attr "athlon_decode")
7019 (if_then_else (eq_attr "cpu" "athlon")
7020 (const_string "vector")
7021 (const_string "double")))
7022 (set_attr "amdfam10_decode" "double")
7023 (set_attr "bdver1_decode" "direct")
7024 (set_attr "mode" "SI")])
7026 ;; The patterns that match these are at the end of this file.
7028 (define_expand "mulxf3"
7029 [(set (match_operand:XF 0 "register_operand" "")
7030 (mult:XF (match_operand:XF 1 "register_operand" "")
7031 (match_operand:XF 2 "register_operand" "")))]
7034 (define_expand "mul<mode>3"
7035 [(set (match_operand:MODEF 0 "register_operand" "")
7036 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7037 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7038 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7039 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7041 ;; Divide instructions
7043 ;; The patterns that match these are at the end of this file.
7045 (define_expand "divxf3"
7046 [(set (match_operand:XF 0 "register_operand" "")
7047 (div:XF (match_operand:XF 1 "register_operand" "")
7048 (match_operand:XF 2 "register_operand" "")))]
7051 (define_expand "divdf3"
7052 [(set (match_operand:DF 0 "register_operand" "")
7053 (div:DF (match_operand:DF 1 "register_operand" "")
7054 (match_operand:DF 2 "nonimmediate_operand" "")))]
7055 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7056 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7058 (define_expand "divsf3"
7059 [(set (match_operand:SF 0 "register_operand" "")
7060 (div:SF (match_operand:SF 1 "register_operand" "")
7061 (match_operand:SF 2 "nonimmediate_operand" "")))]
7062 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7065 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7066 && flag_finite_math_only && !flag_trapping_math
7067 && flag_unsafe_math_optimizations)
7069 ix86_emit_swdivsf (operands[0], operands[1],
7070 operands[2], SFmode);
7075 ;; Divmod instructions.
7077 (define_expand "divmod<mode>4"
7078 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7080 (match_operand:SWIM248 1 "register_operand" "")
7081 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7082 (set (match_operand:SWIM248 3 "register_operand" "")
7083 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7084 (clobber (reg:CC FLAGS_REG))])])
7086 ;; Split with 8bit unsigned divide:
7087 ;; if (dividend an divisor are in [0-255])
7088 ;; use 8bit unsigned integer divide
7090 ;; use original integer divide
7092 [(set (match_operand:SWI48 0 "register_operand" "")
7093 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7094 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7095 (set (match_operand:SWI48 1 "register_operand" "")
7096 (mod:SWI48 (match_dup 2) (match_dup 3)))
7097 (clobber (reg:CC FLAGS_REG))]
7098 "TARGET_USE_8BIT_IDIV
7099 && TARGET_QIMODE_MATH
7100 && can_create_pseudo_p ()
7101 && !optimize_insn_for_size_p ()"
7103 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7105 (define_insn_and_split "divmod<mode>4_1"
7106 [(set (match_operand:SWI48 0 "register_operand" "=a")
7107 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7108 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7109 (set (match_operand:SWI48 1 "register_operand" "=&d")
7110 (mod:SWI48 (match_dup 2) (match_dup 3)))
7111 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7112 (clobber (reg:CC FLAGS_REG))]
7116 [(parallel [(set (match_dup 1)
7117 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7118 (clobber (reg:CC FLAGS_REG))])
7119 (parallel [(set (match_dup 0)
7120 (div:SWI48 (match_dup 2) (match_dup 3)))
7122 (mod:SWI48 (match_dup 2) (match_dup 3)))
7124 (clobber (reg:CC FLAGS_REG))])]
7126 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7128 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7129 operands[4] = operands[2];
7132 /* Avoid use of cltd in favor of a mov+shift. */
7133 emit_move_insn (operands[1], operands[2]);
7134 operands[4] = operands[1];
7137 [(set_attr "type" "multi")
7138 (set_attr "mode" "<MODE>")])
7140 (define_insn_and_split "*divmod<mode>4"
7141 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7142 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7143 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7144 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7145 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7146 (clobber (reg:CC FLAGS_REG))]
7150 [(parallel [(set (match_dup 1)
7151 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7152 (clobber (reg:CC FLAGS_REG))])
7153 (parallel [(set (match_dup 0)
7154 (div:SWIM248 (match_dup 2) (match_dup 3)))
7156 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7158 (clobber (reg:CC FLAGS_REG))])]
7160 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7162 if (<MODE>mode != HImode
7163 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7164 operands[4] = operands[2];
7167 /* Avoid use of cltd in favor of a mov+shift. */
7168 emit_move_insn (operands[1], operands[2]);
7169 operands[4] = operands[1];
7172 [(set_attr "type" "multi")
7173 (set_attr "mode" "<MODE>")])
7175 (define_insn "*divmod<mode>4_noext"
7176 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7177 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7178 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7179 (set (match_operand:SWIM248 1 "register_operand" "=d")
7180 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7181 (use (match_operand:SWIM248 4 "register_operand" "1"))
7182 (clobber (reg:CC FLAGS_REG))]
7184 "idiv{<imodesuffix>}\t%3"
7185 [(set_attr "type" "idiv")
7186 (set_attr "mode" "<MODE>")])
7188 (define_expand "divmodqi4"
7189 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7191 (match_operand:QI 1 "register_operand" "")
7192 (match_operand:QI 2 "nonimmediate_operand" "")))
7193 (set (match_operand:QI 3 "register_operand" "")
7194 (mod:QI (match_dup 1) (match_dup 2)))
7195 (clobber (reg:CC FLAGS_REG))])]
7196 "TARGET_QIMODE_MATH"
7201 tmp0 = gen_reg_rtx (HImode);
7202 tmp1 = gen_reg_rtx (HImode);
7204 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7206 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7207 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7209 /* Extract remainder from AH. */
7210 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7211 insn = emit_move_insn (operands[3], tmp1);
7213 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7214 set_unique_reg_note (insn, REG_EQUAL, mod);
7216 /* Extract quotient from AL. */
7217 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7219 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7220 set_unique_reg_note (insn, REG_EQUAL, div);
7225 ;; Divide AX by r/m8, with result stored in
7228 ;; Change div/mod to HImode and extend the second argument to HImode
7229 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7230 ;; combine may fail.
7231 (define_insn "divmodhiqi3"
7232 [(set (match_operand:HI 0 "register_operand" "=a")
7237 (mod:HI (match_operand:HI 1 "register_operand" "0")
7239 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7243 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7244 (clobber (reg:CC FLAGS_REG))]
7245 "TARGET_QIMODE_MATH"
7247 [(set_attr "type" "idiv")
7248 (set_attr "mode" "QI")])
7250 (define_expand "udivmod<mode>4"
7251 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7253 (match_operand:SWIM248 1 "register_operand" "")
7254 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7255 (set (match_operand:SWIM248 3 "register_operand" "")
7256 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7257 (clobber (reg:CC FLAGS_REG))])])
7259 ;; Split with 8bit unsigned divide:
7260 ;; if (dividend an divisor are in [0-255])
7261 ;; use 8bit unsigned integer divide
7263 ;; use original integer divide
7265 [(set (match_operand:SWI48 0 "register_operand" "")
7266 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7267 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7268 (set (match_operand:SWI48 1 "register_operand" "")
7269 (umod:SWI48 (match_dup 2) (match_dup 3)))
7270 (clobber (reg:CC FLAGS_REG))]
7271 "TARGET_USE_8BIT_IDIV
7272 && TARGET_QIMODE_MATH
7273 && can_create_pseudo_p ()
7274 && !optimize_insn_for_size_p ()"
7276 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7278 (define_insn_and_split "udivmod<mode>4_1"
7279 [(set (match_operand:SWI48 0 "register_operand" "=a")
7280 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7281 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7282 (set (match_operand:SWI48 1 "register_operand" "=&d")
7283 (umod:SWI48 (match_dup 2) (match_dup 3)))
7284 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7285 (clobber (reg:CC FLAGS_REG))]
7289 [(set (match_dup 1) (const_int 0))
7290 (parallel [(set (match_dup 0)
7291 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7293 (umod:SWI48 (match_dup 2) (match_dup 3)))
7295 (clobber (reg:CC FLAGS_REG))])]
7297 [(set_attr "type" "multi")
7298 (set_attr "mode" "<MODE>")])
7300 (define_insn_and_split "*udivmod<mode>4"
7301 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7302 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7303 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7304 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7305 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7306 (clobber (reg:CC FLAGS_REG))]
7310 [(set (match_dup 1) (const_int 0))
7311 (parallel [(set (match_dup 0)
7312 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7314 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7316 (clobber (reg:CC FLAGS_REG))])]
7318 [(set_attr "type" "multi")
7319 (set_attr "mode" "<MODE>")])
7321 (define_insn "*udivmod<mode>4_noext"
7322 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7323 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7324 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7325 (set (match_operand:SWIM248 1 "register_operand" "=d")
7326 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7327 (use (match_operand:SWIM248 4 "register_operand" "1"))
7328 (clobber (reg:CC FLAGS_REG))]
7330 "div{<imodesuffix>}\t%3"
7331 [(set_attr "type" "idiv")
7332 (set_attr "mode" "<MODE>")])
7334 (define_expand "udivmodqi4"
7335 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7337 (match_operand:QI 1 "register_operand" "")
7338 (match_operand:QI 2 "nonimmediate_operand" "")))
7339 (set (match_operand:QI 3 "register_operand" "")
7340 (umod:QI (match_dup 1) (match_dup 2)))
7341 (clobber (reg:CC FLAGS_REG))])]
7342 "TARGET_QIMODE_MATH"
7347 tmp0 = gen_reg_rtx (HImode);
7348 tmp1 = gen_reg_rtx (HImode);
7350 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7352 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7353 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7355 /* Extract remainder from AH. */
7356 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7357 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7358 insn = emit_move_insn (operands[3], tmp1);
7360 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7361 set_unique_reg_note (insn, REG_EQUAL, mod);
7363 /* Extract quotient from AL. */
7364 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7366 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7367 set_unique_reg_note (insn, REG_EQUAL, div);
7372 (define_insn "udivmodhiqi3"
7373 [(set (match_operand:HI 0 "register_operand" "=a")
7378 (mod:HI (match_operand:HI 1 "register_operand" "0")
7380 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7384 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7385 (clobber (reg:CC FLAGS_REG))]
7386 "TARGET_QIMODE_MATH"
7388 [(set_attr "type" "idiv")
7389 (set_attr "mode" "QI")])
7391 ;; We cannot use div/idiv for double division, because it causes
7392 ;; "division by zero" on the overflow and that's not what we expect
7393 ;; from truncate. Because true (non truncating) double division is
7394 ;; never generated, we can't create this insn anyway.
7397 ; [(set (match_operand:SI 0 "register_operand" "=a")
7399 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7401 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7402 ; (set (match_operand:SI 3 "register_operand" "=d")
7404 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7405 ; (clobber (reg:CC FLAGS_REG))]
7407 ; "div{l}\t{%2, %0|%0, %2}"
7408 ; [(set_attr "type" "idiv")])
7410 ;;- Logical AND instructions
7412 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7413 ;; Note that this excludes ah.
7415 (define_expand "testsi_ccno_1"
7416 [(set (reg:CCNO FLAGS_REG)
7418 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7419 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7422 (define_expand "testqi_ccz_1"
7423 [(set (reg:CCZ FLAGS_REG)
7424 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7425 (match_operand:QI 1 "nonmemory_operand" ""))
7428 (define_expand "testdi_ccno_1"
7429 [(set (reg:CCNO FLAGS_REG)
7431 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7432 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7434 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7436 (define_insn "*testdi_1"
7437 [(set (reg FLAGS_REG)
7440 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7441 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7443 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7444 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7446 test{l}\t{%k1, %k0|%k0, %k1}
7447 test{l}\t{%k1, %k0|%k0, %k1}
7448 test{q}\t{%1, %0|%0, %1}
7449 test{q}\t{%1, %0|%0, %1}
7450 test{q}\t{%1, %0|%0, %1}"
7451 [(set_attr "type" "test")
7452 (set_attr "modrm" "0,1,0,1,1")
7453 (set_attr "mode" "SI,SI,DI,DI,DI")])
7455 (define_insn "*testqi_1_maybe_si"
7456 [(set (reg FLAGS_REG)
7459 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7460 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7462 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7463 && ix86_match_ccmode (insn,
7464 CONST_INT_P (operands[1])
7465 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7467 if (which_alternative == 3)
7469 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7470 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7471 return "test{l}\t{%1, %k0|%k0, %1}";
7473 return "test{b}\t{%1, %0|%0, %1}";
7475 [(set_attr "type" "test")
7476 (set_attr "modrm" "0,1,1,1")
7477 (set_attr "mode" "QI,QI,QI,SI")
7478 (set_attr "pent_pair" "uv,np,uv,np")])
7480 (define_insn "*test<mode>_1"
7481 [(set (reg FLAGS_REG)
7484 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7485 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7487 "ix86_match_ccmode (insn, CCNOmode)
7488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7489 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "modrm" "0,1,1")
7492 (set_attr "mode" "<MODE>")
7493 (set_attr "pent_pair" "uv,np,uv")])
7495 (define_expand "testqi_ext_ccno_0"
7496 [(set (reg:CCNO FLAGS_REG)
7500 (match_operand 0 "ext_register_operand" "")
7503 (match_operand 1 "const_int_operand" ""))
7506 (define_insn "*testqi_ext_0"
7507 [(set (reg FLAGS_REG)
7511 (match_operand 0 "ext_register_operand" "Q")
7514 (match_operand 1 "const_int_operand" "n"))
7516 "ix86_match_ccmode (insn, CCNOmode)"
7517 "test{b}\t{%1, %h0|%h0, %1}"
7518 [(set_attr "type" "test")
7519 (set_attr "mode" "QI")
7520 (set_attr "length_immediate" "1")
7521 (set_attr "modrm" "1")
7522 (set_attr "pent_pair" "np")])
7524 (define_insn "*testqi_ext_1_rex64"
7525 [(set (reg FLAGS_REG)
7529 (match_operand 0 "ext_register_operand" "Q")
7533 (match_operand:QI 1 "register_operand" "Q")))
7535 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7536 "test{b}\t{%1, %h0|%h0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "mode" "QI")])
7540 (define_insn "*testqi_ext_1"
7541 [(set (reg FLAGS_REG)
7545 (match_operand 0 "ext_register_operand" "Q")
7549 (match_operand:QI 1 "general_operand" "Qm")))
7551 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7552 "test{b}\t{%1, %h0|%h0, %1}"
7553 [(set_attr "type" "test")
7554 (set_attr "mode" "QI")])
7556 (define_insn "*testqi_ext_2"
7557 [(set (reg FLAGS_REG)
7561 (match_operand 0 "ext_register_operand" "Q")
7565 (match_operand 1 "ext_register_operand" "Q")
7569 "ix86_match_ccmode (insn, CCNOmode)"
7570 "test{b}\t{%h1, %h0|%h0, %h1}"
7571 [(set_attr "type" "test")
7572 (set_attr "mode" "QI")])
7574 (define_insn "*testqi_ext_3_rex64"
7575 [(set (reg FLAGS_REG)
7576 (compare (zero_extract:DI
7577 (match_operand 0 "nonimmediate_operand" "rm")
7578 (match_operand:DI 1 "const_int_operand" "")
7579 (match_operand:DI 2 "const_int_operand" ""))
7582 && ix86_match_ccmode (insn, CCNOmode)
7583 && INTVAL (operands[1]) > 0
7584 && INTVAL (operands[2]) >= 0
7585 /* Ensure that resulting mask is zero or sign extended operand. */
7586 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7587 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7588 && INTVAL (operands[1]) > 32))
7589 && (GET_MODE (operands[0]) == SImode
7590 || GET_MODE (operands[0]) == DImode
7591 || GET_MODE (operands[0]) == HImode
7592 || GET_MODE (operands[0]) == QImode)"
7595 ;; Combine likes to form bit extractions for some tests. Humor it.
7596 (define_insn "*testqi_ext_3"
7597 [(set (reg FLAGS_REG)
7598 (compare (zero_extract:SI
7599 (match_operand 0 "nonimmediate_operand" "rm")
7600 (match_operand:SI 1 "const_int_operand" "")
7601 (match_operand:SI 2 "const_int_operand" ""))
7603 "ix86_match_ccmode (insn, CCNOmode)
7604 && INTVAL (operands[1]) > 0
7605 && INTVAL (operands[2]) >= 0
7606 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7607 && (GET_MODE (operands[0]) == SImode
7608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7609 || GET_MODE (operands[0]) == HImode
7610 || GET_MODE (operands[0]) == QImode)"
7614 [(set (match_operand 0 "flags_reg_operand" "")
7615 (match_operator 1 "compare_operator"
7617 (match_operand 2 "nonimmediate_operand" "")
7618 (match_operand 3 "const_int_operand" "")
7619 (match_operand 4 "const_int_operand" ""))
7621 "ix86_match_ccmode (insn, CCNOmode)"
7622 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7624 rtx val = operands[2];
7625 HOST_WIDE_INT len = INTVAL (operands[3]);
7626 HOST_WIDE_INT pos = INTVAL (operands[4]);
7628 enum machine_mode mode, submode;
7630 mode = GET_MODE (val);
7633 /* ??? Combine likes to put non-volatile mem extractions in QImode
7634 no matter the size of the test. So find a mode that works. */
7635 if (! MEM_VOLATILE_P (val))
7637 mode = smallest_mode_for_size (pos + len, MODE_INT);
7638 val = adjust_address (val, mode, 0);
7641 else if (GET_CODE (val) == SUBREG
7642 && (submode = GET_MODE (SUBREG_REG (val)),
7643 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7644 && pos + len <= GET_MODE_BITSIZE (submode)
7645 && GET_MODE_CLASS (submode) == MODE_INT)
7647 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7649 val = SUBREG_REG (val);
7651 else if (mode == HImode && pos + len <= 8)
7653 /* Small HImode tests can be converted to QImode. */
7655 val = gen_lowpart (QImode, val);
7658 if (len == HOST_BITS_PER_WIDE_INT)
7661 mask = ((HOST_WIDE_INT)1 << len) - 1;
7664 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7667 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7668 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7669 ;; this is relatively important trick.
7670 ;; Do the conversion only post-reload to avoid limiting of the register class
7673 [(set (match_operand 0 "flags_reg_operand" "")
7674 (match_operator 1 "compare_operator"
7675 [(and (match_operand 2 "register_operand" "")
7676 (match_operand 3 "const_int_operand" ""))
7679 && QI_REG_P (operands[2])
7680 && GET_MODE (operands[2]) != QImode
7681 && ((ix86_match_ccmode (insn, CCZmode)
7682 && !(INTVAL (operands[3]) & ~(255 << 8)))
7683 || (ix86_match_ccmode (insn, CCNOmode)
7684 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7687 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7690 "operands[2] = gen_lowpart (SImode, operands[2]);
7691 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7694 [(set (match_operand 0 "flags_reg_operand" "")
7695 (match_operator 1 "compare_operator"
7696 [(and (match_operand 2 "nonimmediate_operand" "")
7697 (match_operand 3 "const_int_operand" ""))
7700 && GET_MODE (operands[2]) != QImode
7701 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7702 && ((ix86_match_ccmode (insn, CCZmode)
7703 && !(INTVAL (operands[3]) & ~255))
7704 || (ix86_match_ccmode (insn, CCNOmode)
7705 && !(INTVAL (operands[3]) & ~127)))"
7707 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7709 "operands[2] = gen_lowpart (QImode, operands[2]);
7710 operands[3] = gen_lowpart (QImode, operands[3]);")
7712 ;; %%% This used to optimize known byte-wide and operations to memory,
7713 ;; and sometimes to QImode registers. If this is considered useful,
7714 ;; it should be done with splitters.
7716 (define_expand "and<mode>3"
7717 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7718 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7719 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7721 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7723 (define_insn "*anddi_1"
7724 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7726 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7727 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7728 (clobber (reg:CC FLAGS_REG))]
7729 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7731 switch (get_attr_type (insn))
7735 enum machine_mode mode;
7737 gcc_assert (CONST_INT_P (operands[2]));
7738 if (INTVAL (operands[2]) == 0xff)
7742 gcc_assert (INTVAL (operands[2]) == 0xffff);
7746 operands[1] = gen_lowpart (mode, operands[1]);
7748 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7750 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7755 if (get_attr_mode (insn) == MODE_SI)
7756 return "and{l}\t{%k2, %k0|%k0, %k2}";
7758 return "and{q}\t{%2, %0|%0, %2}";
7761 [(set_attr "type" "alu,alu,alu,imovx")
7762 (set_attr "length_immediate" "*,*,*,0")
7763 (set (attr "prefix_rex")
7765 (and (eq_attr "type" "imovx")
7766 (and (match_test "INTVAL (operands[2]) == 0xff")
7767 (match_operand 1 "ext_QIreg_operand" "")))
7769 (const_string "*")))
7770 (set_attr "mode" "SI,DI,DI,SI")])
7772 (define_insn "*andsi_1"
7773 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7774 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7775 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7776 (clobber (reg:CC FLAGS_REG))]
7777 "ix86_binary_operator_ok (AND, SImode, operands)"
7779 switch (get_attr_type (insn))
7783 enum machine_mode mode;
7785 gcc_assert (CONST_INT_P (operands[2]));
7786 if (INTVAL (operands[2]) == 0xff)
7790 gcc_assert (INTVAL (operands[2]) == 0xffff);
7794 operands[1] = gen_lowpart (mode, operands[1]);
7796 return "movz{bl|x}\t{%1, %0|%0, %1}";
7798 return "movz{wl|x}\t{%1, %0|%0, %1}";
7802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7803 return "and{l}\t{%2, %0|%0, %2}";
7806 [(set_attr "type" "alu,alu,imovx")
7807 (set (attr "prefix_rex")
7809 (and (eq_attr "type" "imovx")
7810 (and (match_test "INTVAL (operands[2]) == 0xff")
7811 (match_operand 1 "ext_QIreg_operand" "")))
7813 (const_string "*")))
7814 (set_attr "length_immediate" "*,*,0")
7815 (set_attr "mode" "SI")])
7817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7818 (define_insn "*andsi_1_zext"
7819 [(set (match_operand:DI 0 "register_operand" "=r")
7821 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7822 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7825 "and{l}\t{%2, %k0|%k0, %2}"
7826 [(set_attr "type" "alu")
7827 (set_attr "mode" "SI")])
7829 (define_insn "*andhi_1"
7830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7831 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7832 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "ix86_binary_operator_ok (AND, HImode, operands)"
7836 switch (get_attr_type (insn))
7839 gcc_assert (CONST_INT_P (operands[2]));
7840 gcc_assert (INTVAL (operands[2]) == 0xff);
7841 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7844 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7846 return "and{w}\t{%2, %0|%0, %2}";
7849 [(set_attr "type" "alu,alu,imovx")
7850 (set_attr "length_immediate" "*,*,0")
7851 (set (attr "prefix_rex")
7853 (and (eq_attr "type" "imovx")
7854 (match_operand 1 "ext_QIreg_operand" ""))
7856 (const_string "*")))
7857 (set_attr "mode" "HI,HI,SI")])
7859 ;; %%% Potential partial reg stall on alternative 2. What to do?
7860 (define_insn "*andqi_1"
7861 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7862 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7863 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "ix86_binary_operator_ok (AND, QImode, operands)"
7867 and{b}\t{%2, %0|%0, %2}
7868 and{b}\t{%2, %0|%0, %2}
7869 and{l}\t{%k2, %k0|%k0, %k2}"
7870 [(set_attr "type" "alu")
7871 (set_attr "mode" "QI,QI,SI")])
7873 (define_insn "*andqi_1_slp"
7874 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7875 (and:QI (match_dup 0)
7876 (match_operand:QI 1 "general_operand" "qn,qmn")))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7879 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7880 "and{b}\t{%1, %0|%0, %1}"
7881 [(set_attr "type" "alu1")
7882 (set_attr "mode" "QI")])
7885 [(set (match_operand 0 "register_operand" "")
7887 (const_int -65536)))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7890 || optimize_function_for_size_p (cfun)"
7891 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892 "operands[1] = gen_lowpart (HImode, operands[0]);")
7895 [(set (match_operand 0 "ext_register_operand" "")
7898 (clobber (reg:CC FLAGS_REG))]
7899 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900 && reload_completed"
7901 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7902 "operands[1] = gen_lowpart (QImode, operands[0]);")
7905 [(set (match_operand 0 "ext_register_operand" "")
7907 (const_int -65281)))
7908 (clobber (reg:CC FLAGS_REG))]
7909 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7910 && reload_completed"
7911 [(parallel [(set (zero_extract:SI (match_dup 0)
7915 (zero_extract:SI (match_dup 0)
7918 (zero_extract:SI (match_dup 0)
7921 (clobber (reg:CC FLAGS_REG))])]
7922 "operands[0] = gen_lowpart (SImode, operands[0]);")
7924 (define_insn "*anddi_2"
7925 [(set (reg FLAGS_REG)
7928 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7929 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7931 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7932 (and:DI (match_dup 1) (match_dup 2)))]
7933 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7934 && ix86_binary_operator_ok (AND, DImode, operands)"
7936 and{l}\t{%k2, %k0|%k0, %k2}
7937 and{q}\t{%2, %0|%0, %2}
7938 and{q}\t{%2, %0|%0, %2}"
7939 [(set_attr "type" "alu")
7940 (set_attr "mode" "SI,DI,DI")])
7942 (define_insn "*andqi_2_maybe_si"
7943 [(set (reg FLAGS_REG)
7945 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7946 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7948 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7949 (and:QI (match_dup 1) (match_dup 2)))]
7950 "ix86_binary_operator_ok (AND, QImode, operands)
7951 && ix86_match_ccmode (insn,
7952 CONST_INT_P (operands[2])
7953 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7955 if (which_alternative == 2)
7957 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7958 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7959 return "and{l}\t{%2, %k0|%k0, %2}";
7961 return "and{b}\t{%2, %0|%0, %2}";
7963 [(set_attr "type" "alu")
7964 (set_attr "mode" "QI,QI,SI")])
7966 (define_insn "*and<mode>_2"
7967 [(set (reg FLAGS_REG)
7968 (compare (and:SWI124
7969 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7970 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7972 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7973 (and:SWI124 (match_dup 1) (match_dup 2)))]
7974 "ix86_match_ccmode (insn, CCNOmode)
7975 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7976 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7977 [(set_attr "type" "alu")
7978 (set_attr "mode" "<MODE>")])
7980 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7981 (define_insn "*andsi_2_zext"
7982 [(set (reg FLAGS_REG)
7984 (match_operand:SI 1 "nonimmediate_operand" "%0")
7985 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7987 (set (match_operand:DI 0 "register_operand" "=r")
7988 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7989 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7990 && ix86_binary_operator_ok (AND, SImode, operands)"
7991 "and{l}\t{%2, %k0|%k0, %2}"
7992 [(set_attr "type" "alu")
7993 (set_attr "mode" "SI")])
7995 (define_insn "*andqi_2_slp"
7996 [(set (reg FLAGS_REG)
7998 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7999 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8001 (set (strict_low_part (match_dup 0))
8002 (and:QI (match_dup 0) (match_dup 1)))]
8003 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8004 && ix86_match_ccmode (insn, CCNOmode)
8005 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8006 "and{b}\t{%1, %0|%0, %1}"
8007 [(set_attr "type" "alu1")
8008 (set_attr "mode" "QI")])
8010 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8011 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8012 ;; for a QImode operand, which of course failed.
8013 (define_insn "andqi_ext_0"
8014 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019 (match_operand 1 "ext_register_operand" "0")
8022 (match_operand 2 "const_int_operand" "n")))
8023 (clobber (reg:CC FLAGS_REG))]
8025 "and{b}\t{%2, %h0|%h0, %2}"
8026 [(set_attr "type" "alu")
8027 (set_attr "length_immediate" "1")
8028 (set_attr "modrm" "1")
8029 (set_attr "mode" "QI")])
8031 ;; Generated by peephole translating test to and. This shows up
8032 ;; often in fp comparisons.
8033 (define_insn "*andqi_ext_0_cc"
8034 [(set (reg FLAGS_REG)
8038 (match_operand 1 "ext_register_operand" "0")
8041 (match_operand 2 "const_int_operand" "n"))
8043 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8052 "ix86_match_ccmode (insn, CCNOmode)"
8053 "and{b}\t{%2, %h0|%h0, %2}"
8054 [(set_attr "type" "alu")
8055 (set_attr "length_immediate" "1")
8056 (set_attr "modrm" "1")
8057 (set_attr "mode" "QI")])
8059 (define_insn "*andqi_ext_1_rex64"
8060 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8065 (match_operand 1 "ext_register_operand" "0")
8069 (match_operand 2 "ext_register_operand" "Q"))))
8070 (clobber (reg:CC FLAGS_REG))]
8072 "and{b}\t{%2, %h0|%h0, %2}"
8073 [(set_attr "type" "alu")
8074 (set_attr "length_immediate" "0")
8075 (set_attr "mode" "QI")])
8077 (define_insn "*andqi_ext_1"
8078 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8083 (match_operand 1 "ext_register_operand" "0")
8087 (match_operand:QI 2 "general_operand" "Qm"))))
8088 (clobber (reg:CC FLAGS_REG))]
8090 "and{b}\t{%2, %h0|%h0, %2}"
8091 [(set_attr "type" "alu")
8092 (set_attr "length_immediate" "0")
8093 (set_attr "mode" "QI")])
8095 (define_insn "*andqi_ext_2"
8096 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8101 (match_operand 1 "ext_register_operand" "%0")
8105 (match_operand 2 "ext_register_operand" "Q")
8108 (clobber (reg:CC FLAGS_REG))]
8110 "and{b}\t{%h2, %h0|%h0, %h2}"
8111 [(set_attr "type" "alu")
8112 (set_attr "length_immediate" "0")
8113 (set_attr "mode" "QI")])
8115 ;; Convert wide AND instructions with immediate operand to shorter QImode
8116 ;; equivalents when possible.
8117 ;; Don't do the splitting with memory operands, since it introduces risk
8118 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8119 ;; for size, but that can (should?) be handled by generic code instead.
8121 [(set (match_operand 0 "register_operand" "")
8122 (and (match_operand 1 "register_operand" "")
8123 (match_operand 2 "const_int_operand" "")))
8124 (clobber (reg:CC FLAGS_REG))]
8126 && QI_REG_P (operands[0])
8127 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128 && !(~INTVAL (operands[2]) & ~(255 << 8))
8129 && GET_MODE (operands[0]) != QImode"
8130 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8131 (and:SI (zero_extract:SI (match_dup 1)
8132 (const_int 8) (const_int 8))
8134 (clobber (reg:CC FLAGS_REG))])]
8135 "operands[0] = gen_lowpart (SImode, operands[0]);
8136 operands[1] = gen_lowpart (SImode, operands[1]);
8137 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8139 ;; Since AND can be encoded with sign extended immediate, this is only
8140 ;; profitable when 7th bit is not set.
8142 [(set (match_operand 0 "register_operand" "")
8143 (and (match_operand 1 "general_operand" "")
8144 (match_operand 2 "const_int_operand" "")))
8145 (clobber (reg:CC FLAGS_REG))]
8147 && ANY_QI_REG_P (operands[0])
8148 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8149 && !(~INTVAL (operands[2]) & ~255)
8150 && !(INTVAL (operands[2]) & 128)
8151 && GET_MODE (operands[0]) != QImode"
8152 [(parallel [(set (strict_low_part (match_dup 0))
8153 (and:QI (match_dup 1)
8155 (clobber (reg:CC FLAGS_REG))])]
8156 "operands[0] = gen_lowpart (QImode, operands[0]);
8157 operands[1] = gen_lowpart (QImode, operands[1]);
8158 operands[2] = gen_lowpart (QImode, operands[2]);")
8160 ;; Logical inclusive and exclusive OR instructions
8162 ;; %%% This used to optimize known byte-wide and operations to memory.
8163 ;; If this is considered useful, it should be done with splitters.
8165 (define_expand "<code><mode>3"
8166 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8167 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8168 (match_operand:SWIM 2 "<general_operand>" "")))]
8170 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8172 (define_insn "*<code><mode>_1"
8173 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8175 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8176 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8179 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "mode" "<MODE>")])
8183 ;; %%% Potential partial reg stall on alternative 2. What to do?
8184 (define_insn "*<code>qi_1"
8185 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8186 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8187 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8191 <logic>{b}\t{%2, %0|%0, %2}
8192 <logic>{b}\t{%2, %0|%0, %2}
8193 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "mode" "QI,QI,SI")])
8197 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8198 (define_insn "*<code>si_1_zext"
8199 [(set (match_operand:DI 0 "register_operand" "=r")
8201 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8202 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8203 (clobber (reg:CC FLAGS_REG))]
8204 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8205 "<logic>{l}\t{%2, %k0|%k0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 (define_insn "*<code>si_1_zext_imm"
8210 [(set (match_operand:DI 0 "register_operand" "=r")
8212 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8213 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8214 (clobber (reg:CC FLAGS_REG))]
8215 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8216 "<logic>{l}\t{%2, %k0|%k0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "mode" "SI")])
8220 (define_insn "*<code>qi_1_slp"
8221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8222 (any_or:QI (match_dup 0)
8223 (match_operand:QI 1 "general_operand" "qmn,qn")))
8224 (clobber (reg:CC FLAGS_REG))]
8225 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8226 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8227 "<logic>{b}\t{%1, %0|%0, %1}"
8228 [(set_attr "type" "alu1")
8229 (set_attr "mode" "QI")])
8231 (define_insn "*<code><mode>_2"
8232 [(set (reg FLAGS_REG)
8233 (compare (any_or:SWI
8234 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8235 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8237 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8238 (any_or:SWI (match_dup 1) (match_dup 2)))]
8239 "ix86_match_ccmode (insn, CCNOmode)
8240 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8241 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8242 [(set_attr "type" "alu")
8243 (set_attr "mode" "<MODE>")])
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 ;; ??? Special case for immediate operand is missing - it is tricky.
8247 (define_insn "*<code>si_2_zext"
8248 [(set (reg FLAGS_REG)
8249 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8252 (set (match_operand:DI 0 "register_operand" "=r")
8253 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8254 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8256 "<logic>{l}\t{%2, %k0|%k0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "SI")])
8260 (define_insn "*<code>si_2_zext_imm"
8261 [(set (reg FLAGS_REG)
8263 (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8266 (set (match_operand:DI 0 "register_operand" "=r")
8267 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8269 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8270 "<logic>{l}\t{%2, %k0|%k0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "SI")])
8274 (define_insn "*<code>qi_2_slp"
8275 [(set (reg FLAGS_REG)
8276 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8277 (match_operand:QI 1 "general_operand" "qmn,qn"))
8279 (set (strict_low_part (match_dup 0))
8280 (any_or:QI (match_dup 0) (match_dup 1)))]
8281 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8282 && ix86_match_ccmode (insn, CCNOmode)
8283 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8284 "<logic>{b}\t{%1, %0|%0, %1}"
8285 [(set_attr "type" "alu1")
8286 (set_attr "mode" "QI")])
8288 (define_insn "*<code><mode>_3"
8289 [(set (reg FLAGS_REG)
8290 (compare (any_or:SWI
8291 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8292 (match_operand:SWI 2 "<general_operand>" "<g>"))
8294 (clobber (match_scratch:SWI 0 "=<r>"))]
8295 "ix86_match_ccmode (insn, CCNOmode)
8296 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8297 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "mode" "<MODE>")])
8301 (define_insn "*<code>qi_ext_0"
8302 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8307 (match_operand 1 "ext_register_operand" "0")
8310 (match_operand 2 "const_int_operand" "n")))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8313 "<logic>{b}\t{%2, %h0|%h0, %2}"
8314 [(set_attr "type" "alu")
8315 (set_attr "length_immediate" "1")
8316 (set_attr "modrm" "1")
8317 (set_attr "mode" "QI")])
8319 (define_insn "*<code>qi_ext_1_rex64"
8320 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325 (match_operand 1 "ext_register_operand" "0")
8329 (match_operand 2 "ext_register_operand" "Q"))))
8330 (clobber (reg:CC FLAGS_REG))]
8332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8333 "<logic>{b}\t{%2, %h0|%h0, %2}"
8334 [(set_attr "type" "alu")
8335 (set_attr "length_immediate" "0")
8336 (set_attr "mode" "QI")])
8338 (define_insn "*<code>qi_ext_1"
8339 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8344 (match_operand 1 "ext_register_operand" "0")
8348 (match_operand:QI 2 "general_operand" "Qm"))))
8349 (clobber (reg:CC FLAGS_REG))]
8351 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8352 "<logic>{b}\t{%2, %h0|%h0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "length_immediate" "0")
8355 (set_attr "mode" "QI")])
8357 (define_insn "*<code>qi_ext_2"
8358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8362 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8365 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8368 (clobber (reg:CC FLAGS_REG))]
8369 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8370 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8371 [(set_attr "type" "alu")
8372 (set_attr "length_immediate" "0")
8373 (set_attr "mode" "QI")])
8376 [(set (match_operand 0 "register_operand" "")
8377 (any_or (match_operand 1 "register_operand" "")
8378 (match_operand 2 "const_int_operand" "")))
8379 (clobber (reg:CC FLAGS_REG))]
8381 && QI_REG_P (operands[0])
8382 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8383 && !(INTVAL (operands[2]) & ~(255 << 8))
8384 && GET_MODE (operands[0]) != QImode"
8385 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8386 (any_or:SI (zero_extract:SI (match_dup 1)
8387 (const_int 8) (const_int 8))
8389 (clobber (reg:CC FLAGS_REG))])]
8390 "operands[0] = gen_lowpart (SImode, operands[0]);
8391 operands[1] = gen_lowpart (SImode, operands[1]);
8392 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8394 ;; Since OR can be encoded with sign extended immediate, this is only
8395 ;; profitable when 7th bit is set.
8397 [(set (match_operand 0 "register_operand" "")
8398 (any_or (match_operand 1 "general_operand" "")
8399 (match_operand 2 "const_int_operand" "")))
8400 (clobber (reg:CC FLAGS_REG))]
8402 && ANY_QI_REG_P (operands[0])
8403 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404 && !(INTVAL (operands[2]) & ~255)
8405 && (INTVAL (operands[2]) & 128)
8406 && GET_MODE (operands[0]) != QImode"
8407 [(parallel [(set (strict_low_part (match_dup 0))
8408 (any_or:QI (match_dup 1)
8410 (clobber (reg:CC FLAGS_REG))])]
8411 "operands[0] = gen_lowpart (QImode, operands[0]);
8412 operands[1] = gen_lowpart (QImode, operands[1]);
8413 operands[2] = gen_lowpart (QImode, operands[2]);")
8415 (define_expand "xorqi_cc_ext_1"
8417 (set (reg:CCNO FLAGS_REG)
8421 (match_operand 1 "ext_register_operand" "")
8424 (match_operand:QI 2 "general_operand" ""))
8426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8436 (define_insn "*xorqi_cc_ext_1_rex64"
8437 [(set (reg FLAGS_REG)
8441 (match_operand 1 "ext_register_operand" "0")
8444 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8446 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8456 "xor{b}\t{%2, %h0|%h0, %2}"
8457 [(set_attr "type" "alu")
8458 (set_attr "modrm" "1")
8459 (set_attr "mode" "QI")])
8461 (define_insn "*xorqi_cc_ext_1"
8462 [(set (reg FLAGS_REG)
8466 (match_operand 1 "ext_register_operand" "0")
8469 (match_operand:QI 2 "general_operand" "qmn"))
8471 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8480 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8481 "xor{b}\t{%2, %h0|%h0, %2}"
8482 [(set_attr "type" "alu")
8483 (set_attr "modrm" "1")
8484 (set_attr "mode" "QI")])
8486 ;; Negation instructions
8488 (define_expand "neg<mode>2"
8489 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8490 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8492 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8494 (define_insn_and_split "*neg<dwi>2_doubleword"
8495 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8496 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8497 (clobber (reg:CC FLAGS_REG))]
8498 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8502 [(set (reg:CCZ FLAGS_REG)
8503 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8504 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8507 (plus:DWIH (match_dup 3)
8508 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8510 (clobber (reg:CC FLAGS_REG))])
8513 (neg:DWIH (match_dup 2)))
8514 (clobber (reg:CC FLAGS_REG))])]
8515 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8517 (define_insn "*neg<mode>2_1"
8518 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8519 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8520 (clobber (reg:CC FLAGS_REG))]
8521 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8522 "neg{<imodesuffix>}\t%0"
8523 [(set_attr "type" "negnot")
8524 (set_attr "mode" "<MODE>")])
8526 ;; Combine is quite creative about this pattern.
8527 (define_insn "*negsi2_1_zext"
8528 [(set (match_operand:DI 0 "register_operand" "=r")
8530 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8533 (clobber (reg:CC FLAGS_REG))]
8534 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8536 [(set_attr "type" "negnot")
8537 (set_attr "mode" "SI")])
8539 ;; The problem with neg is that it does not perform (compare x 0),
8540 ;; it really performs (compare 0 x), which leaves us with the zero
8541 ;; flag being the only useful item.
8543 (define_insn "*neg<mode>2_cmpz"
8544 [(set (reg:CCZ FLAGS_REG)
8546 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8548 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8549 (neg:SWI (match_dup 1)))]
8550 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8551 "neg{<imodesuffix>}\t%0"
8552 [(set_attr "type" "negnot")
8553 (set_attr "mode" "<MODE>")])
8555 (define_insn "*negsi2_cmpz_zext"
8556 [(set (reg:CCZ FLAGS_REG)
8560 (match_operand:DI 1 "register_operand" "0")
8564 (set (match_operand:DI 0 "register_operand" "=r")
8565 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8568 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8570 [(set_attr "type" "negnot")
8571 (set_attr "mode" "SI")])
8573 ;; Changing of sign for FP values is doable using integer unit too.
8575 (define_expand "<code><mode>2"
8576 [(set (match_operand:X87MODEF 0 "register_operand" "")
8577 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8578 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8579 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8581 (define_insn "*absneg<mode>2_mixed"
8582 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8583 (match_operator:MODEF 3 "absneg_operator"
8584 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8585 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8590 (define_insn "*absneg<mode>2_sse"
8591 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8592 (match_operator:MODEF 3 "absneg_operator"
8593 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8594 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8595 (clobber (reg:CC FLAGS_REG))]
8596 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8599 (define_insn "*absneg<mode>2_i387"
8600 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8601 (match_operator:X87MODEF 3 "absneg_operator"
8602 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8603 (use (match_operand 2 "" ""))
8604 (clobber (reg:CC FLAGS_REG))]
8605 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8608 (define_expand "<code>tf2"
8609 [(set (match_operand:TF 0 "register_operand" "")
8610 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8612 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8614 (define_insn "*absnegtf2_sse"
8615 [(set (match_operand:TF 0 "register_operand" "=x,x")
8616 (match_operator:TF 3 "absneg_operator"
8617 [(match_operand:TF 1 "register_operand" "0,x")]))
8618 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8619 (clobber (reg:CC FLAGS_REG))]
8623 ;; Splitters for fp abs and neg.
8626 [(set (match_operand 0 "fp_register_operand" "")
8627 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8628 (use (match_operand 2 "" ""))
8629 (clobber (reg:CC FLAGS_REG))]
8631 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8634 [(set (match_operand 0 "register_operand" "")
8635 (match_operator 3 "absneg_operator"
8636 [(match_operand 1 "register_operand" "")]))
8637 (use (match_operand 2 "nonimmediate_operand" ""))
8638 (clobber (reg:CC FLAGS_REG))]
8639 "reload_completed && SSE_REG_P (operands[0])"
8640 [(set (match_dup 0) (match_dup 3))]
8642 enum machine_mode mode = GET_MODE (operands[0]);
8643 enum machine_mode vmode = GET_MODE (operands[2]);
8646 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8647 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8648 if (operands_match_p (operands[0], operands[2]))
8651 operands[1] = operands[2];
8654 if (GET_CODE (operands[3]) == ABS)
8655 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8657 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8662 [(set (match_operand:SF 0 "register_operand" "")
8663 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8664 (use (match_operand:V4SF 2 "" ""))
8665 (clobber (reg:CC FLAGS_REG))]
8667 [(parallel [(set (match_dup 0) (match_dup 1))
8668 (clobber (reg:CC FLAGS_REG))])]
8671 operands[0] = gen_lowpart (SImode, operands[0]);
8672 if (GET_CODE (operands[1]) == ABS)
8674 tmp = gen_int_mode (0x7fffffff, SImode);
8675 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8679 tmp = gen_int_mode (0x80000000, SImode);
8680 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8686 [(set (match_operand:DF 0 "register_operand" "")
8687 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8688 (use (match_operand 2 "" ""))
8689 (clobber (reg:CC FLAGS_REG))]
8691 [(parallel [(set (match_dup 0) (match_dup 1))
8692 (clobber (reg:CC FLAGS_REG))])]
8697 tmp = gen_lowpart (DImode, operands[0]);
8698 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8701 if (GET_CODE (operands[1]) == ABS)
8704 tmp = gen_rtx_NOT (DImode, tmp);
8708 operands[0] = gen_highpart (SImode, operands[0]);
8709 if (GET_CODE (operands[1]) == ABS)
8711 tmp = gen_int_mode (0x7fffffff, SImode);
8712 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8716 tmp = gen_int_mode (0x80000000, SImode);
8717 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8724 [(set (match_operand:XF 0 "register_operand" "")
8725 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8726 (use (match_operand 2 "" ""))
8727 (clobber (reg:CC FLAGS_REG))]
8729 [(parallel [(set (match_dup 0) (match_dup 1))
8730 (clobber (reg:CC FLAGS_REG))])]
8733 operands[0] = gen_rtx_REG (SImode,
8734 true_regnum (operands[0])
8735 + (TARGET_64BIT ? 1 : 2));
8736 if (GET_CODE (operands[1]) == ABS)
8738 tmp = GEN_INT (0x7fff);
8739 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8743 tmp = GEN_INT (0x8000);
8744 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8749 ;; Conditionalize these after reload. If they match before reload, we
8750 ;; lose the clobber and ability to use integer instructions.
8752 (define_insn "*<code><mode>2_1"
8753 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8754 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8756 && (reload_completed
8757 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8758 "f<absneg_mnemonic>"
8759 [(set_attr "type" "fsgn")
8760 (set_attr "mode" "<MODE>")])
8762 (define_insn "*<code>extendsfdf2"
8763 [(set (match_operand:DF 0 "register_operand" "=f")
8764 (absneg:DF (float_extend:DF
8765 (match_operand:SF 1 "register_operand" "0"))))]
8766 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8767 "f<absneg_mnemonic>"
8768 [(set_attr "type" "fsgn")
8769 (set_attr "mode" "DF")])
8771 (define_insn "*<code>extendsfxf2"
8772 [(set (match_operand:XF 0 "register_operand" "=f")
8773 (absneg:XF (float_extend:XF
8774 (match_operand:SF 1 "register_operand" "0"))))]
8776 "f<absneg_mnemonic>"
8777 [(set_attr "type" "fsgn")
8778 (set_attr "mode" "XF")])
8780 (define_insn "*<code>extenddfxf2"
8781 [(set (match_operand:XF 0 "register_operand" "=f")
8782 (absneg:XF (float_extend:XF
8783 (match_operand:DF 1 "register_operand" "0"))))]
8785 "f<absneg_mnemonic>"
8786 [(set_attr "type" "fsgn")
8787 (set_attr "mode" "XF")])
8789 ;; Copysign instructions
8791 (define_mode_iterator CSGNMODE [SF DF TF])
8792 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8794 (define_expand "copysign<mode>3"
8795 [(match_operand:CSGNMODE 0 "register_operand" "")
8796 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8797 (match_operand:CSGNMODE 2 "register_operand" "")]
8798 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8799 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8800 "ix86_expand_copysign (operands); DONE;")
8802 (define_insn_and_split "copysign<mode>3_const"
8803 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8805 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8806 (match_operand:CSGNMODE 2 "register_operand" "0")
8807 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812 "&& reload_completed"
8814 "ix86_split_copysign_const (operands); DONE;")
8816 (define_insn "copysign<mode>3_var"
8817 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8819 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8820 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8821 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8822 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8824 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8825 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8826 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8830 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8832 [(match_operand:CSGNMODE 2 "register_operand" "")
8833 (match_operand:CSGNMODE 3 "register_operand" "")
8834 (match_operand:<CSGNVMODE> 4 "" "")
8835 (match_operand:<CSGNVMODE> 5 "" "")]
8837 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8838 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8839 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8840 && reload_completed"
8842 "ix86_split_copysign_var (operands); DONE;")
8844 ;; One complement instructions
8846 (define_expand "one_cmpl<mode>2"
8847 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8848 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8850 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8852 (define_insn "*one_cmpl<mode>2_1"
8853 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8854 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8855 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8856 "not{<imodesuffix>}\t%0"
8857 [(set_attr "type" "negnot")
8858 (set_attr "mode" "<MODE>")])
8860 ;; %%% Potential partial reg stall on alternative 1. What to do?
8861 (define_insn "*one_cmplqi2_1"
8862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8863 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8864 "ix86_unary_operator_ok (NOT, QImode, operands)"
8868 [(set_attr "type" "negnot")
8869 (set_attr "mode" "QI,SI")])
8871 ;; ??? Currently never generated - xor is used instead.
8872 (define_insn "*one_cmplsi2_1_zext"
8873 [(set (match_operand:DI 0 "register_operand" "=r")
8875 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8876 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8878 [(set_attr "type" "negnot")
8879 (set_attr "mode" "SI")])
8881 (define_insn "*one_cmpl<mode>2_2"
8882 [(set (reg FLAGS_REG)
8883 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8885 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8886 (not:SWI (match_dup 1)))]
8887 "ix86_match_ccmode (insn, CCNOmode)
8888 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8890 [(set_attr "type" "alu1")
8891 (set_attr "mode" "<MODE>")])
8894 [(set (match_operand 0 "flags_reg_operand" "")
8895 (match_operator 2 "compare_operator"
8896 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8898 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8899 (not:SWI (match_dup 3)))]
8900 "ix86_match_ccmode (insn, CCNOmode)"
8901 [(parallel [(set (match_dup 0)
8902 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8905 (xor:SWI (match_dup 3) (const_int -1)))])])
8907 ;; ??? Currently never generated - xor is used instead.
8908 (define_insn "*one_cmplsi2_2_zext"
8909 [(set (reg FLAGS_REG)
8910 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8912 (set (match_operand:DI 0 "register_operand" "=r")
8913 (zero_extend:DI (not:SI (match_dup 1))))]
8914 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8915 && ix86_unary_operator_ok (NOT, SImode, operands)"
8917 [(set_attr "type" "alu1")
8918 (set_attr "mode" "SI")])
8921 [(set (match_operand 0 "flags_reg_operand" "")
8922 (match_operator 2 "compare_operator"
8923 [(not:SI (match_operand:SI 3 "register_operand" ""))
8925 (set (match_operand:DI 1 "register_operand" "")
8926 (zero_extend:DI (not:SI (match_dup 3))))]
8927 "ix86_match_ccmode (insn, CCNOmode)"
8928 [(parallel [(set (match_dup 0)
8929 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8932 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8934 ;; Shift instructions
8936 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8937 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8938 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8939 ;; from the assembler input.
8941 ;; This instruction shifts the target reg/mem as usual, but instead of
8942 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8943 ;; is a left shift double, bits are taken from the high order bits of
8944 ;; reg, else if the insn is a shift right double, bits are taken from the
8945 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8946 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8948 ;; Since sh[lr]d does not change the `reg' operand, that is done
8949 ;; separately, making all shifts emit pairs of shift double and normal
8950 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8951 ;; support a 63 bit shift, each shift where the count is in a reg expands
8952 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8954 ;; If the shift count is a constant, we need never emit more than one
8955 ;; shift pair, instead using moves and sign extension for counts greater
8958 (define_expand "ashl<mode>3"
8959 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8960 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8961 (match_operand:QI 2 "nonmemory_operand" "")))]
8963 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8965 (define_insn "*ashl<mode>3_doubleword"
8966 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8967 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8968 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8969 (clobber (reg:CC FLAGS_REG))]
8972 [(set_attr "type" "multi")])
8975 [(set (match_operand:DWI 0 "register_operand" "")
8976 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8977 (match_operand:QI 2 "nonmemory_operand" "")))
8978 (clobber (reg:CC FLAGS_REG))]
8979 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8981 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8983 ;; By default we don't ask for a scratch register, because when DWImode
8984 ;; values are manipulated, registers are already at a premium. But if
8985 ;; we have one handy, we won't turn it away.
8988 [(match_scratch:DWIH 3 "r")
8989 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8991 (match_operand:<DWI> 1 "nonmemory_operand" "")
8992 (match_operand:QI 2 "nonmemory_operand" "")))
8993 (clobber (reg:CC FLAGS_REG))])
8997 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8999 (define_insn "x86_64_shld"
9000 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9001 (ior:DI (ashift:DI (match_dup 0)
9002 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9003 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9004 (minus:QI (const_int 64) (match_dup 2)))))
9005 (clobber (reg:CC FLAGS_REG))]
9007 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9008 [(set_attr "type" "ishift")
9009 (set_attr "prefix_0f" "1")
9010 (set_attr "mode" "DI")
9011 (set_attr "athlon_decode" "vector")
9012 (set_attr "amdfam10_decode" "vector")
9013 (set_attr "bdver1_decode" "vector")])
9015 (define_insn "x86_shld"
9016 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9017 (ior:SI (ashift:SI (match_dup 0)
9018 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9019 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9020 (minus:QI (const_int 32) (match_dup 2)))))
9021 (clobber (reg:CC FLAGS_REG))]
9023 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9024 [(set_attr "type" "ishift")
9025 (set_attr "prefix_0f" "1")
9026 (set_attr "mode" "SI")
9027 (set_attr "pent_pair" "np")
9028 (set_attr "athlon_decode" "vector")
9029 (set_attr "amdfam10_decode" "vector")
9030 (set_attr "bdver1_decode" "vector")])
9032 (define_expand "x86_shift<mode>_adj_1"
9033 [(set (reg:CCZ FLAGS_REG)
9034 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9037 (set (match_operand:SWI48 0 "register_operand" "")
9038 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9039 (match_operand:SWI48 1 "register_operand" "")
9042 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9043 (match_operand:SWI48 3 "register_operand" "r")
9046 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9048 (define_expand "x86_shift<mode>_adj_2"
9049 [(use (match_operand:SWI48 0 "register_operand" ""))
9050 (use (match_operand:SWI48 1 "register_operand" ""))
9051 (use (match_operand:QI 2 "register_operand" ""))]
9054 rtx label = gen_label_rtx ();
9057 emit_insn (gen_testqi_ccz_1 (operands[2],
9058 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9060 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9061 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9062 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9063 gen_rtx_LABEL_REF (VOIDmode, label),
9065 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9066 JUMP_LABEL (tmp) = label;
9068 emit_move_insn (operands[0], operands[1]);
9069 ix86_expand_clear (operands[1]);
9072 LABEL_NUSES (label) = 1;
9077 ;; Avoid useless masking of count operand.
9078 (define_insn_and_split "*ashl<mode>3_mask"
9079 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9081 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9084 (match_operand:SI 2 "nonimmediate_operand" "c")
9085 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9086 (clobber (reg:CC FLAGS_REG))]
9087 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9088 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9089 == GET_MODE_BITSIZE (<MODE>mode)-1"
9092 [(parallel [(set (match_dup 0)
9093 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9094 (clobber (reg:CC FLAGS_REG))])]
9096 if (can_create_pseudo_p ())
9097 operands [2] = force_reg (SImode, operands[2]);
9099 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9101 [(set_attr "type" "ishift")
9102 (set_attr "mode" "<MODE>")])
9104 (define_insn "*bmi2_ashl<mode>3_1"
9105 [(set (match_operand:SWI48 0 "register_operand" "=r")
9106 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9107 (match_operand:SWI48 2 "register_operand" "r")))]
9109 "shlx\t{%2, %1, %0|%0, %1, %2}"
9110 [(set_attr "type" "ishiftx")
9111 (set_attr "mode" "<MODE>")])
9113 (define_insn "*ashl<mode>3_1"
9114 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9115 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9116 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9117 (clobber (reg:CC FLAGS_REG))]
9118 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9120 switch (get_attr_type (insn))
9127 gcc_assert (operands[2] == const1_rtx);
9128 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9129 return "add{<imodesuffix>}\t%0, %0";
9132 if (operands[2] == const1_rtx
9133 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9134 return "sal{<imodesuffix>}\t%0";
9136 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9139 [(set_attr "isa" "*,*,bmi2")
9141 (cond [(eq_attr "alternative" "1")
9142 (const_string "lea")
9143 (eq_attr "alternative" "2")
9144 (const_string "ishiftx")
9145 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9146 (match_operand 0 "register_operand" ""))
9147 (match_operand 2 "const1_operand" ""))
9148 (const_string "alu")
9150 (const_string "ishift")))
9151 (set (attr "length_immediate")
9153 (ior (eq_attr "type" "alu")
9154 (and (eq_attr "type" "ishift")
9155 (and (match_operand 2 "const1_operand" "")
9156 (ior (match_test "TARGET_SHIFT1")
9157 (match_test "optimize_function_for_size_p (cfun)")))))
9159 (const_string "*")))
9160 (set_attr "mode" "<MODE>")])
9162 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9164 [(set (match_operand:SWI48 0 "register_operand" "")
9165 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9166 (match_operand:QI 2 "register_operand" "")))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "TARGET_BMI2 && reload_completed"
9170 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9171 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9173 (define_insn "*bmi2_ashlsi3_1_zext"
9174 [(set (match_operand:DI 0 "register_operand" "=r")
9176 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9177 (match_operand:SI 2 "register_operand" "r"))))]
9178 "TARGET_64BIT && TARGET_BMI2"
9179 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9180 [(set_attr "type" "ishiftx")
9181 (set_attr "mode" "SI")])
9183 (define_insn "*ashlsi3_1_zext"
9184 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9186 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9187 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9191 switch (get_attr_type (insn))
9198 gcc_assert (operands[2] == const1_rtx);
9199 return "add{l}\t%k0, %k0";
9202 if (operands[2] == const1_rtx
9203 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9204 return "sal{l}\t%k0";
9206 return "sal{l}\t{%2, %k0|%k0, %2}";
9209 [(set_attr "isa" "*,*,bmi2")
9211 (cond [(eq_attr "alternative" "1")
9212 (const_string "lea")
9213 (eq_attr "alternative" "2")
9214 (const_string "ishiftx")
9215 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9216 (match_operand 2 "const1_operand" ""))
9217 (const_string "alu")
9219 (const_string "ishift")))
9220 (set (attr "length_immediate")
9222 (ior (eq_attr "type" "alu")
9223 (and (eq_attr "type" "ishift")
9224 (and (match_operand 2 "const1_operand" "")
9225 (ior (match_test "TARGET_SHIFT1")
9226 (match_test "optimize_function_for_size_p (cfun)")))))
9228 (const_string "*")))
9229 (set_attr "mode" "SI")])
9231 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9233 [(set (match_operand:DI 0 "register_operand" "")
9235 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9236 (match_operand:QI 2 "register_operand" ""))))
9237 (clobber (reg:CC FLAGS_REG))]
9238 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9240 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9241 "operands[2] = gen_lowpart (SImode, operands[2]);")
9243 (define_insn "*ashlhi3_1"
9244 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9245 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9246 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9250 switch (get_attr_type (insn))
9256 gcc_assert (operands[2] == const1_rtx);
9257 return "add{w}\t%0, %0";
9260 if (operands[2] == const1_rtx
9261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262 return "sal{w}\t%0";
9264 return "sal{w}\t{%2, %0|%0, %2}";
9268 (cond [(eq_attr "alternative" "1")
9269 (const_string "lea")
9270 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9271 (match_operand 0 "register_operand" ""))
9272 (match_operand 2 "const1_operand" ""))
9273 (const_string "alu")
9275 (const_string "ishift")))
9276 (set (attr "length_immediate")
9278 (ior (eq_attr "type" "alu")
9279 (and (eq_attr "type" "ishift")
9280 (and (match_operand 2 "const1_operand" "")
9281 (ior (match_test "TARGET_SHIFT1")
9282 (match_test "optimize_function_for_size_p (cfun)")))))
9284 (const_string "*")))
9285 (set_attr "mode" "HI,SI")])
9287 ;; %%% Potential partial reg stall on alternative 1. What to do?
9288 (define_insn "*ashlqi3_1"
9289 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9290 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9291 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9292 (clobber (reg:CC FLAGS_REG))]
9293 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9295 switch (get_attr_type (insn))
9301 gcc_assert (operands[2] == const1_rtx);
9302 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303 return "add{l}\t%k0, %k0";
9305 return "add{b}\t%0, %0";
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 if (get_attr_mode (insn) == MODE_SI)
9312 return "sal{l}\t%k0";
9314 return "sal{b}\t%0";
9318 if (get_attr_mode (insn) == MODE_SI)
9319 return "sal{l}\t{%2, %k0|%k0, %2}";
9321 return "sal{b}\t{%2, %0|%0, %2}";
9326 (cond [(eq_attr "alternative" "2")
9327 (const_string "lea")
9328 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9329 (match_operand 0 "register_operand" ""))
9330 (match_operand 2 "const1_operand" ""))
9331 (const_string "alu")
9333 (const_string "ishift")))
9334 (set (attr "length_immediate")
9336 (ior (eq_attr "type" "alu")
9337 (and (eq_attr "type" "ishift")
9338 (and (match_operand 2 "const1_operand" "")
9339 (ior (match_test "TARGET_SHIFT1")
9340 (match_test "optimize_function_for_size_p (cfun)")))))
9342 (const_string "*")))
9343 (set_attr "mode" "QI,SI,SI")])
9345 (define_insn "*ashlqi3_1_slp"
9346 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9347 (ashift:QI (match_dup 0)
9348 (match_operand:QI 1 "nonmemory_operand" "cI")))
9349 (clobber (reg:CC FLAGS_REG))]
9350 "(optimize_function_for_size_p (cfun)
9351 || !TARGET_PARTIAL_FLAG_REG_STALL
9352 || (operands[1] == const1_rtx
9354 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9356 switch (get_attr_type (insn))
9359 gcc_assert (operands[1] == const1_rtx);
9360 return "add{b}\t%0, %0";
9363 if (operands[1] == const1_rtx
9364 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9365 return "sal{b}\t%0";
9367 return "sal{b}\t{%1, %0|%0, %1}";
9371 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9372 (match_operand 0 "register_operand" ""))
9373 (match_operand 1 "const1_operand" ""))
9374 (const_string "alu")
9376 (const_string "ishift1")))
9377 (set (attr "length_immediate")
9379 (ior (eq_attr "type" "alu")
9380 (and (eq_attr "type" "ishift1")
9381 (and (match_operand 1 "const1_operand" "")
9382 (ior (match_test "TARGET_SHIFT1")
9383 (match_test "optimize_function_for_size_p (cfun)")))))
9385 (const_string "*")))
9386 (set_attr "mode" "QI")])
9388 ;; Convert ashift to the lea pattern to avoid flags dependency.
9390 [(set (match_operand 0 "register_operand" "")
9391 (ashift (match_operand 1 "index_register_operand" "")
9392 (match_operand:QI 2 "const_int_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9396 && true_regnum (operands[0]) != true_regnum (operands[1])"
9399 enum machine_mode mode = GET_MODE (operands[0]);
9402 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9405 operands[0] = gen_lowpart (mode, operands[0]);
9406 operands[1] = gen_lowpart (mode, operands[1]);
9409 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9411 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9413 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9417 ;; Convert ashift to the lea pattern to avoid flags dependency.
9419 [(set (match_operand:DI 0 "register_operand" "")
9421 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9422 (match_operand:QI 2 "const_int_operand" ""))))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "TARGET_64BIT && reload_completed
9425 && true_regnum (operands[0]) != true_regnum (operands[1])"
9427 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9429 operands[1] = gen_lowpart (DImode, operands[1]);
9430 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9433 ;; This pattern can't accept a variable shift count, since shifts by
9434 ;; zero don't affect the flags. We assume that shifts by constant
9435 ;; zero are optimized away.
9436 (define_insn "*ashl<mode>3_cmp"
9437 [(set (reg FLAGS_REG)
9439 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9440 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9442 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9443 (ashift:SWI (match_dup 1) (match_dup 2)))]
9444 "(optimize_function_for_size_p (cfun)
9445 || !TARGET_PARTIAL_FLAG_REG_STALL
9446 || (operands[2] == const1_rtx
9448 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9449 && ix86_match_ccmode (insn, CCGOCmode)
9450 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9452 switch (get_attr_type (insn))
9455 gcc_assert (operands[2] == const1_rtx);
9456 return "add{<imodesuffix>}\t%0, %0";
9459 if (operands[2] == const1_rtx
9460 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9461 return "sal{<imodesuffix>}\t%0";
9463 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9467 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9468 (match_operand 0 "register_operand" ""))
9469 (match_operand 2 "const1_operand" ""))
9470 (const_string "alu")
9472 (const_string "ishift")))
9473 (set (attr "length_immediate")
9475 (ior (eq_attr "type" "alu")
9476 (and (eq_attr "type" "ishift")
9477 (and (match_operand 2 "const1_operand" "")
9478 (ior (match_test "TARGET_SHIFT1")
9479 (match_test "optimize_function_for_size_p (cfun)")))))
9481 (const_string "*")))
9482 (set_attr "mode" "<MODE>")])
9484 (define_insn "*ashlsi3_cmp_zext"
9485 [(set (reg FLAGS_REG)
9487 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9488 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9490 (set (match_operand:DI 0 "register_operand" "=r")
9491 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9493 && (optimize_function_for_size_p (cfun)
9494 || !TARGET_PARTIAL_FLAG_REG_STALL
9495 || (operands[2] == const1_rtx
9497 || TARGET_DOUBLE_WITH_ADD)))
9498 && ix86_match_ccmode (insn, CCGOCmode)
9499 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9501 switch (get_attr_type (insn))
9504 gcc_assert (operands[2] == const1_rtx);
9505 return "add{l}\t%k0, %k0";
9508 if (operands[2] == const1_rtx
9509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9510 return "sal{l}\t%k0";
9512 return "sal{l}\t{%2, %k0|%k0, %2}";
9516 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9517 (match_operand 2 "const1_operand" ""))
9518 (const_string "alu")
9520 (const_string "ishift")))
9521 (set (attr "length_immediate")
9523 (ior (eq_attr "type" "alu")
9524 (and (eq_attr "type" "ishift")
9525 (and (match_operand 2 "const1_operand" "")
9526 (ior (match_test "TARGET_SHIFT1")
9527 (match_test "optimize_function_for_size_p (cfun)")))))
9529 (const_string "*")))
9530 (set_attr "mode" "SI")])
9532 (define_insn "*ashl<mode>3_cconly"
9533 [(set (reg FLAGS_REG)
9535 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9536 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9538 (clobber (match_scratch:SWI 0 "=<r>"))]
9539 "(optimize_function_for_size_p (cfun)
9540 || !TARGET_PARTIAL_FLAG_REG_STALL
9541 || (operands[2] == const1_rtx
9543 || TARGET_DOUBLE_WITH_ADD)))
9544 && ix86_match_ccmode (insn, CCGOCmode)"
9546 switch (get_attr_type (insn))
9549 gcc_assert (operands[2] == const1_rtx);
9550 return "add{<imodesuffix>}\t%0, %0";
9553 if (operands[2] == const1_rtx
9554 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9555 return "sal{<imodesuffix>}\t%0";
9557 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9561 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9562 (match_operand 0 "register_operand" ""))
9563 (match_operand 2 "const1_operand" ""))
9564 (const_string "alu")
9566 (const_string "ishift")))
9567 (set (attr "length_immediate")
9569 (ior (eq_attr "type" "alu")
9570 (and (eq_attr "type" "ishift")
9571 (and (match_operand 2 "const1_operand" "")
9572 (ior (match_test "TARGET_SHIFT1")
9573 (match_test "optimize_function_for_size_p (cfun)")))))
9575 (const_string "*")))
9576 (set_attr "mode" "<MODE>")])
9578 ;; See comment above `ashl<mode>3' about how this works.
9580 (define_expand "<shiftrt_insn><mode>3"
9581 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9583 (match_operand:QI 2 "nonmemory_operand" "")))]
9585 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9587 ;; Avoid useless masking of count operand.
9588 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9589 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9591 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9594 (match_operand:SI 2 "nonimmediate_operand" "c")
9595 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9596 (clobber (reg:CC FLAGS_REG))]
9597 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9598 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9599 == GET_MODE_BITSIZE (<MODE>mode)-1"
9602 [(parallel [(set (match_dup 0)
9603 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9604 (clobber (reg:CC FLAGS_REG))])]
9606 if (can_create_pseudo_p ())
9607 operands [2] = force_reg (SImode, operands[2]);
9609 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9611 [(set_attr "type" "ishift")
9612 (set_attr "mode" "<MODE>")])
9614 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9615 [(set (match_operand:DWI 0 "register_operand" "=r")
9616 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9617 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9618 (clobber (reg:CC FLAGS_REG))]
9621 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9623 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9624 [(set_attr "type" "multi")])
9626 ;; By default we don't ask for a scratch register, because when DWImode
9627 ;; values are manipulated, registers are already at a premium. But if
9628 ;; we have one handy, we won't turn it away.
9631 [(match_scratch:DWIH 3 "r")
9632 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9634 (match_operand:<DWI> 1 "register_operand" "")
9635 (match_operand:QI 2 "nonmemory_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))])
9640 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9642 (define_insn "x86_64_shrd"
9643 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9644 (ior:DI (ashiftrt:DI (match_dup 0)
9645 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9646 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9647 (minus:QI (const_int 64) (match_dup 2)))))
9648 (clobber (reg:CC FLAGS_REG))]
9650 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9651 [(set_attr "type" "ishift")
9652 (set_attr "prefix_0f" "1")
9653 (set_attr "mode" "DI")
9654 (set_attr "athlon_decode" "vector")
9655 (set_attr "amdfam10_decode" "vector")
9656 (set_attr "bdver1_decode" "vector")])
9658 (define_insn "x86_shrd"
9659 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9660 (ior:SI (ashiftrt:SI (match_dup 0)
9661 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9662 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9663 (minus:QI (const_int 32) (match_dup 2)))))
9664 (clobber (reg:CC FLAGS_REG))]
9666 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9667 [(set_attr "type" "ishift")
9668 (set_attr "prefix_0f" "1")
9669 (set_attr "mode" "SI")
9670 (set_attr "pent_pair" "np")
9671 (set_attr "athlon_decode" "vector")
9672 (set_attr "amdfam10_decode" "vector")
9673 (set_attr "bdver1_decode" "vector")])
9675 (define_insn "ashrdi3_cvt"
9676 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9677 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9678 (match_operand:QI 2 "const_int_operand" "")))
9679 (clobber (reg:CC FLAGS_REG))]
9680 "TARGET_64BIT && INTVAL (operands[2]) == 63
9681 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9682 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9685 sar{q}\t{%2, %0|%0, %2}"
9686 [(set_attr "type" "imovx,ishift")
9687 (set_attr "prefix_0f" "0,*")
9688 (set_attr "length_immediate" "0,*")
9689 (set_attr "modrm" "0,1")
9690 (set_attr "mode" "DI")])
9692 (define_insn "ashrsi3_cvt"
9693 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9694 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9695 (match_operand:QI 2 "const_int_operand" "")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "INTVAL (operands[2]) == 31
9698 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9699 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9702 sar{l}\t{%2, %0|%0, %2}"
9703 [(set_attr "type" "imovx,ishift")
9704 (set_attr "prefix_0f" "0,*")
9705 (set_attr "length_immediate" "0,*")
9706 (set_attr "modrm" "0,1")
9707 (set_attr "mode" "SI")])
9709 (define_insn "*ashrsi3_cvt_zext"
9710 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9713 (match_operand:QI 2 "const_int_operand" ""))))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "TARGET_64BIT && INTVAL (operands[2]) == 31
9716 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9717 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9720 sar{l}\t{%2, %k0|%k0, %2}"
9721 [(set_attr "type" "imovx,ishift")
9722 (set_attr "prefix_0f" "0,*")
9723 (set_attr "length_immediate" "0,*")
9724 (set_attr "modrm" "0,1")
9725 (set_attr "mode" "SI")])
9727 (define_expand "x86_shift<mode>_adj_3"
9728 [(use (match_operand:SWI48 0 "register_operand" ""))
9729 (use (match_operand:SWI48 1 "register_operand" ""))
9730 (use (match_operand:QI 2 "register_operand" ""))]
9733 rtx label = gen_label_rtx ();
9736 emit_insn (gen_testqi_ccz_1 (operands[2],
9737 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9739 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9740 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9741 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9742 gen_rtx_LABEL_REF (VOIDmode, label),
9744 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9745 JUMP_LABEL (tmp) = label;
9747 emit_move_insn (operands[0], operands[1]);
9748 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9749 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9751 LABEL_NUSES (label) = 1;
9756 (define_insn "*bmi2_<shiftrt_insn><mode>3_1"
9757 [(set (match_operand:SWI48 0 "register_operand" "=r")
9758 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9759 (match_operand:SWI48 2 "register_operand" "r")))]
9761 "<shiftrt>x\t{%2, %1, %0|%0, %1, %2}"
9762 [(set_attr "type" "ishiftx")
9763 (set_attr "mode" "<MODE>")])
9765 (define_insn "*<shiftrt_insn><mode>3_1"
9766 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9768 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9769 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9770 (clobber (reg:CC FLAGS_REG))]
9771 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9773 switch (get_attr_type (insn))
9779 if (operands[2] == const1_rtx
9780 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9781 return "<shiftrt>{<imodesuffix>}\t%0";
9783 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9786 [(set_attr "isa" "*,bmi2")
9787 (set_attr "type" "ishift,ishiftx")
9788 (set (attr "length_immediate")
9790 (and (match_operand 2 "const1_operand" "")
9791 (ior (match_test "TARGET_SHIFT1")
9792 (match_test "optimize_function_for_size_p (cfun)")))
9794 (const_string "*")))
9795 (set_attr "mode" "<MODE>")])
9797 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9799 [(set (match_operand:SWI48 0 "register_operand" "")
9800 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9801 (match_operand:QI 2 "register_operand" "")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "TARGET_BMI2 && reload_completed"
9805 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9806 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9808 (define_insn "*bmi2_<shiftrt_insn>si3_1_zext"
9809 [(set (match_operand:DI 0 "register_operand" "=r")
9811 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9812 (match_operand:SI 2 "register_operand" "r"))))]
9813 "TARGET_64BIT && TARGET_BMI2"
9814 "<shiftrt>x\t{%2, %1, %k0|%k0, %1, %2}"
9815 [(set_attr "type" "ishiftx")
9816 (set_attr "mode" "SI")])
9818 (define_insn "*<shiftrt_insn>si3_1_zext"
9819 [(set (match_operand:DI 0 "register_operand" "=r,r")
9821 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9822 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9823 (clobber (reg:CC FLAGS_REG))]
9824 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9826 switch (get_attr_type (insn))
9832 if (operands[2] == const1_rtx
9833 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9834 return "<shiftrt>{l}\t%k0";
9836 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9839 [(set_attr "isa" "*,bmi2")
9840 (set_attr "type" "ishift,ishiftx")
9841 (set (attr "length_immediate")
9843 (and (match_operand 2 "const1_operand" "")
9844 (ior (match_test "TARGET_SHIFT1")
9845 (match_test "optimize_function_for_size_p (cfun)")))
9847 (const_string "*")))
9848 (set_attr "mode" "SI")])
9850 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9852 [(set (match_operand:DI 0 "register_operand" "")
9854 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9855 (match_operand:QI 2 "register_operand" ""))))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9859 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9860 "operands[2] = gen_lowpart (SImode, operands[2]);")
9862 (define_insn "*<shiftrt_insn><mode>3_1"
9863 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9865 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9866 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9867 (clobber (reg:CC FLAGS_REG))]
9868 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<shiftrt>{<imodesuffix>}\t%0";
9874 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9876 [(set_attr "type" "ishift")
9877 (set (attr "length_immediate")
9879 (and (match_operand 2 "const1_operand" "")
9880 (ior (match_test "TARGET_SHIFT1")
9881 (match_test "optimize_function_for_size_p (cfun)")))
9883 (const_string "*")))
9884 (set_attr "mode" "<MODE>")])
9886 (define_insn "*<shiftrt_insn>qi3_1_slp"
9887 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9888 (any_shiftrt:QI (match_dup 0)
9889 (match_operand:QI 1 "nonmemory_operand" "cI")))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "(optimize_function_for_size_p (cfun)
9892 || !TARGET_PARTIAL_REG_STALL
9893 || (operands[1] == const1_rtx
9896 if (operands[1] == const1_rtx
9897 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9898 return "<shiftrt>{b}\t%0";
9900 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9902 [(set_attr "type" "ishift1")
9903 (set (attr "length_immediate")
9905 (and (match_operand 1 "const1_operand" "")
9906 (ior (match_test "TARGET_SHIFT1")
9907 (match_test "optimize_function_for_size_p (cfun)")))
9909 (const_string "*")))
9910 (set_attr "mode" "QI")])
9912 ;; This pattern can't accept a variable shift count, since shifts by
9913 ;; zero don't affect the flags. We assume that shifts by constant
9914 ;; zero are optimized away.
9915 (define_insn "*<shiftrt_insn><mode>3_cmp"
9916 [(set (reg FLAGS_REG)
9919 (match_operand:SWI 1 "nonimmediate_operand" "0")
9920 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9922 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9923 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9924 "(optimize_function_for_size_p (cfun)
9925 || !TARGET_PARTIAL_FLAG_REG_STALL
9926 || (operands[2] == const1_rtx
9928 && ix86_match_ccmode (insn, CCGOCmode)
9929 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9931 if (operands[2] == const1_rtx
9932 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9933 return "<shiftrt>{<imodesuffix>}\t%0";
9935 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9937 [(set_attr "type" "ishift")
9938 (set (attr "length_immediate")
9940 (and (match_operand 2 "const1_operand" "")
9941 (ior (match_test "TARGET_SHIFT1")
9942 (match_test "optimize_function_for_size_p (cfun)")))
9944 (const_string "*")))
9945 (set_attr "mode" "<MODE>")])
9947 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9948 [(set (reg FLAGS_REG)
9950 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9951 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9953 (set (match_operand:DI 0 "register_operand" "=r")
9954 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9956 && (optimize_function_for_size_p (cfun)
9957 || !TARGET_PARTIAL_FLAG_REG_STALL
9958 || (operands[2] == const1_rtx
9960 && ix86_match_ccmode (insn, CCGOCmode)
9961 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9963 if (operands[2] == const1_rtx
9964 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965 return "<shiftrt>{l}\t%k0";
9967 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9969 [(set_attr "type" "ishift")
9970 (set (attr "length_immediate")
9972 (and (match_operand 2 "const1_operand" "")
9973 (ior (match_test "TARGET_SHIFT1")
9974 (match_test "optimize_function_for_size_p (cfun)")))
9976 (const_string "*")))
9977 (set_attr "mode" "SI")])
9979 (define_insn "*<shiftrt_insn><mode>3_cconly"
9980 [(set (reg FLAGS_REG)
9983 (match_operand:SWI 1 "register_operand" "0")
9984 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9986 (clobber (match_scratch:SWI 0 "=<r>"))]
9987 "(optimize_function_for_size_p (cfun)
9988 || !TARGET_PARTIAL_FLAG_REG_STALL
9989 || (operands[2] == const1_rtx
9991 && ix86_match_ccmode (insn, CCGOCmode)"
9993 if (operands[2] == const1_rtx
9994 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995 return "<shiftrt>{<imodesuffix>}\t%0";
9997 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9999 [(set_attr "type" "ishift")
10000 (set (attr "length_immediate")
10002 (and (match_operand 2 "const1_operand" "")
10003 (ior (match_test "TARGET_SHIFT1")
10004 (match_test "optimize_function_for_size_p (cfun)")))
10006 (const_string "*")))
10007 (set_attr "mode" "<MODE>")])
10009 ;; Rotate instructions
10011 (define_expand "<rotate_insn>ti3"
10012 [(set (match_operand:TI 0 "register_operand" "")
10013 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10014 (match_operand:QI 2 "nonmemory_operand" "")))]
10017 if (const_1_to_63_operand (operands[2], VOIDmode))
10018 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10019 (operands[0], operands[1], operands[2]));
10026 (define_expand "<rotate_insn>di3"
10027 [(set (match_operand:DI 0 "shiftdi_operand" "")
10028 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10029 (match_operand:QI 2 "nonmemory_operand" "")))]
10033 ix86_expand_binary_operator (<CODE>, DImode, operands);
10034 else if (const_1_to_31_operand (operands[2], VOIDmode))
10035 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10036 (operands[0], operands[1], operands[2]));
10043 (define_expand "<rotate_insn><mode>3"
10044 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10045 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10046 (match_operand:QI 2 "nonmemory_operand" "")))]
10048 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10050 ;; Avoid useless masking of count operand.
10051 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10052 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10054 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10057 (match_operand:SI 2 "nonimmediate_operand" "c")
10058 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10059 (clobber (reg:CC FLAGS_REG))]
10060 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10061 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10062 == GET_MODE_BITSIZE (<MODE>mode)-1"
10065 [(parallel [(set (match_dup 0)
10066 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10067 (clobber (reg:CC FLAGS_REG))])]
10069 if (can_create_pseudo_p ())
10070 operands [2] = force_reg (SImode, operands[2]);
10072 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10074 [(set_attr "type" "rotate")
10075 (set_attr "mode" "<MODE>")])
10077 ;; Implement rotation using two double-precision
10078 ;; shift instructions and a scratch register.
10080 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10081 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10082 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10083 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10084 (clobber (reg:CC FLAGS_REG))
10085 (clobber (match_scratch:DWIH 3 "=&r"))]
10089 [(set (match_dup 3) (match_dup 4))
10091 [(set (match_dup 4)
10092 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10093 (lshiftrt:DWIH (match_dup 5)
10094 (minus:QI (match_dup 6) (match_dup 2)))))
10095 (clobber (reg:CC FLAGS_REG))])
10097 [(set (match_dup 5)
10098 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10099 (lshiftrt:DWIH (match_dup 3)
10100 (minus:QI (match_dup 6) (match_dup 2)))))
10101 (clobber (reg:CC FLAGS_REG))])]
10103 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10105 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10108 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10109 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10110 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10111 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10112 (clobber (reg:CC FLAGS_REG))
10113 (clobber (match_scratch:DWIH 3 "=&r"))]
10117 [(set (match_dup 3) (match_dup 4))
10119 [(set (match_dup 4)
10120 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10121 (ashift:DWIH (match_dup 5)
10122 (minus:QI (match_dup 6) (match_dup 2)))))
10123 (clobber (reg:CC FLAGS_REG))])
10125 [(set (match_dup 5)
10126 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10127 (ashift:DWIH (match_dup 3)
10128 (minus:QI (match_dup 6) (match_dup 2)))))
10129 (clobber (reg:CC FLAGS_REG))])]
10131 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10133 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10136 (define_insn "*bmi2_rorx<mode>3_1"
10137 [(set (match_operand:SWI48 0 "register_operand" "=r")
10138 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10139 (match_operand:QI 2 "immediate_operand" "<S>")))]
10141 "rorx\t{%2, %1, %0|%0, %1, %2}"
10142 [(set_attr "type" "rotatex")
10143 (set_attr "mode" "<MODE>")])
10145 (define_insn "*<rotate_insn><mode>3_1"
10146 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10148 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10149 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10150 (clobber (reg:CC FLAGS_REG))]
10151 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10153 switch (get_attr_type (insn))
10159 if (operands[2] == const1_rtx
10160 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10161 return "<rotate>{<imodesuffix>}\t%0";
10163 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10166 [(set_attr "isa" "*,bmi2")
10167 (set_attr "type" "rotate,rotatex")
10168 (set (attr "length_immediate")
10170 (and (eq_attr "type" "rotate")
10171 (and (match_operand 2 "const1_operand" "")
10172 (ior (match_test "TARGET_SHIFT1")
10173 (match_test "optimize_function_for_size_p (cfun)"))))
10175 (const_string "*")))
10176 (set_attr "mode" "<MODE>")])
10178 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10180 [(set (match_operand:SWI48 0 "register_operand" "")
10181 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10182 (match_operand:QI 2 "immediate_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "TARGET_BMI2 && reload_completed"
10185 [(set (match_dup 0)
10186 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10189 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10193 [(set (match_operand:SWI48 0 "register_operand" "")
10194 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10195 (match_operand:QI 2 "immediate_operand" "")))
10196 (clobber (reg:CC FLAGS_REG))]
10197 "TARGET_BMI2 && reload_completed"
10198 [(set (match_dup 0)
10199 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10201 (define_insn "*bmi2_rorxsi3_1_zext"
10202 [(set (match_operand:DI 0 "register_operand" "=r")
10204 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10205 (match_operand:QI 2 "immediate_operand" "I"))))]
10206 "TARGET_64BIT && TARGET_BMI2"
10207 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10208 [(set_attr "type" "rotatex")
10209 (set_attr "mode" "SI")])
10211 (define_insn "*<rotate_insn>si3_1_zext"
10212 [(set (match_operand:DI 0 "register_operand" "=r,r")
10214 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10215 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10216 (clobber (reg:CC FLAGS_REG))]
10217 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10219 switch (get_attr_type (insn))
10225 if (operands[2] == const1_rtx
10226 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10227 return "<rotate>{l}\t%k0";
10229 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10232 [(set_attr "isa" "*,bmi2")
10233 (set_attr "type" "rotate,rotatex")
10234 (set (attr "length_immediate")
10236 (and (eq_attr "type" "rotate")
10237 (and (match_operand 2 "const1_operand" "")
10238 (ior (match_test "TARGET_SHIFT1")
10239 (match_test "optimize_function_for_size_p (cfun)"))))
10241 (const_string "*")))
10242 (set_attr "mode" "SI")])
10244 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10246 [(set (match_operand:DI 0 "register_operand" "")
10248 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10249 (match_operand:QI 2 "immediate_operand" ""))))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10252 [(set (match_dup 0)
10253 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10256 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10260 [(set (match_operand:DI 0 "register_operand" "")
10262 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10263 (match_operand:QI 2 "immediate_operand" ""))))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10266 [(set (match_dup 0)
10267 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10269 (define_insn "*<rotate_insn><mode>3_1"
10270 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10271 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10272 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10273 (clobber (reg:CC FLAGS_REG))]
10274 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10276 if (operands[2] == const1_rtx
10277 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10278 return "<rotate>{<imodesuffix>}\t%0";
10280 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10282 [(set_attr "type" "rotate")
10283 (set (attr "length_immediate")
10285 (and (match_operand 2 "const1_operand" "")
10286 (ior (match_test "TARGET_SHIFT1")
10287 (match_test "optimize_function_for_size_p (cfun)")))
10289 (const_string "*")))
10290 (set_attr "mode" "<MODE>")])
10292 (define_insn "*<rotate_insn>qi3_1_slp"
10293 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10294 (any_rotate:QI (match_dup 0)
10295 (match_operand:QI 1 "nonmemory_operand" "cI")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "(optimize_function_for_size_p (cfun)
10298 || !TARGET_PARTIAL_REG_STALL
10299 || (operands[1] == const1_rtx
10300 && TARGET_SHIFT1))"
10302 if (operands[1] == const1_rtx
10303 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10304 return "<rotate>{b}\t%0";
10306 return "<rotate>{b}\t{%1, %0|%0, %1}";
10308 [(set_attr "type" "rotate1")
10309 (set (attr "length_immediate")
10311 (and (match_operand 1 "const1_operand" "")
10312 (ior (match_test "TARGET_SHIFT1")
10313 (match_test "optimize_function_for_size_p (cfun)")))
10315 (const_string "*")))
10316 (set_attr "mode" "QI")])
10319 [(set (match_operand:HI 0 "register_operand" "")
10320 (any_rotate:HI (match_dup 0) (const_int 8)))
10321 (clobber (reg:CC FLAGS_REG))]
10323 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10324 [(parallel [(set (strict_low_part (match_dup 0))
10325 (bswap:HI (match_dup 0)))
10326 (clobber (reg:CC FLAGS_REG))])])
10328 ;; Bit set / bit test instructions
10330 (define_expand "extv"
10331 [(set (match_operand:SI 0 "register_operand" "")
10332 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10333 (match_operand:SI 2 "const8_operand" "")
10334 (match_operand:SI 3 "const8_operand" "")))]
10337 /* Handle extractions from %ah et al. */
10338 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10341 /* From mips.md: extract_bit_field doesn't verify that our source
10342 matches the predicate, so check it again here. */
10343 if (! ext_register_operand (operands[1], VOIDmode))
10347 (define_expand "extzv"
10348 [(set (match_operand:SI 0 "register_operand" "")
10349 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10350 (match_operand:SI 2 "const8_operand" "")
10351 (match_operand:SI 3 "const8_operand" "")))]
10354 /* Handle extractions from %ah et al. */
10355 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10358 /* From mips.md: extract_bit_field doesn't verify that our source
10359 matches the predicate, so check it again here. */
10360 if (! ext_register_operand (operands[1], VOIDmode))
10364 (define_expand "insv"
10365 [(set (zero_extract (match_operand 0 "register_operand" "")
10366 (match_operand 1 "const_int_operand" "")
10367 (match_operand 2 "const_int_operand" ""))
10368 (match_operand 3 "register_operand" ""))]
10371 rtx (*gen_mov_insv_1) (rtx, rtx);
10373 if (ix86_expand_pinsr (operands))
10376 /* Handle insertions to %ah et al. */
10377 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10380 /* From mips.md: insert_bit_field doesn't verify that our source
10381 matches the predicate, so check it again here. */
10382 if (! ext_register_operand (operands[0], VOIDmode))
10385 gen_mov_insv_1 = (TARGET_64BIT
10386 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10388 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10392 ;; %%% bts, btr, btc, bt.
10393 ;; In general these instructions are *slow* when applied to memory,
10394 ;; since they enforce atomic operation. When applied to registers,
10395 ;; it depends on the cpu implementation. They're never faster than
10396 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10397 ;; no point. But in 64-bit, we can't hold the relevant immediates
10398 ;; within the instruction itself, so operating on bits in the high
10399 ;; 32-bits of a register becomes easier.
10401 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10402 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10403 ;; negdf respectively, so they can never be disabled entirely.
10405 (define_insn "*btsq"
10406 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412 "bts{q}\t{%1, %0|%0, %1}"
10413 [(set_attr "type" "alu1")
10414 (set_attr "prefix_0f" "1")
10415 (set_attr "mode" "DI")])
10417 (define_insn "*btrq"
10418 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10420 (match_operand:DI 1 "const_0_to_63_operand" ""))
10422 (clobber (reg:CC FLAGS_REG))]
10423 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424 "btr{q}\t{%1, %0|%0, %1}"
10425 [(set_attr "type" "alu1")
10426 (set_attr "prefix_0f" "1")
10427 (set_attr "mode" "DI")])
10429 (define_insn "*btcq"
10430 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10432 (match_operand:DI 1 "const_0_to_63_operand" ""))
10433 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10434 (clobber (reg:CC FLAGS_REG))]
10435 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10436 "btc{q}\t{%1, %0|%0, %1}"
10437 [(set_attr "type" "alu1")
10438 (set_attr "prefix_0f" "1")
10439 (set_attr "mode" "DI")])
10441 ;; Allow Nocona to avoid these instructions if a register is available.
10444 [(match_scratch:DI 2 "r")
10445 (parallel [(set (zero_extract:DI
10446 (match_operand:DI 0 "register_operand" "")
10448 (match_operand:DI 1 "const_0_to_63_operand" ""))
10450 (clobber (reg:CC FLAGS_REG))])]
10451 "TARGET_64BIT && !TARGET_USE_BT"
10454 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10457 if (HOST_BITS_PER_WIDE_INT >= 64)
10458 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10459 else if (i < HOST_BITS_PER_WIDE_INT)
10460 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10464 op1 = immed_double_const (lo, hi, DImode);
10467 emit_move_insn (operands[2], op1);
10471 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10476 [(match_scratch:DI 2 "r")
10477 (parallel [(set (zero_extract:DI
10478 (match_operand:DI 0 "register_operand" "")
10480 (match_operand:DI 1 "const_0_to_63_operand" ""))
10482 (clobber (reg:CC FLAGS_REG))])]
10483 "TARGET_64BIT && !TARGET_USE_BT"
10486 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10489 if (HOST_BITS_PER_WIDE_INT >= 64)
10490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491 else if (i < HOST_BITS_PER_WIDE_INT)
10492 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496 op1 = immed_double_const (~lo, ~hi, DImode);
10499 emit_move_insn (operands[2], op1);
10503 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10508 [(match_scratch:DI 2 "r")
10509 (parallel [(set (zero_extract:DI
10510 (match_operand:DI 0 "register_operand" "")
10512 (match_operand:DI 1 "const_0_to_63_operand" ""))
10513 (not:DI (zero_extract:DI
10514 (match_dup 0) (const_int 1) (match_dup 1))))
10515 (clobber (reg:CC FLAGS_REG))])]
10516 "TARGET_64BIT && !TARGET_USE_BT"
10519 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10522 if (HOST_BITS_PER_WIDE_INT >= 64)
10523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524 else if (i < HOST_BITS_PER_WIDE_INT)
10525 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10529 op1 = immed_double_const (lo, hi, DImode);
10532 emit_move_insn (operands[2], op1);
10536 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10540 (define_insn "*bt<mode>"
10541 [(set (reg:CCC FLAGS_REG)
10543 (zero_extract:SWI48
10544 (match_operand:SWI48 0 "register_operand" "r")
10546 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10548 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10549 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10550 [(set_attr "type" "alu1")
10551 (set_attr "prefix_0f" "1")
10552 (set_attr "mode" "<MODE>")])
10554 ;; Store-flag instructions.
10556 ;; For all sCOND expanders, also expand the compare or test insn that
10557 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10559 (define_insn_and_split "*setcc_di_1"
10560 [(set (match_operand:DI 0 "register_operand" "=q")
10561 (match_operator:DI 1 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)]))]
10563 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10565 "&& reload_completed"
10566 [(set (match_dup 2) (match_dup 1))
10567 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10569 PUT_MODE (operands[1], QImode);
10570 operands[2] = gen_lowpart (QImode, operands[0]);
10573 (define_insn_and_split "*setcc_si_1_and"
10574 [(set (match_operand:SI 0 "register_operand" "=q")
10575 (match_operator:SI 1 "ix86_comparison_operator"
10576 [(reg FLAGS_REG) (const_int 0)]))
10577 (clobber (reg:CC FLAGS_REG))]
10578 "!TARGET_PARTIAL_REG_STALL
10579 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10581 "&& reload_completed"
10582 [(set (match_dup 2) (match_dup 1))
10583 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10584 (clobber (reg:CC FLAGS_REG))])]
10586 PUT_MODE (operands[1], QImode);
10587 operands[2] = gen_lowpart (QImode, operands[0]);
10590 (define_insn_and_split "*setcc_si_1_movzbl"
10591 [(set (match_operand:SI 0 "register_operand" "=q")
10592 (match_operator:SI 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)]))]
10594 "!TARGET_PARTIAL_REG_STALL
10595 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10597 "&& reload_completed"
10598 [(set (match_dup 2) (match_dup 1))
10599 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10601 PUT_MODE (operands[1], QImode);
10602 operands[2] = gen_lowpart (QImode, operands[0]);
10605 (define_insn "*setcc_qi"
10606 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10607 (match_operator:QI 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)]))]
10611 [(set_attr "type" "setcc")
10612 (set_attr "mode" "QI")])
10614 (define_insn "*setcc_qi_slp"
10615 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10616 (match_operator:QI 1 "ix86_comparison_operator"
10617 [(reg FLAGS_REG) (const_int 0)]))]
10620 [(set_attr "type" "setcc")
10621 (set_attr "mode" "QI")])
10623 ;; In general it is not safe to assume too much about CCmode registers,
10624 ;; so simplify-rtx stops when it sees a second one. Under certain
10625 ;; conditions this is safe on x86, so help combine not create
10632 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10633 (ne:QI (match_operator 1 "ix86_comparison_operator"
10634 [(reg FLAGS_REG) (const_int 0)])
10637 [(set (match_dup 0) (match_dup 1))]
10638 "PUT_MODE (operands[1], QImode);")
10641 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10642 (ne:QI (match_operator 1 "ix86_comparison_operator"
10643 [(reg FLAGS_REG) (const_int 0)])
10646 [(set (match_dup 0) (match_dup 1))]
10647 "PUT_MODE (operands[1], QImode);")
10650 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10651 (eq:QI (match_operator 1 "ix86_comparison_operator"
10652 [(reg FLAGS_REG) (const_int 0)])
10655 [(set (match_dup 0) (match_dup 1))]
10657 rtx new_op1 = copy_rtx (operands[1]);
10658 operands[1] = new_op1;
10659 PUT_MODE (new_op1, QImode);
10660 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10661 GET_MODE (XEXP (new_op1, 0))));
10663 /* Make sure that (a) the CCmode we have for the flags is strong
10664 enough for the reversed compare or (b) we have a valid FP compare. */
10665 if (! ix86_comparison_operator (new_op1, VOIDmode))
10670 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10671 (eq:QI (match_operator 1 "ix86_comparison_operator"
10672 [(reg FLAGS_REG) (const_int 0)])
10675 [(set (match_dup 0) (match_dup 1))]
10677 rtx new_op1 = copy_rtx (operands[1]);
10678 operands[1] = new_op1;
10679 PUT_MODE (new_op1, QImode);
10680 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10681 GET_MODE (XEXP (new_op1, 0))));
10683 /* Make sure that (a) the CCmode we have for the flags is strong
10684 enough for the reversed compare or (b) we have a valid FP compare. */
10685 if (! ix86_comparison_operator (new_op1, VOIDmode))
10689 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10690 ;; subsequent logical operations are used to imitate conditional moves.
10691 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10694 (define_insn "setcc_<mode>_sse"
10695 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10696 (match_operator:MODEF 3 "sse_comparison_operator"
10697 [(match_operand:MODEF 1 "register_operand" "0,x")
10698 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10699 "SSE_FLOAT_MODE_P (<MODE>mode)"
10701 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10702 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10703 [(set_attr "isa" "noavx,avx")
10704 (set_attr "type" "ssecmp")
10705 (set_attr "length_immediate" "1")
10706 (set_attr "prefix" "orig,vex")
10707 (set_attr "mode" "<MODE>")])
10709 ;; Basic conditional jump instructions.
10710 ;; We ignore the overflow flag for signed branch instructions.
10712 (define_insn "*jcc_1"
10714 (if_then_else (match_operator 1 "ix86_comparison_operator"
10715 [(reg FLAGS_REG) (const_int 0)])
10716 (label_ref (match_operand 0 "" ""))
10720 [(set_attr "type" "ibr")
10721 (set_attr "modrm" "0")
10722 (set (attr "length")
10723 (if_then_else (and (ge (minus (match_dup 0) (pc))
10725 (lt (minus (match_dup 0) (pc))
10730 (define_insn "*jcc_2"
10732 (if_then_else (match_operator 1 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)])
10735 (label_ref (match_operand 0 "" ""))))]
10738 [(set_attr "type" "ibr")
10739 (set_attr "modrm" "0")
10740 (set (attr "length")
10741 (if_then_else (and (ge (minus (match_dup 0) (pc))
10743 (lt (minus (match_dup 0) (pc))
10748 ;; In general it is not safe to assume too much about CCmode registers,
10749 ;; so simplify-rtx stops when it sees a second one. Under certain
10750 ;; conditions this is safe on x86, so help combine not create
10758 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10761 (label_ref (match_operand 1 "" ""))
10765 (if_then_else (match_dup 0)
10766 (label_ref (match_dup 1))
10768 "PUT_MODE (operands[0], VOIDmode);")
10772 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10773 [(reg FLAGS_REG) (const_int 0)])
10775 (label_ref (match_operand 1 "" ""))
10779 (if_then_else (match_dup 0)
10780 (label_ref (match_dup 1))
10783 rtx new_op0 = copy_rtx (operands[0]);
10784 operands[0] = new_op0;
10785 PUT_MODE (new_op0, VOIDmode);
10786 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10787 GET_MODE (XEXP (new_op0, 0))));
10789 /* Make sure that (a) the CCmode we have for the flags is strong
10790 enough for the reversed compare or (b) we have a valid FP compare. */
10791 if (! ix86_comparison_operator (new_op0, VOIDmode))
10795 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10796 ;; pass generates from shift insn with QImode operand. Actually, the mode
10797 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10798 ;; appropriate modulo of the bit offset value.
10800 (define_insn_and_split "*jcc_bt<mode>"
10802 (if_then_else (match_operator 0 "bt_comparison_operator"
10803 [(zero_extract:SWI48
10804 (match_operand:SWI48 1 "register_operand" "r")
10807 (match_operand:QI 2 "register_operand" "r")))
10809 (label_ref (match_operand 3 "" ""))
10811 (clobber (reg:CC FLAGS_REG))]
10812 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10815 [(set (reg:CCC FLAGS_REG)
10817 (zero_extract:SWI48
10823 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10824 (label_ref (match_dup 3))
10827 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10829 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10832 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10833 ;; also for DImode, this is what combine produces.
10834 (define_insn_and_split "*jcc_bt<mode>_mask"
10836 (if_then_else (match_operator 0 "bt_comparison_operator"
10837 [(zero_extract:SWI48
10838 (match_operand:SWI48 1 "register_operand" "r")
10841 (match_operand:SI 2 "register_operand" "r")
10842 (match_operand:SI 3 "const_int_operand" "n")))])
10843 (label_ref (match_operand 4 "" ""))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10847 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10848 == GET_MODE_BITSIZE (<MODE>mode)-1"
10851 [(set (reg:CCC FLAGS_REG)
10853 (zero_extract:SWI48
10859 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10860 (label_ref (match_dup 4))
10863 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10865 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10868 (define_insn_and_split "*jcc_btsi_1"
10870 (if_then_else (match_operator 0 "bt_comparison_operator"
10873 (match_operand:SI 1 "register_operand" "r")
10874 (match_operand:QI 2 "register_operand" "r"))
10877 (label_ref (match_operand 3 "" ""))
10879 (clobber (reg:CC FLAGS_REG))]
10880 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10883 [(set (reg:CCC FLAGS_REG)
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 3))
10895 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10900 ;; avoid useless masking of bit offset operand
10901 (define_insn_and_split "*jcc_btsi_mask_1"
10904 (match_operator 0 "bt_comparison_operator"
10907 (match_operand:SI 1 "register_operand" "r")
10910 (match_operand:SI 2 "register_operand" "r")
10911 (match_operand:SI 3 "const_int_operand" "n")) 0))
10914 (label_ref (match_operand 4 "" ""))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10918 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10921 [(set (reg:CCC FLAGS_REG)
10929 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10930 (label_ref (match_dup 4))
10932 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10934 ;; Define combination compare-and-branch fp compare instructions to help
10937 (define_insn "*fp_jcc_1_387"
10939 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10940 [(match_operand 1 "register_operand" "f")
10941 (match_operand 2 "nonimmediate_operand" "fm")])
10942 (label_ref (match_operand 3 "" ""))
10944 (clobber (reg:CCFP FPSR_REG))
10945 (clobber (reg:CCFP FLAGS_REG))
10946 (clobber (match_scratch:HI 4 "=a"))]
10948 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10949 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10950 && SELECT_CC_MODE (GET_CODE (operands[0]),
10951 operands[1], operands[2]) == CCFPmode
10955 (define_insn "*fp_jcc_1r_387"
10957 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10958 [(match_operand 1 "register_operand" "f")
10959 (match_operand 2 "nonimmediate_operand" "fm")])
10961 (label_ref (match_operand 3 "" ""))))
10962 (clobber (reg:CCFP FPSR_REG))
10963 (clobber (reg:CCFP FLAGS_REG))
10964 (clobber (match_scratch:HI 4 "=a"))]
10966 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10967 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10968 && SELECT_CC_MODE (GET_CODE (operands[0]),
10969 operands[1], operands[2]) == CCFPmode
10973 (define_insn "*fp_jcc_2_387"
10975 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10976 [(match_operand 1 "register_operand" "f")
10977 (match_operand 2 "register_operand" "f")])
10978 (label_ref (match_operand 3 "" ""))
10980 (clobber (reg:CCFP FPSR_REG))
10981 (clobber (reg:CCFP FLAGS_REG))
10982 (clobber (match_scratch:HI 4 "=a"))]
10983 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10984 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988 (define_insn "*fp_jcc_2r_387"
10990 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991 [(match_operand 1 "register_operand" "f")
10992 (match_operand 2 "register_operand" "f")])
10994 (label_ref (match_operand 3 "" ""))))
10995 (clobber (reg:CCFP FPSR_REG))
10996 (clobber (reg:CCFP FLAGS_REG))
10997 (clobber (match_scratch:HI 4 "=a"))]
10998 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10999 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 (define_insn "*fp_jcc_3_387"
11005 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11006 [(match_operand 1 "register_operand" "f")
11007 (match_operand 2 "const0_operand" "")])
11008 (label_ref (match_operand 3 "" ""))
11010 (clobber (reg:CCFP FPSR_REG))
11011 (clobber (reg:CCFP FLAGS_REG))
11012 (clobber (match_scratch:HI 4 "=a"))]
11013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11014 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11015 && SELECT_CC_MODE (GET_CODE (operands[0]),
11016 operands[1], operands[2]) == CCFPmode
11022 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11023 [(match_operand 1 "register_operand" "")
11024 (match_operand 2 "nonimmediate_operand" "")])
11025 (match_operand 3 "" "")
11026 (match_operand 4 "" "")))
11027 (clobber (reg:CCFP FPSR_REG))
11028 (clobber (reg:CCFP FLAGS_REG))]
11032 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11033 operands[3], operands[4], NULL_RTX, NULL_RTX);
11039 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11040 [(match_operand 1 "register_operand" "")
11041 (match_operand 2 "general_operand" "")])
11042 (match_operand 3 "" "")
11043 (match_operand 4 "" "")))
11044 (clobber (reg:CCFP FPSR_REG))
11045 (clobber (reg:CCFP FLAGS_REG))
11046 (clobber (match_scratch:HI 5 "=a"))]
11050 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11051 operands[3], operands[4], operands[5], NULL_RTX);
11055 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11056 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11057 ;; with a precedence over other operators and is always put in the first
11058 ;; place. Swap condition and operands to match ficom instruction.
11060 (define_insn "*fp_jcc_4_<mode>_387"
11063 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11064 [(match_operator 1 "float_operator"
11065 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11066 (match_operand 3 "register_operand" "f,f")])
11067 (label_ref (match_operand 4 "" ""))
11069 (clobber (reg:CCFP FPSR_REG))
11070 (clobber (reg:CCFP FLAGS_REG))
11071 (clobber (match_scratch:HI 5 "=a,a"))]
11072 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11073 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11074 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11075 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11082 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11083 [(match_operator 1 "float_operator"
11084 [(match_operand:SWI24 2 "memory_operand" "")])
11085 (match_operand 3 "register_operand" "")])
11086 (match_operand 4 "" "")
11087 (match_operand 5 "" "")))
11088 (clobber (reg:CCFP FPSR_REG))
11089 (clobber (reg:CCFP FLAGS_REG))
11090 (clobber (match_scratch:HI 6 "=a"))]
11094 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11096 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11097 operands[3], operands[7],
11098 operands[4], operands[5], operands[6], NULL_RTX);
11102 ;; %%% Kill this when reload knows how to do it.
11106 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11107 [(match_operator 1 "float_operator"
11108 [(match_operand:SWI24 2 "register_operand" "")])
11109 (match_operand 3 "register_operand" "")])
11110 (match_operand 4 "" "")
11111 (match_operand 5 "" "")))
11112 (clobber (reg:CCFP FPSR_REG))
11113 (clobber (reg:CCFP FLAGS_REG))
11114 (clobber (match_scratch:HI 6 "=a"))]
11118 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11119 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11121 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11122 operands[3], operands[7],
11123 operands[4], operands[5], operands[6], operands[2]);
11127 ;; Unconditional and other jump instructions
11129 (define_insn "jump"
11131 (label_ref (match_operand 0 "" "")))]
11134 [(set_attr "type" "ibr")
11135 (set (attr "length")
11136 (if_then_else (and (ge (minus (match_dup 0) (pc))
11138 (lt (minus (match_dup 0) (pc))
11142 (set_attr "modrm" "0")])
11144 (define_expand "indirect_jump"
11145 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11147 (define_insn "*indirect_jump"
11148 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11151 [(set_attr "type" "ibr")
11152 (set_attr "length_immediate" "0")])
11154 (define_expand "tablejump"
11155 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11156 (use (label_ref (match_operand 1 "" "")))])]
11159 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11160 relative. Convert the relative address to an absolute address. */
11164 enum rtx_code code;
11166 /* We can't use @GOTOFF for text labels on VxWorks;
11167 see gotoff_operand. */
11168 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11172 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11174 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11178 op1 = pic_offset_table_rtx;
11183 op0 = pic_offset_table_rtx;
11187 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11190 else if (TARGET_X32)
11191 operands[0] = convert_memory_address (Pmode, operands[0]);
11194 (define_insn "*tablejump_1"
11195 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11196 (use (label_ref (match_operand 1 "" "")))]
11199 [(set_attr "type" "ibr")
11200 (set_attr "length_immediate" "0")])
11202 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11205 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11206 (set (match_operand:QI 1 "register_operand" "")
11207 (match_operator:QI 2 "ix86_comparison_operator"
11208 [(reg FLAGS_REG) (const_int 0)]))
11209 (set (match_operand 3 "q_regs_operand" "")
11210 (zero_extend (match_dup 1)))]
11211 "(peep2_reg_dead_p (3, operands[1])
11212 || operands_match_p (operands[1], operands[3]))
11213 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11214 [(set (match_dup 4) (match_dup 0))
11215 (set (strict_low_part (match_dup 5))
11218 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11219 operands[5] = gen_lowpart (QImode, operands[3]);
11220 ix86_expand_clear (operands[3]);
11223 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11226 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11227 (set (match_operand:QI 1 "register_operand" "")
11228 (match_operator:QI 2 "ix86_comparison_operator"
11229 [(reg FLAGS_REG) (const_int 0)]))
11230 (parallel [(set (match_operand 3 "q_regs_operand" "")
11231 (zero_extend (match_dup 1)))
11232 (clobber (reg:CC FLAGS_REG))])]
11233 "(peep2_reg_dead_p (3, operands[1])
11234 || operands_match_p (operands[1], operands[3]))
11235 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11236 [(set (match_dup 4) (match_dup 0))
11237 (set (strict_low_part (match_dup 5))
11240 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11241 operands[5] = gen_lowpart (QImode, operands[3]);
11242 ix86_expand_clear (operands[3]);
11245 ;; Call instructions.
11247 ;; The predicates normally associated with named expanders are not properly
11248 ;; checked for calls. This is a bug in the generic code, but it isn't that
11249 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11251 ;; P6 processors will jump to the address after the decrement when %esp
11252 ;; is used as a call operand, so they will execute return address as a code.
11253 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11255 ;; Register constraint for call instruction.
11256 (define_mode_attr c [(SI "l") (DI "r")])
11258 ;; Call subroutine returning no value.
11260 (define_expand "call"
11261 [(call (match_operand:QI 0 "" "")
11262 (match_operand 1 "" ""))
11263 (use (match_operand 2 "" ""))]
11266 ix86_expand_call (NULL, operands[0], operands[1],
11267 operands[2], NULL, false);
11271 (define_expand "sibcall"
11272 [(call (match_operand:QI 0 "" "")
11273 (match_operand 1 "" ""))
11274 (use (match_operand 2 "" ""))]
11277 ix86_expand_call (NULL, operands[0], operands[1],
11278 operands[2], NULL, true);
11282 (define_insn_and_split "*call_vzeroupper"
11283 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284 (match_operand 1 "" ""))
11285 (unspec [(match_operand 2 "const_int_operand" "")]
11286 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11287 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11289 "&& reload_completed"
11291 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11292 [(set_attr "type" "call")])
11294 (define_insn "*call"
11295 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11296 (match_operand 1 "" ""))]
11297 "!SIBLING_CALL_P (insn)"
11298 "* return ix86_output_call_insn (insn, operands[0]);"
11299 [(set_attr "type" "call")])
11301 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11302 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11303 (match_operand 1 "" ""))
11304 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11305 (clobber (reg:TI XMM6_REG))
11306 (clobber (reg:TI XMM7_REG))
11307 (clobber (reg:TI XMM8_REG))
11308 (clobber (reg:TI XMM9_REG))
11309 (clobber (reg:TI XMM10_REG))
11310 (clobber (reg:TI XMM11_REG))
11311 (clobber (reg:TI XMM12_REG))
11312 (clobber (reg:TI XMM13_REG))
11313 (clobber (reg:TI XMM14_REG))
11314 (clobber (reg:TI XMM15_REG))
11315 (clobber (reg:DI SI_REG))
11316 (clobber (reg:DI DI_REG))
11317 (unspec [(match_operand 2 "const_int_operand" "")]
11318 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11321 "&& reload_completed"
11323 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11324 [(set_attr "type" "call")])
11326 (define_insn "*call_rex64_ms_sysv"
11327 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11328 (match_operand 1 "" ""))
11329 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11330 (clobber (reg:TI XMM6_REG))
11331 (clobber (reg:TI XMM7_REG))
11332 (clobber (reg:TI XMM8_REG))
11333 (clobber (reg:TI XMM9_REG))
11334 (clobber (reg:TI XMM10_REG))
11335 (clobber (reg:TI XMM11_REG))
11336 (clobber (reg:TI XMM12_REG))
11337 (clobber (reg:TI XMM13_REG))
11338 (clobber (reg:TI XMM14_REG))
11339 (clobber (reg:TI XMM15_REG))
11340 (clobber (reg:DI SI_REG))
11341 (clobber (reg:DI DI_REG))]
11342 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11343 "* return ix86_output_call_insn (insn, operands[0]);"
11344 [(set_attr "type" "call")])
11346 (define_insn_and_split "*sibcall_vzeroupper"
11347 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348 (match_operand 1 "" ""))
11349 (unspec [(match_operand 2 "const_int_operand" "")]
11350 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11351 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11353 "&& reload_completed"
11355 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11356 [(set_attr "type" "call")])
11358 (define_insn "*sibcall"
11359 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11360 (match_operand 1 "" ""))]
11361 "SIBLING_CALL_P (insn)"
11362 "* return ix86_output_call_insn (insn, operands[0]);"
11363 [(set_attr "type" "call")])
11365 (define_expand "call_pop"
11366 [(parallel [(call (match_operand:QI 0 "" "")
11367 (match_operand:SI 1 "" ""))
11368 (set (reg:SI SP_REG)
11369 (plus:SI (reg:SI SP_REG)
11370 (match_operand:SI 3 "" "")))])]
11373 ix86_expand_call (NULL, operands[0], operands[1],
11374 operands[2], operands[3], false);
11378 (define_insn_and_split "*call_pop_vzeroupper"
11379 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11380 (match_operand:SI 1 "" ""))
11381 (set (reg:SI SP_REG)
11382 (plus:SI (reg:SI SP_REG)
11383 (match_operand:SI 2 "immediate_operand" "i")))
11384 (unspec [(match_operand 3 "const_int_operand" "")]
11385 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11386 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388 "&& reload_completed"
11390 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11391 [(set_attr "type" "call")])
11393 (define_insn "*call_pop"
11394 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11395 (match_operand 1 "" ""))
11396 (set (reg:SI SP_REG)
11397 (plus:SI (reg:SI SP_REG)
11398 (match_operand:SI 2 "immediate_operand" "i")))]
11399 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11400 "* return ix86_output_call_insn (insn, operands[0]);"
11401 [(set_attr "type" "call")])
11403 (define_insn_and_split "*sibcall_pop_vzeroupper"
11404 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11405 (match_operand 1 "" ""))
11406 (set (reg:SI SP_REG)
11407 (plus:SI (reg:SI SP_REG)
11408 (match_operand:SI 2 "immediate_operand" "i")))
11409 (unspec [(match_operand 3 "const_int_operand" "")]
11410 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11411 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "&& reload_completed"
11415 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11416 [(set_attr "type" "call")])
11418 (define_insn "*sibcall_pop"
11419 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11420 (match_operand 1 "" ""))
11421 (set (reg:SI SP_REG)
11422 (plus:SI (reg:SI SP_REG)
11423 (match_operand:SI 2 "immediate_operand" "i")))]
11424 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11425 "* return ix86_output_call_insn (insn, operands[0]);"
11426 [(set_attr "type" "call")])
11428 ;; Call subroutine, returning value in operand 0
11430 (define_expand "call_value"
11431 [(set (match_operand 0 "" "")
11432 (call (match_operand:QI 1 "" "")
11433 (match_operand 2 "" "")))
11434 (use (match_operand 3 "" ""))]
11437 ix86_expand_call (operands[0], operands[1], operands[2],
11438 operands[3], NULL, false);
11442 (define_expand "sibcall_value"
11443 [(set (match_operand 0 "" "")
11444 (call (match_operand:QI 1 "" "")
11445 (match_operand 2 "" "")))
11446 (use (match_operand 3 "" ""))]
11449 ix86_expand_call (operands[0], operands[1], operands[2],
11450 operands[3], NULL, true);
11454 (define_insn_and_split "*call_value_vzeroupper"
11455 [(set (match_operand 0 "" "")
11456 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11457 (match_operand 2 "" "")))
11458 (unspec [(match_operand 3 "const_int_operand" "")]
11459 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11460 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11462 "&& reload_completed"
11464 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11465 [(set_attr "type" "callv")])
11467 (define_insn "*call_value"
11468 [(set (match_operand 0 "" "")
11469 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11470 (match_operand 2 "" "")))]
11471 "!SIBLING_CALL_P (insn)"
11472 "* return ix86_output_call_insn (insn, operands[1]);"
11473 [(set_attr "type" "callv")])
11475 (define_insn_and_split "*sibcall_value_vzeroupper"
11476 [(set (match_operand 0 "" "")
11477 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11478 (match_operand 2 "" "")))
11479 (unspec [(match_operand 3 "const_int_operand" "")]
11480 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11481 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11483 "&& reload_completed"
11485 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11486 [(set_attr "type" "callv")])
11488 (define_insn "*sibcall_value"
11489 [(set (match_operand 0 "" "")
11490 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11491 (match_operand 2 "" "")))]
11492 "SIBLING_CALL_P (insn)"
11493 "* return ix86_output_call_insn (insn, operands[1]);"
11494 [(set_attr "type" "callv")])
11496 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11497 [(set (match_operand 0 "" "")
11498 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11499 (match_operand 2 "" "")))
11500 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11501 (clobber (reg:TI XMM6_REG))
11502 (clobber (reg:TI XMM7_REG))
11503 (clobber (reg:TI XMM8_REG))
11504 (clobber (reg:TI XMM9_REG))
11505 (clobber (reg:TI XMM10_REG))
11506 (clobber (reg:TI XMM11_REG))
11507 (clobber (reg:TI XMM12_REG))
11508 (clobber (reg:TI XMM13_REG))
11509 (clobber (reg:TI XMM14_REG))
11510 (clobber (reg:TI XMM15_REG))
11511 (clobber (reg:DI SI_REG))
11512 (clobber (reg:DI DI_REG))
11513 (unspec [(match_operand 3 "const_int_operand" "")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11517 "&& reload_completed"
11519 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11520 [(set_attr "type" "callv")])
11522 (define_insn "*call_value_rex64_ms_sysv"
11523 [(set (match_operand 0 "" "")
11524 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11525 (match_operand 2 "" "")))
11526 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11527 (clobber (reg:TI XMM6_REG))
11528 (clobber (reg:TI XMM7_REG))
11529 (clobber (reg:TI XMM8_REG))
11530 (clobber (reg:TI XMM9_REG))
11531 (clobber (reg:TI XMM10_REG))
11532 (clobber (reg:TI XMM11_REG))
11533 (clobber (reg:TI XMM12_REG))
11534 (clobber (reg:TI XMM13_REG))
11535 (clobber (reg:TI XMM14_REG))
11536 (clobber (reg:TI XMM15_REG))
11537 (clobber (reg:DI SI_REG))
11538 (clobber (reg:DI DI_REG))]
11539 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11540 "* return ix86_output_call_insn (insn, operands[1]);"
11541 [(set_attr "type" "callv")])
11543 (define_expand "call_value_pop"
11544 [(parallel [(set (match_operand 0 "" "")
11545 (call (match_operand:QI 1 "" "")
11546 (match_operand:SI 2 "" "")))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 4 "" "")))])]
11552 ix86_expand_call (operands[0], operands[1], operands[2],
11553 operands[3], operands[4], false);
11557 (define_insn_and_split "*call_value_pop_vzeroupper"
11558 [(set (match_operand 0 "" "")
11559 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11560 (match_operand 2 "" "")))
11561 (set (reg:SI SP_REG)
11562 (plus:SI (reg:SI SP_REG)
11563 (match_operand:SI 3 "immediate_operand" "i")))
11564 (unspec [(match_operand 4 "const_int_operand" "")]
11565 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11566 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568 "&& reload_completed"
11570 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11571 [(set_attr "type" "callv")])
11573 (define_insn "*call_value_pop"
11574 [(set (match_operand 0 "" "")
11575 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11576 (match_operand 2 "" "")))
11577 (set (reg:SI SP_REG)
11578 (plus:SI (reg:SI SP_REG)
11579 (match_operand:SI 3 "immediate_operand" "i")))]
11580 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11581 "* return ix86_output_call_insn (insn, operands[1]);"
11582 [(set_attr "type" "callv")])
11584 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11585 [(set (match_operand 0 "" "")
11586 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11587 (match_operand 2 "" "")))
11588 (set (reg:SI SP_REG)
11589 (plus:SI (reg:SI SP_REG)
11590 (match_operand:SI 3 "immediate_operand" "i")))
11591 (unspec [(match_operand 4 "const_int_operand" "")]
11592 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11593 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11595 "&& reload_completed"
11597 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11598 [(set_attr "type" "callv")])
11600 (define_insn "*sibcall_value_pop"
11601 [(set (match_operand 0 "" "")
11602 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11603 (match_operand 2 "" "")))
11604 (set (reg:SI SP_REG)
11605 (plus:SI (reg:SI SP_REG)
11606 (match_operand:SI 3 "immediate_operand" "i")))]
11607 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11608 "* return ix86_output_call_insn (insn, operands[1]);"
11609 [(set_attr "type" "callv")])
11611 ;; Call subroutine returning any type.
11613 (define_expand "untyped_call"
11614 [(parallel [(call (match_operand 0 "" "")
11616 (match_operand 1 "" "")
11617 (match_operand 2 "" "")])]
11622 /* In order to give reg-stack an easier job in validating two
11623 coprocessor registers as containing a possible return value,
11624 simply pretend the untyped call returns a complex long double
11627 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11628 and should have the default ABI. */
11630 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11631 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11632 operands[0], const0_rtx,
11633 GEN_INT ((TARGET_64BIT
11634 ? (ix86_abi == SYSV_ABI
11635 ? X86_64_SSE_REGPARM_MAX
11636 : X86_64_MS_SSE_REGPARM_MAX)
11637 : X86_32_SSE_REGPARM_MAX)
11641 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11643 rtx set = XVECEXP (operands[2], 0, i);
11644 emit_move_insn (SET_DEST (set), SET_SRC (set));
11647 /* The optimizer does not know that the call sets the function value
11648 registers we stored in the result block. We avoid problems by
11649 claiming that all hard registers are used and clobbered at this
11651 emit_insn (gen_blockage ());
11656 ;; Prologue and epilogue instructions
11658 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11659 ;; all of memory. This blocks insns from being moved across this point.
11661 (define_insn "blockage"
11662 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11665 [(set_attr "length" "0")])
11667 ;; Do not schedule instructions accessing memory across this point.
11669 (define_expand "memory_blockage"
11670 [(set (match_dup 0)
11671 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11674 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11675 MEM_VOLATILE_P (operands[0]) = 1;
11678 (define_insn "*memory_blockage"
11679 [(set (match_operand:BLK 0 "" "")
11680 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11683 [(set_attr "length" "0")])
11685 ;; As USE insns aren't meaningful after reload, this is used instead
11686 ;; to prevent deleting instructions setting registers for PIC code
11687 (define_insn "prologue_use"
11688 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11691 [(set_attr "length" "0")])
11693 ;; Insn emitted into the body of a function to return from a function.
11694 ;; This is only done if the function's epilogue is known to be simple.
11695 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11697 (define_expand "return"
11699 "ix86_can_use_return_insn_p ()"
11701 if (crtl->args.pops_args)
11703 rtx popc = GEN_INT (crtl->args.pops_args);
11704 emit_jump_insn (gen_return_pop_internal (popc));
11709 (define_insn "return_internal"
11713 [(set_attr "length" "1")
11714 (set_attr "atom_unit" "jeu")
11715 (set_attr "length_immediate" "0")
11716 (set_attr "modrm" "0")])
11718 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11719 ;; instruction Athlon and K8 have.
11721 (define_insn "return_internal_long"
11723 (unspec [(const_int 0)] UNSPEC_REP)]
11726 [(set_attr "length" "2")
11727 (set_attr "atom_unit" "jeu")
11728 (set_attr "length_immediate" "0")
11729 (set_attr "prefix_rep" "1")
11730 (set_attr "modrm" "0")])
11732 (define_insn "return_pop_internal"
11734 (use (match_operand:SI 0 "const_int_operand" ""))]
11737 [(set_attr "length" "3")
11738 (set_attr "atom_unit" "jeu")
11739 (set_attr "length_immediate" "2")
11740 (set_attr "modrm" "0")])
11742 (define_insn "return_indirect_internal"
11744 (use (match_operand:SI 0 "register_operand" "r"))]
11747 [(set_attr "type" "ibr")
11748 (set_attr "length_immediate" "0")])
11754 [(set_attr "length" "1")
11755 (set_attr "length_immediate" "0")
11756 (set_attr "modrm" "0")])
11758 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11759 (define_insn "nops"
11760 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11764 int num = INTVAL (operands[0]);
11766 gcc_assert (num >= 1 && num <= 8);
11769 fputs ("\tnop\n", asm_out_file);
11773 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11774 (set_attr "length_immediate" "0")
11775 (set_attr "modrm" "0")])
11777 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11778 ;; branch prediction penalty for the third jump in a 16-byte
11782 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11785 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11786 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11788 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11789 The align insn is used to avoid 3 jump instructions in the row to improve
11790 branch prediction and the benefits hardly outweigh the cost of extra 8
11791 nops on the average inserted by full alignment pseudo operation. */
11795 [(set_attr "length" "16")])
11797 (define_expand "prologue"
11800 "ix86_expand_prologue (); DONE;")
11802 (define_insn "set_got"
11803 [(set (match_operand:SI 0 "register_operand" "=r")
11804 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11805 (clobber (reg:CC FLAGS_REG))]
11807 "* return output_set_got (operands[0], NULL_RTX);"
11808 [(set_attr "type" "multi")
11809 (set_attr "length" "12")])
11811 (define_insn "set_got_labelled"
11812 [(set (match_operand:SI 0 "register_operand" "=r")
11813 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11815 (clobber (reg:CC FLAGS_REG))]
11817 "* return output_set_got (operands[0], operands[1]);"
11818 [(set_attr "type" "multi")
11819 (set_attr "length" "12")])
11821 (define_insn "set_got_rex64"
11822 [(set (match_operand:DI 0 "register_operand" "=r")
11823 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11825 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11826 [(set_attr "type" "lea")
11827 (set_attr "length_address" "4")
11828 (set_attr "mode" "DI")])
11830 (define_insn "set_rip_rex64"
11831 [(set (match_operand:DI 0 "register_operand" "=r")
11832 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11834 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11835 [(set_attr "type" "lea")
11836 (set_attr "length_address" "4")
11837 (set_attr "mode" "DI")])
11839 (define_insn "set_got_offset_rex64"
11840 [(set (match_operand:DI 0 "register_operand" "=r")
11842 [(label_ref (match_operand 1 "" ""))]
11843 UNSPEC_SET_GOT_OFFSET))]
11845 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11846 [(set_attr "type" "imov")
11847 (set_attr "length_immediate" "0")
11848 (set_attr "length_address" "8")
11849 (set_attr "mode" "DI")])
11851 (define_expand "epilogue"
11854 "ix86_expand_epilogue (1); DONE;")
11856 (define_expand "sibcall_epilogue"
11859 "ix86_expand_epilogue (0); DONE;")
11861 (define_expand "eh_return"
11862 [(use (match_operand 0 "register_operand" ""))]
11865 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11867 /* Tricky bit: we write the address of the handler to which we will
11868 be returning into someone else's stack frame, one word below the
11869 stack address we wish to restore. */
11870 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11871 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11872 tmp = gen_rtx_MEM (Pmode, tmp);
11873 emit_move_insn (tmp, ra);
11875 emit_jump_insn (gen_eh_return_internal ());
11880 (define_insn_and_split "eh_return_internal"
11884 "epilogue_completed"
11886 "ix86_expand_epilogue (2); DONE;")
11888 (define_insn "leave"
11889 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11890 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11891 (clobber (mem:BLK (scratch)))]
11894 [(set_attr "type" "leave")])
11896 (define_insn "leave_rex64"
11897 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11898 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11899 (clobber (mem:BLK (scratch)))]
11902 [(set_attr "type" "leave")])
11904 ;; Handle -fsplit-stack.
11906 (define_expand "split_stack_prologue"
11910 ix86_expand_split_stack_prologue ();
11914 ;; In order to support the call/return predictor, we use a return
11915 ;; instruction which the middle-end doesn't see.
11916 (define_insn "split_stack_return"
11917 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11918 UNSPECV_SPLIT_STACK_RETURN)]
11921 if (operands[0] == const0_rtx)
11926 [(set_attr "atom_unit" "jeu")
11927 (set_attr "modrm" "0")
11928 (set (attr "length")
11929 (if_then_else (match_operand:SI 0 "const0_operand" "")
11932 (set (attr "length_immediate")
11933 (if_then_else (match_operand:SI 0 "const0_operand" "")
11937 ;; If there are operand 0 bytes available on the stack, jump to
11940 (define_expand "split_stack_space_check"
11941 [(set (pc) (if_then_else
11942 (ltu (minus (reg SP_REG)
11943 (match_operand 0 "register_operand" ""))
11944 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11945 (label_ref (match_operand 1 "" ""))
11949 rtx reg, size, limit;
11951 reg = gen_reg_rtx (Pmode);
11952 size = force_reg (Pmode, operands[0]);
11953 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11954 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11955 UNSPEC_STACK_CHECK);
11956 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11957 ix86_expand_branch (GEU, reg, limit, operands[1]);
11962 ;; Bit manipulation instructions.
11964 (define_expand "ffs<mode>2"
11965 [(set (match_dup 2) (const_int -1))
11966 (parallel [(set (reg:CCZ FLAGS_REG)
11968 (match_operand:SWI48 1 "nonimmediate_operand" "")
11970 (set (match_operand:SWI48 0 "register_operand" "")
11971 (ctz:SWI48 (match_dup 1)))])
11972 (set (match_dup 0) (if_then_else:SWI48
11973 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11976 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11977 (clobber (reg:CC FLAGS_REG))])]
11980 if (<MODE>mode == SImode && !TARGET_CMOVE)
11982 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11985 operands[2] = gen_reg_rtx (<MODE>mode);
11988 (define_insn_and_split "ffssi2_no_cmove"
11989 [(set (match_operand:SI 0 "register_operand" "=r")
11990 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11991 (clobber (match_scratch:SI 2 "=&q"))
11992 (clobber (reg:CC FLAGS_REG))]
11995 "&& reload_completed"
11996 [(parallel [(set (reg:CCZ FLAGS_REG)
11997 (compare:CCZ (match_dup 1) (const_int 0)))
11998 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11999 (set (strict_low_part (match_dup 3))
12000 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12001 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12002 (clobber (reg:CC FLAGS_REG))])
12003 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12004 (clobber (reg:CC FLAGS_REG))])
12005 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12006 (clobber (reg:CC FLAGS_REG))])]
12008 operands[3] = gen_lowpart (QImode, operands[2]);
12009 ix86_expand_clear (operands[2]);
12012 (define_insn "*ffs<mode>_1"
12013 [(set (reg:CCZ FLAGS_REG)
12014 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12016 (set (match_operand:SWI48 0 "register_operand" "=r")
12017 (ctz:SWI48 (match_dup 1)))]
12019 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12020 [(set_attr "type" "alu1")
12021 (set_attr "prefix_0f" "1")
12022 (set_attr "mode" "<MODE>")])
12024 (define_insn "ctz<mode>2"
12025 [(set (match_operand:SWI248 0 "register_operand" "=r")
12026 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12027 (clobber (reg:CC FLAGS_REG))]
12031 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12033 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12035 [(set_attr "type" "alu1")
12036 (set_attr "prefix_0f" "1")
12037 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12038 (set_attr "mode" "<MODE>")])
12040 (define_expand "clz<mode>2"
12042 [(set (match_operand:SWI248 0 "register_operand" "")
12045 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12046 (clobber (reg:CC FLAGS_REG))])
12048 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12049 (clobber (reg:CC FLAGS_REG))])]
12054 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12057 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12060 (define_insn "clz<mode>2_lzcnt"
12061 [(set (match_operand:SWI248 0 "register_operand" "=r")
12062 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12063 (clobber (reg:CC FLAGS_REG))]
12065 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12066 [(set_attr "prefix_rep" "1")
12067 (set_attr "type" "bitmanip")
12068 (set_attr "mode" "<MODE>")])
12070 ;; BMI instructions.
12071 (define_insn "*bmi_andn_<mode>"
12072 [(set (match_operand:SWI48 0 "register_operand" "=r")
12075 (match_operand:SWI48 1 "register_operand" "r"))
12076 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12077 (clobber (reg:CC FLAGS_REG))]
12079 "andn\t{%2, %1, %0|%0, %1, %2}"
12080 [(set_attr "type" "bitmanip")
12081 (set_attr "mode" "<MODE>")])
12083 (define_insn "bmi_bextr_<mode>"
12084 [(set (match_operand:SWI48 0 "register_operand" "=r")
12085 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12086 (match_operand:SWI48 2 "register_operand" "r")]
12088 (clobber (reg:CC FLAGS_REG))]
12090 "bextr\t{%2, %1, %0|%0, %1, %2}"
12091 [(set_attr "type" "bitmanip")
12092 (set_attr "mode" "<MODE>")])
12094 (define_insn "*bmi_blsi_<mode>"
12095 [(set (match_operand:SWI48 0 "register_operand" "=r")
12098 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12100 (clobber (reg:CC FLAGS_REG))]
12102 "blsi\t{%1, %0|%0, %1}"
12103 [(set_attr "type" "bitmanip")
12104 (set_attr "mode" "<MODE>")])
12106 (define_insn "*bmi_blsmsk_<mode>"
12107 [(set (match_operand:SWI48 0 "register_operand" "=r")
12110 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12113 (clobber (reg:CC FLAGS_REG))]
12115 "blsmsk\t{%1, %0|%0, %1}"
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "mode" "<MODE>")])
12119 (define_insn "*bmi_blsr_<mode>"
12120 [(set (match_operand:SWI48 0 "register_operand" "=r")
12123 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12126 (clobber (reg:CC FLAGS_REG))]
12128 "blsr\t{%1, %0|%0, %1}"
12129 [(set_attr "type" "bitmanip")
12130 (set_attr "mode" "<MODE>")])
12132 ;; BMI2 instructions.
12133 (define_insn "bmi2_bzhi_<mode>3"
12134 [(set (match_operand:SWI48 0 "register_operand" "=r")
12135 (and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12136 (lshiftrt:SWI48 (const_int -1)
12137 (match_operand:SWI48 2 "register_operand" "r"))))
12138 (clobber (reg:CC FLAGS_REG))]
12140 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12141 [(set_attr "type" "bitmanip")
12142 (set_attr "prefix" "vex")
12143 (set_attr "mode" "<MODE>")])
12145 (define_insn "bmi2_pdep_<mode>3"
12146 [(set (match_operand:SWI48 0 "register_operand" "=r")
12147 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12148 (match_operand:SWI48 2 "register_operand" "r")]
12151 "pdep\t{%2, %1, %0|%0, %1, %2}"
12152 [(set_attr "type" "bitmanip")
12153 (set_attr "prefix" "vex")
12154 (set_attr "mode" "<MODE>")])
12156 (define_insn "bmi2_pext_<mode>3"
12157 [(set (match_operand:SWI48 0 "register_operand" "=r")
12158 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12159 (match_operand:SWI48 2 "register_operand" "r")]
12162 "pext\t{%2, %1, %0|%0, %1, %2}"
12163 [(set_attr "type" "bitmanip")
12164 (set_attr "prefix" "vex")
12165 (set_attr "mode" "<MODE>")])
12167 ;; TBM instructions.
12168 (define_insn "tbm_bextri_<mode>"
12169 [(set (match_operand:SWI48 0 "register_operand" "=r")
12170 (zero_extract:SWI48
12171 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12172 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12173 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12174 (clobber (reg:CC FLAGS_REG))]
12177 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12178 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "mode" "<MODE>")])
12183 (define_insn "*tbm_blcfill_<mode>"
12184 [(set (match_operand:SWI48 0 "register_operand" "=r")
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12190 (clobber (reg:CC FLAGS_REG))]
12192 "blcfill\t{%1, %0|%0, %1}"
12193 [(set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12196 (define_insn "*tbm_blci_<mode>"
12197 [(set (match_operand:SWI48 0 "register_operand" "=r")
12201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204 (clobber (reg:CC FLAGS_REG))]
12206 "blci\t{%1, %0|%0, %1}"
12207 [(set_attr "type" "bitmanip")
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "*tbm_blcic_<mode>"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12214 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218 (clobber (reg:CC FLAGS_REG))]
12220 "blcic\t{%1, %0|%0, %1}"
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "mode" "<MODE>")])
12224 (define_insn "*tbm_blcmsk_<mode>"
12225 [(set (match_operand:SWI48 0 "register_operand" "=r")
12228 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231 (clobber (reg:CC FLAGS_REG))]
12233 "blcmsk\t{%1, %0|%0, %1}"
12234 [(set_attr "type" "bitmanip")
12235 (set_attr "mode" "<MODE>")])
12237 (define_insn "*tbm_blcs_<mode>"
12238 [(set (match_operand:SWI48 0 "register_operand" "=r")
12241 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244 (clobber (reg:CC FLAGS_REG))]
12246 "blcs\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12250 (define_insn "*tbm_blsfill_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12257 (clobber (reg:CC FLAGS_REG))]
12259 "blsfill\t{%1, %0|%0, %1}"
12260 [(set_attr "type" "bitmanip")
12261 (set_attr "mode" "<MODE>")])
12263 (define_insn "*tbm_blsic_<mode>"
12264 [(set (match_operand:SWI48 0 "register_operand" "=r")
12267 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271 (clobber (reg:CC FLAGS_REG))]
12273 "blsic\t{%1, %0|%0, %1}"
12274 [(set_attr "type" "bitmanip")
12275 (set_attr "mode" "<MODE>")])
12277 (define_insn "*tbm_t1mskc_<mode>"
12278 [(set (match_operand:SWI48 0 "register_operand" "=r")
12281 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12285 (clobber (reg:CC FLAGS_REG))]
12287 "t1mskc\t{%1, %0|%0, %1}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*tbm_tzmsk_<mode>"
12292 [(set (match_operand:SWI48 0 "register_operand" "=r")
12295 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12299 (clobber (reg:CC FLAGS_REG))]
12301 "tzmsk\t{%1, %0|%0, %1}"
12302 [(set_attr "type" "bitmanip")
12303 (set_attr "mode" "<MODE>")])
12305 (define_insn "bsr_rex64"
12306 [(set (match_operand:DI 0 "register_operand" "=r")
12307 (minus:DI (const_int 63)
12308 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12309 (clobber (reg:CC FLAGS_REG))]
12311 "bsr{q}\t{%1, %0|%0, %1}"
12312 [(set_attr "type" "alu1")
12313 (set_attr "prefix_0f" "1")
12314 (set_attr "mode" "DI")])
12317 [(set (match_operand:SI 0 "register_operand" "=r")
12318 (minus:SI (const_int 31)
12319 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12320 (clobber (reg:CC FLAGS_REG))]
12322 "bsr{l}\t{%1, %0|%0, %1}"
12323 [(set_attr "type" "alu1")
12324 (set_attr "prefix_0f" "1")
12325 (set_attr "mode" "SI")])
12327 (define_insn "*bsrhi"
12328 [(set (match_operand:HI 0 "register_operand" "=r")
12329 (minus:HI (const_int 15)
12330 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12331 (clobber (reg:CC FLAGS_REG))]
12333 "bsr{w}\t{%1, %0|%0, %1}"
12334 [(set_attr "type" "alu1")
12335 (set_attr "prefix_0f" "1")
12336 (set_attr "mode" "HI")])
12338 (define_insn "popcount<mode>2"
12339 [(set (match_operand:SWI248 0 "register_operand" "=r")
12341 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12342 (clobber (reg:CC FLAGS_REG))]
12346 return "popcnt\t{%1, %0|%0, %1}";
12348 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12351 [(set_attr "prefix_rep" "1")
12352 (set_attr "type" "bitmanip")
12353 (set_attr "mode" "<MODE>")])
12355 (define_insn "*popcount<mode>2_cmp"
12356 [(set (reg FLAGS_REG)
12359 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12361 (set (match_operand:SWI248 0 "register_operand" "=r")
12362 (popcount:SWI248 (match_dup 1)))]
12363 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12366 return "popcnt\t{%1, %0|%0, %1}";
12368 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12371 [(set_attr "prefix_rep" "1")
12372 (set_attr "type" "bitmanip")
12373 (set_attr "mode" "<MODE>")])
12375 (define_insn "*popcountsi2_cmp_zext"
12376 [(set (reg FLAGS_REG)
12378 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12380 (set (match_operand:DI 0 "register_operand" "=r")
12381 (zero_extend:DI(popcount:SI (match_dup 1))))]
12382 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12385 return "popcnt\t{%1, %0|%0, %1}";
12387 return "popcnt{l}\t{%1, %0|%0, %1}";
12390 [(set_attr "prefix_rep" "1")
12391 (set_attr "type" "bitmanip")
12392 (set_attr "mode" "SI")])
12394 (define_expand "bswap<mode>2"
12395 [(set (match_operand:SWI48 0 "register_operand" "")
12396 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12399 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12401 rtx x = operands[0];
12403 emit_move_insn (x, operands[1]);
12404 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12405 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12406 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411 (define_insn "*bswap<mode>2_movbe"
12412 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12413 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12415 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12418 movbe\t{%1, %0|%0, %1}
12419 movbe\t{%1, %0|%0, %1}"
12420 [(set_attr "type" "bitmanip,imov,imov")
12421 (set_attr "modrm" "0,1,1")
12422 (set_attr "prefix_0f" "*,1,1")
12423 (set_attr "prefix_extra" "*,1,1")
12424 (set_attr "mode" "<MODE>")])
12426 (define_insn "*bswap<mode>2_1"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12428 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12431 [(set_attr "type" "bitmanip")
12432 (set_attr "modrm" "0")
12433 (set_attr "mode" "<MODE>")])
12435 (define_insn "*bswaphi_lowpart_1"
12436 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12437 (bswap:HI (match_dup 0)))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12441 xchg{b}\t{%h0, %b0|%b0, %h0}
12442 rol{w}\t{$8, %0|%0, 8}"
12443 [(set_attr "length" "2,4")
12444 (set_attr "mode" "QI,HI")])
12446 (define_insn "bswaphi_lowpart"
12447 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12448 (bswap:HI (match_dup 0)))
12449 (clobber (reg:CC FLAGS_REG))]
12451 "rol{w}\t{$8, %0|%0, 8}"
12452 [(set_attr "length" "4")
12453 (set_attr "mode" "HI")])
12455 (define_expand "paritydi2"
12456 [(set (match_operand:DI 0 "register_operand" "")
12457 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12460 rtx scratch = gen_reg_rtx (QImode);
12463 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12464 NULL_RTX, operands[1]));
12466 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12467 gen_rtx_REG (CCmode, FLAGS_REG),
12469 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12472 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12475 rtx tmp = gen_reg_rtx (SImode);
12477 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12478 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12483 (define_expand "paritysi2"
12484 [(set (match_operand:SI 0 "register_operand" "")
12485 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12488 rtx scratch = gen_reg_rtx (QImode);
12491 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12493 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12494 gen_rtx_REG (CCmode, FLAGS_REG),
12496 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12498 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12502 (define_insn_and_split "paritydi2_cmp"
12503 [(set (reg:CC FLAGS_REG)
12504 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12506 (clobber (match_scratch:DI 0 "=r"))
12507 (clobber (match_scratch:SI 1 "=&r"))
12508 (clobber (match_scratch:HI 2 "=Q"))]
12511 "&& reload_completed"
12513 [(set (match_dup 1)
12514 (xor:SI (match_dup 1) (match_dup 4)))
12515 (clobber (reg:CC FLAGS_REG))])
12517 [(set (reg:CC FLAGS_REG)
12518 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12519 (clobber (match_dup 1))
12520 (clobber (match_dup 2))])]
12522 operands[4] = gen_lowpart (SImode, operands[3]);
12526 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12527 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12530 operands[1] = gen_highpart (SImode, operands[3]);
12533 (define_insn_and_split "paritysi2_cmp"
12534 [(set (reg:CC FLAGS_REG)
12535 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12537 (clobber (match_scratch:SI 0 "=r"))
12538 (clobber (match_scratch:HI 1 "=&Q"))]
12541 "&& reload_completed"
12543 [(set (match_dup 1)
12544 (xor:HI (match_dup 1) (match_dup 3)))
12545 (clobber (reg:CC FLAGS_REG))])
12547 [(set (reg:CC FLAGS_REG)
12548 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12549 (clobber (match_dup 1))])]
12551 operands[3] = gen_lowpart (HImode, operands[2]);
12553 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12554 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12557 (define_insn "*parityhi2_cmp"
12558 [(set (reg:CC FLAGS_REG)
12559 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12561 (clobber (match_scratch:HI 0 "=Q"))]
12563 "xor{b}\t{%h0, %b0|%b0, %h0}"
12564 [(set_attr "length" "2")
12565 (set_attr "mode" "HI")])
12568 ;; Thread-local storage patterns for ELF.
12570 ;; Note that these code sequences must appear exactly as shown
12571 ;; in order to allow linker relaxation.
12573 (define_insn "*tls_global_dynamic_32_gnu"
12574 [(set (match_operand:SI 0 "register_operand" "=a")
12576 [(match_operand:SI 1 "register_operand" "b")
12577 (match_operand:SI 2 "tls_symbolic_operand" "")
12578 (match_operand:SI 3 "constant_call_address_operand" "z")]
12580 (clobber (match_scratch:SI 4 "=d"))
12581 (clobber (match_scratch:SI 5 "=c"))
12582 (clobber (reg:CC FLAGS_REG))]
12583 "!TARGET_64BIT && TARGET_GNU_TLS"
12586 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12587 if (TARGET_SUN_TLS)
12588 #ifdef HAVE_AS_IX86_TLSGDPLT
12589 return "call\t%a2@tlsgdplt";
12591 return "call\t%p3@plt";
12593 return "call\t%P3";
12595 [(set_attr "type" "multi")
12596 (set_attr "length" "12")])
12598 (define_expand "tls_global_dynamic_32"
12600 [(set (match_operand:SI 0 "register_operand" "")
12601 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12602 (match_operand:SI 1 "tls_symbolic_operand" "")
12603 (match_operand:SI 3 "constant_call_address_operand" "")]
12605 (clobber (match_scratch:SI 4 ""))
12606 (clobber (match_scratch:SI 5 ""))
12607 (clobber (reg:CC FLAGS_REG))])])
12609 (define_insn "*tls_global_dynamic_64"
12610 [(set (match_operand:DI 0 "register_operand" "=a")
12612 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12613 (match_operand:DI 3 "" "")))
12614 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12619 fputs (ASM_BYTE "0x66\n", asm_out_file);
12621 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12622 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12623 fputs ("\trex64\n", asm_out_file);
12624 if (TARGET_SUN_TLS)
12625 return "call\t%p2@plt";
12626 return "call\t%P2";
12628 [(set_attr "type" "multi")
12629 (set (attr "length")
12630 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12632 (define_expand "tls_global_dynamic_64"
12634 [(set (match_operand:DI 0 "register_operand" "")
12636 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12638 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12641 (define_insn "*tls_local_dynamic_base_32_gnu"
12642 [(set (match_operand:SI 0 "register_operand" "=a")
12644 [(match_operand:SI 1 "register_operand" "b")
12645 (match_operand:SI 2 "constant_call_address_operand" "z")]
12646 UNSPEC_TLS_LD_BASE))
12647 (clobber (match_scratch:SI 3 "=d"))
12648 (clobber (match_scratch:SI 4 "=c"))
12649 (clobber (reg:CC FLAGS_REG))]
12650 "!TARGET_64BIT && TARGET_GNU_TLS"
12653 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12654 if (TARGET_SUN_TLS)
12655 #ifdef HAVE_AS_IX86_TLSLDMPLT
12656 return "call\t%&@tlsldmplt";
12658 return "call\t%p2@plt";
12660 return "call\t%P2";
12662 [(set_attr "type" "multi")
12663 (set_attr "length" "11")])
12665 (define_expand "tls_local_dynamic_base_32"
12667 [(set (match_operand:SI 0 "register_operand" "")
12669 [(match_operand:SI 1 "register_operand" "")
12670 (match_operand:SI 2 "constant_call_address_operand" "")]
12671 UNSPEC_TLS_LD_BASE))
12672 (clobber (match_scratch:SI 3 ""))
12673 (clobber (match_scratch:SI 4 ""))
12674 (clobber (reg:CC FLAGS_REG))])])
12676 (define_insn "*tls_local_dynamic_base_64"
12677 [(set (match_operand:DI 0 "register_operand" "=a")
12679 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12680 (match_operand:DI 2 "" "")))
12681 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12685 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12686 if (TARGET_SUN_TLS)
12687 return "call\t%p1@plt";
12688 return "call\t%P1";
12690 [(set_attr "type" "multi")
12691 (set_attr "length" "12")])
12693 (define_expand "tls_local_dynamic_base_64"
12695 [(set (match_operand:DI 0 "register_operand" "")
12697 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12699 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12701 ;; Local dynamic of a single variable is a lose. Show combine how
12702 ;; to convert that back to global dynamic.
12704 (define_insn_and_split "*tls_local_dynamic_32_once"
12705 [(set (match_operand:SI 0 "register_operand" "=a")
12707 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12708 (match_operand:SI 2 "constant_call_address_operand" "z")]
12709 UNSPEC_TLS_LD_BASE)
12710 (const:SI (unspec:SI
12711 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12713 (clobber (match_scratch:SI 4 "=d"))
12714 (clobber (match_scratch:SI 5 "=c"))
12715 (clobber (reg:CC FLAGS_REG))]
12720 [(set (match_dup 0)
12721 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12723 (clobber (match_dup 4))
12724 (clobber (match_dup 5))
12725 (clobber (reg:CC FLAGS_REG))])])
12727 ;; Segment register for the thread base ptr load
12728 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12730 ;; Load and add the thread base pointer from %<tp_seg>:0.
12731 (define_insn "*load_tp_x32"
12732 [(set (match_operand:SI 0 "register_operand" "=r")
12733 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12735 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12736 [(set_attr "type" "imov")
12737 (set_attr "modrm" "0")
12738 (set_attr "length" "7")
12739 (set_attr "memory" "load")
12740 (set_attr "imm_disp" "false")])
12742 (define_insn "*load_tp_x32_zext"
12743 [(set (match_operand:DI 0 "register_operand" "=r")
12744 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12746 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12747 [(set_attr "type" "imov")
12748 (set_attr "modrm" "0")
12749 (set_attr "length" "7")
12750 (set_attr "memory" "load")
12751 (set_attr "imm_disp" "false")])
12753 (define_insn "*load_tp_<mode>"
12754 [(set (match_operand:P 0 "register_operand" "=r")
12755 (unspec:P [(const_int 0)] UNSPEC_TP))]
12757 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12758 [(set_attr "type" "imov")
12759 (set_attr "modrm" "0")
12760 (set_attr "length" "7")
12761 (set_attr "memory" "load")
12762 (set_attr "imm_disp" "false")])
12764 (define_insn "*add_tp_x32"
12765 [(set (match_operand:SI 0 "register_operand" "=r")
12766 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12767 (match_operand:SI 1 "register_operand" "0")))
12768 (clobber (reg:CC FLAGS_REG))]
12770 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12771 [(set_attr "type" "alu")
12772 (set_attr "modrm" "0")
12773 (set_attr "length" "7")
12774 (set_attr "memory" "load")
12775 (set_attr "imm_disp" "false")])
12777 (define_insn "*add_tp_x32_zext"
12778 [(set (match_operand:DI 0 "register_operand" "=r")
12780 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12781 (match_operand:SI 1 "register_operand" "0"))))
12782 (clobber (reg:CC FLAGS_REG))]
12784 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12785 [(set_attr "type" "alu")
12786 (set_attr "modrm" "0")
12787 (set_attr "length" "7")
12788 (set_attr "memory" "load")
12789 (set_attr "imm_disp" "false")])
12791 (define_insn "*add_tp_<mode>"
12792 [(set (match_operand:P 0 "register_operand" "=r")
12793 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12794 (match_operand:P 1 "register_operand" "0")))
12795 (clobber (reg:CC FLAGS_REG))]
12797 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12798 [(set_attr "type" "alu")
12799 (set_attr "modrm" "0")
12800 (set_attr "length" "7")
12801 (set_attr "memory" "load")
12802 (set_attr "imm_disp" "false")])
12804 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12805 ;; %rax as destination of the initial executable code sequence.
12806 (define_insn "tls_initial_exec_64_sun"
12807 [(set (match_operand:DI 0 "register_operand" "=a")
12809 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12810 UNSPEC_TLS_IE_SUN))
12811 (clobber (reg:CC FLAGS_REG))]
12812 "TARGET_64BIT && TARGET_SUN_TLS"
12815 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12816 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12818 [(set_attr "type" "multi")])
12820 ;; GNU2 TLS patterns can be split.
12822 (define_expand "tls_dynamic_gnu2_32"
12823 [(set (match_dup 3)
12824 (plus:SI (match_operand:SI 2 "register_operand" "")
12826 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12829 [(set (match_operand:SI 0 "register_operand" "")
12830 (unspec:SI [(match_dup 1) (match_dup 3)
12831 (match_dup 2) (reg:SI SP_REG)]
12833 (clobber (reg:CC FLAGS_REG))])]
12834 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12837 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12840 (define_insn "*tls_dynamic_gnu2_lea_32"
12841 [(set (match_operand:SI 0 "register_operand" "=r")
12842 (plus:SI (match_operand:SI 1 "register_operand" "b")
12844 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12845 UNSPEC_TLSDESC))))]
12846 "!TARGET_64BIT && TARGET_GNU2_TLS"
12847 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12848 [(set_attr "type" "lea")
12849 (set_attr "mode" "SI")
12850 (set_attr "length" "6")
12851 (set_attr "length_address" "4")])
12853 (define_insn "*tls_dynamic_gnu2_call_32"
12854 [(set (match_operand:SI 0 "register_operand" "=a")
12855 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12856 (match_operand:SI 2 "register_operand" "0")
12857 ;; we have to make sure %ebx still points to the GOT
12858 (match_operand:SI 3 "register_operand" "b")
12861 (clobber (reg:CC FLAGS_REG))]
12862 "!TARGET_64BIT && TARGET_GNU2_TLS"
12863 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12864 [(set_attr "type" "call")
12865 (set_attr "length" "2")
12866 (set_attr "length_address" "0")])
12868 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12869 [(set (match_operand:SI 0 "register_operand" "=&a")
12871 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12872 (match_operand:SI 4 "" "")
12873 (match_operand:SI 2 "register_operand" "b")
12876 (const:SI (unspec:SI
12877 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12879 (clobber (reg:CC FLAGS_REG))]
12880 "!TARGET_64BIT && TARGET_GNU2_TLS"
12883 [(set (match_dup 0) (match_dup 5))]
12885 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12886 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12889 (define_expand "tls_dynamic_gnu2_64"
12890 [(set (match_dup 2)
12891 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12894 [(set (match_operand:DI 0 "register_operand" "")
12895 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12897 (clobber (reg:CC FLAGS_REG))])]
12898 "TARGET_64BIT && TARGET_GNU2_TLS"
12900 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12901 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12904 (define_insn "*tls_dynamic_gnu2_lea_64"
12905 [(set (match_operand:DI 0 "register_operand" "=r")
12906 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12908 "TARGET_64BIT && TARGET_GNU2_TLS"
12909 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12910 [(set_attr "type" "lea")
12911 (set_attr "mode" "DI")
12912 (set_attr "length" "7")
12913 (set_attr "length_address" "4")])
12915 (define_insn "*tls_dynamic_gnu2_call_64"
12916 [(set (match_operand:DI 0 "register_operand" "=a")
12917 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12918 (match_operand:DI 2 "register_operand" "0")
12921 (clobber (reg:CC FLAGS_REG))]
12922 "TARGET_64BIT && TARGET_GNU2_TLS"
12923 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12924 [(set_attr "type" "call")
12925 (set_attr "length" "2")
12926 (set_attr "length_address" "0")])
12928 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12929 [(set (match_operand:DI 0 "register_operand" "=&a")
12931 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12932 (match_operand:DI 3 "" "")
12935 (const:DI (unspec:DI
12936 [(match_operand 1 "tls_symbolic_operand" "")]
12938 (clobber (reg:CC FLAGS_REG))]
12939 "TARGET_64BIT && TARGET_GNU2_TLS"
12942 [(set (match_dup 0) (match_dup 4))]
12944 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12945 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12948 ;; These patterns match the binary 387 instructions for addM3, subM3,
12949 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12950 ;; SFmode. The first is the normal insn, the second the same insn but
12951 ;; with one operand a conversion, and the third the same insn but with
12952 ;; the other operand a conversion. The conversion may be SFmode or
12953 ;; SImode if the target mode DFmode, but only SImode if the target mode
12956 ;; Gcc is slightly more smart about handling normal two address instructions
12957 ;; so use special patterns for add and mull.
12959 (define_insn "*fop_<mode>_comm_mixed"
12960 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12961 (match_operator:MODEF 3 "binary_fp_operator"
12962 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12963 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12964 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12965 && COMMUTATIVE_ARITH_P (operands[3])
12966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12967 "* return output_387_binary_op (insn, operands);"
12968 [(set (attr "type")
12969 (if_then_else (eq_attr "alternative" "1,2")
12970 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12971 (const_string "ssemul")
12972 (const_string "sseadd"))
12973 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12974 (const_string "fmul")
12975 (const_string "fop"))))
12976 (set_attr "isa" "*,noavx,avx")
12977 (set_attr "prefix" "orig,orig,vex")
12978 (set_attr "mode" "<MODE>")])
12980 (define_insn "*fop_<mode>_comm_sse"
12981 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12982 (match_operator:MODEF 3 "binary_fp_operator"
12983 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12984 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12985 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12986 && COMMUTATIVE_ARITH_P (operands[3])
12987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12988 "* return output_387_binary_op (insn, operands);"
12989 [(set (attr "type")
12990 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12991 (const_string "ssemul")
12992 (const_string "sseadd")))
12993 (set_attr "isa" "noavx,avx")
12994 (set_attr "prefix" "orig,vex")
12995 (set_attr "mode" "<MODE>")])
12997 (define_insn "*fop_<mode>_comm_i387"
12998 [(set (match_operand:MODEF 0 "register_operand" "=f")
12999 (match_operator:MODEF 3 "binary_fp_operator"
13000 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13001 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13002 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
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 "fmul")
13009 (const_string "fop")))
13010 (set_attr "mode" "<MODE>")])
13012 (define_insn "*fop_<mode>_1_mixed"
13013 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13014 (match_operator:MODEF 3 "binary_fp_operator"
13015 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13016 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13017 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13018 && !COMMUTATIVE_ARITH_P (operands[3])
13019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13020 "* return output_387_binary_op (insn, operands);"
13021 [(set (attr "type")
13022 (cond [(and (eq_attr "alternative" "2,3")
13023 (match_operand:MODEF 3 "mult_operator" ""))
13024 (const_string "ssemul")
13025 (and (eq_attr "alternative" "2,3")
13026 (match_operand:MODEF 3 "div_operator" ""))
13027 (const_string "ssediv")
13028 (eq_attr "alternative" "2,3")
13029 (const_string "sseadd")
13030 (match_operand:MODEF 3 "mult_operator" "")
13031 (const_string "fmul")
13032 (match_operand:MODEF 3 "div_operator" "")
13033 (const_string "fdiv")
13035 (const_string "fop")))
13036 (set_attr "isa" "*,*,noavx,avx")
13037 (set_attr "prefix" "orig,orig,orig,vex")
13038 (set_attr "mode" "<MODE>")])
13040 (define_insn "*rcpsf2_sse"
13041 [(set (match_operand:SF 0 "register_operand" "=x")
13042 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13045 "%vrcpss\t{%1, %d0|%d0, %1}"
13046 [(set_attr "type" "sse")
13047 (set_attr "atom_sse_attr" "rcp")
13048 (set_attr "prefix" "maybe_vex")
13049 (set_attr "mode" "SF")])
13051 (define_insn "*fop_<mode>_1_sse"
13052 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13053 (match_operator:MODEF 3 "binary_fp_operator"
13054 [(match_operand:MODEF 1 "register_operand" "0,x")
13055 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13056 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13057 && !COMMUTATIVE_ARITH_P (operands[3])"
13058 "* return output_387_binary_op (insn, operands);"
13059 [(set (attr "type")
13060 (cond [(match_operand:MODEF 3 "mult_operator" "")
13061 (const_string "ssemul")
13062 (match_operand:MODEF 3 "div_operator" "")
13063 (const_string "ssediv")
13065 (const_string "sseadd")))
13066 (set_attr "isa" "noavx,avx")
13067 (set_attr "prefix" "orig,vex")
13068 (set_attr "mode" "<MODE>")])
13070 ;; This pattern is not fully shadowed by the pattern above.
13071 (define_insn "*fop_<mode>_1_i387"
13072 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13073 (match_operator:MODEF 3 "binary_fp_operator"
13074 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13075 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13076 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13077 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13078 && !COMMUTATIVE_ARITH_P (operands[3])
13079 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13080 "* return output_387_binary_op (insn, operands);"
13081 [(set (attr "type")
13082 (cond [(match_operand:MODEF 3 "mult_operator" "")
13083 (const_string "fmul")
13084 (match_operand:MODEF 3 "div_operator" "")
13085 (const_string "fdiv")
13087 (const_string "fop")))
13088 (set_attr "mode" "<MODE>")])
13090 ;; ??? Add SSE splitters for these!
13091 (define_insn "*fop_<MODEF:mode>_2_i387"
13092 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13093 (match_operator:MODEF 3 "binary_fp_operator"
13095 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13096 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13097 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13098 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13099 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13100 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13101 [(set (attr "type")
13102 (cond [(match_operand:MODEF 3 "mult_operator" "")
13103 (const_string "fmul")
13104 (match_operand:MODEF 3 "div_operator" "")
13105 (const_string "fdiv")
13107 (const_string "fop")))
13108 (set_attr "fp_int_src" "true")
13109 (set_attr "mode" "<SWI24:MODE>")])
13111 (define_insn "*fop_<MODEF:mode>_3_i387"
13112 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13113 (match_operator:MODEF 3 "binary_fp_operator"
13114 [(match_operand:MODEF 1 "register_operand" "0,0")
13116 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13117 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13118 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13119 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13120 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13121 [(set (attr "type")
13122 (cond [(match_operand:MODEF 3 "mult_operator" "")
13123 (const_string "fmul")
13124 (match_operand:MODEF 3 "div_operator" "")
13125 (const_string "fdiv")
13127 (const_string "fop")))
13128 (set_attr "fp_int_src" "true")
13129 (set_attr "mode" "<MODE>")])
13131 (define_insn "*fop_df_4_i387"
13132 [(set (match_operand:DF 0 "register_operand" "=f,f")
13133 (match_operator:DF 3 "binary_fp_operator"
13135 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13136 (match_operand:DF 2 "register_operand" "0,f")]))]
13137 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13138 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13140 "* return output_387_binary_op (insn, operands);"
13141 [(set (attr "type")
13142 (cond [(match_operand:DF 3 "mult_operator" "")
13143 (const_string "fmul")
13144 (match_operand:DF 3 "div_operator" "")
13145 (const_string "fdiv")
13147 (const_string "fop")))
13148 (set_attr "mode" "SF")])
13150 (define_insn "*fop_df_5_i387"
13151 [(set (match_operand:DF 0 "register_operand" "=f,f")
13152 (match_operator:DF 3 "binary_fp_operator"
13153 [(match_operand:DF 1 "register_operand" "0,f")
13155 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13156 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13157 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13158 "* return output_387_binary_op (insn, operands);"
13159 [(set (attr "type")
13160 (cond [(match_operand:DF 3 "mult_operator" "")
13161 (const_string "fmul")
13162 (match_operand:DF 3 "div_operator" "")
13163 (const_string "fdiv")
13165 (const_string "fop")))
13166 (set_attr "mode" "SF")])
13168 (define_insn "*fop_df_6_i387"
13169 [(set (match_operand:DF 0 "register_operand" "=f,f")
13170 (match_operator:DF 3 "binary_fp_operator"
13172 (match_operand:SF 1 "register_operand" "0,f"))
13174 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13175 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13176 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13177 "* return output_387_binary_op (insn, operands);"
13178 [(set (attr "type")
13179 (cond [(match_operand:DF 3 "mult_operator" "")
13180 (const_string "fmul")
13181 (match_operand:DF 3 "div_operator" "")
13182 (const_string "fdiv")
13184 (const_string "fop")))
13185 (set_attr "mode" "SF")])
13187 (define_insn "*fop_xf_comm_i387"
13188 [(set (match_operand:XF 0 "register_operand" "=f")
13189 (match_operator:XF 3 "binary_fp_operator"
13190 [(match_operand:XF 1 "register_operand" "%0")
13191 (match_operand:XF 2 "register_operand" "f")]))]
13193 && COMMUTATIVE_ARITH_P (operands[3])"
13194 "* return output_387_binary_op (insn, operands);"
13195 [(set (attr "type")
13196 (if_then_else (match_operand:XF 3 "mult_operator" "")
13197 (const_string "fmul")
13198 (const_string "fop")))
13199 (set_attr "mode" "XF")])
13201 (define_insn "*fop_xf_1_i387"
13202 [(set (match_operand:XF 0 "register_operand" "=f,f")
13203 (match_operator:XF 3 "binary_fp_operator"
13204 [(match_operand:XF 1 "register_operand" "0,f")
13205 (match_operand:XF 2 "register_operand" "f,0")]))]
13207 && !COMMUTATIVE_ARITH_P (operands[3])"
13208 "* return output_387_binary_op (insn, operands);"
13209 [(set (attr "type")
13210 (cond [(match_operand:XF 3 "mult_operator" "")
13211 (const_string "fmul")
13212 (match_operand:XF 3 "div_operator" "")
13213 (const_string "fdiv")
13215 (const_string "fop")))
13216 (set_attr "mode" "XF")])
13218 (define_insn "*fop_xf_2_i387"
13219 [(set (match_operand:XF 0 "register_operand" "=f,f")
13220 (match_operator:XF 3 "binary_fp_operator"
13222 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13223 (match_operand:XF 2 "register_operand" "0,0")]))]
13224 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13225 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
13234 (set_attr "mode" "<MODE>")])
13236 (define_insn "*fop_xf_3_i387"
13237 [(set (match_operand:XF 0 "register_operand" "=f,f")
13238 (match_operator:XF 3 "binary_fp_operator"
13239 [(match_operand:XF 1 "register_operand" "0,0")
13241 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13242 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13243 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13244 [(set (attr "type")
13245 (cond [(match_operand:XF 3 "mult_operator" "")
13246 (const_string "fmul")
13247 (match_operand:XF 3 "div_operator" "")
13248 (const_string "fdiv")
13250 (const_string "fop")))
13251 (set_attr "fp_int_src" "true")
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_xf_4_i387"
13255 [(set (match_operand:XF 0 "register_operand" "=f,f")
13256 (match_operator:XF 3 "binary_fp_operator"
13258 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13259 (match_operand:XF 2 "register_operand" "0,f")]))]
13261 "* return output_387_binary_op (insn, operands);"
13262 [(set (attr "type")
13263 (cond [(match_operand:XF 3 "mult_operator" "")
13264 (const_string "fmul")
13265 (match_operand:XF 3 "div_operator" "")
13266 (const_string "fdiv")
13268 (const_string "fop")))
13269 (set_attr "mode" "<MODE>")])
13271 (define_insn "*fop_xf_5_i387"
13272 [(set (match_operand:XF 0 "register_operand" "=f,f")
13273 (match_operator:XF 3 "binary_fp_operator"
13274 [(match_operand:XF 1 "register_operand" "0,f")
13276 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
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_6_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f,f")
13290 (match_operator:XF 3 "binary_fp_operator"
13292 (match_operand:MODEF 1 "register_operand" "0,f"))
13294 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13296 "* return output_387_binary_op (insn, operands);"
13297 [(set (attr "type")
13298 (cond [(match_operand:XF 3 "mult_operator" "")
13299 (const_string "fmul")
13300 (match_operand:XF 3 "div_operator" "")
13301 (const_string "fdiv")
13303 (const_string "fop")))
13304 (set_attr "mode" "<MODE>")])
13307 [(set (match_operand 0 "register_operand" "")
13308 (match_operator 3 "binary_fp_operator"
13309 [(float (match_operand:SWI24 1 "register_operand" ""))
13310 (match_operand 2 "register_operand" "")]))]
13312 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13313 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13316 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13317 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13318 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13319 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13320 GET_MODE (operands[3]),
13323 ix86_free_from_memory (GET_MODE (operands[1]));
13328 [(set (match_operand 0 "register_operand" "")
13329 (match_operator 3 "binary_fp_operator"
13330 [(match_operand 1 "register_operand" "")
13331 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13333 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13334 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13337 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13338 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13339 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13340 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13341 GET_MODE (operands[3]),
13344 ix86_free_from_memory (GET_MODE (operands[2]));
13348 ;; FPU special functions.
13350 ;; This pattern implements a no-op XFmode truncation for
13351 ;; all fancy i386 XFmode math functions.
13353 (define_insn "truncxf<mode>2_i387_noop_unspec"
13354 [(set (match_operand:MODEF 0 "register_operand" "=f")
13355 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13356 UNSPEC_TRUNC_NOOP))]
13357 "TARGET_USE_FANCY_MATH_387"
13358 "* return output_387_reg_move (insn, operands);"
13359 [(set_attr "type" "fmov")
13360 (set_attr "mode" "<MODE>")])
13362 (define_insn "sqrtxf2"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13365 "TARGET_USE_FANCY_MATH_387"
13367 [(set_attr "type" "fpspc")
13368 (set_attr "mode" "XF")
13369 (set_attr "athlon_decode" "direct")
13370 (set_attr "amdfam10_decode" "direct")
13371 (set_attr "bdver1_decode" "direct")])
13373 (define_insn "sqrt_extend<mode>xf2_i387"
13374 [(set (match_operand:XF 0 "register_operand" "=f")
13377 (match_operand:MODEF 1 "register_operand" "0"))))]
13378 "TARGET_USE_FANCY_MATH_387"
13380 [(set_attr "type" "fpspc")
13381 (set_attr "mode" "XF")
13382 (set_attr "athlon_decode" "direct")
13383 (set_attr "amdfam10_decode" "direct")
13384 (set_attr "bdver1_decode" "direct")])
13386 (define_insn "*rsqrtsf2_sse"
13387 [(set (match_operand:SF 0 "register_operand" "=x")
13388 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13391 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13392 [(set_attr "type" "sse")
13393 (set_attr "atom_sse_attr" "rcp")
13394 (set_attr "prefix" "maybe_vex")
13395 (set_attr "mode" "SF")])
13397 (define_expand "rsqrtsf2"
13398 [(set (match_operand:SF 0 "register_operand" "")
13399 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13403 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13407 (define_insn "*sqrt<mode>2_sse"
13408 [(set (match_operand:MODEF 0 "register_operand" "=x")
13410 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13411 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13412 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13413 [(set_attr "type" "sse")
13414 (set_attr "atom_sse_attr" "sqrt")
13415 (set_attr "prefix" "maybe_vex")
13416 (set_attr "mode" "<MODE>")
13417 (set_attr "athlon_decode" "*")
13418 (set_attr "amdfam10_decode" "*")
13419 (set_attr "bdver1_decode" "*")])
13421 (define_expand "sqrt<mode>2"
13422 [(set (match_operand:MODEF 0 "register_operand" "")
13424 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13425 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13426 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13428 if (<MODE>mode == SFmode
13429 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13430 && flag_finite_math_only && !flag_trapping_math
13431 && flag_unsafe_math_optimizations)
13433 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13437 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13439 rtx op0 = gen_reg_rtx (XFmode);
13440 rtx op1 = force_reg (<MODE>mode, operands[1]);
13442 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13443 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13448 (define_insn "fpremxf4_i387"
13449 [(set (match_operand:XF 0 "register_operand" "=f")
13450 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13451 (match_operand:XF 3 "register_operand" "1")]
13453 (set (match_operand:XF 1 "register_operand" "=u")
13454 (unspec:XF [(match_dup 2) (match_dup 3)]
13456 (set (reg:CCFP FPSR_REG)
13457 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13459 "TARGET_USE_FANCY_MATH_387"
13461 [(set_attr "type" "fpspc")
13462 (set_attr "mode" "XF")])
13464 (define_expand "fmodxf3"
13465 [(use (match_operand:XF 0 "register_operand" ""))
13466 (use (match_operand:XF 1 "general_operand" ""))
13467 (use (match_operand:XF 2 "general_operand" ""))]
13468 "TARGET_USE_FANCY_MATH_387"
13470 rtx label = gen_label_rtx ();
13472 rtx op1 = gen_reg_rtx (XFmode);
13473 rtx op2 = gen_reg_rtx (XFmode);
13475 emit_move_insn (op2, operands[2]);
13476 emit_move_insn (op1, operands[1]);
13478 emit_label (label);
13479 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13480 ix86_emit_fp_unordered_jump (label);
13481 LABEL_NUSES (label) = 1;
13483 emit_move_insn (operands[0], op1);
13487 (define_expand "fmod<mode>3"
13488 [(use (match_operand:MODEF 0 "register_operand" ""))
13489 (use (match_operand:MODEF 1 "general_operand" ""))
13490 (use (match_operand:MODEF 2 "general_operand" ""))]
13491 "TARGET_USE_FANCY_MATH_387"
13493 rtx (*gen_truncxf) (rtx, rtx);
13495 rtx label = gen_label_rtx ();
13497 rtx op1 = gen_reg_rtx (XFmode);
13498 rtx op2 = gen_reg_rtx (XFmode);
13500 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13503 emit_label (label);
13504 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13505 ix86_emit_fp_unordered_jump (label);
13506 LABEL_NUSES (label) = 1;
13508 /* Truncate the result properly for strict SSE math. */
13509 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13510 && !TARGET_MIX_SSE_I387)
13511 gen_truncxf = gen_truncxf<mode>2;
13513 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13515 emit_insn (gen_truncxf (operands[0], op1));
13519 (define_insn "fprem1xf4_i387"
13520 [(set (match_operand:XF 0 "register_operand" "=f")
13521 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13522 (match_operand:XF 3 "register_operand" "1")]
13524 (set (match_operand:XF 1 "register_operand" "=u")
13525 (unspec:XF [(match_dup 2) (match_dup 3)]
13527 (set (reg:CCFP FPSR_REG)
13528 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13530 "TARGET_USE_FANCY_MATH_387"
13532 [(set_attr "type" "fpspc")
13533 (set_attr "mode" "XF")])
13535 (define_expand "remainderxf3"
13536 [(use (match_operand:XF 0 "register_operand" ""))
13537 (use (match_operand:XF 1 "general_operand" ""))
13538 (use (match_operand:XF 2 "general_operand" ""))]
13539 "TARGET_USE_FANCY_MATH_387"
13541 rtx label = gen_label_rtx ();
13543 rtx op1 = gen_reg_rtx (XFmode);
13544 rtx op2 = gen_reg_rtx (XFmode);
13546 emit_move_insn (op2, operands[2]);
13547 emit_move_insn (op1, operands[1]);
13549 emit_label (label);
13550 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13551 ix86_emit_fp_unordered_jump (label);
13552 LABEL_NUSES (label) = 1;
13554 emit_move_insn (operands[0], op1);
13558 (define_expand "remainder<mode>3"
13559 [(use (match_operand:MODEF 0 "register_operand" ""))
13560 (use (match_operand:MODEF 1 "general_operand" ""))
13561 (use (match_operand:MODEF 2 "general_operand" ""))]
13562 "TARGET_USE_FANCY_MATH_387"
13564 rtx (*gen_truncxf) (rtx, rtx);
13566 rtx label = gen_label_rtx ();
13568 rtx op1 = gen_reg_rtx (XFmode);
13569 rtx op2 = gen_reg_rtx (XFmode);
13571 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13572 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13574 emit_label (label);
13576 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13577 ix86_emit_fp_unordered_jump (label);
13578 LABEL_NUSES (label) = 1;
13580 /* Truncate the result properly for strict SSE math. */
13581 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13582 && !TARGET_MIX_SSE_I387)
13583 gen_truncxf = gen_truncxf<mode>2;
13585 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13587 emit_insn (gen_truncxf (operands[0], op1));
13591 (define_insn "*sinxf2_i387"
13592 [(set (match_operand:XF 0 "register_operand" "=f")
13593 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13594 "TARGET_USE_FANCY_MATH_387
13595 && flag_unsafe_math_optimizations"
13597 [(set_attr "type" "fpspc")
13598 (set_attr "mode" "XF")])
13600 (define_insn "*sin_extend<mode>xf2_i387"
13601 [(set (match_operand:XF 0 "register_operand" "=f")
13602 (unspec:XF [(float_extend:XF
13603 (match_operand:MODEF 1 "register_operand" "0"))]
13605 "TARGET_USE_FANCY_MATH_387
13606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13607 || TARGET_MIX_SSE_I387)
13608 && flag_unsafe_math_optimizations"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13613 (define_insn "*cosxf2_i387"
13614 [(set (match_operand:XF 0 "register_operand" "=f")
13615 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13616 "TARGET_USE_FANCY_MATH_387
13617 && flag_unsafe_math_optimizations"
13619 [(set_attr "type" "fpspc")
13620 (set_attr "mode" "XF")])
13622 (define_insn "*cos_extend<mode>xf2_i387"
13623 [(set (match_operand:XF 0 "register_operand" "=f")
13624 (unspec:XF [(float_extend:XF
13625 (match_operand:MODEF 1 "register_operand" "0"))]
13627 "TARGET_USE_FANCY_MATH_387
13628 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13629 || TARGET_MIX_SSE_I387)
13630 && flag_unsafe_math_optimizations"
13632 [(set_attr "type" "fpspc")
13633 (set_attr "mode" "XF")])
13635 ;; When sincos pattern is defined, sin and cos builtin functions will be
13636 ;; expanded to sincos pattern with one of its outputs left unused.
13637 ;; CSE pass will figure out if two sincos patterns can be combined,
13638 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13639 ;; depending on the unused output.
13641 (define_insn "sincosxf3"
13642 [(set (match_operand:XF 0 "register_operand" "=f")
13643 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13644 UNSPEC_SINCOS_COS))
13645 (set (match_operand:XF 1 "register_operand" "=u")
13646 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13647 "TARGET_USE_FANCY_MATH_387
13648 && flag_unsafe_math_optimizations"
13650 [(set_attr "type" "fpspc")
13651 (set_attr "mode" "XF")])
13654 [(set (match_operand:XF 0 "register_operand" "")
13655 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13656 UNSPEC_SINCOS_COS))
13657 (set (match_operand:XF 1 "register_operand" "")
13658 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13659 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13660 && can_create_pseudo_p ()"
13661 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13664 [(set (match_operand:XF 0 "register_operand" "")
13665 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13666 UNSPEC_SINCOS_COS))
13667 (set (match_operand:XF 1 "register_operand" "")
13668 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13669 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13670 && can_create_pseudo_p ()"
13671 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13673 (define_insn "sincos_extend<mode>xf3_i387"
13674 [(set (match_operand:XF 0 "register_operand" "=f")
13675 (unspec:XF [(float_extend:XF
13676 (match_operand:MODEF 2 "register_operand" "0"))]
13677 UNSPEC_SINCOS_COS))
13678 (set (match_operand:XF 1 "register_operand" "=u")
13679 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13680 "TARGET_USE_FANCY_MATH_387
13681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682 || TARGET_MIX_SSE_I387)
13683 && flag_unsafe_math_optimizations"
13685 [(set_attr "type" "fpspc")
13686 (set_attr "mode" "XF")])
13689 [(set (match_operand:XF 0 "register_operand" "")
13690 (unspec:XF [(float_extend:XF
13691 (match_operand:MODEF 2 "register_operand" ""))]
13692 UNSPEC_SINCOS_COS))
13693 (set (match_operand:XF 1 "register_operand" "")
13694 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13696 && can_create_pseudo_p ()"
13697 [(set (match_dup 1)
13698 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13701 [(set (match_operand:XF 0 "register_operand" "")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 2 "register_operand" ""))]
13704 UNSPEC_SINCOS_COS))
13705 (set (match_operand:XF 1 "register_operand" "")
13706 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13707 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13708 && can_create_pseudo_p ()"
13709 [(set (match_dup 0)
13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13712 (define_expand "sincos<mode>3"
13713 [(use (match_operand:MODEF 0 "register_operand" ""))
13714 (use (match_operand:MODEF 1 "register_operand" ""))
13715 (use (match_operand:MODEF 2 "register_operand" ""))]
13716 "TARGET_USE_FANCY_MATH_387
13717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13718 || TARGET_MIX_SSE_I387)
13719 && flag_unsafe_math_optimizations"
13721 rtx op0 = gen_reg_rtx (XFmode);
13722 rtx op1 = gen_reg_rtx (XFmode);
13724 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13725 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13726 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13730 (define_insn "fptanxf4_i387"
13731 [(set (match_operand:XF 0 "register_operand" "=f")
13732 (match_operand:XF 3 "const_double_operand" "F"))
13733 (set (match_operand:XF 1 "register_operand" "=u")
13734 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13736 "TARGET_USE_FANCY_MATH_387
13737 && flag_unsafe_math_optimizations
13738 && standard_80387_constant_p (operands[3]) == 2"
13740 [(set_attr "type" "fpspc")
13741 (set_attr "mode" "XF")])
13743 (define_insn "fptan_extend<mode>xf4_i387"
13744 [(set (match_operand:MODEF 0 "register_operand" "=f")
13745 (match_operand:MODEF 3 "const_double_operand" "F"))
13746 (set (match_operand:XF 1 "register_operand" "=u")
13747 (unspec:XF [(float_extend:XF
13748 (match_operand:MODEF 2 "register_operand" "0"))]
13750 "TARGET_USE_FANCY_MATH_387
13751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13752 || TARGET_MIX_SSE_I387)
13753 && flag_unsafe_math_optimizations
13754 && standard_80387_constant_p (operands[3]) == 2"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13759 (define_expand "tanxf2"
13760 [(use (match_operand:XF 0 "register_operand" ""))
13761 (use (match_operand:XF 1 "register_operand" ""))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && flag_unsafe_math_optimizations"
13765 rtx one = gen_reg_rtx (XFmode);
13766 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13768 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13772 (define_expand "tan<mode>2"
13773 [(use (match_operand:MODEF 0 "register_operand" ""))
13774 (use (match_operand:MODEF 1 "register_operand" ""))]
13775 "TARGET_USE_FANCY_MATH_387
13776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13777 || TARGET_MIX_SSE_I387)
13778 && flag_unsafe_math_optimizations"
13780 rtx op0 = gen_reg_rtx (XFmode);
13782 rtx one = gen_reg_rtx (<MODE>mode);
13783 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13785 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13786 operands[1], op2));
13787 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13791 (define_insn "*fpatanxf3_i387"
13792 [(set (match_operand:XF 0 "register_operand" "=f")
13793 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13794 (match_operand:XF 2 "register_operand" "u")]
13796 (clobber (match_scratch:XF 3 "=2"))]
13797 "TARGET_USE_FANCY_MATH_387
13798 && flag_unsafe_math_optimizations"
13800 [(set_attr "type" "fpspc")
13801 (set_attr "mode" "XF")])
13803 (define_insn "fpatan_extend<mode>xf3_i387"
13804 [(set (match_operand:XF 0 "register_operand" "=f")
13805 (unspec:XF [(float_extend:XF
13806 (match_operand:MODEF 1 "register_operand" "0"))
13808 (match_operand:MODEF 2 "register_operand" "u"))]
13810 (clobber (match_scratch:XF 3 "=2"))]
13811 "TARGET_USE_FANCY_MATH_387
13812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13813 || TARGET_MIX_SSE_I387)
13814 && flag_unsafe_math_optimizations"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13819 (define_expand "atan2xf3"
13820 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13821 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13822 (match_operand:XF 1 "register_operand" "")]
13824 (clobber (match_scratch:XF 3 ""))])]
13825 "TARGET_USE_FANCY_MATH_387
13826 && flag_unsafe_math_optimizations")
13828 (define_expand "atan2<mode>3"
13829 [(use (match_operand:MODEF 0 "register_operand" ""))
13830 (use (match_operand:MODEF 1 "register_operand" ""))
13831 (use (match_operand:MODEF 2 "register_operand" ""))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13834 || TARGET_MIX_SSE_I387)
13835 && flag_unsafe_math_optimizations"
13837 rtx op0 = gen_reg_rtx (XFmode);
13839 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13844 (define_expand "atanxf2"
13845 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13846 (unspec:XF [(match_dup 2)
13847 (match_operand:XF 1 "register_operand" "")]
13849 (clobber (match_scratch:XF 3 ""))])]
13850 "TARGET_USE_FANCY_MATH_387
13851 && flag_unsafe_math_optimizations"
13853 operands[2] = gen_reg_rtx (XFmode);
13854 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13857 (define_expand "atan<mode>2"
13858 [(use (match_operand:MODEF 0 "register_operand" ""))
13859 (use (match_operand:MODEF 1 "register_operand" ""))]
13860 "TARGET_USE_FANCY_MATH_387
13861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13862 || TARGET_MIX_SSE_I387)
13863 && flag_unsafe_math_optimizations"
13865 rtx op0 = gen_reg_rtx (XFmode);
13867 rtx op2 = gen_reg_rtx (<MODE>mode);
13868 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13870 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13875 (define_expand "asinxf2"
13876 [(set (match_dup 2)
13877 (mult:XF (match_operand:XF 1 "register_operand" "")
13879 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13880 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13881 (parallel [(set (match_operand:XF 0 "register_operand" "")
13882 (unspec:XF [(match_dup 5) (match_dup 1)]
13884 (clobber (match_scratch:XF 6 ""))])]
13885 "TARGET_USE_FANCY_MATH_387
13886 && flag_unsafe_math_optimizations"
13890 if (optimize_insn_for_size_p ())
13893 for (i = 2; i < 6; i++)
13894 operands[i] = gen_reg_rtx (XFmode);
13896 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13899 (define_expand "asin<mode>2"
13900 [(use (match_operand:MODEF 0 "register_operand" ""))
13901 (use (match_operand:MODEF 1 "general_operand" ""))]
13902 "TARGET_USE_FANCY_MATH_387
13903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13904 || TARGET_MIX_SSE_I387)
13905 && flag_unsafe_math_optimizations"
13907 rtx op0 = gen_reg_rtx (XFmode);
13908 rtx op1 = gen_reg_rtx (XFmode);
13910 if (optimize_insn_for_size_p ())
13913 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13914 emit_insn (gen_asinxf2 (op0, op1));
13915 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13919 (define_expand "acosxf2"
13920 [(set (match_dup 2)
13921 (mult:XF (match_operand:XF 1 "register_operand" "")
13923 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13924 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13925 (parallel [(set (match_operand:XF 0 "register_operand" "")
13926 (unspec:XF [(match_dup 1) (match_dup 5)]
13928 (clobber (match_scratch:XF 6 ""))])]
13929 "TARGET_USE_FANCY_MATH_387
13930 && flag_unsafe_math_optimizations"
13934 if (optimize_insn_for_size_p ())
13937 for (i = 2; i < 6; i++)
13938 operands[i] = gen_reg_rtx (XFmode);
13940 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13943 (define_expand "acos<mode>2"
13944 [(use (match_operand:MODEF 0 "register_operand" ""))
13945 (use (match_operand:MODEF 1 "general_operand" ""))]
13946 "TARGET_USE_FANCY_MATH_387
13947 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948 || TARGET_MIX_SSE_I387)
13949 && flag_unsafe_math_optimizations"
13951 rtx op0 = gen_reg_rtx (XFmode);
13952 rtx op1 = gen_reg_rtx (XFmode);
13954 if (optimize_insn_for_size_p ())
13957 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13958 emit_insn (gen_acosxf2 (op0, op1));
13959 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13963 (define_insn "fyl2xxf3_i387"
13964 [(set (match_operand:XF 0 "register_operand" "=f")
13965 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13966 (match_operand:XF 2 "register_operand" "u")]
13968 (clobber (match_scratch:XF 3 "=2"))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_insn "fyl2x_extend<mode>xf3_i387"
13976 [(set (match_operand:XF 0 "register_operand" "=f")
13977 (unspec:XF [(float_extend:XF
13978 (match_operand:MODEF 1 "register_operand" "0"))
13979 (match_operand:XF 2 "register_operand" "u")]
13981 (clobber (match_scratch:XF 3 "=2"))]
13982 "TARGET_USE_FANCY_MATH_387
13983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13984 || TARGET_MIX_SSE_I387)
13985 && flag_unsafe_math_optimizations"
13987 [(set_attr "type" "fpspc")
13988 (set_attr "mode" "XF")])
13990 (define_expand "logxf2"
13991 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13992 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13993 (match_dup 2)] UNSPEC_FYL2X))
13994 (clobber (match_scratch:XF 3 ""))])]
13995 "TARGET_USE_FANCY_MATH_387
13996 && flag_unsafe_math_optimizations"
13998 operands[2] = gen_reg_rtx (XFmode);
13999 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14002 (define_expand "log<mode>2"
14003 [(use (match_operand:MODEF 0 "register_operand" ""))
14004 (use (match_operand:MODEF 1 "register_operand" ""))]
14005 "TARGET_USE_FANCY_MATH_387
14006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14007 || TARGET_MIX_SSE_I387)
14008 && flag_unsafe_math_optimizations"
14010 rtx op0 = gen_reg_rtx (XFmode);
14012 rtx op2 = gen_reg_rtx (XFmode);
14013 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14015 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14016 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14020 (define_expand "log10xf2"
14021 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14022 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14023 (match_dup 2)] UNSPEC_FYL2X))
14024 (clobber (match_scratch:XF 3 ""))])]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14028 operands[2] = gen_reg_rtx (XFmode);
14029 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14032 (define_expand "log10<mode>2"
14033 [(use (match_operand:MODEF 0 "register_operand" ""))
14034 (use (match_operand:MODEF 1 "register_operand" ""))]
14035 "TARGET_USE_FANCY_MATH_387
14036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037 || TARGET_MIX_SSE_I387)
14038 && flag_unsafe_math_optimizations"
14040 rtx op0 = gen_reg_rtx (XFmode);
14042 rtx op2 = gen_reg_rtx (XFmode);
14043 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14045 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 (define_expand "log2xf2"
14051 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14052 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14053 (match_dup 2)] UNSPEC_FYL2X))
14054 (clobber (match_scratch:XF 3 ""))])]
14055 "TARGET_USE_FANCY_MATH_387
14056 && flag_unsafe_math_optimizations"
14058 operands[2] = gen_reg_rtx (XFmode);
14059 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14062 (define_expand "log2<mode>2"
14063 [(use (match_operand:MODEF 0 "register_operand" ""))
14064 (use (match_operand:MODEF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067 || TARGET_MIX_SSE_I387)
14068 && flag_unsafe_math_optimizations"
14070 rtx op0 = gen_reg_rtx (XFmode);
14072 rtx op2 = gen_reg_rtx (XFmode);
14073 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14075 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14080 (define_insn "fyl2xp1xf3_i387"
14081 [(set (match_operand:XF 0 "register_operand" "=f")
14082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14083 (match_operand:XF 2 "register_operand" "u")]
14085 (clobber (match_scratch:XF 3 "=2"))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14089 [(set_attr "type" "fpspc")
14090 (set_attr "mode" "XF")])
14092 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14093 [(set (match_operand:XF 0 "register_operand" "=f")
14094 (unspec:XF [(float_extend:XF
14095 (match_operand:MODEF 1 "register_operand" "0"))
14096 (match_operand:XF 2 "register_operand" "u")]
14098 (clobber (match_scratch:XF 3 "=2"))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101 || TARGET_MIX_SSE_I387)
14102 && flag_unsafe_math_optimizations"
14104 [(set_attr "type" "fpspc")
14105 (set_attr "mode" "XF")])
14107 (define_expand "log1pxf2"
14108 [(use (match_operand:XF 0 "register_operand" ""))
14109 (use (match_operand:XF 1 "register_operand" ""))]
14110 "TARGET_USE_FANCY_MATH_387
14111 && flag_unsafe_math_optimizations"
14113 if (optimize_insn_for_size_p ())
14116 ix86_emit_i387_log1p (operands[0], operands[1]);
14120 (define_expand "log1p<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand" ""))
14122 (use (match_operand:MODEF 1 "register_operand" ""))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14130 if (optimize_insn_for_size_p ())
14133 op0 = gen_reg_rtx (XFmode);
14135 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14137 ix86_emit_i387_log1p (op0, operands[1]);
14138 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14142 (define_insn "fxtractxf3_i387"
14143 [(set (match_operand:XF 0 "register_operand" "=f")
14144 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14145 UNSPEC_XTRACT_FRACT))
14146 (set (match_operand:XF 1 "register_operand" "=u")
14147 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14151 [(set_attr "type" "fpspc")
14152 (set_attr "mode" "XF")])
14154 (define_insn "fxtract_extend<mode>xf3_i387"
14155 [(set (match_operand:XF 0 "register_operand" "=f")
14156 (unspec:XF [(float_extend:XF
14157 (match_operand:MODEF 2 "register_operand" "0"))]
14158 UNSPEC_XTRACT_FRACT))
14159 (set (match_operand:XF 1 "register_operand" "=u")
14160 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14161 "TARGET_USE_FANCY_MATH_387
14162 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163 || TARGET_MIX_SSE_I387)
14164 && flag_unsafe_math_optimizations"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "XF")])
14169 (define_expand "logbxf2"
14170 [(parallel [(set (match_dup 2)
14171 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14172 UNSPEC_XTRACT_FRACT))
14173 (set (match_operand:XF 0 "register_operand" "")
14174 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14175 "TARGET_USE_FANCY_MATH_387
14176 && flag_unsafe_math_optimizations"
14177 "operands[2] = gen_reg_rtx (XFmode);")
14179 (define_expand "logb<mode>2"
14180 [(use (match_operand:MODEF 0 "register_operand" ""))
14181 (use (match_operand:MODEF 1 "register_operand" ""))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations"
14187 rtx op0 = gen_reg_rtx (XFmode);
14188 rtx op1 = gen_reg_rtx (XFmode);
14190 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14195 (define_expand "ilogbxf2"
14196 [(use (match_operand:SI 0 "register_operand" ""))
14197 (use (match_operand:XF 1 "register_operand" ""))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations"
14203 if (optimize_insn_for_size_p ())
14206 op0 = gen_reg_rtx (XFmode);
14207 op1 = gen_reg_rtx (XFmode);
14209 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14210 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14214 (define_expand "ilogb<mode>2"
14215 [(use (match_operand:SI 0 "register_operand" ""))
14216 (use (match_operand:MODEF 1 "register_operand" ""))]
14217 "TARGET_USE_FANCY_MATH_387
14218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14219 || TARGET_MIX_SSE_I387)
14220 && flag_unsafe_math_optimizations"
14224 if (optimize_insn_for_size_p ())
14227 op0 = gen_reg_rtx (XFmode);
14228 op1 = gen_reg_rtx (XFmode);
14230 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14235 (define_insn "*f2xm1xf2_i387"
14236 [(set (match_operand:XF 0 "register_operand" "=f")
14237 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14239 "TARGET_USE_FANCY_MATH_387
14240 && flag_unsafe_math_optimizations"
14242 [(set_attr "type" "fpspc")
14243 (set_attr "mode" "XF")])
14245 (define_insn "*fscalexf4_i387"
14246 [(set (match_operand:XF 0 "register_operand" "=f")
14247 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14248 (match_operand:XF 3 "register_operand" "1")]
14249 UNSPEC_FSCALE_FRACT))
14250 (set (match_operand:XF 1 "register_operand" "=u")
14251 (unspec:XF [(match_dup 2) (match_dup 3)]
14252 UNSPEC_FSCALE_EXP))]
14253 "TARGET_USE_FANCY_MATH_387
14254 && flag_unsafe_math_optimizations"
14256 [(set_attr "type" "fpspc")
14257 (set_attr "mode" "XF")])
14259 (define_expand "expNcorexf3"
14260 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14261 (match_operand:XF 2 "register_operand" "")))
14262 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14263 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14264 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14265 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14266 (parallel [(set (match_operand:XF 0 "register_operand" "")
14267 (unspec:XF [(match_dup 8) (match_dup 4)]
14268 UNSPEC_FSCALE_FRACT))
14270 (unspec:XF [(match_dup 8) (match_dup 4)]
14271 UNSPEC_FSCALE_EXP))])]
14272 "TARGET_USE_FANCY_MATH_387
14273 && flag_unsafe_math_optimizations"
14277 if (optimize_insn_for_size_p ())
14280 for (i = 3; i < 10; i++)
14281 operands[i] = gen_reg_rtx (XFmode);
14283 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14286 (define_expand "expxf2"
14287 [(use (match_operand:XF 0 "register_operand" ""))
14288 (use (match_operand:XF 1 "register_operand" ""))]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14294 if (optimize_insn_for_size_p ())
14297 op2 = gen_reg_rtx (XFmode);
14298 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14300 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14304 (define_expand "exp<mode>2"
14305 [(use (match_operand:MODEF 0 "register_operand" ""))
14306 (use (match_operand:MODEF 1 "general_operand" ""))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309 || TARGET_MIX_SSE_I387)
14310 && flag_unsafe_math_optimizations"
14314 if (optimize_insn_for_size_p ())
14317 op0 = gen_reg_rtx (XFmode);
14318 op1 = gen_reg_rtx (XFmode);
14320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321 emit_insn (gen_expxf2 (op0, op1));
14322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14326 (define_expand "exp10xf2"
14327 [(use (match_operand:XF 0 "register_operand" ""))
14328 (use (match_operand:XF 1 "register_operand" ""))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && flag_unsafe_math_optimizations"
14334 if (optimize_insn_for_size_p ())
14337 op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14344 (define_expand "exp10<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand" ""))
14346 (use (match_operand:MODEF 1 "general_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14354 if (optimize_insn_for_size_p ())
14357 op0 = gen_reg_rtx (XFmode);
14358 op1 = gen_reg_rtx (XFmode);
14360 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14361 emit_insn (gen_exp10xf2 (op0, op1));
14362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14366 (define_expand "exp2xf2"
14367 [(use (match_operand:XF 0 "register_operand" ""))
14368 (use (match_operand:XF 1 "register_operand" ""))]
14369 "TARGET_USE_FANCY_MATH_387
14370 && flag_unsafe_math_optimizations"
14374 if (optimize_insn_for_size_p ())
14377 op2 = gen_reg_rtx (XFmode);
14378 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14380 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14384 (define_expand "exp2<mode>2"
14385 [(use (match_operand:MODEF 0 "register_operand" ""))
14386 (use (match_operand:MODEF 1 "general_operand" ""))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14389 || TARGET_MIX_SSE_I387)
14390 && flag_unsafe_math_optimizations"
14394 if (optimize_insn_for_size_p ())
14397 op0 = gen_reg_rtx (XFmode);
14398 op1 = gen_reg_rtx (XFmode);
14400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14401 emit_insn (gen_exp2xf2 (op0, op1));
14402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14406 (define_expand "expm1xf2"
14407 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14409 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14410 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14411 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14412 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14413 (parallel [(set (match_dup 7)
14414 (unspec:XF [(match_dup 6) (match_dup 4)]
14415 UNSPEC_FSCALE_FRACT))
14417 (unspec:XF [(match_dup 6) (match_dup 4)]
14418 UNSPEC_FSCALE_EXP))])
14419 (parallel [(set (match_dup 10)
14420 (unspec:XF [(match_dup 9) (match_dup 8)]
14421 UNSPEC_FSCALE_FRACT))
14422 (set (match_dup 11)
14423 (unspec:XF [(match_dup 9) (match_dup 8)]
14424 UNSPEC_FSCALE_EXP))])
14425 (set (match_dup 12) (minus:XF (match_dup 10)
14426 (float_extend:XF (match_dup 13))))
14427 (set (match_operand:XF 0 "register_operand" "")
14428 (plus:XF (match_dup 12) (match_dup 7)))]
14429 "TARGET_USE_FANCY_MATH_387
14430 && flag_unsafe_math_optimizations"
14434 if (optimize_insn_for_size_p ())
14437 for (i = 2; i < 13; i++)
14438 operands[i] = gen_reg_rtx (XFmode);
14441 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14443 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14446 (define_expand "expm1<mode>2"
14447 [(use (match_operand:MODEF 0 "register_operand" ""))
14448 (use (match_operand:MODEF 1 "general_operand" ""))]
14449 "TARGET_USE_FANCY_MATH_387
14450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14451 || TARGET_MIX_SSE_I387)
14452 && flag_unsafe_math_optimizations"
14456 if (optimize_insn_for_size_p ())
14459 op0 = gen_reg_rtx (XFmode);
14460 op1 = gen_reg_rtx (XFmode);
14462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14463 emit_insn (gen_expm1xf2 (op0, op1));
14464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14468 (define_expand "ldexpxf3"
14469 [(set (match_dup 3)
14470 (float:XF (match_operand:SI 2 "register_operand" "")))
14471 (parallel [(set (match_operand:XF 0 " register_operand" "")
14472 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14474 UNSPEC_FSCALE_FRACT))
14476 (unspec:XF [(match_dup 1) (match_dup 3)]
14477 UNSPEC_FSCALE_EXP))])]
14478 "TARGET_USE_FANCY_MATH_387
14479 && flag_unsafe_math_optimizations"
14481 if (optimize_insn_for_size_p ())
14484 operands[3] = gen_reg_rtx (XFmode);
14485 operands[4] = gen_reg_rtx (XFmode);
14488 (define_expand "ldexp<mode>3"
14489 [(use (match_operand:MODEF 0 "register_operand" ""))
14490 (use (match_operand:MODEF 1 "general_operand" ""))
14491 (use (match_operand:SI 2 "register_operand" ""))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 op0 = gen_reg_rtx (XFmode);
14503 op1 = gen_reg_rtx (XFmode);
14505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14506 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14507 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14511 (define_expand "scalbxf3"
14512 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14513 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14514 (match_operand:XF 2 "register_operand" "")]
14515 UNSPEC_FSCALE_FRACT))
14517 (unspec:XF [(match_dup 1) (match_dup 2)]
14518 UNSPEC_FSCALE_EXP))])]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_unsafe_math_optimizations"
14522 if (optimize_insn_for_size_p ())
14525 operands[3] = gen_reg_rtx (XFmode);
14528 (define_expand "scalb<mode>3"
14529 [(use (match_operand:MODEF 0 "register_operand" ""))
14530 (use (match_operand:MODEF 1 "general_operand" ""))
14531 (use (match_operand:MODEF 2 "general_operand" ""))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534 || TARGET_MIX_SSE_I387)
14535 && flag_unsafe_math_optimizations"
14539 if (optimize_insn_for_size_p ())
14542 op0 = gen_reg_rtx (XFmode);
14543 op1 = gen_reg_rtx (XFmode);
14544 op2 = gen_reg_rtx (XFmode);
14546 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14547 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14548 emit_insn (gen_scalbxf3 (op0, op1, op2));
14549 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14553 (define_expand "significandxf2"
14554 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14555 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14556 UNSPEC_XTRACT_FRACT))
14558 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14559 "TARGET_USE_FANCY_MATH_387
14560 && flag_unsafe_math_optimizations"
14561 "operands[2] = gen_reg_rtx (XFmode);")
14563 (define_expand "significand<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand" ""))
14565 (use (match_operand:MODEF 1 "register_operand" ""))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations"
14571 rtx op0 = gen_reg_rtx (XFmode);
14572 rtx op1 = gen_reg_rtx (XFmode);
14574 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14580 (define_insn "sse4_1_round<mode>2"
14581 [(set (match_operand:MODEF 0 "register_operand" "=x")
14582 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14583 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14586 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14587 [(set_attr "type" "ssecvt")
14588 (set_attr "prefix_extra" "1")
14589 (set_attr "prefix" "maybe_vex")
14590 (set_attr "mode" "<MODE>")])
14592 (define_insn "rintxf2"
14593 [(set (match_operand:XF 0 "register_operand" "=f")
14594 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14596 "TARGET_USE_FANCY_MATH_387
14597 && flag_unsafe_math_optimizations"
14599 [(set_attr "type" "fpspc")
14600 (set_attr "mode" "XF")])
14602 (define_expand "rint<mode>2"
14603 [(use (match_operand:MODEF 0 "register_operand" ""))
14604 (use (match_operand:MODEF 1 "register_operand" ""))]
14605 "(TARGET_USE_FANCY_MATH_387
14606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14607 || TARGET_MIX_SSE_I387)
14608 && flag_unsafe_math_optimizations)
14609 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14610 && !flag_trapping_math)"
14612 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14613 && !flag_trapping_math)
14616 emit_insn (gen_sse4_1_round<mode>2
14617 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14618 else if (optimize_insn_for_size_p ())
14621 ix86_expand_rint (operand0, operand1);
14625 rtx op0 = gen_reg_rtx (XFmode);
14626 rtx op1 = gen_reg_rtx (XFmode);
14628 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14629 emit_insn (gen_rintxf2 (op0, op1));
14631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14636 (define_expand "round<mode>2"
14637 [(match_operand:X87MODEF 0 "register_operand" "")
14638 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14639 "(TARGET_USE_FANCY_MATH_387
14640 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14641 || TARGET_MIX_SSE_I387)
14642 && flag_unsafe_math_optimizations)
14643 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14644 && !flag_trapping_math && !flag_rounding_math)"
14646 if (optimize_insn_for_size_p ())
14649 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14650 && !flag_trapping_math && !flag_rounding_math)
14654 operands[1] = force_reg (<MODE>mode, operands[1]);
14655 ix86_expand_round_sse4 (operands[0], operands[1]);
14657 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14658 ix86_expand_round (operands[0], operands[1]);
14660 ix86_expand_rounddf_32 (operands[0], operands[1]);
14664 operands[1] = force_reg (<MODE>mode, operands[1]);
14665 ix86_emit_i387_round (operands[0], operands[1]);
14670 (define_insn_and_split "*fistdi2_1"
14671 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14672 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14674 "TARGET_USE_FANCY_MATH_387
14675 && can_create_pseudo_p ()"
14680 if (memory_operand (operands[0], VOIDmode))
14681 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14684 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14685 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14690 [(set_attr "type" "fpspc")
14691 (set_attr "mode" "DI")])
14693 (define_insn "fistdi2"
14694 [(set (match_operand:DI 0 "memory_operand" "=m")
14695 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14697 (clobber (match_scratch:XF 2 "=&1f"))]
14698 "TARGET_USE_FANCY_MATH_387"
14699 "* return output_fix_trunc (insn, operands, false);"
14700 [(set_attr "type" "fpspc")
14701 (set_attr "mode" "DI")])
14703 (define_insn "fistdi2_with_temp"
14704 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14707 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14708 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14709 "TARGET_USE_FANCY_MATH_387"
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "DI")])
14715 [(set (match_operand:DI 0 "register_operand" "")
14716 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14718 (clobber (match_operand:DI 2 "memory_operand" ""))
14719 (clobber (match_scratch 3 ""))]
14721 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14722 (clobber (match_dup 3))])
14723 (set (match_dup 0) (match_dup 2))])
14726 [(set (match_operand:DI 0 "memory_operand" "")
14727 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14729 (clobber (match_operand:DI 2 "memory_operand" ""))
14730 (clobber (match_scratch 3 ""))]
14732 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14733 (clobber (match_dup 3))])])
14735 (define_insn_and_split "*fist<mode>2_1"
14736 [(set (match_operand:SWI24 0 "register_operand" "")
14737 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14739 "TARGET_USE_FANCY_MATH_387
14740 && can_create_pseudo_p ()"
14745 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14746 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14750 [(set_attr "type" "fpspc")
14751 (set_attr "mode" "<MODE>")])
14753 (define_insn "fist<mode>2"
14754 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14757 "TARGET_USE_FANCY_MATH_387"
14758 "* return output_fix_trunc (insn, operands, false);"
14759 [(set_attr "type" "fpspc")
14760 (set_attr "mode" "<MODE>")])
14762 (define_insn "fist<mode>2_with_temp"
14763 [(set (match_operand:SWI24 0 "register_operand" "=r")
14764 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14766 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14767 "TARGET_USE_FANCY_MATH_387"
14769 [(set_attr "type" "fpspc")
14770 (set_attr "mode" "<MODE>")])
14773 [(set (match_operand:SWI24 0 "register_operand" "")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14776 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14778 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14779 (set (match_dup 0) (match_dup 2))])
14782 [(set (match_operand:SWI24 0 "memory_operand" "")
14783 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14785 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14787 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14789 (define_expand "lrintxf<mode>2"
14790 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14791 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14793 "TARGET_USE_FANCY_MATH_387")
14795 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14796 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14797 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14798 UNSPEC_FIX_NOTRUNC))]
14799 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14800 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14802 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14803 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14804 (match_operand:X87MODEF 1 "register_operand" "")]
14805 "(TARGET_USE_FANCY_MATH_387
14806 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14807 || TARGET_MIX_SSE_I387)
14808 && flag_unsafe_math_optimizations)
14809 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14810 && <SWI248x:MODE>mode != HImode
14811 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14812 && !flag_trapping_math && !flag_rounding_math)"
14814 if (optimize_insn_for_size_p ())
14817 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818 && <SWI248x:MODE>mode != HImode
14819 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820 && !flag_trapping_math && !flag_rounding_math)
14821 ix86_expand_lround (operand0, operand1);
14823 ix86_emit_i387_round (operands[0], operands[1]);
14827 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14828 (define_insn_and_split "frndintxf2_floor"
14829 [(set (match_operand:XF 0 "register_operand" "")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14831 UNSPEC_FRNDINT_FLOOR))
14832 (clobber (reg:CC FLAGS_REG))]
14833 "TARGET_USE_FANCY_MATH_387
14834 && flag_unsafe_math_optimizations
14835 && can_create_pseudo_p ()"
14840 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14842 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14843 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14845 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14846 operands[2], operands[3]));
14849 [(set_attr "type" "frndint")
14850 (set_attr "i387_cw" "floor")
14851 (set_attr "mode" "XF")])
14853 (define_insn "frndintxf2_floor_i387"
14854 [(set (match_operand:XF 0 "register_operand" "=f")
14855 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14856 UNSPEC_FRNDINT_FLOOR))
14857 (use (match_operand:HI 2 "memory_operand" "m"))
14858 (use (match_operand:HI 3 "memory_operand" "m"))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14861 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14862 [(set_attr "type" "frndint")
14863 (set_attr "i387_cw" "floor")
14864 (set_attr "mode" "XF")])
14866 (define_expand "floorxf2"
14867 [(use (match_operand:XF 0 "register_operand" ""))
14868 (use (match_operand:XF 1 "register_operand" ""))]
14869 "TARGET_USE_FANCY_MATH_387
14870 && flag_unsafe_math_optimizations"
14872 if (optimize_insn_for_size_p ())
14874 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14878 (define_expand "floor<mode>2"
14879 [(use (match_operand:MODEF 0 "register_operand" ""))
14880 (use (match_operand:MODEF 1 "register_operand" ""))]
14881 "(TARGET_USE_FANCY_MATH_387
14882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14883 || TARGET_MIX_SSE_I387)
14884 && flag_unsafe_math_optimizations)
14885 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14886 && !flag_trapping_math)"
14888 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889 && !flag_trapping_math)
14892 emit_insn (gen_sse4_1_round<mode>2
14893 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14894 else if (optimize_insn_for_size_p ())
14896 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14897 ix86_expand_floorceil (operand0, operand1, true);
14899 ix86_expand_floorceildf_32 (operand0, operand1, true);
14905 if (optimize_insn_for_size_p ())
14908 op0 = gen_reg_rtx (XFmode);
14909 op1 = gen_reg_rtx (XFmode);
14910 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14911 emit_insn (gen_frndintxf2_floor (op0, op1));
14913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14918 (define_insn_and_split "*fist<mode>2_floor_1"
14919 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14920 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14921 UNSPEC_FIST_FLOOR))
14922 (clobber (reg:CC FLAGS_REG))]
14923 "TARGET_USE_FANCY_MATH_387
14924 && flag_unsafe_math_optimizations
14925 && can_create_pseudo_p ()"
14930 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14932 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14933 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14934 if (memory_operand (operands[0], VOIDmode))
14935 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14936 operands[2], operands[3]));
14939 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14940 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14941 operands[2], operands[3],
14946 [(set_attr "type" "fistp")
14947 (set_attr "i387_cw" "floor")
14948 (set_attr "mode" "<MODE>")])
14950 (define_insn "fistdi2_floor"
14951 [(set (match_operand:DI 0 "memory_operand" "=m")
14952 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14953 UNSPEC_FIST_FLOOR))
14954 (use (match_operand:HI 2 "memory_operand" "m"))
14955 (use (match_operand:HI 3 "memory_operand" "m"))
14956 (clobber (match_scratch:XF 4 "=&1f"))]
14957 "TARGET_USE_FANCY_MATH_387
14958 && flag_unsafe_math_optimizations"
14959 "* return output_fix_trunc (insn, operands, false);"
14960 [(set_attr "type" "fistp")
14961 (set_attr "i387_cw" "floor")
14962 (set_attr "mode" "DI")])
14964 (define_insn "fistdi2_floor_with_temp"
14965 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14966 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14967 UNSPEC_FIST_FLOOR))
14968 (use (match_operand:HI 2 "memory_operand" "m,m"))
14969 (use (match_operand:HI 3 "memory_operand" "m,m"))
14970 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14971 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14975 [(set_attr "type" "fistp")
14976 (set_attr "i387_cw" "floor")
14977 (set_attr "mode" "DI")])
14980 [(set (match_operand:DI 0 "register_operand" "")
14981 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14982 UNSPEC_FIST_FLOOR))
14983 (use (match_operand:HI 2 "memory_operand" ""))
14984 (use (match_operand:HI 3 "memory_operand" ""))
14985 (clobber (match_operand:DI 4 "memory_operand" ""))
14986 (clobber (match_scratch 5 ""))]
14988 [(parallel [(set (match_dup 4)
14989 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14990 (use (match_dup 2))
14991 (use (match_dup 3))
14992 (clobber (match_dup 5))])
14993 (set (match_dup 0) (match_dup 4))])
14996 [(set (match_operand:DI 0 "memory_operand" "")
14997 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14998 UNSPEC_FIST_FLOOR))
14999 (use (match_operand:HI 2 "memory_operand" ""))
15000 (use (match_operand:HI 3 "memory_operand" ""))
15001 (clobber (match_operand:DI 4 "memory_operand" ""))
15002 (clobber (match_scratch 5 ""))]
15004 [(parallel [(set (match_dup 0)
15005 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15006 (use (match_dup 2))
15007 (use (match_dup 3))
15008 (clobber (match_dup 5))])])
15010 (define_insn "fist<mode>2_floor"
15011 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15012 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15013 UNSPEC_FIST_FLOOR))
15014 (use (match_operand:HI 2 "memory_operand" "m"))
15015 (use (match_operand:HI 3 "memory_operand" "m"))]
15016 "TARGET_USE_FANCY_MATH_387
15017 && flag_unsafe_math_optimizations"
15018 "* return output_fix_trunc (insn, operands, false);"
15019 [(set_attr "type" "fistp")
15020 (set_attr "i387_cw" "floor")
15021 (set_attr "mode" "<MODE>")])
15023 (define_insn "fist<mode>2_floor_with_temp"
15024 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15025 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15026 UNSPEC_FIST_FLOOR))
15027 (use (match_operand:HI 2 "memory_operand" "m,m"))
15028 (use (match_operand:HI 3 "memory_operand" "m,m"))
15029 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15030 "TARGET_USE_FANCY_MATH_387
15031 && flag_unsafe_math_optimizations"
15033 [(set_attr "type" "fistp")
15034 (set_attr "i387_cw" "floor")
15035 (set_attr "mode" "<MODE>")])
15038 [(set (match_operand:SWI24 0 "register_operand" "")
15039 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15040 UNSPEC_FIST_FLOOR))
15041 (use (match_operand:HI 2 "memory_operand" ""))
15042 (use (match_operand:HI 3 "memory_operand" ""))
15043 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15045 [(parallel [(set (match_dup 4)
15046 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15047 (use (match_dup 2))
15048 (use (match_dup 3))])
15049 (set (match_dup 0) (match_dup 4))])
15052 [(set (match_operand:SWI24 0 "memory_operand" "")
15053 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15054 UNSPEC_FIST_FLOOR))
15055 (use (match_operand:HI 2 "memory_operand" ""))
15056 (use (match_operand:HI 3 "memory_operand" ""))
15057 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15059 [(parallel [(set (match_dup 0)
15060 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15061 (use (match_dup 2))
15062 (use (match_dup 3))])])
15064 (define_expand "lfloorxf<mode>2"
15065 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15066 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15067 UNSPEC_FIST_FLOOR))
15068 (clobber (reg:CC FLAGS_REG))])]
15069 "TARGET_USE_FANCY_MATH_387
15070 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15071 && flag_unsafe_math_optimizations")
15073 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15074 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15075 (match_operand:MODEF 1 "register_operand" "")]
15076 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15077 && !flag_trapping_math"
15079 if (TARGET_64BIT && optimize_insn_for_size_p ())
15081 ix86_expand_lfloorceil (operand0, operand1, true);
15085 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15086 (define_insn_and_split "frndintxf2_ceil"
15087 [(set (match_operand:XF 0 "register_operand" "")
15088 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15089 UNSPEC_FRNDINT_CEIL))
15090 (clobber (reg:CC FLAGS_REG))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && flag_unsafe_math_optimizations
15093 && can_create_pseudo_p ()"
15098 ix86_optimize_mode_switching[I387_CEIL] = 1;
15100 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15101 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15103 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15104 operands[2], operands[3]));
15107 [(set_attr "type" "frndint")
15108 (set_attr "i387_cw" "ceil")
15109 (set_attr "mode" "XF")])
15111 (define_insn "frndintxf2_ceil_i387"
15112 [(set (match_operand:XF 0 "register_operand" "=f")
15113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15114 UNSPEC_FRNDINT_CEIL))
15115 (use (match_operand:HI 2 "memory_operand" "m"))
15116 (use (match_operand:HI 3 "memory_operand" "m"))]
15117 "TARGET_USE_FANCY_MATH_387
15118 && flag_unsafe_math_optimizations"
15119 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15120 [(set_attr "type" "frndint")
15121 (set_attr "i387_cw" "ceil")
15122 (set_attr "mode" "XF")])
15124 (define_expand "ceilxf2"
15125 [(use (match_operand:XF 0 "register_operand" ""))
15126 (use (match_operand:XF 1 "register_operand" ""))]
15127 "TARGET_USE_FANCY_MATH_387
15128 && flag_unsafe_math_optimizations"
15130 if (optimize_insn_for_size_p ())
15132 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15136 (define_expand "ceil<mode>2"
15137 [(use (match_operand:MODEF 0 "register_operand" ""))
15138 (use (match_operand:MODEF 1 "register_operand" ""))]
15139 "(TARGET_USE_FANCY_MATH_387
15140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15141 || TARGET_MIX_SSE_I387)
15142 && flag_unsafe_math_optimizations)
15143 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15144 && !flag_trapping_math)"
15146 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15147 && !flag_trapping_math)
15150 emit_insn (gen_sse4_1_round<mode>2
15151 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15152 else if (optimize_insn_for_size_p ())
15154 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15155 ix86_expand_floorceil (operand0, operand1, false);
15157 ix86_expand_floorceildf_32 (operand0, operand1, false);
15163 if (optimize_insn_for_size_p ())
15166 op0 = gen_reg_rtx (XFmode);
15167 op1 = gen_reg_rtx (XFmode);
15168 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15169 emit_insn (gen_frndintxf2_ceil (op0, op1));
15171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15176 (define_insn_and_split "*fist<mode>2_ceil_1"
15177 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15178 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15180 (clobber (reg:CC FLAGS_REG))]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations
15183 && can_create_pseudo_p ()"
15188 ix86_optimize_mode_switching[I387_CEIL] = 1;
15190 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15191 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15192 if (memory_operand (operands[0], VOIDmode))
15193 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15194 operands[2], operands[3]));
15197 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15198 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15199 operands[2], operands[3],
15204 [(set_attr "type" "fistp")
15205 (set_attr "i387_cw" "ceil")
15206 (set_attr "mode" "<MODE>")])
15208 (define_insn "fistdi2_ceil"
15209 [(set (match_operand:DI 0 "memory_operand" "=m")
15210 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15212 (use (match_operand:HI 2 "memory_operand" "m"))
15213 (use (match_operand:HI 3 "memory_operand" "m"))
15214 (clobber (match_scratch:XF 4 "=&1f"))]
15215 "TARGET_USE_FANCY_MATH_387
15216 && flag_unsafe_math_optimizations"
15217 "* return output_fix_trunc (insn, operands, false);"
15218 [(set_attr "type" "fistp")
15219 (set_attr "i387_cw" "ceil")
15220 (set_attr "mode" "DI")])
15222 (define_insn "fistdi2_ceil_with_temp"
15223 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15224 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15226 (use (match_operand:HI 2 "memory_operand" "m,m"))
15227 (use (match_operand:HI 3 "memory_operand" "m,m"))
15228 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15229 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15233 [(set_attr "type" "fistp")
15234 (set_attr "i387_cw" "ceil")
15235 (set_attr "mode" "DI")])
15238 [(set (match_operand:DI 0 "register_operand" "")
15239 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15241 (use (match_operand:HI 2 "memory_operand" ""))
15242 (use (match_operand:HI 3 "memory_operand" ""))
15243 (clobber (match_operand:DI 4 "memory_operand" ""))
15244 (clobber (match_scratch 5 ""))]
15246 [(parallel [(set (match_dup 4)
15247 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15248 (use (match_dup 2))
15249 (use (match_dup 3))
15250 (clobber (match_dup 5))])
15251 (set (match_dup 0) (match_dup 4))])
15254 [(set (match_operand:DI 0 "memory_operand" "")
15255 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15257 (use (match_operand:HI 2 "memory_operand" ""))
15258 (use (match_operand:HI 3 "memory_operand" ""))
15259 (clobber (match_operand:DI 4 "memory_operand" ""))
15260 (clobber (match_scratch 5 ""))]
15262 [(parallel [(set (match_dup 0)
15263 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15264 (use (match_dup 2))
15265 (use (match_dup 3))
15266 (clobber (match_dup 5))])])
15268 (define_insn "fist<mode>2_ceil"
15269 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15270 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15272 (use (match_operand:HI 2 "memory_operand" "m"))
15273 (use (match_operand:HI 3 "memory_operand" "m"))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations"
15276 "* return output_fix_trunc (insn, operands, false);"
15277 [(set_attr "type" "fistp")
15278 (set_attr "i387_cw" "ceil")
15279 (set_attr "mode" "<MODE>")])
15281 (define_insn "fist<mode>2_ceil_with_temp"
15282 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15283 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15285 (use (match_operand:HI 2 "memory_operand" "m,m"))
15286 (use (match_operand:HI 3 "memory_operand" "m,m"))
15287 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && flag_unsafe_math_optimizations"
15291 [(set_attr "type" "fistp")
15292 (set_attr "i387_cw" "ceil")
15293 (set_attr "mode" "<MODE>")])
15296 [(set (match_operand:SWI24 0 "register_operand" "")
15297 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15299 (use (match_operand:HI 2 "memory_operand" ""))
15300 (use (match_operand:HI 3 "memory_operand" ""))
15301 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15303 [(parallel [(set (match_dup 4)
15304 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15305 (use (match_dup 2))
15306 (use (match_dup 3))])
15307 (set (match_dup 0) (match_dup 4))])
15310 [(set (match_operand:SWI24 0 "memory_operand" "")
15311 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15313 (use (match_operand:HI 2 "memory_operand" ""))
15314 (use (match_operand:HI 3 "memory_operand" ""))
15315 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15317 [(parallel [(set (match_dup 0)
15318 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15319 (use (match_dup 2))
15320 (use (match_dup 3))])])
15322 (define_expand "lceilxf<mode>2"
15323 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15324 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15326 (clobber (reg:CC FLAGS_REG))])]
15327 "TARGET_USE_FANCY_MATH_387
15328 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15329 && flag_unsafe_math_optimizations")
15331 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15332 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15333 (match_operand:MODEF 1 "register_operand" "")]
15334 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15335 && !flag_trapping_math"
15337 ix86_expand_lfloorceil (operand0, operand1, false);
15341 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15342 (define_insn_and_split "frndintxf2_trunc"
15343 [(set (match_operand:XF 0 "register_operand" "")
15344 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15345 UNSPEC_FRNDINT_TRUNC))
15346 (clobber (reg:CC FLAGS_REG))]
15347 "TARGET_USE_FANCY_MATH_387
15348 && flag_unsafe_math_optimizations
15349 && can_create_pseudo_p ()"
15354 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15356 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15357 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15359 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15360 operands[2], operands[3]));
15363 [(set_attr "type" "frndint")
15364 (set_attr "i387_cw" "trunc")
15365 (set_attr "mode" "XF")])
15367 (define_insn "frndintxf2_trunc_i387"
15368 [(set (match_operand:XF 0 "register_operand" "=f")
15369 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15370 UNSPEC_FRNDINT_TRUNC))
15371 (use (match_operand:HI 2 "memory_operand" "m"))
15372 (use (match_operand:HI 3 "memory_operand" "m"))]
15373 "TARGET_USE_FANCY_MATH_387
15374 && flag_unsafe_math_optimizations"
15375 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15376 [(set_attr "type" "frndint")
15377 (set_attr "i387_cw" "trunc")
15378 (set_attr "mode" "XF")])
15380 (define_expand "btruncxf2"
15381 [(use (match_operand:XF 0 "register_operand" ""))
15382 (use (match_operand:XF 1 "register_operand" ""))]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15386 if (optimize_insn_for_size_p ())
15388 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15392 (define_expand "btrunc<mode>2"
15393 [(use (match_operand:MODEF 0 "register_operand" ""))
15394 (use (match_operand:MODEF 1 "register_operand" ""))]
15395 "(TARGET_USE_FANCY_MATH_387
15396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15397 || TARGET_MIX_SSE_I387)
15398 && flag_unsafe_math_optimizations)
15399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15400 && !flag_trapping_math)"
15402 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15403 && !flag_trapping_math)
15406 emit_insn (gen_sse4_1_round<mode>2
15407 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15408 else if (optimize_insn_for_size_p ())
15410 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15411 ix86_expand_trunc (operand0, operand1);
15413 ix86_expand_truncdf_32 (operand0, operand1);
15419 if (optimize_insn_for_size_p ())
15422 op0 = gen_reg_rtx (XFmode);
15423 op1 = gen_reg_rtx (XFmode);
15424 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15425 emit_insn (gen_frndintxf2_trunc (op0, op1));
15427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15432 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15433 (define_insn_and_split "frndintxf2_mask_pm"
15434 [(set (match_operand:XF 0 "register_operand" "")
15435 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15436 UNSPEC_FRNDINT_MASK_PM))
15437 (clobber (reg:CC FLAGS_REG))]
15438 "TARGET_USE_FANCY_MATH_387
15439 && flag_unsafe_math_optimizations
15440 && can_create_pseudo_p ()"
15445 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15447 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15448 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15450 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15451 operands[2], operands[3]));
15454 [(set_attr "type" "frndint")
15455 (set_attr "i387_cw" "mask_pm")
15456 (set_attr "mode" "XF")])
15458 (define_insn "frndintxf2_mask_pm_i387"
15459 [(set (match_operand:XF 0 "register_operand" "=f")
15460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15461 UNSPEC_FRNDINT_MASK_PM))
15462 (use (match_operand:HI 2 "memory_operand" "m"))
15463 (use (match_operand:HI 3 "memory_operand" "m"))]
15464 "TARGET_USE_FANCY_MATH_387
15465 && flag_unsafe_math_optimizations"
15466 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15467 [(set_attr "type" "frndint")
15468 (set_attr "i387_cw" "mask_pm")
15469 (set_attr "mode" "XF")])
15471 (define_expand "nearbyintxf2"
15472 [(use (match_operand:XF 0 "register_operand" ""))
15473 (use (match_operand:XF 1 "register_operand" ""))]
15474 "TARGET_USE_FANCY_MATH_387
15475 && flag_unsafe_math_optimizations"
15477 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15481 (define_expand "nearbyint<mode>2"
15482 [(use (match_operand:MODEF 0 "register_operand" ""))
15483 (use (match_operand:MODEF 1 "register_operand" ""))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15486 || TARGET_MIX_SSE_I387)
15487 && flag_unsafe_math_optimizations"
15489 rtx op0 = gen_reg_rtx (XFmode);
15490 rtx op1 = gen_reg_rtx (XFmode);
15492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15493 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15495 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15499 (define_insn "fxam<mode>2_i387"
15500 [(set (match_operand:HI 0 "register_operand" "=a")
15502 [(match_operand:X87MODEF 1 "register_operand" "f")]
15504 "TARGET_USE_FANCY_MATH_387"
15505 "fxam\n\tfnstsw\t%0"
15506 [(set_attr "type" "multi")
15507 (set_attr "length" "4")
15508 (set_attr "unit" "i387")
15509 (set_attr "mode" "<MODE>")])
15511 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15512 [(set (match_operand:HI 0 "register_operand" "")
15514 [(match_operand:MODEF 1 "memory_operand" "")]
15516 "TARGET_USE_FANCY_MATH_387
15517 && can_create_pseudo_p ()"
15520 [(set (match_dup 2)(match_dup 1))
15522 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15524 operands[2] = gen_reg_rtx (<MODE>mode);
15526 MEM_VOLATILE_P (operands[1]) = 1;
15528 [(set_attr "type" "multi")
15529 (set_attr "unit" "i387")
15530 (set_attr "mode" "<MODE>")])
15532 (define_expand "isinfxf2"
15533 [(use (match_operand:SI 0 "register_operand" ""))
15534 (use (match_operand:XF 1 "register_operand" ""))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && TARGET_C99_FUNCTIONS"
15538 rtx mask = GEN_INT (0x45);
15539 rtx val = GEN_INT (0x05);
15543 rtx scratch = gen_reg_rtx (HImode);
15544 rtx res = gen_reg_rtx (QImode);
15546 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15548 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15549 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15550 cond = gen_rtx_fmt_ee (EQ, QImode,
15551 gen_rtx_REG (CCmode, FLAGS_REG),
15553 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15554 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15558 (define_expand "isinf<mode>2"
15559 [(use (match_operand:SI 0 "register_operand" ""))
15560 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15561 "TARGET_USE_FANCY_MATH_387
15562 && TARGET_C99_FUNCTIONS
15563 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15565 rtx mask = GEN_INT (0x45);
15566 rtx val = GEN_INT (0x05);
15570 rtx scratch = gen_reg_rtx (HImode);
15571 rtx res = gen_reg_rtx (QImode);
15573 /* Remove excess precision by forcing value through memory. */
15574 if (memory_operand (operands[1], VOIDmode))
15575 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15578 enum ix86_stack_slot slot = (virtuals_instantiated
15581 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15583 emit_move_insn (temp, operands[1]);
15584 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15587 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15588 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15589 cond = gen_rtx_fmt_ee (EQ, QImode,
15590 gen_rtx_REG (CCmode, FLAGS_REG),
15592 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15593 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15597 (define_expand "signbitxf2"
15598 [(use (match_operand:SI 0 "register_operand" ""))
15599 (use (match_operand:XF 1 "register_operand" ""))]
15600 "TARGET_USE_FANCY_MATH_387"
15602 rtx scratch = gen_reg_rtx (HImode);
15604 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15605 emit_insn (gen_andsi3 (operands[0],
15606 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15610 (define_insn "movmsk_df"
15611 [(set (match_operand:SI 0 "register_operand" "=r")
15613 [(match_operand:DF 1 "register_operand" "x")]
15615 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15616 "%vmovmskpd\t{%1, %0|%0, %1}"
15617 [(set_attr "type" "ssemov")
15618 (set_attr "prefix" "maybe_vex")
15619 (set_attr "mode" "DF")])
15621 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15622 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15623 (define_expand "signbitdf2"
15624 [(use (match_operand:SI 0 "register_operand" ""))
15625 (use (match_operand:DF 1 "register_operand" ""))]
15626 "TARGET_USE_FANCY_MATH_387
15627 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15629 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15631 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15632 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15636 rtx scratch = gen_reg_rtx (HImode);
15638 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15639 emit_insn (gen_andsi3 (operands[0],
15640 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15645 (define_expand "signbitsf2"
15646 [(use (match_operand:SI 0 "register_operand" ""))
15647 (use (match_operand:SF 1 "register_operand" ""))]
15648 "TARGET_USE_FANCY_MATH_387
15649 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15651 rtx scratch = gen_reg_rtx (HImode);
15653 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15654 emit_insn (gen_andsi3 (operands[0],
15655 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15659 ;; Block operation instructions
15662 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15665 [(set_attr "length" "1")
15666 (set_attr "length_immediate" "0")
15667 (set_attr "modrm" "0")])
15669 (define_expand "movmem<mode>"
15670 [(use (match_operand:BLK 0 "memory_operand" ""))
15671 (use (match_operand:BLK 1 "memory_operand" ""))
15672 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15673 (use (match_operand:SWI48 3 "const_int_operand" ""))
15674 (use (match_operand:SI 4 "const_int_operand" ""))
15675 (use (match_operand:SI 5 "const_int_operand" ""))]
15678 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15679 operands[4], operands[5]))
15685 ;; Most CPUs don't like single string operations
15686 ;; Handle this case here to simplify previous expander.
15688 (define_expand "strmov"
15689 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15690 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15691 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15692 (clobber (reg:CC FLAGS_REG))])
15693 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15694 (clobber (reg:CC FLAGS_REG))])]
15697 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15699 /* If .md ever supports :P for Pmode, these can be directly
15700 in the pattern above. */
15701 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15702 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15704 /* Can't use this if the user has appropriated esi or edi. */
15705 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15706 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15708 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15709 operands[2], operands[3],
15710 operands[5], operands[6]));
15714 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15717 (define_expand "strmov_singleop"
15718 [(parallel [(set (match_operand 1 "memory_operand" "")
15719 (match_operand 3 "memory_operand" ""))
15720 (set (match_operand 0 "register_operand" "")
15721 (match_operand 4 "" ""))
15722 (set (match_operand 2 "register_operand" "")
15723 (match_operand 5 "" ""))])]
15725 "ix86_current_function_needs_cld = 1;")
15727 (define_insn "*strmovdi_rex_1"
15728 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15729 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15730 (set (match_operand:DI 0 "register_operand" "=D")
15731 (plus:DI (match_dup 2)
15733 (set (match_operand:DI 1 "register_operand" "=S")
15734 (plus:DI (match_dup 3)
15737 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "both")
15741 (set_attr "mode" "DI")])
15743 (define_insn "*strmovsi_1"
15744 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15745 (mem:SI (match_operand:P 3 "register_operand" "1")))
15746 (set (match_operand:P 0 "register_operand" "=D")
15747 (plus:P (match_dup 2)
15749 (set (match_operand:P 1 "register_operand" "=S")
15750 (plus:P (match_dup 3)
15752 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15754 [(set_attr "type" "str")
15755 (set_attr "memory" "both")
15756 (set_attr "mode" "SI")])
15758 (define_insn "*strmovhi_1"
15759 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15760 (mem:HI (match_operand:P 3 "register_operand" "1")))
15761 (set (match_operand:P 0 "register_operand" "=D")
15762 (plus:P (match_dup 2)
15764 (set (match_operand:P 1 "register_operand" "=S")
15765 (plus:P (match_dup 3)
15767 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "both")
15771 (set_attr "mode" "HI")])
15773 (define_insn "*strmovqi_1"
15774 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15775 (mem:QI (match_operand:P 3 "register_operand" "1")))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_dup 2)
15779 (set (match_operand:P 1 "register_operand" "=S")
15780 (plus:P (match_dup 3)
15782 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15784 [(set_attr "type" "str")
15785 (set_attr "memory" "both")
15786 (set (attr "prefix_rex")
15788 (match_test "<P:MODE>mode == DImode")
15790 (const_string "*")))
15791 (set_attr "mode" "QI")])
15793 (define_expand "rep_mov"
15794 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15795 (set (match_operand 0 "register_operand" "")
15796 (match_operand 5 "" ""))
15797 (set (match_operand 2 "register_operand" "")
15798 (match_operand 6 "" ""))
15799 (set (match_operand 1 "memory_operand" "")
15800 (match_operand 3 "memory_operand" ""))
15801 (use (match_dup 4))])]
15803 "ix86_current_function_needs_cld = 1;")
15805 (define_insn "*rep_movdi_rex64"
15806 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15807 (set (match_operand:DI 0 "register_operand" "=D")
15808 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15810 (match_operand:DI 3 "register_operand" "0")))
15811 (set (match_operand:DI 1 "register_operand" "=S")
15812 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15813 (match_operand:DI 4 "register_operand" "1")))
15814 (set (mem:BLK (match_dup 3))
15815 (mem:BLK (match_dup 4)))
15816 (use (match_dup 5))]
15818 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15820 [(set_attr "type" "str")
15821 (set_attr "prefix_rep" "1")
15822 (set_attr "memory" "both")
15823 (set_attr "mode" "DI")])
15825 (define_insn "*rep_movsi"
15826 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15827 (set (match_operand:P 0 "register_operand" "=D")
15828 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15830 (match_operand:P 3 "register_operand" "0")))
15831 (set (match_operand:P 1 "register_operand" "=S")
15832 (plus:P (ashift:P (match_dup 5) (const_int 2))
15833 (match_operand:P 4 "register_operand" "1")))
15834 (set (mem:BLK (match_dup 3))
15835 (mem:BLK (match_dup 4)))
15836 (use (match_dup 5))]
15837 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838 "rep{%;} movs{l|d}"
15839 [(set_attr "type" "str")
15840 (set_attr "prefix_rep" "1")
15841 (set_attr "memory" "both")
15842 (set_attr "mode" "SI")])
15844 (define_insn "*rep_movqi"
15845 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15846 (set (match_operand:P 0 "register_operand" "=D")
15847 (plus:P (match_operand:P 3 "register_operand" "0")
15848 (match_operand:P 5 "register_operand" "2")))
15849 (set (match_operand:P 1 "register_operand" "=S")
15850 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15851 (set (mem:BLK (match_dup 3))
15852 (mem:BLK (match_dup 4)))
15853 (use (match_dup 5))]
15854 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15856 [(set_attr "type" "str")
15857 (set_attr "prefix_rep" "1")
15858 (set_attr "memory" "both")
15859 (set_attr "mode" "QI")])
15861 (define_expand "setmem<mode>"
15862 [(use (match_operand:BLK 0 "memory_operand" ""))
15863 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15864 (use (match_operand:QI 2 "nonmemory_operand" ""))
15865 (use (match_operand 3 "const_int_operand" ""))
15866 (use (match_operand:SI 4 "const_int_operand" ""))
15867 (use (match_operand:SI 5 "const_int_operand" ""))]
15870 if (ix86_expand_setmem (operands[0], operands[1],
15871 operands[2], operands[3],
15872 operands[4], operands[5]))
15878 ;; Most CPUs don't like single string operations
15879 ;; Handle this case here to simplify previous expander.
15881 (define_expand "strset"
15882 [(set (match_operand 1 "memory_operand" "")
15883 (match_operand 2 "register_operand" ""))
15884 (parallel [(set (match_operand 0 "register_operand" "")
15886 (clobber (reg:CC FLAGS_REG))])]
15889 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15890 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15892 /* If .md ever supports :P for Pmode, this can be directly
15893 in the pattern above. */
15894 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15895 GEN_INT (GET_MODE_SIZE (GET_MODE
15897 /* Can't use this if the user has appropriated eax or edi. */
15898 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15899 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15901 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15907 (define_expand "strset_singleop"
15908 [(parallel [(set (match_operand 1 "memory_operand" "")
15909 (match_operand 2 "register_operand" ""))
15910 (set (match_operand 0 "register_operand" "")
15911 (match_operand 3 "" ""))])]
15913 "ix86_current_function_needs_cld = 1;")
15915 (define_insn "*strsetdi_rex_1"
15916 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15917 (match_operand:DI 2 "register_operand" "a"))
15918 (set (match_operand:DI 0 "register_operand" "=D")
15919 (plus:DI (match_dup 1)
15922 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15924 [(set_attr "type" "str")
15925 (set_attr "memory" "store")
15926 (set_attr "mode" "DI")])
15928 (define_insn "*strsetsi_1"
15929 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15930 (match_operand:SI 2 "register_operand" "a"))
15931 (set (match_operand:P 0 "register_operand" "=D")
15932 (plus:P (match_dup 1)
15934 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15936 [(set_attr "type" "str")
15937 (set_attr "memory" "store")
15938 (set_attr "mode" "SI")])
15940 (define_insn "*strsethi_1"
15941 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15942 (match_operand:HI 2 "register_operand" "a"))
15943 (set (match_operand:P 0 "register_operand" "=D")
15944 (plus:P (match_dup 1)
15946 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15948 [(set_attr "type" "str")
15949 (set_attr "memory" "store")
15950 (set_attr "mode" "HI")])
15952 (define_insn "*strsetqi_1"
15953 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15954 (match_operand:QI 2 "register_operand" "a"))
15955 (set (match_operand:P 0 "register_operand" "=D")
15956 (plus:P (match_dup 1)
15958 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15960 [(set_attr "type" "str")
15961 (set_attr "memory" "store")
15962 (set (attr "prefix_rex")
15964 (match_test "<P:MODE>mode == DImode")
15966 (const_string "*")))
15967 (set_attr "mode" "QI")])
15969 (define_expand "rep_stos"
15970 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15971 (set (match_operand 0 "register_operand" "")
15972 (match_operand 4 "" ""))
15973 (set (match_operand 2 "memory_operand" "") (const_int 0))
15974 (use (match_operand 3 "register_operand" ""))
15975 (use (match_dup 1))])]
15977 "ix86_current_function_needs_cld = 1;")
15979 (define_insn "*rep_stosdi_rex64"
15980 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15981 (set (match_operand:DI 0 "register_operand" "=D")
15982 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15984 (match_operand:DI 3 "register_operand" "0")))
15985 (set (mem:BLK (match_dup 3))
15987 (use (match_operand:DI 2 "register_operand" "a"))
15988 (use (match_dup 4))]
15990 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15992 [(set_attr "type" "str")
15993 (set_attr "prefix_rep" "1")
15994 (set_attr "memory" "store")
15995 (set_attr "mode" "DI")])
15997 (define_insn "*rep_stossi"
15998 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15999 (set (match_operand:P 0 "register_operand" "=D")
16000 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16002 (match_operand:P 3 "register_operand" "0")))
16003 (set (mem:BLK (match_dup 3))
16005 (use (match_operand:SI 2 "register_operand" "a"))
16006 (use (match_dup 4))]
16007 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008 "rep{%;} stos{l|d}"
16009 [(set_attr "type" "str")
16010 (set_attr "prefix_rep" "1")
16011 (set_attr "memory" "store")
16012 (set_attr "mode" "SI")])
16014 (define_insn "*rep_stosqi"
16015 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16016 (set (match_operand:P 0 "register_operand" "=D")
16017 (plus:P (match_operand:P 3 "register_operand" "0")
16018 (match_operand:P 4 "register_operand" "1")))
16019 (set (mem:BLK (match_dup 3))
16021 (use (match_operand:QI 2 "register_operand" "a"))
16022 (use (match_dup 4))]
16023 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set (attr "prefix_rex")
16030 (match_test "<P:MODE>mode == DImode")
16032 (const_string "*")))
16033 (set_attr "mode" "QI")])
16035 (define_expand "cmpstrnsi"
16036 [(set (match_operand:SI 0 "register_operand" "")
16037 (compare:SI (match_operand:BLK 1 "general_operand" "")
16038 (match_operand:BLK 2 "general_operand" "")))
16039 (use (match_operand 3 "general_operand" ""))
16040 (use (match_operand 4 "immediate_operand" ""))]
16043 rtx addr1, addr2, out, outlow, count, countreg, align;
16045 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16048 /* Can't use this if the user has appropriated ecx, esi or edi. */
16049 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16054 out = gen_reg_rtx (SImode);
16056 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16057 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16058 if (addr1 != XEXP (operands[1], 0))
16059 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16060 if (addr2 != XEXP (operands[2], 0))
16061 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16063 count = operands[3];
16064 countreg = ix86_zero_extend_to_Pmode (count);
16066 /* %%% Iff we are testing strict equality, we can use known alignment
16067 to good advantage. This may be possible with combine, particularly
16068 once cc0 is dead. */
16069 align = operands[4];
16071 if (CONST_INT_P (count))
16073 if (INTVAL (count) == 0)
16075 emit_move_insn (operands[0], const0_rtx);
16078 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16079 operands[1], operands[2]));
16083 rtx (*gen_cmp) (rtx, rtx);
16085 gen_cmp = (TARGET_64BIT
16086 ? gen_cmpdi_1 : gen_cmpsi_1);
16088 emit_insn (gen_cmp (countreg, countreg));
16089 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16090 operands[1], operands[2]));
16093 outlow = gen_lowpart (QImode, out);
16094 emit_insn (gen_cmpintqi (outlow));
16095 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16097 if (operands[0] != out)
16098 emit_move_insn (operands[0], out);
16103 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16105 (define_expand "cmpintqi"
16106 [(set (match_dup 1)
16107 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16109 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16110 (parallel [(set (match_operand:QI 0 "register_operand" "")
16111 (minus:QI (match_dup 1)
16113 (clobber (reg:CC FLAGS_REG))])]
16116 operands[1] = gen_reg_rtx (QImode);
16117 operands[2] = gen_reg_rtx (QImode);
16120 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16121 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16123 (define_expand "cmpstrnqi_nz_1"
16124 [(parallel [(set (reg:CC FLAGS_REG)
16125 (compare:CC (match_operand 4 "memory_operand" "")
16126 (match_operand 5 "memory_operand" "")))
16127 (use (match_operand 2 "register_operand" ""))
16128 (use (match_operand:SI 3 "immediate_operand" ""))
16129 (clobber (match_operand 0 "register_operand" ""))
16130 (clobber (match_operand 1 "register_operand" ""))
16131 (clobber (match_dup 2))])]
16133 "ix86_current_function_needs_cld = 1;")
16135 (define_insn "*cmpstrnqi_nz_1"
16136 [(set (reg:CC FLAGS_REG)
16137 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16138 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16139 (use (match_operand:P 6 "register_operand" "2"))
16140 (use (match_operand:SI 3 "immediate_operand" "i"))
16141 (clobber (match_operand:P 0 "register_operand" "=S"))
16142 (clobber (match_operand:P 1 "register_operand" "=D"))
16143 (clobber (match_operand:P 2 "register_operand" "=c"))]
16144 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set (attr "prefix_rex")
16150 (match_test "<P:MODE>mode == DImode")
16152 (const_string "*")))
16153 (set_attr "prefix_rep" "1")])
16155 ;; The same, but the count is not known to not be zero.
16157 (define_expand "cmpstrnqi_1"
16158 [(parallel [(set (reg:CC FLAGS_REG)
16159 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16161 (compare:CC (match_operand 4 "memory_operand" "")
16162 (match_operand 5 "memory_operand" ""))
16164 (use (match_operand:SI 3 "immediate_operand" ""))
16165 (use (reg:CC FLAGS_REG))
16166 (clobber (match_operand 0 "register_operand" ""))
16167 (clobber (match_operand 1 "register_operand" ""))
16168 (clobber (match_dup 2))])]
16170 "ix86_current_function_needs_cld = 1;")
16172 (define_insn "*cmpstrnqi_1"
16173 [(set (reg:CC FLAGS_REG)
16174 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16176 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16177 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16179 (use (match_operand:SI 3 "immediate_operand" "i"))
16180 (use (reg:CC FLAGS_REG))
16181 (clobber (match_operand:P 0 "register_operand" "=S"))
16182 (clobber (match_operand:P 1 "register_operand" "=D"))
16183 (clobber (match_operand:P 2 "register_operand" "=c"))]
16184 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16186 [(set_attr "type" "str")
16187 (set_attr "mode" "QI")
16188 (set (attr "prefix_rex")
16190 (match_test "<P:MODE>mode == DImode")
16192 (const_string "*")))
16193 (set_attr "prefix_rep" "1")])
16195 (define_expand "strlen<mode>"
16196 [(set (match_operand:P 0 "register_operand" "")
16197 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16198 (match_operand:QI 2 "immediate_operand" "")
16199 (match_operand 3 "immediate_operand" "")]
16203 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16209 (define_expand "strlenqi_1"
16210 [(parallel [(set (match_operand 0 "register_operand" "")
16211 (match_operand 2 "" ""))
16212 (clobber (match_operand 1 "register_operand" ""))
16213 (clobber (reg:CC FLAGS_REG))])]
16215 "ix86_current_function_needs_cld = 1;")
16217 (define_insn "*strlenqi_1"
16218 [(set (match_operand:P 0 "register_operand" "=&c")
16219 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16220 (match_operand:QI 2 "register_operand" "a")
16221 (match_operand:P 3 "immediate_operand" "i")
16222 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16223 (clobber (match_operand:P 1 "register_operand" "=D"))
16224 (clobber (reg:CC FLAGS_REG))]
16225 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16227 [(set_attr "type" "str")
16228 (set_attr "mode" "QI")
16229 (set (attr "prefix_rex")
16231 (match_test "<P:MODE>mode == DImode")
16233 (const_string "*")))
16234 (set_attr "prefix_rep" "1")])
16236 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16237 ;; handled in combine, but it is not currently up to the task.
16238 ;; When used for their truth value, the cmpstrn* expanders generate
16247 ;; The intermediate three instructions are unnecessary.
16249 ;; This one handles cmpstrn*_nz_1...
16252 (set (reg:CC FLAGS_REG)
16253 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16254 (mem:BLK (match_operand 5 "register_operand" ""))))
16255 (use (match_operand 6 "register_operand" ""))
16256 (use (match_operand:SI 3 "immediate_operand" ""))
16257 (clobber (match_operand 0 "register_operand" ""))
16258 (clobber (match_operand 1 "register_operand" ""))
16259 (clobber (match_operand 2 "register_operand" ""))])
16260 (set (match_operand:QI 7 "register_operand" "")
16261 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16262 (set (match_operand:QI 8 "register_operand" "")
16263 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16264 (set (reg FLAGS_REG)
16265 (compare (match_dup 7) (match_dup 8)))
16267 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16269 (set (reg:CC FLAGS_REG)
16270 (compare:CC (mem:BLK (match_dup 4))
16271 (mem:BLK (match_dup 5))))
16272 (use (match_dup 6))
16273 (use (match_dup 3))
16274 (clobber (match_dup 0))
16275 (clobber (match_dup 1))
16276 (clobber (match_dup 2))])])
16278 ;; ...and this one handles cmpstrn*_1.
16281 (set (reg:CC FLAGS_REG)
16282 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16284 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16285 (mem:BLK (match_operand 5 "register_operand" "")))
16287 (use (match_operand:SI 3 "immediate_operand" ""))
16288 (use (reg:CC FLAGS_REG))
16289 (clobber (match_operand 0 "register_operand" ""))
16290 (clobber (match_operand 1 "register_operand" ""))
16291 (clobber (match_operand 2 "register_operand" ""))])
16292 (set (match_operand:QI 7 "register_operand" "")
16293 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16294 (set (match_operand:QI 8 "register_operand" "")
16295 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16296 (set (reg FLAGS_REG)
16297 (compare (match_dup 7) (match_dup 8)))
16299 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16301 (set (reg:CC FLAGS_REG)
16302 (if_then_else:CC (ne (match_dup 6)
16304 (compare:CC (mem:BLK (match_dup 4))
16305 (mem:BLK (match_dup 5)))
16307 (use (match_dup 3))
16308 (use (reg:CC FLAGS_REG))
16309 (clobber (match_dup 0))
16310 (clobber (match_dup 1))
16311 (clobber (match_dup 2))])])
16313 ;; Conditional move instructions.
16315 (define_expand "mov<mode>cc"
16316 [(set (match_operand:SWIM 0 "register_operand" "")
16317 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16318 (match_operand:SWIM 2 "<general_operand>" "")
16319 (match_operand:SWIM 3 "<general_operand>" "")))]
16321 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16323 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16324 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16325 ;; So just document what we're doing explicitly.
16327 (define_expand "x86_mov<mode>cc_0_m1"
16329 [(set (match_operand:SWI48 0 "register_operand" "")
16330 (if_then_else:SWI48
16331 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16332 [(match_operand 1 "flags_reg_operand" "")
16336 (clobber (reg:CC FLAGS_REG))])])
16338 (define_insn "*x86_mov<mode>cc_0_m1"
16339 [(set (match_operand:SWI48 0 "register_operand" "=r")
16340 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16341 [(reg FLAGS_REG) (const_int 0)])
16344 (clobber (reg:CC FLAGS_REG))]
16346 "sbb{<imodesuffix>}\t%0, %0"
16347 ; Since we don't have the proper number of operands for an alu insn,
16348 ; fill in all the blanks.
16349 [(set_attr "type" "alu")
16350 (set_attr "use_carry" "1")
16351 (set_attr "pent_pair" "pu")
16352 (set_attr "memory" "none")
16353 (set_attr "imm_disp" "false")
16354 (set_attr "mode" "<MODE>")
16355 (set_attr "length_immediate" "0")])
16357 (define_insn "*x86_mov<mode>cc_0_m1_se"
16358 [(set (match_operand:SWI48 0 "register_operand" "=r")
16359 (sign_extract: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 [(set_attr "type" "alu")
16367 (set_attr "use_carry" "1")
16368 (set_attr "pent_pair" "pu")
16369 (set_attr "memory" "none")
16370 (set_attr "imm_disp" "false")
16371 (set_attr "mode" "<MODE>")
16372 (set_attr "length_immediate" "0")])
16374 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16375 [(set (match_operand:SWI48 0 "register_operand" "=r")
16376 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16377 [(reg FLAGS_REG) (const_int 0)])))]
16379 "sbb{<imodesuffix>}\t%0, %0"
16380 [(set_attr "type" "alu")
16381 (set_attr "use_carry" "1")
16382 (set_attr "pent_pair" "pu")
16383 (set_attr "memory" "none")
16384 (set_attr "imm_disp" "false")
16385 (set_attr "mode" "<MODE>")
16386 (set_attr "length_immediate" "0")])
16388 (define_insn "*mov<mode>cc_noc"
16389 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16390 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16392 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16393 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16394 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16396 cmov%O2%C1\t{%2, %0|%0, %2}
16397 cmov%O2%c1\t{%3, %0|%0, %3}"
16398 [(set_attr "type" "icmov")
16399 (set_attr "mode" "<MODE>")])
16401 (define_insn_and_split "*movqicc_noc"
16402 [(set (match_operand:QI 0 "register_operand" "=r,r")
16403 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16404 [(match_operand 4 "flags_reg_operand" "")
16406 (match_operand:QI 2 "register_operand" "r,0")
16407 (match_operand:QI 3 "register_operand" "0,r")))]
16408 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16410 "&& reload_completed"
16411 [(set (match_dup 0)
16412 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16415 "operands[0] = gen_lowpart (SImode, operands[0]);
16416 operands[2] = gen_lowpart (SImode, operands[2]);
16417 operands[3] = gen_lowpart (SImode, operands[3]);"
16418 [(set_attr "type" "icmov")
16419 (set_attr "mode" "SI")])
16421 (define_expand "mov<mode>cc"
16422 [(set (match_operand:X87MODEF 0 "register_operand" "")
16423 (if_then_else:X87MODEF
16424 (match_operand 1 "ix86_fp_comparison_operator" "")
16425 (match_operand:X87MODEF 2 "register_operand" "")
16426 (match_operand:X87MODEF 3 "register_operand" "")))]
16427 "(TARGET_80387 && TARGET_CMOVE)
16428 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16429 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16431 (define_insn "*movxfcc_1"
16432 [(set (match_operand:XF 0 "register_operand" "=f,f")
16433 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16434 [(reg FLAGS_REG) (const_int 0)])
16435 (match_operand:XF 2 "register_operand" "f,0")
16436 (match_operand:XF 3 "register_operand" "0,f")))]
16437 "TARGET_80387 && TARGET_CMOVE"
16439 fcmov%F1\t{%2, %0|%0, %2}
16440 fcmov%f1\t{%3, %0|%0, %3}"
16441 [(set_attr "type" "fcmov")
16442 (set_attr "mode" "XF")])
16444 (define_insn "*movdfcc_1_rex64"
16445 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16446 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16447 [(reg FLAGS_REG) (const_int 0)])
16448 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16449 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16450 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16451 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16453 fcmov%F1\t{%2, %0|%0, %2}
16454 fcmov%f1\t{%3, %0|%0, %3}
16455 cmov%O2%C1\t{%2, %0|%0, %2}
16456 cmov%O2%c1\t{%3, %0|%0, %3}"
16457 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16458 (set_attr "mode" "DF,DF,DI,DI")])
16460 (define_insn "*movdfcc_1"
16461 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16462 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16463 [(reg FLAGS_REG) (const_int 0)])
16464 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16465 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16466 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16467 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16469 fcmov%F1\t{%2, %0|%0, %2}
16470 fcmov%f1\t{%3, %0|%0, %3}
16473 [(set_attr "type" "fcmov,fcmov,multi,multi")
16474 (set_attr "mode" "DF,DF,DI,DI")])
16477 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16478 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16479 [(match_operand 4 "flags_reg_operand" "")
16481 (match_operand:DF 2 "nonimmediate_operand" "")
16482 (match_operand:DF 3 "nonimmediate_operand" "")))]
16483 "!TARGET_64BIT && reload_completed"
16484 [(set (match_dup 2)
16485 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16489 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16493 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16494 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16497 (define_insn "*movsfcc_1_387"
16498 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16499 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)])
16501 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16502 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16503 "TARGET_80387 && TARGET_CMOVE
16504 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16506 fcmov%F1\t{%2, %0|%0, %2}
16507 fcmov%f1\t{%3, %0|%0, %3}
16508 cmov%O2%C1\t{%2, %0|%0, %2}
16509 cmov%O2%c1\t{%3, %0|%0, %3}"
16510 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16511 (set_attr "mode" "SF,SF,SI,SI")])
16513 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16514 ;; the scalar versions to have only XMM registers as operands.
16516 ;; XOP conditional move
16517 (define_insn "*xop_pcmov_<mode>"
16518 [(set (match_operand:MODEF 0 "register_operand" "=x")
16519 (if_then_else:MODEF
16520 (match_operand:MODEF 1 "register_operand" "x")
16521 (match_operand:MODEF 2 "register_operand" "x")
16522 (match_operand:MODEF 3 "register_operand" "x")))]
16524 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16525 [(set_attr "type" "sse4arg")])
16527 ;; These versions of the min/max patterns are intentionally ignorant of
16528 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16529 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16530 ;; are undefined in this condition, we're certain this is correct.
16532 (define_insn "<code><mode>3"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16535 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16536 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16539 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16540 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16541 [(set_attr "isa" "noavx,avx")
16542 (set_attr "prefix" "orig,vex")
16543 (set_attr "type" "sseadd")
16544 (set_attr "mode" "<MODE>")])
16546 ;; These versions of the min/max patterns implement exactly the operations
16547 ;; min = (op1 < op2 ? op1 : op2)
16548 ;; max = (!(op1 < op2) ? op1 : op2)
16549 ;; Their operands are not commutative, and thus they may be used in the
16550 ;; presence of -0.0 and NaN.
16552 (define_insn "*ieee_smin<mode>3"
16553 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16555 [(match_operand:MODEF 1 "register_operand" "0,x")
16556 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16560 min<ssemodesuffix>\t{%2, %0|%0, %2}
16561 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562 [(set_attr "isa" "noavx,avx")
16563 (set_attr "prefix" "orig,vex")
16564 (set_attr "type" "sseadd")
16565 (set_attr "mode" "<MODE>")])
16567 (define_insn "*ieee_smax<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16575 max<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16582 ;; Make two stack loads independent:
16584 ;; fld %st(0) -> fld bb
16585 ;; fmul bb fmul %st(1), %st
16587 ;; Actually we only match the last two instructions for simplicity.
16589 [(set (match_operand 0 "fp_register_operand" "")
16590 (match_operand 1 "fp_register_operand" ""))
16592 (match_operator 2 "binary_fp_operator"
16594 (match_operand 3 "memory_operand" "")]))]
16595 "REGNO (operands[0]) != REGNO (operands[1])"
16596 [(set (match_dup 0) (match_dup 3))
16597 (set (match_dup 0) (match_dup 4))]
16599 ;; The % modifier is not operational anymore in peephole2's, so we have to
16600 ;; swap the operands manually in the case of addition and multiplication.
16601 "if (COMMUTATIVE_ARITH_P (operands[2]))
16602 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16603 GET_MODE (operands[2]),
16604 operands[0], operands[1]);
16606 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16607 GET_MODE (operands[2]),
16608 operands[1], operands[0]);")
16610 ;; Conditional addition patterns
16611 (define_expand "add<mode>cc"
16612 [(match_operand:SWI 0 "register_operand" "")
16613 (match_operand 1 "ordered_comparison_operator" "")
16614 (match_operand:SWI 2 "register_operand" "")
16615 (match_operand:SWI 3 "const_int_operand" "")]
16617 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16619 ;; Misc patterns (?)
16621 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16622 ;; Otherwise there will be nothing to keep
16624 ;; [(set (reg ebp) (reg esp))]
16625 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16626 ;; (clobber (eflags)]
16627 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16629 ;; in proper program order.
16631 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16632 [(set (match_operand:P 0 "register_operand" "=r,r")
16633 (plus:P (match_operand:P 1 "register_operand" "0,r")
16634 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16635 (clobber (reg:CC FLAGS_REG))
16636 (clobber (mem:BLK (scratch)))]
16639 switch (get_attr_type (insn))
16642 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16646 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16647 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16649 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16652 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16653 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16656 [(set (attr "type")
16657 (cond [(and (eq_attr "alternative" "0")
16658 (not (match_test "TARGET_OPT_AGU")))
16659 (const_string "alu")
16660 (match_operand:<MODE> 2 "const0_operand" "")
16661 (const_string "imov")
16663 (const_string "lea")))
16664 (set (attr "length_immediate")
16665 (cond [(eq_attr "type" "imov")
16667 (and (eq_attr "type" "alu")
16668 (match_operand 2 "const128_operand" ""))
16671 (const_string "*")))
16672 (set_attr "mode" "<MODE>")])
16674 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16675 [(set (match_operand:P 0 "register_operand" "=r")
16676 (minus:P (match_operand:P 1 "register_operand" "0")
16677 (match_operand:P 2 "register_operand" "r")))
16678 (clobber (reg:CC FLAGS_REG))
16679 (clobber (mem:BLK (scratch)))]
16681 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16682 [(set_attr "type" "alu")
16683 (set_attr "mode" "<MODE>")])
16685 (define_insn "allocate_stack_worker_probe_<mode>"
16686 [(set (match_operand:P 0 "register_operand" "=a")
16687 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16688 UNSPECV_STACK_PROBE))
16689 (clobber (reg:CC FLAGS_REG))]
16690 "ix86_target_stack_probe ()"
16691 "call\t___chkstk_ms"
16692 [(set_attr "type" "multi")
16693 (set_attr "length" "5")])
16695 (define_expand "allocate_stack"
16696 [(match_operand 0 "register_operand" "")
16697 (match_operand 1 "general_operand" "")]
16698 "ix86_target_stack_probe ()"
16702 #ifndef CHECK_STACK_LIMIT
16703 #define CHECK_STACK_LIMIT 0
16706 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16707 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16709 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16710 stack_pointer_rtx, 0, OPTAB_DIRECT);
16711 if (x != stack_pointer_rtx)
16712 emit_move_insn (stack_pointer_rtx, x);
16716 x = copy_to_mode_reg (Pmode, operands[1]);
16718 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16720 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16721 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16722 stack_pointer_rtx, 0, OPTAB_DIRECT);
16723 if (x != stack_pointer_rtx)
16724 emit_move_insn (stack_pointer_rtx, x);
16727 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16731 ;; Use IOR for stack probes, this is shorter.
16732 (define_expand "probe_stack"
16733 [(match_operand 0 "memory_operand" "")]
16736 rtx (*gen_ior3) (rtx, rtx, rtx);
16738 gen_ior3 = (GET_MODE (operands[0]) == DImode
16739 ? gen_iordi3 : gen_iorsi3);
16741 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16745 (define_insn "adjust_stack_and_probe<mode>"
16746 [(set (match_operand:P 0 "register_operand" "=r")
16747 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16748 UNSPECV_PROBE_STACK_RANGE))
16749 (set (reg:P SP_REG)
16750 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16751 (clobber (reg:CC FLAGS_REG))
16752 (clobber (mem:BLK (scratch)))]
16754 "* return output_adjust_stack_and_probe (operands[0]);"
16755 [(set_attr "type" "multi")])
16757 (define_insn "probe_stack_range<mode>"
16758 [(set (match_operand:P 0 "register_operand" "=r")
16759 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16760 (match_operand:P 2 "const_int_operand" "n")]
16761 UNSPECV_PROBE_STACK_RANGE))
16762 (clobber (reg:CC FLAGS_REG))]
16764 "* return output_probe_stack_range (operands[0], operands[2]);"
16765 [(set_attr "type" "multi")])
16767 (define_expand "builtin_setjmp_receiver"
16768 [(label_ref (match_operand 0 "" ""))]
16769 "!TARGET_64BIT && flag_pic"
16775 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16776 rtx label_rtx = gen_label_rtx ();
16777 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16778 xops[0] = xops[1] = picreg;
16779 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16780 ix86_expand_binary_operator (MINUS, SImode, xops);
16784 emit_insn (gen_set_got (pic_offset_table_rtx));
16788 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16791 [(set (match_operand 0 "register_operand" "")
16792 (match_operator 3 "promotable_binary_operator"
16793 [(match_operand 1 "register_operand" "")
16794 (match_operand 2 "aligned_operand" "")]))
16795 (clobber (reg:CC FLAGS_REG))]
16796 "! TARGET_PARTIAL_REG_STALL && reload_completed
16797 && ((GET_MODE (operands[0]) == HImode
16798 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16799 /* ??? next two lines just !satisfies_constraint_K (...) */
16800 || !CONST_INT_P (operands[2])
16801 || satisfies_constraint_K (operands[2])))
16802 || (GET_MODE (operands[0]) == QImode
16803 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16804 [(parallel [(set (match_dup 0)
16805 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16806 (clobber (reg:CC FLAGS_REG))])]
16807 "operands[0] = gen_lowpart (SImode, operands[0]);
16808 operands[1] = gen_lowpart (SImode, operands[1]);
16809 if (GET_CODE (operands[3]) != ASHIFT)
16810 operands[2] = gen_lowpart (SImode, operands[2]);
16811 PUT_MODE (operands[3], SImode);")
16813 ; Promote the QImode tests, as i386 has encoding of the AND
16814 ; instruction with 32-bit sign-extended immediate and thus the
16815 ; instruction size is unchanged, except in the %eax case for
16816 ; which it is increased by one byte, hence the ! optimize_size.
16818 [(set (match_operand 0 "flags_reg_operand" "")
16819 (match_operator 2 "compare_operator"
16820 [(and (match_operand 3 "aligned_operand" "")
16821 (match_operand 4 "const_int_operand" ""))
16823 (set (match_operand 1 "register_operand" "")
16824 (and (match_dup 3) (match_dup 4)))]
16825 "! TARGET_PARTIAL_REG_STALL && reload_completed
16826 && optimize_insn_for_speed_p ()
16827 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16828 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16829 /* Ensure that the operand will remain sign-extended immediate. */
16830 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16831 [(parallel [(set (match_dup 0)
16832 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16835 (and:SI (match_dup 3) (match_dup 4)))])]
16838 = gen_int_mode (INTVAL (operands[4])
16839 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16840 operands[1] = gen_lowpart (SImode, operands[1]);
16841 operands[3] = gen_lowpart (SImode, operands[3]);
16844 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16845 ; the TEST instruction with 32-bit sign-extended immediate and thus
16846 ; the instruction size would at least double, which is not what we
16847 ; want even with ! optimize_size.
16849 [(set (match_operand 0 "flags_reg_operand" "")
16850 (match_operator 1 "compare_operator"
16851 [(and (match_operand:HI 2 "aligned_operand" "")
16852 (match_operand:HI 3 "const_int_operand" ""))
16854 "! TARGET_PARTIAL_REG_STALL && reload_completed
16855 && ! TARGET_FAST_PREFIX
16856 && optimize_insn_for_speed_p ()
16857 /* Ensure that the operand will remain sign-extended immediate. */
16858 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16859 [(set (match_dup 0)
16860 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16864 = gen_int_mode (INTVAL (operands[3])
16865 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16866 operands[2] = gen_lowpart (SImode, operands[2]);
16870 [(set (match_operand 0 "register_operand" "")
16871 (neg (match_operand 1 "register_operand" "")))
16872 (clobber (reg:CC FLAGS_REG))]
16873 "! TARGET_PARTIAL_REG_STALL && reload_completed
16874 && (GET_MODE (operands[0]) == HImode
16875 || (GET_MODE (operands[0]) == QImode
16876 && (TARGET_PROMOTE_QImode
16877 || optimize_insn_for_size_p ())))"
16878 [(parallel [(set (match_dup 0)
16879 (neg:SI (match_dup 1)))
16880 (clobber (reg:CC FLAGS_REG))])]
16881 "operands[0] = gen_lowpart (SImode, operands[0]);
16882 operands[1] = gen_lowpart (SImode, operands[1]);")
16885 [(set (match_operand 0 "register_operand" "")
16886 (not (match_operand 1 "register_operand" "")))]
16887 "! TARGET_PARTIAL_REG_STALL && reload_completed
16888 && (GET_MODE (operands[0]) == HImode
16889 || (GET_MODE (operands[0]) == QImode
16890 && (TARGET_PROMOTE_QImode
16891 || optimize_insn_for_size_p ())))"
16892 [(set (match_dup 0)
16893 (not:SI (match_dup 1)))]
16894 "operands[0] = gen_lowpart (SImode, operands[0]);
16895 operands[1] = gen_lowpart (SImode, operands[1]);")
16898 [(set (match_operand 0 "register_operand" "")
16899 (if_then_else (match_operator 1 "ordered_comparison_operator"
16900 [(reg FLAGS_REG) (const_int 0)])
16901 (match_operand 2 "register_operand" "")
16902 (match_operand 3 "register_operand" "")))]
16903 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16904 && (GET_MODE (operands[0]) == HImode
16905 || (GET_MODE (operands[0]) == QImode
16906 && (TARGET_PROMOTE_QImode
16907 || optimize_insn_for_size_p ())))"
16908 [(set (match_dup 0)
16909 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16910 "operands[0] = gen_lowpart (SImode, operands[0]);
16911 operands[2] = gen_lowpart (SImode, operands[2]);
16912 operands[3] = gen_lowpart (SImode, operands[3]);")
16914 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16915 ;; transform a complex memory operation into two memory to register operations.
16917 ;; Don't push memory operands
16919 [(set (match_operand:SWI 0 "push_operand" "")
16920 (match_operand:SWI 1 "memory_operand" ""))
16921 (match_scratch:SWI 2 "<r>")]
16922 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16923 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16924 [(set (match_dup 2) (match_dup 1))
16925 (set (match_dup 0) (match_dup 2))])
16927 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16930 [(set (match_operand:SF 0 "push_operand" "")
16931 (match_operand:SF 1 "memory_operand" ""))
16932 (match_scratch:SF 2 "r")]
16933 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16934 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16935 [(set (match_dup 2) (match_dup 1))
16936 (set (match_dup 0) (match_dup 2))])
16938 ;; Don't move an immediate directly to memory when the instruction
16941 [(match_scratch:SWI124 1 "<r>")
16942 (set (match_operand:SWI124 0 "memory_operand" "")
16944 "optimize_insn_for_speed_p ()
16945 && !TARGET_USE_MOV0
16946 && TARGET_SPLIT_LONG_MOVES
16947 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16948 && peep2_regno_dead_p (0, FLAGS_REG)"
16949 [(parallel [(set (match_dup 2) (const_int 0))
16950 (clobber (reg:CC FLAGS_REG))])
16951 (set (match_dup 0) (match_dup 1))]
16952 "operands[2] = gen_lowpart (SImode, operands[1]);")
16955 [(match_scratch:SWI124 2 "<r>")
16956 (set (match_operand:SWI124 0 "memory_operand" "")
16957 (match_operand:SWI124 1 "immediate_operand" ""))]
16958 "optimize_insn_for_speed_p ()
16959 && TARGET_SPLIT_LONG_MOVES
16960 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16961 [(set (match_dup 2) (match_dup 1))
16962 (set (match_dup 0) (match_dup 2))])
16964 ;; Don't compare memory with zero, load and use a test instead.
16966 [(set (match_operand 0 "flags_reg_operand" "")
16967 (match_operator 1 "compare_operator"
16968 [(match_operand:SI 2 "memory_operand" "")
16970 (match_scratch:SI 3 "r")]
16971 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16972 [(set (match_dup 3) (match_dup 2))
16973 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16975 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16976 ;; Don't split NOTs with a displacement operand, because resulting XOR
16977 ;; will not be pairable anyway.
16979 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16980 ;; represented using a modRM byte. The XOR replacement is long decoded,
16981 ;; so this split helps here as well.
16983 ;; Note: Can't do this as a regular split because we can't get proper
16984 ;; lifetime information then.
16987 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16988 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16989 "optimize_insn_for_speed_p ()
16990 && ((TARGET_NOT_UNPAIRABLE
16991 && (!MEM_P (operands[0])
16992 || !memory_displacement_operand (operands[0], <MODE>mode)))
16993 || (TARGET_NOT_VECTORMODE
16994 && long_memory_operand (operands[0], <MODE>mode)))
16995 && peep2_regno_dead_p (0, FLAGS_REG)"
16996 [(parallel [(set (match_dup 0)
16997 (xor:SWI124 (match_dup 1) (const_int -1)))
16998 (clobber (reg:CC FLAGS_REG))])])
17000 ;; Non pairable "test imm, reg" instructions can be translated to
17001 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17002 ;; byte opcode instead of two, have a short form for byte operands),
17003 ;; so do it for other CPUs as well. Given that the value was dead,
17004 ;; this should not create any new dependencies. Pass on the sub-word
17005 ;; versions if we're concerned about partial register stalls.
17008 [(set (match_operand 0 "flags_reg_operand" "")
17009 (match_operator 1 "compare_operator"
17010 [(and:SI (match_operand:SI 2 "register_operand" "")
17011 (match_operand:SI 3 "immediate_operand" ""))
17013 "ix86_match_ccmode (insn, CCNOmode)
17014 && (true_regnum (operands[2]) != AX_REG
17015 || satisfies_constraint_K (operands[3]))
17016 && peep2_reg_dead_p (1, operands[2])"
17018 [(set (match_dup 0)
17019 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17022 (and:SI (match_dup 2) (match_dup 3)))])])
17024 ;; We don't need to handle HImode case, because it will be promoted to SImode
17025 ;; on ! TARGET_PARTIAL_REG_STALL
17028 [(set (match_operand 0 "flags_reg_operand" "")
17029 (match_operator 1 "compare_operator"
17030 [(and:QI (match_operand:QI 2 "register_operand" "")
17031 (match_operand:QI 3 "immediate_operand" ""))
17033 "! TARGET_PARTIAL_REG_STALL
17034 && ix86_match_ccmode (insn, CCNOmode)
17035 && true_regnum (operands[2]) != AX_REG
17036 && peep2_reg_dead_p (1, operands[2])"
17038 [(set (match_dup 0)
17039 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17042 (and:QI (match_dup 2) (match_dup 3)))])])
17045 [(set (match_operand 0 "flags_reg_operand" "")
17046 (match_operator 1 "compare_operator"
17049 (match_operand 2 "ext_register_operand" "")
17052 (match_operand 3 "const_int_operand" ""))
17054 "! TARGET_PARTIAL_REG_STALL
17055 && ix86_match_ccmode (insn, CCNOmode)
17056 && true_regnum (operands[2]) != AX_REG
17057 && peep2_reg_dead_p (1, operands[2])"
17058 [(parallel [(set (match_dup 0)
17067 (set (zero_extract:SI (match_dup 2)
17075 (match_dup 3)))])])
17077 ;; Don't do logical operations with memory inputs.
17079 [(match_scratch:SI 2 "r")
17080 (parallel [(set (match_operand:SI 0 "register_operand" "")
17081 (match_operator:SI 3 "arith_or_logical_operator"
17083 (match_operand:SI 1 "memory_operand" "")]))
17084 (clobber (reg:CC FLAGS_REG))])]
17085 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17086 [(set (match_dup 2) (match_dup 1))
17087 (parallel [(set (match_dup 0)
17088 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17089 (clobber (reg:CC FLAGS_REG))])])
17092 [(match_scratch:SI 2 "r")
17093 (parallel [(set (match_operand:SI 0 "register_operand" "")
17094 (match_operator:SI 3 "arith_or_logical_operator"
17095 [(match_operand:SI 1 "memory_operand" "")
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17099 [(set (match_dup 2) (match_dup 1))
17100 (parallel [(set (match_dup 0)
17101 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17102 (clobber (reg:CC FLAGS_REG))])])
17104 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17105 ;; refers to the destination of the load!
17108 [(set (match_operand:SI 0 "register_operand" "")
17109 (match_operand:SI 1 "register_operand" ""))
17110 (parallel [(set (match_dup 0)
17111 (match_operator:SI 3 "commutative_operator"
17113 (match_operand:SI 2 "memory_operand" "")]))
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "REGNO (operands[0]) != REGNO (operands[1])
17116 && GENERAL_REGNO_P (REGNO (operands[0]))
17117 && GENERAL_REGNO_P (REGNO (operands[1]))"
17118 [(set (match_dup 0) (match_dup 4))
17119 (parallel [(set (match_dup 0)
17120 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17121 (clobber (reg:CC FLAGS_REG))])]
17122 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17125 [(set (match_operand 0 "register_operand" "")
17126 (match_operand 1 "register_operand" ""))
17128 (match_operator 3 "commutative_operator"
17130 (match_operand 2 "memory_operand" "")]))]
17131 "REGNO (operands[0]) != REGNO (operands[1])
17132 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17133 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17134 [(set (match_dup 0) (match_dup 2))
17136 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17138 ; Don't do logical operations with memory outputs
17140 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17141 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17142 ; the same decoder scheduling characteristics as the original.
17145 [(match_scratch:SI 2 "r")
17146 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17147 (match_operator:SI 3 "arith_or_logical_operator"
17149 (match_operand:SI 1 "nonmemory_operand" "")]))
17150 (clobber (reg:CC FLAGS_REG))])]
17151 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17152 /* Do not split stack checking probes. */
17153 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17154 [(set (match_dup 2) (match_dup 0))
17155 (parallel [(set (match_dup 2)
17156 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17157 (clobber (reg:CC FLAGS_REG))])
17158 (set (match_dup 0) (match_dup 2))])
17161 [(match_scratch:SI 2 "r")
17162 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17163 (match_operator:SI 3 "arith_or_logical_operator"
17164 [(match_operand:SI 1 "nonmemory_operand" "")
17166 (clobber (reg:CC FLAGS_REG))])]
17167 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17168 /* Do not split stack checking probes. */
17169 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17170 [(set (match_dup 2) (match_dup 0))
17171 (parallel [(set (match_dup 2)
17172 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17173 (clobber (reg:CC FLAGS_REG))])
17174 (set (match_dup 0) (match_dup 2))])
17176 ;; Attempt to use arith or logical operations with memory outputs with
17177 ;; setting of flags.
17179 [(set (match_operand:SWI 0 "register_operand" "")
17180 (match_operand:SWI 1 "memory_operand" ""))
17181 (parallel [(set (match_dup 0)
17182 (match_operator:SWI 3 "plusminuslogic_operator"
17184 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17185 (clobber (reg:CC FLAGS_REG))])
17186 (set (match_dup 1) (match_dup 0))
17187 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17188 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17189 && peep2_reg_dead_p (4, operands[0])
17190 && !reg_overlap_mentioned_p (operands[0], operands[1])
17191 && ix86_match_ccmode (peep2_next_insn (3),
17192 (GET_CODE (operands[3]) == PLUS
17193 || GET_CODE (operands[3]) == MINUS)
17194 ? CCGOCmode : CCNOmode)"
17195 [(parallel [(set (match_dup 4) (match_dup 5))
17196 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17197 (match_dup 2)]))])]
17198 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17199 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17200 copy_rtx (operands[1]),
17201 copy_rtx (operands[2]));
17202 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17203 operands[5], const0_rtx);")
17206 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17207 (match_operator:SWI 2 "plusminuslogic_operator"
17209 (match_operand:SWI 1 "memory_operand" "")]))
17210 (clobber (reg:CC FLAGS_REG))])
17211 (set (match_dup 1) (match_dup 0))
17212 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17213 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17214 && GET_CODE (operands[2]) != MINUS
17215 && peep2_reg_dead_p (3, operands[0])
17216 && !reg_overlap_mentioned_p (operands[0], operands[1])
17217 && ix86_match_ccmode (peep2_next_insn (2),
17218 GET_CODE (operands[2]) == PLUS
17219 ? CCGOCmode : CCNOmode)"
17220 [(parallel [(set (match_dup 3) (match_dup 4))
17221 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17222 (match_dup 0)]))])]
17223 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17224 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17225 copy_rtx (operands[1]),
17226 copy_rtx (operands[0]));
17227 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17228 operands[4], const0_rtx);")
17231 [(set (match_operand:SWI12 0 "register_operand" "")
17232 (match_operand:SWI12 1 "memory_operand" ""))
17233 (parallel [(set (match_operand:SI 4 "register_operand" "")
17234 (match_operator:SI 3 "plusminuslogic_operator"
17236 (match_operand:SI 2 "nonmemory_operand" "")]))
17237 (clobber (reg:CC FLAGS_REG))])
17238 (set (match_dup 1) (match_dup 0))
17239 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17240 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17241 && REG_P (operands[0]) && REG_P (operands[4])
17242 && REGNO (operands[0]) == REGNO (operands[4])
17243 && peep2_reg_dead_p (4, operands[0])
17244 && !reg_overlap_mentioned_p (operands[0], operands[1])
17245 && ix86_match_ccmode (peep2_next_insn (3),
17246 (GET_CODE (operands[3]) == PLUS
17247 || GET_CODE (operands[3]) == MINUS)
17248 ? CCGOCmode : CCNOmode)"
17249 [(parallel [(set (match_dup 4) (match_dup 5))
17250 (set (match_dup 1) (match_dup 6))])]
17251 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17252 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17253 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17254 copy_rtx (operands[1]), operands[2]);
17255 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17256 operands[5], const0_rtx);
17257 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17258 copy_rtx (operands[1]),
17259 copy_rtx (operands[2]));")
17261 ;; Attempt to always use XOR for zeroing registers.
17263 [(set (match_operand 0 "register_operand" "")
17264 (match_operand 1 "const0_operand" ""))]
17265 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17266 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17267 && GENERAL_REG_P (operands[0])
17268 && peep2_regno_dead_p (0, FLAGS_REG)"
17269 [(parallel [(set (match_dup 0) (const_int 0))
17270 (clobber (reg:CC FLAGS_REG))])]
17271 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17274 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17276 "(GET_MODE (operands[0]) == QImode
17277 || GET_MODE (operands[0]) == HImode)
17278 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17279 && peep2_regno_dead_p (0, FLAGS_REG)"
17280 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17281 (clobber (reg:CC FLAGS_REG))])])
17283 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17285 [(set (match_operand:SWI248 0 "register_operand" "")
17287 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17288 && peep2_regno_dead_p (0, FLAGS_REG)"
17289 [(parallel [(set (match_dup 0) (const_int -1))
17290 (clobber (reg:CC FLAGS_REG))])]
17292 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17293 operands[0] = gen_lowpart (SImode, operands[0]);
17296 ;; Attempt to convert simple lea to add/shift.
17297 ;; These can be created by move expanders.
17300 [(set (match_operand:SWI48 0 "register_operand" "")
17301 (plus:SWI48 (match_dup 0)
17302 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17303 "peep2_regno_dead_p (0, FLAGS_REG)"
17304 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17305 (clobber (reg:CC FLAGS_REG))])])
17308 [(set (match_operand:SI 0 "register_operand" "")
17309 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17310 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17312 && peep2_regno_dead_p (0, FLAGS_REG)
17313 && REGNO (operands[0]) == REGNO (operands[1])"
17314 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17315 (clobber (reg:CC FLAGS_REG))])]
17316 "operands[2] = gen_lowpart (SImode, operands[2]);")
17319 [(set (match_operand:SWI48 0 "register_operand" "")
17320 (mult:SWI48 (match_dup 0)
17321 (match_operand:SWI48 1 "const_int_operand" "")))]
17322 "exact_log2 (INTVAL (operands[1])) >= 0
17323 && peep2_regno_dead_p (0, FLAGS_REG)"
17324 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17325 (clobber (reg:CC FLAGS_REG))])]
17326 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17329 [(set (match_operand:SI 0 "register_operand" "")
17330 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17331 (match_operand:DI 2 "const_int_operand" "")) 0))]
17333 && exact_log2 (INTVAL (operands[2])) >= 0
17334 && REGNO (operands[0]) == REGNO (operands[1])
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17340 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17341 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17342 ;; On many CPUs it is also faster, since special hardware to avoid esp
17343 ;; dependencies is present.
17345 ;; While some of these conversions may be done using splitters, we use
17346 ;; peepholes in order to allow combine_stack_adjustments pass to see
17347 ;; nonobfuscated RTL.
17349 ;; Convert prologue esp subtractions to push.
17350 ;; We need register to push. In order to keep verify_flow_info happy we have
17352 ;; - use scratch and clobber it in order to avoid dependencies
17353 ;; - use already live register
17354 ;; We can't use the second way right now, since there is no reliable way how to
17355 ;; verify that given register is live. First choice will also most likely in
17356 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17357 ;; call clobbered registers are dead. We may want to use base pointer as an
17358 ;; alternative when no register is available later.
17361 [(match_scratch:P 1 "r")
17362 (parallel [(set (reg:P SP_REG)
17363 (plus:P (reg:P SP_REG)
17364 (match_operand:P 0 "const_int_operand" "")))
17365 (clobber (reg:CC FLAGS_REG))
17366 (clobber (mem:BLK (scratch)))])]
17367 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17368 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17369 [(clobber (match_dup 1))
17370 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17371 (clobber (mem:BLK (scratch)))])])
17374 [(match_scratch:P 1 "r")
17375 (parallel [(set (reg:P SP_REG)
17376 (plus:P (reg:P SP_REG)
17377 (match_operand:P 0 "const_int_operand" "")))
17378 (clobber (reg:CC FLAGS_REG))
17379 (clobber (mem:BLK (scratch)))])]
17380 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17381 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17382 [(clobber (match_dup 1))
17383 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17384 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (clobber (mem:BLK (scratch)))])])
17387 ;; Convert esp subtractions to push.
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))])]
17394 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17395 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17396 [(clobber (match_dup 1))
17397 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17400 [(match_scratch:P 1 "r")
17401 (parallel [(set (reg:P SP_REG)
17402 (plus:P (reg:P SP_REG)
17403 (match_operand:P 0 "const_int_operand" "")))
17404 (clobber (reg:CC FLAGS_REG))])]
17405 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17406 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17407 [(clobber (match_dup 1))
17408 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17411 ;; Convert epilogue deallocator to pop.
17413 [(match_scratch:P 1 "r")
17414 (parallel [(set (reg:P SP_REG)
17415 (plus:P (reg:P SP_REG)
17416 (match_operand:P 0 "const_int_operand" "")))
17417 (clobber (reg:CC FLAGS_REG))
17418 (clobber (mem:BLK (scratch)))])]
17419 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17420 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17421 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17422 (clobber (mem:BLK (scratch)))])])
17424 ;; Two pops case is tricky, since pop causes dependency
17425 ;; on destination register. We use two registers if available.
17427 [(match_scratch:P 1 "r")
17428 (match_scratch:P 2 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand" "")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17436 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])
17438 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17441 [(match_scratch:P 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand" "")))
17445 (clobber (reg:CC FLAGS_REG))
17446 (clobber (mem:BLK (scratch)))])]
17447 "optimize_insn_for_size_p ()
17448 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17449 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17450 (clobber (mem:BLK (scratch)))])
17451 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17453 ;; Convert esp additions to pop.
17455 [(match_scratch:P 1 "r")
17456 (parallel [(set (reg:P SP_REG)
17457 (plus:P (reg:P SP_REG)
17458 (match_operand:P 0 "const_int_operand" "")))
17459 (clobber (reg:CC FLAGS_REG))])]
17460 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17461 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17463 ;; Two pops case is tricky, since pop causes dependency
17464 ;; on destination register. We use two registers if available.
17466 [(match_scratch:P 1 "r")
17467 (match_scratch:P 2 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand" "")))
17471 (clobber (reg:CC FLAGS_REG))])]
17472 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17473 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17477 [(match_scratch:P 1 "r")
17478 (parallel [(set (reg:P SP_REG)
17479 (plus:P (reg:P SP_REG)
17480 (match_operand:P 0 "const_int_operand" "")))
17481 (clobber (reg:CC FLAGS_REG))])]
17482 "optimize_insn_for_size_p ()
17483 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17484 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17485 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17487 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17488 ;; required and register dies. Similarly for 128 to -128.
17490 [(set (match_operand 0 "flags_reg_operand" "")
17491 (match_operator 1 "compare_operator"
17492 [(match_operand 2 "register_operand" "")
17493 (match_operand 3 "const_int_operand" "")]))]
17494 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17495 && incdec_operand (operands[3], GET_MODE (operands[3])))
17496 || (!TARGET_FUSE_CMP_AND_BRANCH
17497 && INTVAL (operands[3]) == 128))
17498 && ix86_match_ccmode (insn, CCGCmode)
17499 && peep2_reg_dead_p (1, operands[2])"
17500 [(parallel [(set (match_dup 0)
17501 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17502 (clobber (match_dup 2))])])
17504 ;; Convert imul by three, five and nine into lea
17507 [(set (match_operand:SWI48 0 "register_operand" "")
17508 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17509 (match_operand:SWI48 2 "const359_operand" "")))
17510 (clobber (reg:CC FLAGS_REG))])]
17511 "!TARGET_PARTIAL_REG_STALL
17512 || <MODE>mode == SImode
17513 || optimize_function_for_size_p (cfun)"
17514 [(set (match_dup 0)
17515 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17517 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17521 [(set (match_operand:SWI48 0 "register_operand" "")
17522 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17523 (match_operand:SWI48 2 "const359_operand" "")))
17524 (clobber (reg:CC FLAGS_REG))])]
17525 "optimize_insn_for_speed_p ()
17526 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17527 [(set (match_dup 0) (match_dup 1))
17529 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17531 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17533 ;; imul $32bit_imm, mem, reg is vector decoded, while
17534 ;; imul $32bit_imm, reg, reg is direct decoded.
17536 [(match_scratch:SWI48 3 "r")
17537 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17538 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17539 (match_operand:SWI48 2 "immediate_operand" "")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17542 && !satisfies_constraint_K (operands[2])"
17543 [(set (match_dup 3) (match_dup 1))
17544 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17545 (clobber (reg:CC FLAGS_REG))])])
17548 [(match_scratch:SI 3 "r")
17549 (parallel [(set (match_operand:DI 0 "register_operand" "")
17551 (mult:SI (match_operand:SI 1 "memory_operand" "")
17552 (match_operand:SI 2 "immediate_operand" ""))))
17553 (clobber (reg:CC FLAGS_REG))])]
17555 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556 && !satisfies_constraint_K (operands[2])"
17557 [(set (match_dup 3) (match_dup 1))
17558 (parallel [(set (match_dup 0)
17559 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17560 (clobber (reg:CC FLAGS_REG))])])
17562 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17563 ;; Convert it into imul reg, reg
17564 ;; It would be better to force assembler to encode instruction using long
17565 ;; immediate, but there is apparently no way to do so.
17567 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17569 (match_operand:SWI248 1 "nonimmediate_operand" "")
17570 (match_operand:SWI248 2 "const_int_operand" "")))
17571 (clobber (reg:CC FLAGS_REG))])
17572 (match_scratch:SWI248 3 "r")]
17573 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17574 && satisfies_constraint_K (operands[2])"
17575 [(set (match_dup 3) (match_dup 2))
17576 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17577 (clobber (reg:CC FLAGS_REG))])]
17579 if (!rtx_equal_p (operands[0], operands[1]))
17580 emit_move_insn (operands[0], operands[1]);
17583 ;; After splitting up read-modify operations, array accesses with memory
17584 ;; operands might end up in form:
17586 ;; movl 4(%esp), %edx
17588 ;; instead of pre-splitting:
17590 ;; addl 4(%esp), %eax
17592 ;; movl 4(%esp), %edx
17593 ;; leal (%edx,%eax,4), %eax
17596 [(match_scratch:P 5 "r")
17597 (parallel [(set (match_operand 0 "register_operand" "")
17598 (ashift (match_operand 1 "register_operand" "")
17599 (match_operand 2 "const_int_operand" "")))
17600 (clobber (reg:CC FLAGS_REG))])
17601 (parallel [(set (match_operand 3 "register_operand" "")
17602 (plus (match_dup 0)
17603 (match_operand 4 "x86_64_general_operand" "")))
17604 (clobber (reg:CC FLAGS_REG))])]
17605 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17606 /* Validate MODE for lea. */
17607 && ((!TARGET_PARTIAL_REG_STALL
17608 && (GET_MODE (operands[0]) == QImode
17609 || GET_MODE (operands[0]) == HImode))
17610 || GET_MODE (operands[0]) == SImode
17611 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17612 && (rtx_equal_p (operands[0], operands[3])
17613 || peep2_reg_dead_p (2, operands[0]))
17614 /* We reorder load and the shift. */
17615 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17616 [(set (match_dup 5) (match_dup 4))
17617 (set (match_dup 0) (match_dup 1))]
17619 enum machine_mode op1mode = GET_MODE (operands[1]);
17620 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17621 int scale = 1 << INTVAL (operands[2]);
17622 rtx index = gen_lowpart (Pmode, operands[1]);
17623 rtx base = gen_lowpart (Pmode, operands[5]);
17624 rtx dest = gen_lowpart (mode, operands[3]);
17626 operands[1] = gen_rtx_PLUS (Pmode, base,
17627 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17628 operands[5] = base;
17630 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17631 if (op1mode != Pmode)
17632 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17633 operands[0] = dest;
17636 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17637 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17638 ;; caught for use by garbage collectors and the like. Using an insn that
17639 ;; maps to SIGILL makes it more likely the program will rightfully die.
17640 ;; Keeping with tradition, "6" is in honor of #UD.
17641 (define_insn "trap"
17642 [(trap_if (const_int 1) (const_int 6))]
17644 { return ASM_SHORT "0x0b0f"; }
17645 [(set_attr "length" "2")])
17647 (define_expand "prefetch"
17648 [(prefetch (match_operand 0 "address_operand" "")
17649 (match_operand:SI 1 "const_int_operand" "")
17650 (match_operand:SI 2 "const_int_operand" ""))]
17651 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17653 int rw = INTVAL (operands[1]);
17654 int locality = INTVAL (operands[2]);
17656 gcc_assert (rw == 0 || rw == 1);
17657 gcc_assert (locality >= 0 && locality <= 3);
17658 gcc_assert (GET_MODE (operands[0]) == Pmode
17659 || GET_MODE (operands[0]) == VOIDmode);
17661 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17662 supported by SSE counterpart or the SSE prefetch is not available
17663 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17665 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17666 operands[2] = GEN_INT (3);
17668 operands[1] = const0_rtx;
17671 (define_insn "*prefetch_sse_<mode>"
17672 [(prefetch (match_operand:P 0 "address_operand" "p")
17674 (match_operand:SI 1 "const_int_operand" ""))]
17675 "TARGET_PREFETCH_SSE"
17677 static const char * const patterns[4] = {
17678 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17681 int locality = INTVAL (operands[1]);
17682 gcc_assert (locality >= 0 && locality <= 3);
17684 return patterns[locality];
17686 [(set_attr "type" "sse")
17687 (set_attr "atom_sse_attr" "prefetch")
17688 (set (attr "length_address")
17689 (symbol_ref "memory_address_length (operands[0])"))
17690 (set_attr "memory" "none")])
17692 (define_insn "*prefetch_3dnow_<mode>"
17693 [(prefetch (match_operand:P 0 "address_operand" "p")
17694 (match_operand:SI 1 "const_int_operand" "n")
17698 if (INTVAL (operands[1]) == 0)
17699 return "prefetch\t%a0";
17701 return "prefetchw\t%a0";
17703 [(set_attr "type" "mmx")
17704 (set (attr "length_address")
17705 (symbol_ref "memory_address_length (operands[0])"))
17706 (set_attr "memory" "none")])
17708 (define_expand "stack_protect_set"
17709 [(match_operand 0 "memory_operand" "")
17710 (match_operand 1 "memory_operand" "")]
17713 rtx (*insn)(rtx, rtx);
17715 #ifdef TARGET_THREAD_SSP_OFFSET
17716 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17717 insn = (TARGET_LP64
17718 ? gen_stack_tls_protect_set_di
17719 : gen_stack_tls_protect_set_si);
17721 insn = (TARGET_LP64
17722 ? gen_stack_protect_set_di
17723 : gen_stack_protect_set_si);
17726 emit_insn (insn (operands[0], operands[1]));
17730 (define_insn "stack_protect_set_<mode>"
17731 [(set (match_operand:PTR 0 "memory_operand" "=m")
17732 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17734 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735 (clobber (reg:CC FLAGS_REG))]
17737 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738 [(set_attr "type" "multi")])
17740 (define_insn "stack_tls_protect_set_<mode>"
17741 [(set (match_operand:PTR 0 "memory_operand" "=m")
17742 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17743 UNSPEC_SP_TLS_SET))
17744 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17745 (clobber (reg:CC FLAGS_REG))]
17747 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17748 [(set_attr "type" "multi")])
17750 (define_expand "stack_protect_test"
17751 [(match_operand 0 "memory_operand" "")
17752 (match_operand 1 "memory_operand" "")
17753 (match_operand 2 "" "")]
17756 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17758 rtx (*insn)(rtx, rtx, rtx);
17760 #ifdef TARGET_THREAD_SSP_OFFSET
17761 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17762 insn = (TARGET_LP64
17763 ? gen_stack_tls_protect_test_di
17764 : gen_stack_tls_protect_test_si);
17766 insn = (TARGET_LP64
17767 ? gen_stack_protect_test_di
17768 : gen_stack_protect_test_si);
17771 emit_insn (insn (flags, operands[0], operands[1]));
17773 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17774 flags, const0_rtx, operands[2]));
17778 (define_insn "stack_protect_test_<mode>"
17779 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17780 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781 (match_operand:PTR 2 "memory_operand" "m")]
17783 (clobber (match_scratch:PTR 3 "=&r"))]
17785 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17786 [(set_attr "type" "multi")])
17788 (define_insn "stack_tls_protect_test_<mode>"
17789 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17790 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17791 (match_operand:PTR 2 "const_int_operand" "i")]
17792 UNSPEC_SP_TLS_TEST))
17793 (clobber (match_scratch:PTR 3 "=r"))]
17795 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17796 [(set_attr "type" "multi")])
17798 (define_insn "sse4_2_crc32<mode>"
17799 [(set (match_operand:SI 0 "register_operand" "=r")
17801 [(match_operand:SI 1 "register_operand" "0")
17802 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17804 "TARGET_SSE4_2 || TARGET_CRC32"
17805 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17806 [(set_attr "type" "sselog1")
17807 (set_attr "prefix_rep" "1")
17808 (set_attr "prefix_extra" "1")
17809 (set (attr "prefix_data16")
17810 (if_then_else (match_operand:HI 2 "" "")
17812 (const_string "*")))
17813 (set (attr "prefix_rex")
17814 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17816 (const_string "*")))
17817 (set_attr "mode" "SI")])
17819 (define_insn "sse4_2_crc32di"
17820 [(set (match_operand:DI 0 "register_operand" "=r")
17822 [(match_operand:DI 1 "register_operand" "0")
17823 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17825 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17826 "crc32{q}\t{%2, %0|%0, %2}"
17827 [(set_attr "type" "sselog1")
17828 (set_attr "prefix_rep" "1")
17829 (set_attr "prefix_extra" "1")
17830 (set_attr "mode" "DI")])
17832 (define_expand "rdpmc"
17833 [(match_operand:DI 0 "register_operand" "")
17834 (match_operand:SI 1 "register_operand" "")]
17837 rtx reg = gen_reg_rtx (DImode);
17840 /* Force operand 1 into ECX. */
17841 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17842 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17843 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17848 rtvec vec = rtvec_alloc (2);
17849 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17850 rtx upper = gen_reg_rtx (DImode);
17851 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17852 gen_rtvec (1, const0_rtx),
17854 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17855 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17857 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17858 NULL, 1, OPTAB_DIRECT);
17859 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17863 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17864 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17868 (define_insn "*rdpmc"
17869 [(set (match_operand:DI 0 "register_operand" "=A")
17870 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17874 [(set_attr "type" "other")
17875 (set_attr "length" "2")])
17877 (define_insn "*rdpmc_rex64"
17878 [(set (match_operand:DI 0 "register_operand" "=a")
17879 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17881 (set (match_operand:DI 1 "register_operand" "=d")
17882 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17885 [(set_attr "type" "other")
17886 (set_attr "length" "2")])
17888 (define_expand "rdtsc"
17889 [(set (match_operand:DI 0 "register_operand" "")
17890 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17895 rtvec vec = rtvec_alloc (2);
17896 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17897 rtx upper = gen_reg_rtx (DImode);
17898 rtx lower = gen_reg_rtx (DImode);
17899 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17900 gen_rtvec (1, const0_rtx),
17902 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17903 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17905 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17906 NULL, 1, OPTAB_DIRECT);
17907 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17909 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17914 (define_insn "*rdtsc"
17915 [(set (match_operand:DI 0 "register_operand" "=A")
17916 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17919 [(set_attr "type" "other")
17920 (set_attr "length" "2")])
17922 (define_insn "*rdtsc_rex64"
17923 [(set (match_operand:DI 0 "register_operand" "=a")
17924 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17925 (set (match_operand:DI 1 "register_operand" "=d")
17926 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17929 [(set_attr "type" "other")
17930 (set_attr "length" "2")])
17932 (define_expand "rdtscp"
17933 [(match_operand:DI 0 "register_operand" "")
17934 (match_operand:SI 1 "memory_operand" "")]
17937 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17938 gen_rtvec (1, const0_rtx),
17940 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17941 gen_rtvec (1, const0_rtx),
17943 rtx reg = gen_reg_rtx (DImode);
17944 rtx tmp = gen_reg_rtx (SImode);
17948 rtvec vec = rtvec_alloc (3);
17949 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17950 rtx upper = gen_reg_rtx (DImode);
17951 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17952 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17953 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17955 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17956 NULL, 1, OPTAB_DIRECT);
17957 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17962 rtvec vec = rtvec_alloc (2);
17963 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17965 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17968 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17969 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17973 (define_insn "*rdtscp"
17974 [(set (match_operand:DI 0 "register_operand" "=A")
17975 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17976 (set (match_operand:SI 1 "register_operand" "=c")
17977 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17980 [(set_attr "type" "other")
17981 (set_attr "length" "3")])
17983 (define_insn "*rdtscp_rex64"
17984 [(set (match_operand:DI 0 "register_operand" "=a")
17985 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17986 (set (match_operand:DI 1 "register_operand" "=d")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988 (set (match_operand:SI 2 "register_operand" "=c")
17989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17992 [(set_attr "type" "other")
17993 (set_attr "length" "3")])
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17997 ;; LWP instructions
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18001 (define_expand "lwp_llwpcb"
18002 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18003 UNSPECV_LLWP_INTRINSIC)]
18006 (define_insn "*lwp_llwpcb<mode>1"
18007 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18008 UNSPECV_LLWP_INTRINSIC)]
18011 [(set_attr "type" "lwp")
18012 (set_attr "mode" "<MODE>")
18013 (set_attr "length" "5")])
18015 (define_expand "lwp_slwpcb"
18016 [(set (match_operand 0 "register_operand" "=r")
18017 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18022 insn = (TARGET_64BIT
18024 : gen_lwp_slwpcbsi);
18026 emit_insn (insn (operands[0]));
18030 (define_insn "lwp_slwpcb<mode>"
18031 [(set (match_operand:P 0 "register_operand" "=r")
18032 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18035 [(set_attr "type" "lwp")
18036 (set_attr "mode" "<MODE>")
18037 (set_attr "length" "5")])
18039 (define_expand "lwp_lwpval<mode>3"
18040 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18041 (match_operand:SI 2 "nonimmediate_operand" "rm")
18042 (match_operand:SI 3 "const_int_operand" "i")]
18043 UNSPECV_LWPVAL_INTRINSIC)]
18045 "/* Avoid unused variable warning. */
18048 (define_insn "*lwp_lwpval<mode>3_1"
18049 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18050 (match_operand:SI 1 "nonimmediate_operand" "rm")
18051 (match_operand:SI 2 "const_int_operand" "i")]
18052 UNSPECV_LWPVAL_INTRINSIC)]
18054 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18055 [(set_attr "type" "lwp")
18056 (set_attr "mode" "<MODE>")
18057 (set (attr "length")
18058 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18060 (define_expand "lwp_lwpins<mode>3"
18061 [(set (reg:CCC FLAGS_REG)
18062 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18063 (match_operand:SI 2 "nonimmediate_operand" "rm")
18064 (match_operand:SI 3 "const_int_operand" "i")]
18065 UNSPECV_LWPINS_INTRINSIC))
18066 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18067 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18070 (define_insn "*lwp_lwpins<mode>3_1"
18071 [(set (reg:CCC FLAGS_REG)
18072 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18073 (match_operand:SI 1 "nonimmediate_operand" "rm")
18074 (match_operand:SI 2 "const_int_operand" "i")]
18075 UNSPECV_LWPINS_INTRINSIC))]
18077 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18078 [(set_attr "type" "lwp")
18079 (set_attr "mode" "<MODE>")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18083 (define_insn "rdfsbase<mode>"
18084 [(set (match_operand:SWI48 0 "register_operand" "=r")
18085 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18086 "TARGET_64BIT && TARGET_FSGSBASE"
18088 [(set_attr "type" "other")
18089 (set_attr "prefix_extra" "2")])
18091 (define_insn "rdgsbase<mode>"
18092 [(set (match_operand:SWI48 0 "register_operand" "=r")
18093 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18094 "TARGET_64BIT && TARGET_FSGSBASE"
18096 [(set_attr "type" "other")
18097 (set_attr "prefix_extra" "2")])
18099 (define_insn "wrfsbase<mode>"
18100 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18102 "TARGET_64BIT && TARGET_FSGSBASE"
18104 [(set_attr "type" "other")
18105 (set_attr "prefix_extra" "2")])
18107 (define_insn "wrgsbase<mode>"
18108 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18110 "TARGET_64BIT && TARGET_FSGSBASE"
18112 [(set_attr "type" "other")
18113 (set_attr "prefix_extra" "2")])
18115 (define_insn "rdrand<mode>_1"
18116 [(set (match_operand:SWI248 0 "register_operand" "=r")
18117 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18118 (set (reg:CCC FLAGS_REG)
18119 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18122 [(set_attr "type" "other")
18123 (set_attr "prefix_extra" "1")])
18125 (define_expand "pause"
18126 [(set (match_dup 0)
18127 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18130 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18131 MEM_VOLATILE_P (operands[0]) = 1;
18134 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18135 ;; They have the same encoding.
18136 (define_insn "*pause"
18137 [(set (match_operand:BLK 0 "" "")
18138 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18141 [(set_attr "length" "2")
18142 (set_attr "memory" "unknown")])
18146 (include "sync.md")