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))
7067 && optimize_insn_for_speed_p ()
7068 && flag_finite_math_only && !flag_trapping_math
7069 && flag_unsafe_math_optimizations)
7071 ix86_emit_swdivsf (operands[0], operands[1],
7072 operands[2], SFmode);
7077 ;; Divmod instructions.
7079 (define_expand "divmod<mode>4"
7080 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7082 (match_operand:SWIM248 1 "register_operand" "")
7083 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7084 (set (match_operand:SWIM248 3 "register_operand" "")
7085 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7086 (clobber (reg:CC FLAGS_REG))])])
7088 ;; Split with 8bit unsigned divide:
7089 ;; if (dividend an divisor are in [0-255])
7090 ;; use 8bit unsigned integer divide
7092 ;; use original integer divide
7094 [(set (match_operand:SWI48 0 "register_operand" "")
7095 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7096 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7097 (set (match_operand:SWI48 1 "register_operand" "")
7098 (mod:SWI48 (match_dup 2) (match_dup 3)))
7099 (clobber (reg:CC FLAGS_REG))]
7100 "TARGET_USE_8BIT_IDIV
7101 && TARGET_QIMODE_MATH
7102 && can_create_pseudo_p ()
7103 && !optimize_insn_for_size_p ()"
7105 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7107 (define_insn_and_split "divmod<mode>4_1"
7108 [(set (match_operand:SWI48 0 "register_operand" "=a")
7109 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7110 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7111 (set (match_operand:SWI48 1 "register_operand" "=&d")
7112 (mod:SWI48 (match_dup 2) (match_dup 3)))
7113 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7114 (clobber (reg:CC FLAGS_REG))]
7118 [(parallel [(set (match_dup 1)
7119 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7120 (clobber (reg:CC FLAGS_REG))])
7121 (parallel [(set (match_dup 0)
7122 (div:SWI48 (match_dup 2) (match_dup 3)))
7124 (mod:SWI48 (match_dup 2) (match_dup 3)))
7126 (clobber (reg:CC FLAGS_REG))])]
7128 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7130 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7131 operands[4] = operands[2];
7134 /* Avoid use of cltd in favor of a mov+shift. */
7135 emit_move_insn (operands[1], operands[2]);
7136 operands[4] = operands[1];
7139 [(set_attr "type" "multi")
7140 (set_attr "mode" "<MODE>")])
7142 (define_insn_and_split "*divmod<mode>4"
7143 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7144 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7145 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7146 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7147 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7148 (clobber (reg:CC FLAGS_REG))]
7152 [(parallel [(set (match_dup 1)
7153 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7154 (clobber (reg:CC FLAGS_REG))])
7155 (parallel [(set (match_dup 0)
7156 (div:SWIM248 (match_dup 2) (match_dup 3)))
7158 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7160 (clobber (reg:CC FLAGS_REG))])]
7162 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7164 if (<MODE>mode != HImode
7165 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7166 operands[4] = operands[2];
7169 /* Avoid use of cltd in favor of a mov+shift. */
7170 emit_move_insn (operands[1], operands[2]);
7171 operands[4] = operands[1];
7174 [(set_attr "type" "multi")
7175 (set_attr "mode" "<MODE>")])
7177 (define_insn "*divmod<mode>4_noext"
7178 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7179 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7180 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7181 (set (match_operand:SWIM248 1 "register_operand" "=d")
7182 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7183 (use (match_operand:SWIM248 4 "register_operand" "1"))
7184 (clobber (reg:CC FLAGS_REG))]
7186 "idiv{<imodesuffix>}\t%3"
7187 [(set_attr "type" "idiv")
7188 (set_attr "mode" "<MODE>")])
7190 (define_expand "divmodqi4"
7191 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7193 (match_operand:QI 1 "register_operand" "")
7194 (match_operand:QI 2 "nonimmediate_operand" "")))
7195 (set (match_operand:QI 3 "register_operand" "")
7196 (mod:QI (match_dup 1) (match_dup 2)))
7197 (clobber (reg:CC FLAGS_REG))])]
7198 "TARGET_QIMODE_MATH"
7203 tmp0 = gen_reg_rtx (HImode);
7204 tmp1 = gen_reg_rtx (HImode);
7206 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7208 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7209 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7211 /* Extract remainder from AH. */
7212 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7213 insn = emit_move_insn (operands[3], tmp1);
7215 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7216 set_unique_reg_note (insn, REG_EQUAL, mod);
7218 /* Extract quotient from AL. */
7219 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7221 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7222 set_unique_reg_note (insn, REG_EQUAL, div);
7227 ;; Divide AX by r/m8, with result stored in
7230 ;; Change div/mod to HImode and extend the second argument to HImode
7231 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7232 ;; combine may fail.
7233 (define_insn "divmodhiqi3"
7234 [(set (match_operand:HI 0 "register_operand" "=a")
7239 (mod:HI (match_operand:HI 1 "register_operand" "0")
7241 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7245 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "TARGET_QIMODE_MATH"
7249 [(set_attr "type" "idiv")
7250 (set_attr "mode" "QI")])
7252 (define_expand "udivmod<mode>4"
7253 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7255 (match_operand:SWIM248 1 "register_operand" "")
7256 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7257 (set (match_operand:SWIM248 3 "register_operand" "")
7258 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7259 (clobber (reg:CC FLAGS_REG))])])
7261 ;; Split with 8bit unsigned divide:
7262 ;; if (dividend an divisor are in [0-255])
7263 ;; use 8bit unsigned integer divide
7265 ;; use original integer divide
7267 [(set (match_operand:SWI48 0 "register_operand" "")
7268 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7269 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7270 (set (match_operand:SWI48 1 "register_operand" "")
7271 (umod:SWI48 (match_dup 2) (match_dup 3)))
7272 (clobber (reg:CC FLAGS_REG))]
7273 "TARGET_USE_8BIT_IDIV
7274 && TARGET_QIMODE_MATH
7275 && can_create_pseudo_p ()
7276 && !optimize_insn_for_size_p ()"
7278 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7280 (define_insn_and_split "udivmod<mode>4_1"
7281 [(set (match_operand:SWI48 0 "register_operand" "=a")
7282 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7283 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7284 (set (match_operand:SWI48 1 "register_operand" "=&d")
7285 (umod:SWI48 (match_dup 2) (match_dup 3)))
7286 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7287 (clobber (reg:CC FLAGS_REG))]
7291 [(set (match_dup 1) (const_int 0))
7292 (parallel [(set (match_dup 0)
7293 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7295 (umod:SWI48 (match_dup 2) (match_dup 3)))
7297 (clobber (reg:CC FLAGS_REG))])]
7299 [(set_attr "type" "multi")
7300 (set_attr "mode" "<MODE>")])
7302 (define_insn_and_split "*udivmod<mode>4"
7303 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7304 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7305 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7306 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7307 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7308 (clobber (reg:CC FLAGS_REG))]
7312 [(set (match_dup 1) (const_int 0))
7313 (parallel [(set (match_dup 0)
7314 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7316 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7318 (clobber (reg:CC FLAGS_REG))])]
7320 [(set_attr "type" "multi")
7321 (set_attr "mode" "<MODE>")])
7323 (define_insn "*udivmod<mode>4_noext"
7324 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7325 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7326 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7327 (set (match_operand:SWIM248 1 "register_operand" "=d")
7328 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7329 (use (match_operand:SWIM248 4 "register_operand" "1"))
7330 (clobber (reg:CC FLAGS_REG))]
7332 "div{<imodesuffix>}\t%3"
7333 [(set_attr "type" "idiv")
7334 (set_attr "mode" "<MODE>")])
7336 (define_expand "udivmodqi4"
7337 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7339 (match_operand:QI 1 "register_operand" "")
7340 (match_operand:QI 2 "nonimmediate_operand" "")))
7341 (set (match_operand:QI 3 "register_operand" "")
7342 (umod:QI (match_dup 1) (match_dup 2)))
7343 (clobber (reg:CC FLAGS_REG))])]
7344 "TARGET_QIMODE_MATH"
7349 tmp0 = gen_reg_rtx (HImode);
7350 tmp1 = gen_reg_rtx (HImode);
7352 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7354 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7355 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7357 /* Extract remainder from AH. */
7358 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7359 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7360 insn = emit_move_insn (operands[3], tmp1);
7362 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7363 set_unique_reg_note (insn, REG_EQUAL, mod);
7365 /* Extract quotient from AL. */
7366 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7368 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7369 set_unique_reg_note (insn, REG_EQUAL, div);
7374 (define_insn "udivmodhiqi3"
7375 [(set (match_operand:HI 0 "register_operand" "=a")
7380 (mod:HI (match_operand:HI 1 "register_operand" "0")
7382 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7386 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "TARGET_QIMODE_MATH"
7390 [(set_attr "type" "idiv")
7391 (set_attr "mode" "QI")])
7393 ;; We cannot use div/idiv for double division, because it causes
7394 ;; "division by zero" on the overflow and that's not what we expect
7395 ;; from truncate. Because true (non truncating) double division is
7396 ;; never generated, we can't create this insn anyway.
7399 ; [(set (match_operand:SI 0 "register_operand" "=a")
7401 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7403 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7404 ; (set (match_operand:SI 3 "register_operand" "=d")
7406 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7407 ; (clobber (reg:CC FLAGS_REG))]
7409 ; "div{l}\t{%2, %0|%0, %2}"
7410 ; [(set_attr "type" "idiv")])
7412 ;;- Logical AND instructions
7414 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7415 ;; Note that this excludes ah.
7417 (define_expand "testsi_ccno_1"
7418 [(set (reg:CCNO FLAGS_REG)
7420 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7421 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7424 (define_expand "testqi_ccz_1"
7425 [(set (reg:CCZ FLAGS_REG)
7426 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7427 (match_operand:QI 1 "nonmemory_operand" ""))
7430 (define_expand "testdi_ccno_1"
7431 [(set (reg:CCNO FLAGS_REG)
7433 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7434 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7436 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7438 (define_insn "*testdi_1"
7439 [(set (reg FLAGS_REG)
7442 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7443 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7445 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7448 test{l}\t{%k1, %k0|%k0, %k1}
7449 test{l}\t{%k1, %k0|%k0, %k1}
7450 test{q}\t{%1, %0|%0, %1}
7451 test{q}\t{%1, %0|%0, %1}
7452 test{q}\t{%1, %0|%0, %1}"
7453 [(set_attr "type" "test")
7454 (set_attr "modrm" "0,1,0,1,1")
7455 (set_attr "mode" "SI,SI,DI,DI,DI")])
7457 (define_insn "*testqi_1_maybe_si"
7458 [(set (reg FLAGS_REG)
7461 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7462 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7464 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7465 && ix86_match_ccmode (insn,
7466 CONST_INT_P (operands[1])
7467 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7469 if (which_alternative == 3)
7471 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7472 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7473 return "test{l}\t{%1, %k0|%k0, %1}";
7475 return "test{b}\t{%1, %0|%0, %1}";
7477 [(set_attr "type" "test")
7478 (set_attr "modrm" "0,1,1,1")
7479 (set_attr "mode" "QI,QI,QI,SI")
7480 (set_attr "pent_pair" "uv,np,uv,np")])
7482 (define_insn "*test<mode>_1"
7483 [(set (reg FLAGS_REG)
7486 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7487 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7489 "ix86_match_ccmode (insn, CCNOmode)
7490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7491 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7492 [(set_attr "type" "test")
7493 (set_attr "modrm" "0,1,1")
7494 (set_attr "mode" "<MODE>")
7495 (set_attr "pent_pair" "uv,np,uv")])
7497 (define_expand "testqi_ext_ccno_0"
7498 [(set (reg:CCNO FLAGS_REG)
7502 (match_operand 0 "ext_register_operand" "")
7505 (match_operand 1 "const_int_operand" ""))
7508 (define_insn "*testqi_ext_0"
7509 [(set (reg FLAGS_REG)
7513 (match_operand 0 "ext_register_operand" "Q")
7516 (match_operand 1 "const_int_operand" "n"))
7518 "ix86_match_ccmode (insn, CCNOmode)"
7519 "test{b}\t{%1, %h0|%h0, %1}"
7520 [(set_attr "type" "test")
7521 (set_attr "mode" "QI")
7522 (set_attr "length_immediate" "1")
7523 (set_attr "modrm" "1")
7524 (set_attr "pent_pair" "np")])
7526 (define_insn "*testqi_ext_1_rex64"
7527 [(set (reg FLAGS_REG)
7531 (match_operand 0 "ext_register_operand" "Q")
7535 (match_operand:QI 1 "register_operand" "Q")))
7537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7538 "test{b}\t{%1, %h0|%h0, %1}"
7539 [(set_attr "type" "test")
7540 (set_attr "mode" "QI")])
7542 (define_insn "*testqi_ext_1"
7543 [(set (reg FLAGS_REG)
7547 (match_operand 0 "ext_register_operand" "Q")
7551 (match_operand:QI 1 "general_operand" "Qm")))
7553 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7554 "test{b}\t{%1, %h0|%h0, %1}"
7555 [(set_attr "type" "test")
7556 (set_attr "mode" "QI")])
7558 (define_insn "*testqi_ext_2"
7559 [(set (reg FLAGS_REG)
7563 (match_operand 0 "ext_register_operand" "Q")
7567 (match_operand 1 "ext_register_operand" "Q")
7571 "ix86_match_ccmode (insn, CCNOmode)"
7572 "test{b}\t{%h1, %h0|%h0, %h1}"
7573 [(set_attr "type" "test")
7574 (set_attr "mode" "QI")])
7576 (define_insn "*testqi_ext_3_rex64"
7577 [(set (reg FLAGS_REG)
7578 (compare (zero_extract:DI
7579 (match_operand 0 "nonimmediate_operand" "rm")
7580 (match_operand:DI 1 "const_int_operand" "")
7581 (match_operand:DI 2 "const_int_operand" ""))
7584 && ix86_match_ccmode (insn, CCNOmode)
7585 && INTVAL (operands[1]) > 0
7586 && INTVAL (operands[2]) >= 0
7587 /* Ensure that resulting mask is zero or sign extended operand. */
7588 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7589 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7590 && INTVAL (operands[1]) > 32))
7591 && (GET_MODE (operands[0]) == SImode
7592 || GET_MODE (operands[0]) == DImode
7593 || GET_MODE (operands[0]) == HImode
7594 || GET_MODE (operands[0]) == QImode)"
7597 ;; Combine likes to form bit extractions for some tests. Humor it.
7598 (define_insn "*testqi_ext_3"
7599 [(set (reg FLAGS_REG)
7600 (compare (zero_extract:SI
7601 (match_operand 0 "nonimmediate_operand" "rm")
7602 (match_operand:SI 1 "const_int_operand" "")
7603 (match_operand:SI 2 "const_int_operand" ""))
7605 "ix86_match_ccmode (insn, CCNOmode)
7606 && INTVAL (operands[1]) > 0
7607 && INTVAL (operands[2]) >= 0
7608 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7609 && (GET_MODE (operands[0]) == SImode
7610 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7611 || GET_MODE (operands[0]) == HImode
7612 || GET_MODE (operands[0]) == QImode)"
7616 [(set (match_operand 0 "flags_reg_operand" "")
7617 (match_operator 1 "compare_operator"
7619 (match_operand 2 "nonimmediate_operand" "")
7620 (match_operand 3 "const_int_operand" "")
7621 (match_operand 4 "const_int_operand" ""))
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7626 rtx val = operands[2];
7627 HOST_WIDE_INT len = INTVAL (operands[3]);
7628 HOST_WIDE_INT pos = INTVAL (operands[4]);
7630 enum machine_mode mode, submode;
7632 mode = GET_MODE (val);
7635 /* ??? Combine likes to put non-volatile mem extractions in QImode
7636 no matter the size of the test. So find a mode that works. */
7637 if (! MEM_VOLATILE_P (val))
7639 mode = smallest_mode_for_size (pos + len, MODE_INT);
7640 val = adjust_address (val, mode, 0);
7643 else if (GET_CODE (val) == SUBREG
7644 && (submode = GET_MODE (SUBREG_REG (val)),
7645 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7646 && pos + len <= GET_MODE_BITSIZE (submode)
7647 && GET_MODE_CLASS (submode) == MODE_INT)
7649 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7651 val = SUBREG_REG (val);
7653 else if (mode == HImode && pos + len <= 8)
7655 /* Small HImode tests can be converted to QImode. */
7657 val = gen_lowpart (QImode, val);
7660 if (len == HOST_BITS_PER_WIDE_INT)
7663 mask = ((HOST_WIDE_INT)1 << len) - 1;
7666 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7669 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7670 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7671 ;; this is relatively important trick.
7672 ;; Do the conversion only post-reload to avoid limiting of the register class
7675 [(set (match_operand 0 "flags_reg_operand" "")
7676 (match_operator 1 "compare_operator"
7677 [(and (match_operand 2 "register_operand" "")
7678 (match_operand 3 "const_int_operand" ""))
7681 && QI_REG_P (operands[2])
7682 && GET_MODE (operands[2]) != QImode
7683 && ((ix86_match_ccmode (insn, CCZmode)
7684 && !(INTVAL (operands[3]) & ~(255 << 8)))
7685 || (ix86_match_ccmode (insn, CCNOmode)
7686 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7689 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7692 "operands[2] = gen_lowpart (SImode, operands[2]);
7693 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7696 [(set (match_operand 0 "flags_reg_operand" "")
7697 (match_operator 1 "compare_operator"
7698 [(and (match_operand 2 "nonimmediate_operand" "")
7699 (match_operand 3 "const_int_operand" ""))
7702 && GET_MODE (operands[2]) != QImode
7703 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7704 && ((ix86_match_ccmode (insn, CCZmode)
7705 && !(INTVAL (operands[3]) & ~255))
7706 || (ix86_match_ccmode (insn, CCNOmode)
7707 && !(INTVAL (operands[3]) & ~127)))"
7709 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7711 "operands[2] = gen_lowpart (QImode, operands[2]);
7712 operands[3] = gen_lowpart (QImode, operands[3]);")
7714 ;; %%% This used to optimize known byte-wide and operations to memory,
7715 ;; and sometimes to QImode registers. If this is considered useful,
7716 ;; it should be done with splitters.
7718 (define_expand "and<mode>3"
7719 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7720 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7721 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7723 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7725 (define_insn "*anddi_1"
7726 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7728 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7729 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7730 (clobber (reg:CC FLAGS_REG))]
7731 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7733 switch (get_attr_type (insn))
7737 enum machine_mode mode;
7739 gcc_assert (CONST_INT_P (operands[2]));
7740 if (INTVAL (operands[2]) == 0xff)
7744 gcc_assert (INTVAL (operands[2]) == 0xffff);
7748 operands[1] = gen_lowpart (mode, operands[1]);
7750 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7752 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7757 if (get_attr_mode (insn) == MODE_SI)
7758 return "and{l}\t{%k2, %k0|%k0, %k2}";
7760 return "and{q}\t{%2, %0|%0, %2}";
7763 [(set_attr "type" "alu,alu,alu,imovx")
7764 (set_attr "length_immediate" "*,*,*,0")
7765 (set (attr "prefix_rex")
7767 (and (eq_attr "type" "imovx")
7768 (and (match_test "INTVAL (operands[2]) == 0xff")
7769 (match_operand 1 "ext_QIreg_operand" "")))
7771 (const_string "*")))
7772 (set_attr "mode" "SI,DI,DI,SI")])
7774 (define_insn "*andsi_1"
7775 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7776 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7777 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "ix86_binary_operator_ok (AND, SImode, operands)"
7781 switch (get_attr_type (insn))
7785 enum machine_mode mode;
7787 gcc_assert (CONST_INT_P (operands[2]));
7788 if (INTVAL (operands[2]) == 0xff)
7792 gcc_assert (INTVAL (operands[2]) == 0xffff);
7796 operands[1] = gen_lowpart (mode, operands[1]);
7798 return "movz{bl|x}\t{%1, %0|%0, %1}";
7800 return "movz{wl|x}\t{%1, %0|%0, %1}";
7804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805 return "and{l}\t{%2, %0|%0, %2}";
7808 [(set_attr "type" "alu,alu,imovx")
7809 (set (attr "prefix_rex")
7811 (and (eq_attr "type" "imovx")
7812 (and (match_test "INTVAL (operands[2]) == 0xff")
7813 (match_operand 1 "ext_QIreg_operand" "")))
7815 (const_string "*")))
7816 (set_attr "length_immediate" "*,*,0")
7817 (set_attr "mode" "SI")])
7819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7820 (define_insn "*andsi_1_zext"
7821 [(set (match_operand:DI 0 "register_operand" "=r")
7823 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7824 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7825 (clobber (reg:CC FLAGS_REG))]
7826 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7827 "and{l}\t{%2, %k0|%k0, %2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "SI")])
7831 (define_insn "*andhi_1"
7832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7833 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7834 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "ix86_binary_operator_ok (AND, HImode, operands)"
7838 switch (get_attr_type (insn))
7841 gcc_assert (CONST_INT_P (operands[2]));
7842 gcc_assert (INTVAL (operands[2]) == 0xff);
7843 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848 return "and{w}\t{%2, %0|%0, %2}";
7851 [(set_attr "type" "alu,alu,imovx")
7852 (set_attr "length_immediate" "*,*,0")
7853 (set (attr "prefix_rex")
7855 (and (eq_attr "type" "imovx")
7856 (match_operand 1 "ext_QIreg_operand" ""))
7858 (const_string "*")))
7859 (set_attr "mode" "HI,HI,SI")])
7861 ;; %%% Potential partial reg stall on alternative 2. What to do?
7862 (define_insn "*andqi_1"
7863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7864 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7865 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "ix86_binary_operator_ok (AND, QImode, operands)"
7869 and{b}\t{%2, %0|%0, %2}
7870 and{b}\t{%2, %0|%0, %2}
7871 and{l}\t{%k2, %k0|%k0, %k2}"
7872 [(set_attr "type" "alu")
7873 (set_attr "mode" "QI,QI,SI")])
7875 (define_insn "*andqi_1_slp"
7876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7877 (and:QI (match_dup 0)
7878 (match_operand:QI 1 "general_operand" "qn,qmn")))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7882 "and{b}\t{%1, %0|%0, %1}"
7883 [(set_attr "type" "alu1")
7884 (set_attr "mode" "QI")])
7887 [(set (match_operand 0 "register_operand" "")
7889 (const_int -65536)))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7892 || optimize_function_for_size_p (cfun)"
7893 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7894 "operands[1] = gen_lowpart (HImode, operands[0]);")
7897 [(set (match_operand 0 "ext_register_operand" "")
7900 (clobber (reg:CC FLAGS_REG))]
7901 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7902 && reload_completed"
7903 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7904 "operands[1] = gen_lowpart (QImode, operands[0]);")
7907 [(set (match_operand 0 "ext_register_operand" "")
7909 (const_int -65281)))
7910 (clobber (reg:CC FLAGS_REG))]
7911 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7912 && reload_completed"
7913 [(parallel [(set (zero_extract:SI (match_dup 0)
7917 (zero_extract:SI (match_dup 0)
7920 (zero_extract:SI (match_dup 0)
7923 (clobber (reg:CC FLAGS_REG))])]
7924 "operands[0] = gen_lowpart (SImode, operands[0]);")
7926 (define_insn "*anddi_2"
7927 [(set (reg FLAGS_REG)
7930 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7931 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7934 (and:DI (match_dup 1) (match_dup 2)))]
7935 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7936 && ix86_binary_operator_ok (AND, DImode, operands)"
7938 and{l}\t{%k2, %k0|%k0, %k2}
7939 and{q}\t{%2, %0|%0, %2}
7940 and{q}\t{%2, %0|%0, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "SI,DI,DI")])
7944 (define_insn "*andqi_2_maybe_si"
7945 [(set (reg FLAGS_REG)
7947 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7948 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7951 (and:QI (match_dup 1) (match_dup 2)))]
7952 "ix86_binary_operator_ok (AND, QImode, operands)
7953 && ix86_match_ccmode (insn,
7954 CONST_INT_P (operands[2])
7955 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 if (which_alternative == 2)
7959 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7960 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7961 return "and{l}\t{%2, %k0|%k0, %2}";
7963 return "and{b}\t{%2, %0|%0, %2}";
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "QI,QI,SI")])
7968 (define_insn "*and<mode>_2"
7969 [(set (reg FLAGS_REG)
7970 (compare (and:SWI124
7971 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7972 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7975 (and:SWI124 (match_dup 1) (match_dup 2)))]
7976 "ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7978 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "<MODE>")])
7982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7983 (define_insn "*andsi_2_zext"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:SI 1 "nonimmediate_operand" "%0")
7987 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989 (set (match_operand:DI 0 "register_operand" "=r")
7990 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7991 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992 && ix86_binary_operator_ok (AND, SImode, operands)"
7993 "and{l}\t{%2, %k0|%k0, %2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "SI")])
7997 (define_insn "*andqi_2_slp"
7998 [(set (reg FLAGS_REG)
8000 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8001 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003 (set (strict_low_part (match_dup 0))
8004 (and:QI (match_dup 0) (match_dup 1)))]
8005 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006 && ix86_match_ccmode (insn, CCNOmode)
8007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008 "and{b}\t{%1, %0|%0, %1}"
8009 [(set_attr "type" "alu1")
8010 (set_attr "mode" "QI")])
8012 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8013 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8014 ;; for a QImode operand, which of course failed.
8015 (define_insn "andqi_ext_0"
8016 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8021 (match_operand 1 "ext_register_operand" "0")
8024 (match_operand 2 "const_int_operand" "n")))
8025 (clobber (reg:CC FLAGS_REG))]
8027 "and{b}\t{%2, %h0|%h0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "length_immediate" "1")
8030 (set_attr "modrm" "1")
8031 (set_attr "mode" "QI")])
8033 ;; Generated by peephole translating test to and. This shows up
8034 ;; often in fp comparisons.
8035 (define_insn "*andqi_ext_0_cc"
8036 [(set (reg FLAGS_REG)
8040 (match_operand 1 "ext_register_operand" "0")
8043 (match_operand 2 "const_int_operand" "n"))
8045 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8054 "ix86_match_ccmode (insn, CCNOmode)"
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8061 (define_insn "*andqi_ext_1_rex64"
8062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8067 (match_operand 1 "ext_register_operand" "0")
8071 (match_operand 2 "ext_register_operand" "Q"))))
8072 (clobber (reg:CC FLAGS_REG))]
8074 "and{b}\t{%2, %h0|%h0, %2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_1"
8080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8085 (match_operand 1 "ext_register_operand" "0")
8089 (match_operand:QI 2 "general_operand" "Qm"))))
8090 (clobber (reg:CC FLAGS_REG))]
8092 "and{b}\t{%2, %h0|%h0, %2}"
8093 [(set_attr "type" "alu")
8094 (set_attr "length_immediate" "0")
8095 (set_attr "mode" "QI")])
8097 (define_insn "*andqi_ext_2"
8098 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8103 (match_operand 1 "ext_register_operand" "%0")
8107 (match_operand 2 "ext_register_operand" "Q")
8110 (clobber (reg:CC FLAGS_REG))]
8112 "and{b}\t{%h2, %h0|%h0, %h2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "length_immediate" "0")
8115 (set_attr "mode" "QI")])
8117 ;; Convert wide AND instructions with immediate operand to shorter QImode
8118 ;; equivalents when possible.
8119 ;; Don't do the splitting with memory operands, since it introduces risk
8120 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8121 ;; for size, but that can (should?) be handled by generic code instead.
8123 [(set (match_operand 0 "register_operand" "")
8124 (and (match_operand 1 "register_operand" "")
8125 (match_operand 2 "const_int_operand" "")))
8126 (clobber (reg:CC FLAGS_REG))]
8128 && QI_REG_P (operands[0])
8129 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8130 && !(~INTVAL (operands[2]) & ~(255 << 8))
8131 && GET_MODE (operands[0]) != QImode"
8132 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8133 (and:SI (zero_extract:SI (match_dup 1)
8134 (const_int 8) (const_int 8))
8136 (clobber (reg:CC FLAGS_REG))])]
8137 "operands[0] = gen_lowpart (SImode, operands[0]);
8138 operands[1] = gen_lowpart (SImode, operands[1]);
8139 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8141 ;; Since AND can be encoded with sign extended immediate, this is only
8142 ;; profitable when 7th bit is not set.
8144 [(set (match_operand 0 "register_operand" "")
8145 (and (match_operand 1 "general_operand" "")
8146 (match_operand 2 "const_int_operand" "")))
8147 (clobber (reg:CC FLAGS_REG))]
8149 && ANY_QI_REG_P (operands[0])
8150 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8151 && !(~INTVAL (operands[2]) & ~255)
8152 && !(INTVAL (operands[2]) & 128)
8153 && GET_MODE (operands[0]) != QImode"
8154 [(parallel [(set (strict_low_part (match_dup 0))
8155 (and:QI (match_dup 1)
8157 (clobber (reg:CC FLAGS_REG))])]
8158 "operands[0] = gen_lowpart (QImode, operands[0]);
8159 operands[1] = gen_lowpart (QImode, operands[1]);
8160 operands[2] = gen_lowpart (QImode, operands[2]);")
8162 ;; Logical inclusive and exclusive OR instructions
8164 ;; %%% This used to optimize known byte-wide and operations to memory.
8165 ;; If this is considered useful, it should be done with splitters.
8167 (define_expand "<code><mode>3"
8168 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8169 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8170 (match_operand:SWIM 2 "<general_operand>" "")))]
8172 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8174 (define_insn "*<code><mode>_1"
8175 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8177 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8178 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8181 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "<MODE>")])
8185 ;; %%% Potential partial reg stall on alternative 2. What to do?
8186 (define_insn "*<code>qi_1"
8187 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8188 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8189 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8193 <logic>{b}\t{%2, %0|%0, %2}
8194 <logic>{b}\t{%2, %0|%0, %2}
8195 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "mode" "QI,QI,SI")])
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*<code>si_1_zext"
8201 [(set (match_operand:DI 0 "register_operand" "=r")
8203 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*<code>si_1_zext_imm"
8212 [(set (match_operand:DI 0 "register_operand" "=r")
8214 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8215 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8218 "<logic>{l}\t{%2, %k0|%k0, %2}"
8219 [(set_attr "type" "alu")
8220 (set_attr "mode" "SI")])
8222 (define_insn "*<code>qi_1_slp"
8223 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8224 (any_or:QI (match_dup 0)
8225 (match_operand:QI 1 "general_operand" "qmn,qn")))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8229 "<logic>{b}\t{%1, %0|%0, %1}"
8230 [(set_attr "type" "alu1")
8231 (set_attr "mode" "QI")])
8233 (define_insn "*<code><mode>_2"
8234 [(set (reg FLAGS_REG)
8235 (compare (any_or:SWI
8236 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8237 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8240 (any_or:SWI (match_dup 1) (match_dup 2)))]
8241 "ix86_match_ccmode (insn, CCNOmode)
8242 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8243 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "<MODE>")])
8247 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8248 ;; ??? Special case for immediate operand is missing - it is tricky.
8249 (define_insn "*<code>si_2_zext"
8250 [(set (reg FLAGS_REG)
8251 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8252 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8254 (set (match_operand:DI 0 "register_operand" "=r")
8255 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8256 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8257 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8258 "<logic>{l}\t{%2, %k0|%k0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "SI")])
8262 (define_insn "*<code>si_2_zext_imm"
8263 [(set (reg FLAGS_REG)
8265 (match_operand:SI 1 "nonimmediate_operand" "%0")
8266 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8268 (set (match_operand:DI 0 "register_operand" "=r")
8269 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8270 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8271 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8272 "<logic>{l}\t{%2, %k0|%k0, %2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "SI")])
8276 (define_insn "*<code>qi_2_slp"
8277 [(set (reg FLAGS_REG)
8278 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8279 (match_operand:QI 1 "general_operand" "qmn,qn"))
8281 (set (strict_low_part (match_dup 0))
8282 (any_or:QI (match_dup 0) (match_dup 1)))]
8283 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8284 && ix86_match_ccmode (insn, CCNOmode)
8285 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8286 "<logic>{b}\t{%1, %0|%0, %1}"
8287 [(set_attr "type" "alu1")
8288 (set_attr "mode" "QI")])
8290 (define_insn "*<code><mode>_3"
8291 [(set (reg FLAGS_REG)
8292 (compare (any_or:SWI
8293 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8294 (match_operand:SWI 2 "<general_operand>" "<g>"))
8296 (clobber (match_scratch:SWI 0 "=<r>"))]
8297 "ix86_match_ccmode (insn, CCNOmode)
8298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8300 [(set_attr "type" "alu")
8301 (set_attr "mode" "<MODE>")])
8303 (define_insn "*<code>qi_ext_0"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (match_operand 1 "ext_register_operand" "0")
8312 (match_operand 2 "const_int_operand" "n")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8315 "<logic>{b}\t{%2, %h0|%h0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "length_immediate" "1")
8318 (set_attr "modrm" "1")
8319 (set_attr "mode" "QI")])
8321 (define_insn "*<code>qi_ext_1_rex64"
8322 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327 (match_operand 1 "ext_register_operand" "0")
8331 (match_operand 2 "ext_register_operand" "Q"))))
8332 (clobber (reg:CC FLAGS_REG))]
8334 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8335 "<logic>{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "0")
8338 (set_attr "mode" "QI")])
8340 (define_insn "*<code>qi_ext_1"
8341 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8346 (match_operand 1 "ext_register_operand" "0")
8350 (match_operand:QI 2 "general_operand" "Qm"))))
8351 (clobber (reg:CC FLAGS_REG))]
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8354 "<logic>{b}\t{%2, %h0|%h0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "length_immediate" "0")
8357 (set_attr "mode" "QI")])
8359 (define_insn "*<code>qi_ext_2"
8360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8367 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8370 (clobber (reg:CC FLAGS_REG))]
8371 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8372 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8373 [(set_attr "type" "alu")
8374 (set_attr "length_immediate" "0")
8375 (set_attr "mode" "QI")])
8378 [(set (match_operand 0 "register_operand" "")
8379 (any_or (match_operand 1 "register_operand" "")
8380 (match_operand 2 "const_int_operand" "")))
8381 (clobber (reg:CC FLAGS_REG))]
8383 && QI_REG_P (operands[0])
8384 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8385 && !(INTVAL (operands[2]) & ~(255 << 8))
8386 && GET_MODE (operands[0]) != QImode"
8387 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8388 (any_or:SI (zero_extract:SI (match_dup 1)
8389 (const_int 8) (const_int 8))
8391 (clobber (reg:CC FLAGS_REG))])]
8392 "operands[0] = gen_lowpart (SImode, operands[0]);
8393 operands[1] = gen_lowpart (SImode, operands[1]);
8394 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8396 ;; Since OR can be encoded with sign extended immediate, this is only
8397 ;; profitable when 7th bit is set.
8399 [(set (match_operand 0 "register_operand" "")
8400 (any_or (match_operand 1 "general_operand" "")
8401 (match_operand 2 "const_int_operand" "")))
8402 (clobber (reg:CC FLAGS_REG))]
8404 && ANY_QI_REG_P (operands[0])
8405 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8406 && !(INTVAL (operands[2]) & ~255)
8407 && (INTVAL (operands[2]) & 128)
8408 && GET_MODE (operands[0]) != QImode"
8409 [(parallel [(set (strict_low_part (match_dup 0))
8410 (any_or:QI (match_dup 1)
8412 (clobber (reg:CC FLAGS_REG))])]
8413 "operands[0] = gen_lowpart (QImode, operands[0]);
8414 operands[1] = gen_lowpart (QImode, operands[1]);
8415 operands[2] = gen_lowpart (QImode, operands[2]);")
8417 (define_expand "xorqi_cc_ext_1"
8419 (set (reg:CCNO FLAGS_REG)
8423 (match_operand 1 "ext_register_operand" "")
8426 (match_operand:QI 2 "general_operand" ""))
8428 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8438 (define_insn "*xorqi_cc_ext_1_rex64"
8439 [(set (reg FLAGS_REG)
8443 (match_operand 1 "ext_register_operand" "0")
8446 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8448 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8458 "xor{b}\t{%2, %h0|%h0, %2}"
8459 [(set_attr "type" "alu")
8460 (set_attr "modrm" "1")
8461 (set_attr "mode" "QI")])
8463 (define_insn "*xorqi_cc_ext_1"
8464 [(set (reg FLAGS_REG)
8468 (match_operand 1 "ext_register_operand" "0")
8471 (match_operand:QI 2 "general_operand" "qmn"))
8473 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8482 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8483 "xor{b}\t{%2, %h0|%h0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "modrm" "1")
8486 (set_attr "mode" "QI")])
8488 ;; Negation instructions
8490 (define_expand "neg<mode>2"
8491 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8492 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8494 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8496 (define_insn_and_split "*neg<dwi>2_doubleword"
8497 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8498 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8499 (clobber (reg:CC FLAGS_REG))]
8500 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8504 [(set (reg:CCZ FLAGS_REG)
8505 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8506 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8509 (plus:DWIH (match_dup 3)
8510 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8512 (clobber (reg:CC FLAGS_REG))])
8515 (neg:DWIH (match_dup 2)))
8516 (clobber (reg:CC FLAGS_REG))])]
8517 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8519 (define_insn "*neg<mode>2_1"
8520 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8521 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8524 "neg{<imodesuffix>}\t%0"
8525 [(set_attr "type" "negnot")
8526 (set_attr "mode" "<MODE>")])
8528 ;; Combine is quite creative about this pattern.
8529 (define_insn "*negsi2_1_zext"
8530 [(set (match_operand:DI 0 "register_operand" "=r")
8532 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8538 [(set_attr "type" "negnot")
8539 (set_attr "mode" "SI")])
8541 ;; The problem with neg is that it does not perform (compare x 0),
8542 ;; it really performs (compare 0 x), which leaves us with the zero
8543 ;; flag being the only useful item.
8545 (define_insn "*neg<mode>2_cmpz"
8546 [(set (reg:CCZ FLAGS_REG)
8548 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8550 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8551 (neg:SWI (match_dup 1)))]
8552 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8553 "neg{<imodesuffix>}\t%0"
8554 [(set_attr "type" "negnot")
8555 (set_attr "mode" "<MODE>")])
8557 (define_insn "*negsi2_cmpz_zext"
8558 [(set (reg:CCZ FLAGS_REG)
8562 (match_operand:DI 1 "register_operand" "0")
8566 (set (match_operand:DI 0 "register_operand" "=r")
8567 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8570 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8572 [(set_attr "type" "negnot")
8573 (set_attr "mode" "SI")])
8575 ;; Changing of sign for FP values is doable using integer unit too.
8577 (define_expand "<code><mode>2"
8578 [(set (match_operand:X87MODEF 0 "register_operand" "")
8579 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8580 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8581 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8583 (define_insn "*absneg<mode>2_mixed"
8584 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8585 (match_operator:MODEF 3 "absneg_operator"
8586 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8587 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8592 (define_insn "*absneg<mode>2_sse"
8593 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8594 (match_operator:MODEF 3 "absneg_operator"
8595 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8596 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8601 (define_insn "*absneg<mode>2_i387"
8602 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8603 (match_operator:X87MODEF 3 "absneg_operator"
8604 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8605 (use (match_operand 2 "" ""))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8610 (define_expand "<code>tf2"
8611 [(set (match_operand:TF 0 "register_operand" "")
8612 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8614 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8616 (define_insn "*absnegtf2_sse"
8617 [(set (match_operand:TF 0 "register_operand" "=x,x")
8618 (match_operator:TF 3 "absneg_operator"
8619 [(match_operand:TF 1 "register_operand" "0,x")]))
8620 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8621 (clobber (reg:CC FLAGS_REG))]
8625 ;; Splitters for fp abs and neg.
8628 [(set (match_operand 0 "fp_register_operand" "")
8629 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8630 (use (match_operand 2 "" ""))
8631 (clobber (reg:CC FLAGS_REG))]
8633 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8636 [(set (match_operand 0 "register_operand" "")
8637 (match_operator 3 "absneg_operator"
8638 [(match_operand 1 "register_operand" "")]))
8639 (use (match_operand 2 "nonimmediate_operand" ""))
8640 (clobber (reg:CC FLAGS_REG))]
8641 "reload_completed && SSE_REG_P (operands[0])"
8642 [(set (match_dup 0) (match_dup 3))]
8644 enum machine_mode mode = GET_MODE (operands[0]);
8645 enum machine_mode vmode = GET_MODE (operands[2]);
8648 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8649 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8650 if (operands_match_p (operands[0], operands[2]))
8653 operands[1] = operands[2];
8656 if (GET_CODE (operands[3]) == ABS)
8657 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8659 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8664 [(set (match_operand:SF 0 "register_operand" "")
8665 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8666 (use (match_operand:V4SF 2 "" ""))
8667 (clobber (reg:CC FLAGS_REG))]
8669 [(parallel [(set (match_dup 0) (match_dup 1))
8670 (clobber (reg:CC FLAGS_REG))])]
8673 operands[0] = gen_lowpart (SImode, operands[0]);
8674 if (GET_CODE (operands[1]) == ABS)
8676 tmp = gen_int_mode (0x7fffffff, SImode);
8677 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8681 tmp = gen_int_mode (0x80000000, SImode);
8682 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8688 [(set (match_operand:DF 0 "register_operand" "")
8689 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8690 (use (match_operand 2 "" ""))
8691 (clobber (reg:CC FLAGS_REG))]
8693 [(parallel [(set (match_dup 0) (match_dup 1))
8694 (clobber (reg:CC FLAGS_REG))])]
8699 tmp = gen_lowpart (DImode, operands[0]);
8700 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8703 if (GET_CODE (operands[1]) == ABS)
8706 tmp = gen_rtx_NOT (DImode, tmp);
8710 operands[0] = gen_highpart (SImode, operands[0]);
8711 if (GET_CODE (operands[1]) == ABS)
8713 tmp = gen_int_mode (0x7fffffff, SImode);
8714 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8718 tmp = gen_int_mode (0x80000000, SImode);
8719 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8726 [(set (match_operand:XF 0 "register_operand" "")
8727 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8728 (use (match_operand 2 "" ""))
8729 (clobber (reg:CC FLAGS_REG))]
8731 [(parallel [(set (match_dup 0) (match_dup 1))
8732 (clobber (reg:CC FLAGS_REG))])]
8735 operands[0] = gen_rtx_REG (SImode,
8736 true_regnum (operands[0])
8737 + (TARGET_64BIT ? 1 : 2));
8738 if (GET_CODE (operands[1]) == ABS)
8740 tmp = GEN_INT (0x7fff);
8741 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8745 tmp = GEN_INT (0x8000);
8746 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8751 ;; Conditionalize these after reload. If they match before reload, we
8752 ;; lose the clobber and ability to use integer instructions.
8754 (define_insn "*<code><mode>2_1"
8755 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8756 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8758 && (reload_completed
8759 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8760 "f<absneg_mnemonic>"
8761 [(set_attr "type" "fsgn")
8762 (set_attr "mode" "<MODE>")])
8764 (define_insn "*<code>extendsfdf2"
8765 [(set (match_operand:DF 0 "register_operand" "=f")
8766 (absneg:DF (float_extend:DF
8767 (match_operand:SF 1 "register_operand" "0"))))]
8768 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8769 "f<absneg_mnemonic>"
8770 [(set_attr "type" "fsgn")
8771 (set_attr "mode" "DF")])
8773 (define_insn "*<code>extendsfxf2"
8774 [(set (match_operand:XF 0 "register_operand" "=f")
8775 (absneg:XF (float_extend:XF
8776 (match_operand:SF 1 "register_operand" "0"))))]
8778 "f<absneg_mnemonic>"
8779 [(set_attr "type" "fsgn")
8780 (set_attr "mode" "XF")])
8782 (define_insn "*<code>extenddfxf2"
8783 [(set (match_operand:XF 0 "register_operand" "=f")
8784 (absneg:XF (float_extend:XF
8785 (match_operand:DF 1 "register_operand" "0"))))]
8787 "f<absneg_mnemonic>"
8788 [(set_attr "type" "fsgn")
8789 (set_attr "mode" "XF")])
8791 ;; Copysign instructions
8793 (define_mode_iterator CSGNMODE [SF DF TF])
8794 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8796 (define_expand "copysign<mode>3"
8797 [(match_operand:CSGNMODE 0 "register_operand" "")
8798 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8799 (match_operand:CSGNMODE 2 "register_operand" "")]
8800 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8801 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8802 "ix86_expand_copysign (operands); DONE;")
8804 (define_insn_and_split "copysign<mode>3_const"
8805 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8807 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8808 (match_operand:CSGNMODE 2 "register_operand" "0")
8809 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8811 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8812 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8814 "&& reload_completed"
8816 "ix86_split_copysign_const (operands); DONE;")
8818 (define_insn "copysign<mode>3_var"
8819 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8821 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8822 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8823 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8824 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8826 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8827 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8828 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8832 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8834 [(match_operand:CSGNMODE 2 "register_operand" "")
8835 (match_operand:CSGNMODE 3 "register_operand" "")
8836 (match_operand:<CSGNVMODE> 4 "" "")
8837 (match_operand:<CSGNVMODE> 5 "" "")]
8839 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8840 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8841 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8842 && reload_completed"
8844 "ix86_split_copysign_var (operands); DONE;")
8846 ;; One complement instructions
8848 (define_expand "one_cmpl<mode>2"
8849 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8850 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8852 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8854 (define_insn "*one_cmpl<mode>2_1"
8855 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8856 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8857 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8858 "not{<imodesuffix>}\t%0"
8859 [(set_attr "type" "negnot")
8860 (set_attr "mode" "<MODE>")])
8862 ;; %%% Potential partial reg stall on alternative 1. What to do?
8863 (define_insn "*one_cmplqi2_1"
8864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8865 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8866 "ix86_unary_operator_ok (NOT, QImode, operands)"
8870 [(set_attr "type" "negnot")
8871 (set_attr "mode" "QI,SI")])
8873 ;; ??? Currently never generated - xor is used instead.
8874 (define_insn "*one_cmplsi2_1_zext"
8875 [(set (match_operand:DI 0 "register_operand" "=r")
8877 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8878 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8880 [(set_attr "type" "negnot")
8881 (set_attr "mode" "SI")])
8883 (define_insn "*one_cmpl<mode>2_2"
8884 [(set (reg FLAGS_REG)
8885 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8887 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8888 (not:SWI (match_dup 1)))]
8889 "ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8892 [(set_attr "type" "alu1")
8893 (set_attr "mode" "<MODE>")])
8896 [(set (match_operand 0 "flags_reg_operand" "")
8897 (match_operator 2 "compare_operator"
8898 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8900 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8901 (not:SWI (match_dup 3)))]
8902 "ix86_match_ccmode (insn, CCNOmode)"
8903 [(parallel [(set (match_dup 0)
8904 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8907 (xor:SWI (match_dup 3) (const_int -1)))])])
8909 ;; ??? Currently never generated - xor is used instead.
8910 (define_insn "*one_cmplsi2_2_zext"
8911 [(set (reg FLAGS_REG)
8912 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8914 (set (match_operand:DI 0 "register_operand" "=r")
8915 (zero_extend:DI (not:SI (match_dup 1))))]
8916 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8917 && ix86_unary_operator_ok (NOT, SImode, operands)"
8919 [(set_attr "type" "alu1")
8920 (set_attr "mode" "SI")])
8923 [(set (match_operand 0 "flags_reg_operand" "")
8924 (match_operator 2 "compare_operator"
8925 [(not:SI (match_operand:SI 3 "register_operand" ""))
8927 (set (match_operand:DI 1 "register_operand" "")
8928 (zero_extend:DI (not:SI (match_dup 3))))]
8929 "ix86_match_ccmode (insn, CCNOmode)"
8930 [(parallel [(set (match_dup 0)
8931 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8934 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8936 ;; Shift instructions
8938 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8939 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8940 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8941 ;; from the assembler input.
8943 ;; This instruction shifts the target reg/mem as usual, but instead of
8944 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8945 ;; is a left shift double, bits are taken from the high order bits of
8946 ;; reg, else if the insn is a shift right double, bits are taken from the
8947 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8948 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8950 ;; Since sh[lr]d does not change the `reg' operand, that is done
8951 ;; separately, making all shifts emit pairs of shift double and normal
8952 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8953 ;; support a 63 bit shift, each shift where the count is in a reg expands
8954 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8956 ;; If the shift count is a constant, we need never emit more than one
8957 ;; shift pair, instead using moves and sign extension for counts greater
8960 (define_expand "ashl<mode>3"
8961 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8962 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8963 (match_operand:QI 2 "nonmemory_operand" "")))]
8965 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8967 (define_insn "*ashl<mode>3_doubleword"
8968 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8969 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8970 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8971 (clobber (reg:CC FLAGS_REG))]
8974 [(set_attr "type" "multi")])
8977 [(set (match_operand:DWI 0 "register_operand" "")
8978 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8979 (match_operand:QI 2 "nonmemory_operand" "")))
8980 (clobber (reg:CC FLAGS_REG))]
8981 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8983 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8985 ;; By default we don't ask for a scratch register, because when DWImode
8986 ;; values are manipulated, registers are already at a premium. But if
8987 ;; we have one handy, we won't turn it away.
8990 [(match_scratch:DWIH 3 "r")
8991 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8993 (match_operand:<DWI> 1 "nonmemory_operand" "")
8994 (match_operand:QI 2 "nonmemory_operand" "")))
8995 (clobber (reg:CC FLAGS_REG))])
8999 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9001 (define_insn "x86_64_shld"
9002 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9003 (ior:DI (ashift:DI (match_dup 0)
9004 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9005 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9006 (minus:QI (const_int 64) (match_dup 2)))))
9007 (clobber (reg:CC FLAGS_REG))]
9009 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9010 [(set_attr "type" "ishift")
9011 (set_attr "prefix_0f" "1")
9012 (set_attr "mode" "DI")
9013 (set_attr "athlon_decode" "vector")
9014 (set_attr "amdfam10_decode" "vector")
9015 (set_attr "bdver1_decode" "vector")])
9017 (define_insn "x86_shld"
9018 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9019 (ior:SI (ashift:SI (match_dup 0)
9020 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9021 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9022 (minus:QI (const_int 32) (match_dup 2)))))
9023 (clobber (reg:CC FLAGS_REG))]
9025 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9026 [(set_attr "type" "ishift")
9027 (set_attr "prefix_0f" "1")
9028 (set_attr "mode" "SI")
9029 (set_attr "pent_pair" "np")
9030 (set_attr "athlon_decode" "vector")
9031 (set_attr "amdfam10_decode" "vector")
9032 (set_attr "bdver1_decode" "vector")])
9034 (define_expand "x86_shift<mode>_adj_1"
9035 [(set (reg:CCZ FLAGS_REG)
9036 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9039 (set (match_operand:SWI48 0 "register_operand" "")
9040 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9041 (match_operand:SWI48 1 "register_operand" "")
9044 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9045 (match_operand:SWI48 3 "register_operand" "r")
9048 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9050 (define_expand "x86_shift<mode>_adj_2"
9051 [(use (match_operand:SWI48 0 "register_operand" ""))
9052 (use (match_operand:SWI48 1 "register_operand" ""))
9053 (use (match_operand:QI 2 "register_operand" ""))]
9056 rtx label = gen_label_rtx ();
9059 emit_insn (gen_testqi_ccz_1 (operands[2],
9060 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9062 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9063 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9064 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9065 gen_rtx_LABEL_REF (VOIDmode, label),
9067 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9068 JUMP_LABEL (tmp) = label;
9070 emit_move_insn (operands[0], operands[1]);
9071 ix86_expand_clear (operands[1]);
9074 LABEL_NUSES (label) = 1;
9079 ;; Avoid useless masking of count operand.
9080 (define_insn_and_split "*ashl<mode>3_mask"
9081 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9083 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9086 (match_operand:SI 2 "nonimmediate_operand" "c")
9087 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9090 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9091 == GET_MODE_BITSIZE (<MODE>mode)-1"
9094 [(parallel [(set (match_dup 0)
9095 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9096 (clobber (reg:CC FLAGS_REG))])]
9098 if (can_create_pseudo_p ())
9099 operands [2] = force_reg (SImode, operands[2]);
9101 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9103 [(set_attr "type" "ishift")
9104 (set_attr "mode" "<MODE>")])
9106 (define_insn "*bmi2_ashl<mode>3_1"
9107 [(set (match_operand:SWI48 0 "register_operand" "=r")
9108 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9109 (match_operand:SWI48 2 "register_operand" "r")))]
9111 "shlx\t{%2, %1, %0|%0, %1, %2}"
9112 [(set_attr "type" "ishiftx")
9113 (set_attr "mode" "<MODE>")])
9115 (define_insn "*ashl<mode>3_1"
9116 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9117 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9118 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9122 switch (get_attr_type (insn))
9129 gcc_assert (operands[2] == const1_rtx);
9130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9131 return "add{<imodesuffix>}\t%0, %0";
9134 if (operands[2] == const1_rtx
9135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9136 return "sal{<imodesuffix>}\t%0";
9138 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9141 [(set_attr "isa" "*,*,bmi2")
9143 (cond [(eq_attr "alternative" "1")
9144 (const_string "lea")
9145 (eq_attr "alternative" "2")
9146 (const_string "ishiftx")
9147 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9148 (match_operand 0 "register_operand" ""))
9149 (match_operand 2 "const1_operand" ""))
9150 (const_string "alu")
9152 (const_string "ishift")))
9153 (set (attr "length_immediate")
9155 (ior (eq_attr "type" "alu")
9156 (and (eq_attr "type" "ishift")
9157 (and (match_operand 2 "const1_operand" "")
9158 (ior (match_test "TARGET_SHIFT1")
9159 (match_test "optimize_function_for_size_p (cfun)")))))
9161 (const_string "*")))
9162 (set_attr "mode" "<MODE>")])
9164 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9166 [(set (match_operand:SWI48 0 "register_operand" "")
9167 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9168 (match_operand:QI 2 "register_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_BMI2 && reload_completed"
9172 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9173 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9175 (define_insn "*bmi2_ashlsi3_1_zext"
9176 [(set (match_operand:DI 0 "register_operand" "=r")
9178 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9179 (match_operand:SI 2 "register_operand" "r"))))]
9180 "TARGET_64BIT && TARGET_BMI2"
9181 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9182 [(set_attr "type" "ishiftx")
9183 (set_attr "mode" "SI")])
9185 (define_insn "*ashlsi3_1_zext"
9186 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9188 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9189 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9193 switch (get_attr_type (insn))
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{l}\t%k0, %k0";
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{l}\t%k0";
9208 return "sal{l}\t{%2, %k0|%k0, %2}";
9211 [(set_attr "isa" "*,*,bmi2")
9213 (cond [(eq_attr "alternative" "1")
9214 (const_string "lea")
9215 (eq_attr "alternative" "2")
9216 (const_string "ishiftx")
9217 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9218 (match_operand 2 "const1_operand" ""))
9219 (const_string "alu")
9221 (const_string "ishift")))
9222 (set (attr "length_immediate")
9224 (ior (eq_attr "type" "alu")
9225 (and (eq_attr "type" "ishift")
9226 (and (match_operand 2 "const1_operand" "")
9227 (ior (match_test "TARGET_SHIFT1")
9228 (match_test "optimize_function_for_size_p (cfun)")))))
9230 (const_string "*")))
9231 (set_attr "mode" "SI")])
9233 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9235 [(set (match_operand:DI 0 "register_operand" "")
9237 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9238 (match_operand:QI 2 "register_operand" ""))))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9242 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9243 "operands[2] = gen_lowpart (SImode, operands[2]);")
9245 (define_insn "*ashlhi3_1"
9246 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9247 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9248 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 return "add{w}\t%0, %0";
9262 if (operands[2] == const1_rtx
9263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9264 return "sal{w}\t%0";
9266 return "sal{w}\t{%2, %0|%0, %2}";
9270 (cond [(eq_attr "alternative" "1")
9271 (const_string "lea")
9272 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ior (match_test "TARGET_SHIFT1")
9284 (match_test "optimize_function_for_size_p (cfun)")))))
9286 (const_string "*")))
9287 (set_attr "mode" "HI,SI")])
9289 ;; %%% Potential partial reg stall on alternative 1. What to do?
9290 (define_insn "*ashlqi3_1"
9291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9292 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9293 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9297 switch (get_attr_type (insn))
9303 gcc_assert (operands[2] == const1_rtx);
9304 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9305 return "add{l}\t%k0, %k0";
9307 return "add{b}\t%0, %0";
9310 if (operands[2] == const1_rtx
9311 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313 if (get_attr_mode (insn) == MODE_SI)
9314 return "sal{l}\t%k0";
9316 return "sal{b}\t%0";
9320 if (get_attr_mode (insn) == MODE_SI)
9321 return "sal{l}\t{%2, %k0|%k0, %2}";
9323 return "sal{b}\t{%2, %0|%0, %2}";
9328 (cond [(eq_attr "alternative" "2")
9329 (const_string "lea")
9330 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9331 (match_operand 0 "register_operand" ""))
9332 (match_operand 2 "const1_operand" ""))
9333 (const_string "alu")
9335 (const_string "ishift")))
9336 (set (attr "length_immediate")
9338 (ior (eq_attr "type" "alu")
9339 (and (eq_attr "type" "ishift")
9340 (and (match_operand 2 "const1_operand" "")
9341 (ior (match_test "TARGET_SHIFT1")
9342 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "*")))
9345 (set_attr "mode" "QI,SI,SI")])
9347 (define_insn "*ashlqi3_1_slp"
9348 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9349 (ashift:QI (match_dup 0)
9350 (match_operand:QI 1 "nonmemory_operand" "cI")))
9351 (clobber (reg:CC FLAGS_REG))]
9352 "(optimize_function_for_size_p (cfun)
9353 || !TARGET_PARTIAL_FLAG_REG_STALL
9354 || (operands[1] == const1_rtx
9356 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9358 switch (get_attr_type (insn))
9361 gcc_assert (operands[1] == const1_rtx);
9362 return "add{b}\t%0, %0";
9365 if (operands[1] == const1_rtx
9366 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9367 return "sal{b}\t%0";
9369 return "sal{b}\t{%1, %0|%0, %1}";
9373 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9374 (match_operand 0 "register_operand" ""))
9375 (match_operand 1 "const1_operand" ""))
9376 (const_string "alu")
9378 (const_string "ishift1")))
9379 (set (attr "length_immediate")
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift1")
9383 (and (match_operand 1 "const1_operand" "")
9384 (ior (match_test "TARGET_SHIFT1")
9385 (match_test "optimize_function_for_size_p (cfun)")))))
9387 (const_string "*")))
9388 (set_attr "mode" "QI")])
9390 ;; Convert ashift to the lea pattern to avoid flags dependency.
9392 [(set (match_operand 0 "register_operand" "")
9393 (ashift (match_operand 1 "index_register_operand" "")
9394 (match_operand:QI 2 "const_int_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9398 && true_regnum (operands[0]) != true_regnum (operands[1])"
9401 enum machine_mode mode = GET_MODE (operands[0]);
9404 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9407 operands[0] = gen_lowpart (mode, operands[0]);
9408 operands[1] = gen_lowpart (mode, operands[1]);
9411 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9413 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9419 ;; Convert ashift to the lea pattern to avoid flags dependency.
9421 [(set (match_operand:DI 0 "register_operand" "")
9423 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424 (match_operand:QI 2 "const_int_operand" ""))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && reload_completed
9427 && true_regnum (operands[0]) != true_regnum (operands[1])"
9429 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 operands[1] = gen_lowpart (DImode, operands[1]);
9432 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags. We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439 [(set (reg FLAGS_REG)
9441 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445 (ashift:SWI (match_dup 1) (match_dup 2)))]
9446 "(optimize_function_for_size_p (cfun)
9447 || !TARGET_PARTIAL_FLAG_REG_STALL
9448 || (operands[2] == const1_rtx
9450 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451 && ix86_match_ccmode (insn, CCGOCmode)
9452 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 switch (get_attr_type (insn))
9457 gcc_assert (operands[2] == const1_rtx);
9458 return "add{<imodesuffix>}\t%0, %0";
9461 if (operands[2] == const1_rtx
9462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463 return "sal{<imodesuffix>}\t%0";
9465 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9469 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9470 (match_operand 0 "register_operand" ""))
9471 (match_operand 2 "const1_operand" ""))
9472 (const_string "alu")
9474 (const_string "ishift")))
9475 (set (attr "length_immediate")
9477 (ior (eq_attr "type" "alu")
9478 (and (eq_attr "type" "ishift")
9479 (and (match_operand 2 "const1_operand" "")
9480 (ior (match_test "TARGET_SHIFT1")
9481 (match_test "optimize_function_for_size_p (cfun)")))))
9483 (const_string "*")))
9484 (set_attr "mode" "<MODE>")])
9486 (define_insn "*ashlsi3_cmp_zext"
9487 [(set (reg FLAGS_REG)
9489 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9490 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492 (set (match_operand:DI 0 "register_operand" "=r")
9493 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495 && (optimize_function_for_size_p (cfun)
9496 || !TARGET_PARTIAL_FLAG_REG_STALL
9497 || (operands[2] == const1_rtx
9499 || TARGET_DOUBLE_WITH_ADD)))
9500 && ix86_match_ccmode (insn, CCGOCmode)
9501 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 switch (get_attr_type (insn))
9506 gcc_assert (operands[2] == const1_rtx);
9507 return "add{l}\t%k0, %k0";
9510 if (operands[2] == const1_rtx
9511 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9512 return "sal{l}\t%k0";
9514 return "sal{l}\t{%2, %k0|%k0, %2}";
9518 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9519 (match_operand 2 "const1_operand" ""))
9520 (const_string "alu")
9522 (const_string "ishift")))
9523 (set (attr "length_immediate")
9525 (ior (eq_attr "type" "alu")
9526 (and (eq_attr "type" "ishift")
9527 (and (match_operand 2 "const1_operand" "")
9528 (ior (match_test "TARGET_SHIFT1")
9529 (match_test "optimize_function_for_size_p (cfun)")))))
9531 (const_string "*")))
9532 (set_attr "mode" "SI")])
9534 (define_insn "*ashl<mode>3_cconly"
9535 [(set (reg FLAGS_REG)
9537 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9538 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9540 (clobber (match_scratch:SWI 0 "=<r>"))]
9541 "(optimize_function_for_size_p (cfun)
9542 || !TARGET_PARTIAL_FLAG_REG_STALL
9543 || (operands[2] == const1_rtx
9545 || TARGET_DOUBLE_WITH_ADD)))
9546 && ix86_match_ccmode (insn, CCGOCmode)"
9548 switch (get_attr_type (insn))
9551 gcc_assert (operands[2] == const1_rtx);
9552 return "add{<imodesuffix>}\t%0, %0";
9555 if (operands[2] == const1_rtx
9556 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557 return "sal{<imodesuffix>}\t%0";
9559 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9563 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9564 (match_operand 0 "register_operand" ""))
9565 (match_operand 2 "const1_operand" ""))
9566 (const_string "alu")
9568 (const_string "ishift")))
9569 (set (attr "length_immediate")
9571 (ior (eq_attr "type" "alu")
9572 (and (eq_attr "type" "ishift")
9573 (and (match_operand 2 "const1_operand" "")
9574 (ior (match_test "TARGET_SHIFT1")
9575 (match_test "optimize_function_for_size_p (cfun)")))))
9577 (const_string "*")))
9578 (set_attr "mode" "<MODE>")])
9580 ;; See comment above `ashl<mode>3' about how this works.
9582 (define_expand "<shiftrt_insn><mode>3"
9583 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9584 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9585 (match_operand:QI 2 "nonmemory_operand" "")))]
9587 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9589 ;; Avoid useless masking of count operand.
9590 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9591 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9593 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9596 (match_operand:SI 2 "nonimmediate_operand" "c")
9597 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9598 (clobber (reg:CC FLAGS_REG))]
9599 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9600 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9601 == GET_MODE_BITSIZE (<MODE>mode)-1"
9604 [(parallel [(set (match_dup 0)
9605 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9606 (clobber (reg:CC FLAGS_REG))])]
9608 if (can_create_pseudo_p ())
9609 operands [2] = force_reg (SImode, operands[2]);
9611 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9613 [(set_attr "type" "ishift")
9614 (set_attr "mode" "<MODE>")])
9616 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9617 [(set (match_operand:DWI 0 "register_operand" "=r")
9618 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9619 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9620 (clobber (reg:CC FLAGS_REG))]
9623 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9625 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9626 [(set_attr "type" "multi")])
9628 ;; By default we don't ask for a scratch register, because when DWImode
9629 ;; values are manipulated, registers are already at a premium. But if
9630 ;; we have one handy, we won't turn it away.
9633 [(match_scratch:DWIH 3 "r")
9634 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9636 (match_operand:<DWI> 1 "register_operand" "")
9637 (match_operand:QI 2 "nonmemory_operand" "")))
9638 (clobber (reg:CC FLAGS_REG))])
9642 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9644 (define_insn "x86_64_shrd"
9645 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9646 (ior:DI (ashiftrt:DI (match_dup 0)
9647 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9648 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9649 (minus:QI (const_int 64) (match_dup 2)))))
9650 (clobber (reg:CC FLAGS_REG))]
9652 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9653 [(set_attr "type" "ishift")
9654 (set_attr "prefix_0f" "1")
9655 (set_attr "mode" "DI")
9656 (set_attr "athlon_decode" "vector")
9657 (set_attr "amdfam10_decode" "vector")
9658 (set_attr "bdver1_decode" "vector")])
9660 (define_insn "x86_shrd"
9661 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9662 (ior:SI (ashiftrt:SI (match_dup 0)
9663 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9664 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9665 (minus:QI (const_int 32) (match_dup 2)))))
9666 (clobber (reg:CC FLAGS_REG))]
9668 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9669 [(set_attr "type" "ishift")
9670 (set_attr "prefix_0f" "1")
9671 (set_attr "mode" "SI")
9672 (set_attr "pent_pair" "np")
9673 (set_attr "athlon_decode" "vector")
9674 (set_attr "amdfam10_decode" "vector")
9675 (set_attr "bdver1_decode" "vector")])
9677 (define_insn "ashrdi3_cvt"
9678 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9679 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9680 (match_operand:QI 2 "const_int_operand" "")))
9681 (clobber (reg:CC FLAGS_REG))]
9682 "TARGET_64BIT && INTVAL (operands[2]) == 63
9683 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9684 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9687 sar{q}\t{%2, %0|%0, %2}"
9688 [(set_attr "type" "imovx,ishift")
9689 (set_attr "prefix_0f" "0,*")
9690 (set_attr "length_immediate" "0,*")
9691 (set_attr "modrm" "0,1")
9692 (set_attr "mode" "DI")])
9694 (define_insn "ashrsi3_cvt"
9695 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9696 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9697 (match_operand:QI 2 "const_int_operand" "")))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "INTVAL (operands[2]) == 31
9700 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9704 sar{l}\t{%2, %0|%0, %2}"
9705 [(set_attr "type" "imovx,ishift")
9706 (set_attr "prefix_0f" "0,*")
9707 (set_attr "length_immediate" "0,*")
9708 (set_attr "modrm" "0,1")
9709 (set_attr "mode" "SI")])
9711 (define_insn "*ashrsi3_cvt_zext"
9712 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9714 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9715 (match_operand:QI 2 "const_int_operand" ""))))
9716 (clobber (reg:CC FLAGS_REG))]
9717 "TARGET_64BIT && INTVAL (operands[2]) == 31
9718 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9719 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9722 sar{l}\t{%2, %k0|%k0, %2}"
9723 [(set_attr "type" "imovx,ishift")
9724 (set_attr "prefix_0f" "0,*")
9725 (set_attr "length_immediate" "0,*")
9726 (set_attr "modrm" "0,1")
9727 (set_attr "mode" "SI")])
9729 (define_expand "x86_shift<mode>_adj_3"
9730 [(use (match_operand:SWI48 0 "register_operand" ""))
9731 (use (match_operand:SWI48 1 "register_operand" ""))
9732 (use (match_operand:QI 2 "register_operand" ""))]
9735 rtx label = gen_label_rtx ();
9738 emit_insn (gen_testqi_ccz_1 (operands[2],
9739 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9741 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9742 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9743 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9744 gen_rtx_LABEL_REF (VOIDmode, label),
9746 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9747 JUMP_LABEL (tmp) = label;
9749 emit_move_insn (operands[0], operands[1]);
9750 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9751 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9753 LABEL_NUSES (label) = 1;
9758 (define_insn "*bmi2_<shiftrt_insn><mode>3_1"
9759 [(set (match_operand:SWI48 0 "register_operand" "=r")
9760 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9761 (match_operand:SWI48 2 "register_operand" "r")))]
9763 "<shiftrt>x\t{%2, %1, %0|%0, %1, %2}"
9764 [(set_attr "type" "ishiftx")
9765 (set_attr "mode" "<MODE>")])
9767 (define_insn "*<shiftrt_insn><mode>3_1"
9768 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9770 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9771 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9775 switch (get_attr_type (insn))
9781 if (operands[2] == const1_rtx
9782 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9783 return "<shiftrt>{<imodesuffix>}\t%0";
9785 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9788 [(set_attr "isa" "*,bmi2")
9789 (set_attr "type" "ishift,ishiftx")
9790 (set (attr "length_immediate")
9792 (and (match_operand 2 "const1_operand" "")
9793 (ior (match_test "TARGET_SHIFT1")
9794 (match_test "optimize_function_for_size_p (cfun)")))
9796 (const_string "*")))
9797 (set_attr "mode" "<MODE>")])
9799 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9801 [(set (match_operand:SWI48 0 "register_operand" "")
9802 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9803 (match_operand:QI 2 "register_operand" "")))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "TARGET_BMI2 && reload_completed"
9807 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9808 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9810 (define_insn "*bmi2_<shiftrt_insn>si3_1_zext"
9811 [(set (match_operand:DI 0 "register_operand" "=r")
9813 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9814 (match_operand:SI 2 "register_operand" "r"))))]
9815 "TARGET_64BIT && TARGET_BMI2"
9816 "<shiftrt>x\t{%2, %1, %k0|%k0, %1, %2}"
9817 [(set_attr "type" "ishiftx")
9818 (set_attr "mode" "SI")])
9820 (define_insn "*<shiftrt_insn>si3_1_zext"
9821 [(set (match_operand:DI 0 "register_operand" "=r,r")
9823 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9824 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9825 (clobber (reg:CC FLAGS_REG))]
9826 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9828 switch (get_attr_type (insn))
9834 if (operands[2] == const1_rtx
9835 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9836 return "<shiftrt>{l}\t%k0";
9838 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9841 [(set_attr "isa" "*,bmi2")
9842 (set_attr "type" "ishift,ishiftx")
9843 (set (attr "length_immediate")
9845 (and (match_operand 2 "const1_operand" "")
9846 (ior (match_test "TARGET_SHIFT1")
9847 (match_test "optimize_function_for_size_p (cfun)")))
9849 (const_string "*")))
9850 (set_attr "mode" "SI")])
9852 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9854 [(set (match_operand:DI 0 "register_operand" "")
9856 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9857 (match_operand:QI 2 "register_operand" ""))))
9858 (clobber (reg:CC FLAGS_REG))]
9859 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9861 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9862 "operands[2] = gen_lowpart (SImode, operands[2]);")
9864 (define_insn "*<shiftrt_insn><mode>3_1"
9865 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9867 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9868 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9872 if (operands[2] == const1_rtx
9873 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874 return "<shiftrt>{<imodesuffix>}\t%0";
9876 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9878 [(set_attr "type" "ishift")
9879 (set (attr "length_immediate")
9881 (and (match_operand 2 "const1_operand" "")
9882 (ior (match_test "TARGET_SHIFT1")
9883 (match_test "optimize_function_for_size_p (cfun)")))
9885 (const_string "*")))
9886 (set_attr "mode" "<MODE>")])
9888 (define_insn "*<shiftrt_insn>qi3_1_slp"
9889 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9890 (any_shiftrt:QI (match_dup 0)
9891 (match_operand:QI 1 "nonmemory_operand" "cI")))
9892 (clobber (reg:CC FLAGS_REG))]
9893 "(optimize_function_for_size_p (cfun)
9894 || !TARGET_PARTIAL_REG_STALL
9895 || (operands[1] == const1_rtx
9898 if (operands[1] == const1_rtx
9899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9900 return "<shiftrt>{b}\t%0";
9902 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9904 [(set_attr "type" "ishift1")
9905 (set (attr "length_immediate")
9907 (and (match_operand 1 "const1_operand" "")
9908 (ior (match_test "TARGET_SHIFT1")
9909 (match_test "optimize_function_for_size_p (cfun)")))
9911 (const_string "*")))
9912 (set_attr "mode" "QI")])
9914 ;; This pattern can't accept a variable shift count, since shifts by
9915 ;; zero don't affect the flags. We assume that shifts by constant
9916 ;; zero are optimized away.
9917 (define_insn "*<shiftrt_insn><mode>3_cmp"
9918 [(set (reg FLAGS_REG)
9921 (match_operand:SWI 1 "nonimmediate_operand" "0")
9922 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9924 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9925 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9926 "(optimize_function_for_size_p (cfun)
9927 || !TARGET_PARTIAL_FLAG_REG_STALL
9928 || (operands[2] == const1_rtx
9930 && ix86_match_ccmode (insn, CCGOCmode)
9931 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9933 if (operands[2] == const1_rtx
9934 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9935 return "<shiftrt>{<imodesuffix>}\t%0";
9937 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9939 [(set_attr "type" "ishift")
9940 (set (attr "length_immediate")
9942 (and (match_operand 2 "const1_operand" "")
9943 (ior (match_test "TARGET_SHIFT1")
9944 (match_test "optimize_function_for_size_p (cfun)")))
9946 (const_string "*")))
9947 (set_attr "mode" "<MODE>")])
9949 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9950 [(set (reg FLAGS_REG)
9952 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9953 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9955 (set (match_operand:DI 0 "register_operand" "=r")
9956 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9958 && (optimize_function_for_size_p (cfun)
9959 || !TARGET_PARTIAL_FLAG_REG_STALL
9960 || (operands[2] == const1_rtx
9962 && ix86_match_ccmode (insn, CCGOCmode)
9963 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9965 if (operands[2] == const1_rtx
9966 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9967 return "<shiftrt>{l}\t%k0";
9969 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9971 [(set_attr "type" "ishift")
9972 (set (attr "length_immediate")
9974 (and (match_operand 2 "const1_operand" "")
9975 (ior (match_test "TARGET_SHIFT1")
9976 (match_test "optimize_function_for_size_p (cfun)")))
9978 (const_string "*")))
9979 (set_attr "mode" "SI")])
9981 (define_insn "*<shiftrt_insn><mode>3_cconly"
9982 [(set (reg FLAGS_REG)
9985 (match_operand:SWI 1 "register_operand" "0")
9986 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9988 (clobber (match_scratch:SWI 0 "=<r>"))]
9989 "(optimize_function_for_size_p (cfun)
9990 || !TARGET_PARTIAL_FLAG_REG_STALL
9991 || (operands[2] == const1_rtx
9993 && ix86_match_ccmode (insn, CCGOCmode)"
9995 if (operands[2] == const1_rtx
9996 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9997 return "<shiftrt>{<imodesuffix>}\t%0";
9999 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10001 [(set_attr "type" "ishift")
10002 (set (attr "length_immediate")
10004 (and (match_operand 2 "const1_operand" "")
10005 (ior (match_test "TARGET_SHIFT1")
10006 (match_test "optimize_function_for_size_p (cfun)")))
10008 (const_string "*")))
10009 (set_attr "mode" "<MODE>")])
10011 ;; Rotate instructions
10013 (define_expand "<rotate_insn>ti3"
10014 [(set (match_operand:TI 0 "register_operand" "")
10015 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10016 (match_operand:QI 2 "nonmemory_operand" "")))]
10019 if (const_1_to_63_operand (operands[2], VOIDmode))
10020 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10021 (operands[0], operands[1], operands[2]));
10028 (define_expand "<rotate_insn>di3"
10029 [(set (match_operand:DI 0 "shiftdi_operand" "")
10030 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10031 (match_operand:QI 2 "nonmemory_operand" "")))]
10035 ix86_expand_binary_operator (<CODE>, DImode, operands);
10036 else if (const_1_to_31_operand (operands[2], VOIDmode))
10037 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10038 (operands[0], operands[1], operands[2]));
10045 (define_expand "<rotate_insn><mode>3"
10046 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10047 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10048 (match_operand:QI 2 "nonmemory_operand" "")))]
10050 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10052 ;; Avoid useless masking of count operand.
10053 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10054 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10056 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10059 (match_operand:SI 2 "nonimmediate_operand" "c")
10060 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10061 (clobber (reg:CC FLAGS_REG))]
10062 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10063 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10064 == GET_MODE_BITSIZE (<MODE>mode)-1"
10067 [(parallel [(set (match_dup 0)
10068 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10069 (clobber (reg:CC FLAGS_REG))])]
10071 if (can_create_pseudo_p ())
10072 operands [2] = force_reg (SImode, operands[2]);
10074 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10076 [(set_attr "type" "rotate")
10077 (set_attr "mode" "<MODE>")])
10079 ;; Implement rotation using two double-precision
10080 ;; shift instructions and a scratch register.
10082 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10083 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10084 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10085 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10086 (clobber (reg:CC FLAGS_REG))
10087 (clobber (match_scratch:DWIH 3 "=&r"))]
10091 [(set (match_dup 3) (match_dup 4))
10093 [(set (match_dup 4)
10094 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10095 (lshiftrt:DWIH (match_dup 5)
10096 (minus:QI (match_dup 6) (match_dup 2)))))
10097 (clobber (reg:CC FLAGS_REG))])
10099 [(set (match_dup 5)
10100 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10101 (lshiftrt:DWIH (match_dup 3)
10102 (minus:QI (match_dup 6) (match_dup 2)))))
10103 (clobber (reg:CC FLAGS_REG))])]
10105 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10107 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10110 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10111 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10112 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10113 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10114 (clobber (reg:CC FLAGS_REG))
10115 (clobber (match_scratch:DWIH 3 "=&r"))]
10119 [(set (match_dup 3) (match_dup 4))
10121 [(set (match_dup 4)
10122 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10123 (ashift:DWIH (match_dup 5)
10124 (minus:QI (match_dup 6) (match_dup 2)))))
10125 (clobber (reg:CC FLAGS_REG))])
10127 [(set (match_dup 5)
10128 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10129 (ashift:DWIH (match_dup 3)
10130 (minus:QI (match_dup 6) (match_dup 2)))))
10131 (clobber (reg:CC FLAGS_REG))])]
10133 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10135 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10138 (define_insn "*bmi2_rorx<mode>3_1"
10139 [(set (match_operand:SWI48 0 "register_operand" "=r")
10140 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10141 (match_operand:QI 2 "immediate_operand" "<S>")))]
10143 "rorx\t{%2, %1, %0|%0, %1, %2}"
10144 [(set_attr "type" "rotatex")
10145 (set_attr "mode" "<MODE>")])
10147 (define_insn "*<rotate_insn><mode>3_1"
10148 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10150 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10151 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10155 switch (get_attr_type (insn))
10161 if (operands[2] == const1_rtx
10162 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10163 return "<rotate>{<imodesuffix>}\t%0";
10165 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10168 [(set_attr "isa" "*,bmi2")
10169 (set_attr "type" "rotate,rotatex")
10170 (set (attr "length_immediate")
10172 (and (eq_attr "type" "rotate")
10173 (and (match_operand 2 "const1_operand" "")
10174 (ior (match_test "TARGET_SHIFT1")
10175 (match_test "optimize_function_for_size_p (cfun)"))))
10177 (const_string "*")))
10178 (set_attr "mode" "<MODE>")])
10180 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10182 [(set (match_operand:SWI48 0 "register_operand" "")
10183 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10184 (match_operand:QI 2 "immediate_operand" "")))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "TARGET_BMI2 && reload_completed"
10187 [(set (match_dup 0)
10188 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10191 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10195 [(set (match_operand:SWI48 0 "register_operand" "")
10196 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10197 (match_operand:QI 2 "immediate_operand" "")))
10198 (clobber (reg:CC FLAGS_REG))]
10199 "TARGET_BMI2 && reload_completed"
10200 [(set (match_dup 0)
10201 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10203 (define_insn "*bmi2_rorxsi3_1_zext"
10204 [(set (match_operand:DI 0 "register_operand" "=r")
10206 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10207 (match_operand:QI 2 "immediate_operand" "I"))))]
10208 "TARGET_64BIT && TARGET_BMI2"
10209 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10210 [(set_attr "type" "rotatex")
10211 (set_attr "mode" "SI")])
10213 (define_insn "*<rotate_insn>si3_1_zext"
10214 [(set (match_operand:DI 0 "register_operand" "=r,r")
10216 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10217 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10221 switch (get_attr_type (insn))
10227 if (operands[2] == const1_rtx
10228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10229 return "<rotate>{l}\t%k0";
10231 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10234 [(set_attr "isa" "*,bmi2")
10235 (set_attr "type" "rotate,rotatex")
10236 (set (attr "length_immediate")
10238 (and (eq_attr "type" "rotate")
10239 (and (match_operand 2 "const1_operand" "")
10240 (ior (match_test "TARGET_SHIFT1")
10241 (match_test "optimize_function_for_size_p (cfun)"))))
10243 (const_string "*")))
10244 (set_attr "mode" "SI")])
10246 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10248 [(set (match_operand:DI 0 "register_operand" "")
10250 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10251 (match_operand:QI 2 "immediate_operand" ""))))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10254 [(set (match_dup 0)
10255 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10258 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10262 [(set (match_operand:DI 0 "register_operand" "")
10264 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10265 (match_operand:QI 2 "immediate_operand" ""))))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10268 [(set (match_dup 0)
10269 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10271 (define_insn "*<rotate_insn><mode>3_1"
10272 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10273 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10274 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10275 (clobber (reg:CC FLAGS_REG))]
10276 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10278 if (operands[2] == const1_rtx
10279 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10280 return "<rotate>{<imodesuffix>}\t%0";
10282 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10284 [(set_attr "type" "rotate")
10285 (set (attr "length_immediate")
10287 (and (match_operand 2 "const1_operand" "")
10288 (ior (match_test "TARGET_SHIFT1")
10289 (match_test "optimize_function_for_size_p (cfun)")))
10291 (const_string "*")))
10292 (set_attr "mode" "<MODE>")])
10294 (define_insn "*<rotate_insn>qi3_1_slp"
10295 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10296 (any_rotate:QI (match_dup 0)
10297 (match_operand:QI 1 "nonmemory_operand" "cI")))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "(optimize_function_for_size_p (cfun)
10300 || !TARGET_PARTIAL_REG_STALL
10301 || (operands[1] == const1_rtx
10302 && TARGET_SHIFT1))"
10304 if (operands[1] == const1_rtx
10305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10306 return "<rotate>{b}\t%0";
10308 return "<rotate>{b}\t{%1, %0|%0, %1}";
10310 [(set_attr "type" "rotate1")
10311 (set (attr "length_immediate")
10313 (and (match_operand 1 "const1_operand" "")
10314 (ior (match_test "TARGET_SHIFT1")
10315 (match_test "optimize_function_for_size_p (cfun)")))
10317 (const_string "*")))
10318 (set_attr "mode" "QI")])
10321 [(set (match_operand:HI 0 "register_operand" "")
10322 (any_rotate:HI (match_dup 0) (const_int 8)))
10323 (clobber (reg:CC FLAGS_REG))]
10325 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10326 [(parallel [(set (strict_low_part (match_dup 0))
10327 (bswap:HI (match_dup 0)))
10328 (clobber (reg:CC FLAGS_REG))])])
10330 ;; Bit set / bit test instructions
10332 (define_expand "extv"
10333 [(set (match_operand:SI 0 "register_operand" "")
10334 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10335 (match_operand:SI 2 "const8_operand" "")
10336 (match_operand:SI 3 "const8_operand" "")))]
10339 /* Handle extractions from %ah et al. */
10340 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10343 /* From mips.md: extract_bit_field doesn't verify that our source
10344 matches the predicate, so check it again here. */
10345 if (! ext_register_operand (operands[1], VOIDmode))
10349 (define_expand "extzv"
10350 [(set (match_operand:SI 0 "register_operand" "")
10351 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10352 (match_operand:SI 2 "const8_operand" "")
10353 (match_operand:SI 3 "const8_operand" "")))]
10356 /* Handle extractions from %ah et al. */
10357 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10360 /* From mips.md: extract_bit_field doesn't verify that our source
10361 matches the predicate, so check it again here. */
10362 if (! ext_register_operand (operands[1], VOIDmode))
10366 (define_expand "insv"
10367 [(set (zero_extract (match_operand 0 "register_operand" "")
10368 (match_operand 1 "const_int_operand" "")
10369 (match_operand 2 "const_int_operand" ""))
10370 (match_operand 3 "register_operand" ""))]
10373 rtx (*gen_mov_insv_1) (rtx, rtx);
10375 if (ix86_expand_pinsr (operands))
10378 /* Handle insertions to %ah et al. */
10379 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10382 /* From mips.md: insert_bit_field doesn't verify that our source
10383 matches the predicate, so check it again here. */
10384 if (! ext_register_operand (operands[0], VOIDmode))
10387 gen_mov_insv_1 = (TARGET_64BIT
10388 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10390 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10394 ;; %%% bts, btr, btc, bt.
10395 ;; In general these instructions are *slow* when applied to memory,
10396 ;; since they enforce atomic operation. When applied to registers,
10397 ;; it depends on the cpu implementation. They're never faster than
10398 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10399 ;; no point. But in 64-bit, we can't hold the relevant immediates
10400 ;; within the instruction itself, so operating on bits in the high
10401 ;; 32-bits of a register becomes easier.
10403 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10404 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10405 ;; negdf respectively, so they can never be disabled entirely.
10407 (define_insn "*btsq"
10408 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10410 (match_operand:DI 1 "const_0_to_63_operand" ""))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10414 "bts{q}\t{%1, %0|%0, %1}"
10415 [(set_attr "type" "alu1")
10416 (set_attr "prefix_0f" "1")
10417 (set_attr "mode" "DI")])
10419 (define_insn "*btrq"
10420 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10422 (match_operand:DI 1 "const_0_to_63_operand" ""))
10424 (clobber (reg:CC FLAGS_REG))]
10425 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10426 "btr{q}\t{%1, %0|%0, %1}"
10427 [(set_attr "type" "alu1")
10428 (set_attr "prefix_0f" "1")
10429 (set_attr "mode" "DI")])
10431 (define_insn "*btcq"
10432 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10434 (match_operand:DI 1 "const_0_to_63_operand" ""))
10435 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10438 "btc{q}\t{%1, %0|%0, %1}"
10439 [(set_attr "type" "alu1")
10440 (set_attr "prefix_0f" "1")
10441 (set_attr "mode" "DI")])
10443 ;; Allow Nocona to avoid these instructions if a register is available.
10446 [(match_scratch:DI 2 "r")
10447 (parallel [(set (zero_extract:DI
10448 (match_operand:DI 0 "register_operand" "")
10450 (match_operand:DI 1 "const_0_to_63_operand" ""))
10452 (clobber (reg:CC FLAGS_REG))])]
10453 "TARGET_64BIT && !TARGET_USE_BT"
10456 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10459 if (HOST_BITS_PER_WIDE_INT >= 64)
10460 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10461 else if (i < HOST_BITS_PER_WIDE_INT)
10462 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10464 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10466 op1 = immed_double_const (lo, hi, DImode);
10469 emit_move_insn (operands[2], op1);
10473 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10478 [(match_scratch:DI 2 "r")
10479 (parallel [(set (zero_extract:DI
10480 (match_operand:DI 0 "register_operand" "")
10482 (match_operand:DI 1 "const_0_to_63_operand" ""))
10484 (clobber (reg:CC FLAGS_REG))])]
10485 "TARGET_64BIT && !TARGET_USE_BT"
10488 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10491 if (HOST_BITS_PER_WIDE_INT >= 64)
10492 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10493 else if (i < HOST_BITS_PER_WIDE_INT)
10494 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10496 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10498 op1 = immed_double_const (~lo, ~hi, DImode);
10501 emit_move_insn (operands[2], op1);
10505 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10510 [(match_scratch:DI 2 "r")
10511 (parallel [(set (zero_extract:DI
10512 (match_operand:DI 0 "register_operand" "")
10514 (match_operand:DI 1 "const_0_to_63_operand" ""))
10515 (not:DI (zero_extract:DI
10516 (match_dup 0) (const_int 1) (match_dup 1))))
10517 (clobber (reg:CC FLAGS_REG))])]
10518 "TARGET_64BIT && !TARGET_USE_BT"
10521 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10524 if (HOST_BITS_PER_WIDE_INT >= 64)
10525 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10526 else if (i < HOST_BITS_PER_WIDE_INT)
10527 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10529 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10531 op1 = immed_double_const (lo, hi, DImode);
10534 emit_move_insn (operands[2], op1);
10538 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10542 (define_insn "*bt<mode>"
10543 [(set (reg:CCC FLAGS_REG)
10545 (zero_extract:SWI48
10546 (match_operand:SWI48 0 "register_operand" "r")
10548 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10550 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10551 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10552 [(set_attr "type" "alu1")
10553 (set_attr "prefix_0f" "1")
10554 (set_attr "mode" "<MODE>")])
10556 ;; Store-flag instructions.
10558 ;; For all sCOND expanders, also expand the compare or test insn that
10559 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10561 (define_insn_and_split "*setcc_di_1"
10562 [(set (match_operand:DI 0 "register_operand" "=q")
10563 (match_operator:DI 1 "ix86_comparison_operator"
10564 [(reg FLAGS_REG) (const_int 0)]))]
10565 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10567 "&& reload_completed"
10568 [(set (match_dup 2) (match_dup 1))
10569 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10571 PUT_MODE (operands[1], QImode);
10572 operands[2] = gen_lowpart (QImode, operands[0]);
10575 (define_insn_and_split "*setcc_si_1_and"
10576 [(set (match_operand:SI 0 "register_operand" "=q")
10577 (match_operator:SI 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)]))
10579 (clobber (reg:CC FLAGS_REG))]
10580 "!TARGET_PARTIAL_REG_STALL
10581 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10583 "&& reload_completed"
10584 [(set (match_dup 2) (match_dup 1))
10585 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10586 (clobber (reg:CC FLAGS_REG))])]
10588 PUT_MODE (operands[1], QImode);
10589 operands[2] = gen_lowpart (QImode, operands[0]);
10592 (define_insn_and_split "*setcc_si_1_movzbl"
10593 [(set (match_operand:SI 0 "register_operand" "=q")
10594 (match_operator:SI 1 "ix86_comparison_operator"
10595 [(reg FLAGS_REG) (const_int 0)]))]
10596 "!TARGET_PARTIAL_REG_STALL
10597 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10599 "&& reload_completed"
10600 [(set (match_dup 2) (match_dup 1))
10601 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10603 PUT_MODE (operands[1], QImode);
10604 operands[2] = gen_lowpart (QImode, operands[0]);
10607 (define_insn "*setcc_qi"
10608 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10609 (match_operator:QI 1 "ix86_comparison_operator"
10610 [(reg FLAGS_REG) (const_int 0)]))]
10613 [(set_attr "type" "setcc")
10614 (set_attr "mode" "QI")])
10616 (define_insn "*setcc_qi_slp"
10617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10618 (match_operator:QI 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)]))]
10622 [(set_attr "type" "setcc")
10623 (set_attr "mode" "QI")])
10625 ;; In general it is not safe to assume too much about CCmode registers,
10626 ;; so simplify-rtx stops when it sees a second one. Under certain
10627 ;; conditions this is safe on x86, so help combine not create
10634 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10635 (ne:QI (match_operator 1 "ix86_comparison_operator"
10636 [(reg FLAGS_REG) (const_int 0)])
10639 [(set (match_dup 0) (match_dup 1))]
10640 "PUT_MODE (operands[1], QImode);")
10643 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10644 (ne:QI (match_operator 1 "ix86_comparison_operator"
10645 [(reg FLAGS_REG) (const_int 0)])
10648 [(set (match_dup 0) (match_dup 1))]
10649 "PUT_MODE (operands[1], QImode);")
10652 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10653 (eq:QI (match_operator 1 "ix86_comparison_operator"
10654 [(reg FLAGS_REG) (const_int 0)])
10657 [(set (match_dup 0) (match_dup 1))]
10659 rtx new_op1 = copy_rtx (operands[1]);
10660 operands[1] = new_op1;
10661 PUT_MODE (new_op1, QImode);
10662 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10663 GET_MODE (XEXP (new_op1, 0))));
10665 /* Make sure that (a) the CCmode we have for the flags is strong
10666 enough for the reversed compare or (b) we have a valid FP compare. */
10667 if (! ix86_comparison_operator (new_op1, VOIDmode))
10672 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10673 (eq:QI (match_operator 1 "ix86_comparison_operator"
10674 [(reg FLAGS_REG) (const_int 0)])
10677 [(set (match_dup 0) (match_dup 1))]
10679 rtx new_op1 = copy_rtx (operands[1]);
10680 operands[1] = new_op1;
10681 PUT_MODE (new_op1, QImode);
10682 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10683 GET_MODE (XEXP (new_op1, 0))));
10685 /* Make sure that (a) the CCmode we have for the flags is strong
10686 enough for the reversed compare or (b) we have a valid FP compare. */
10687 if (! ix86_comparison_operator (new_op1, VOIDmode))
10691 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10692 ;; subsequent logical operations are used to imitate conditional moves.
10693 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10696 (define_insn "setcc_<mode>_sse"
10697 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10698 (match_operator:MODEF 3 "sse_comparison_operator"
10699 [(match_operand:MODEF 1 "register_operand" "0,x")
10700 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10701 "SSE_FLOAT_MODE_P (<MODE>mode)"
10703 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10704 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10705 [(set_attr "isa" "noavx,avx")
10706 (set_attr "type" "ssecmp")
10707 (set_attr "length_immediate" "1")
10708 (set_attr "prefix" "orig,vex")
10709 (set_attr "mode" "<MODE>")])
10711 ;; Basic conditional jump instructions.
10712 ;; We ignore the overflow flag for signed branch instructions.
10714 (define_insn "*jcc_1"
10716 (if_then_else (match_operator 1 "ix86_comparison_operator"
10717 [(reg FLAGS_REG) (const_int 0)])
10718 (label_ref (match_operand 0 "" ""))
10722 [(set_attr "type" "ibr")
10723 (set_attr "modrm" "0")
10724 (set (attr "length")
10725 (if_then_else (and (ge (minus (match_dup 0) (pc))
10727 (lt (minus (match_dup 0) (pc))
10732 (define_insn "*jcc_2"
10734 (if_then_else (match_operator 1 "ix86_comparison_operator"
10735 [(reg FLAGS_REG) (const_int 0)])
10737 (label_ref (match_operand 0 "" ""))))]
10740 [(set_attr "type" "ibr")
10741 (set_attr "modrm" "0")
10742 (set (attr "length")
10743 (if_then_else (and (ge (minus (match_dup 0) (pc))
10745 (lt (minus (match_dup 0) (pc))
10750 ;; In general it is not safe to assume too much about CCmode registers,
10751 ;; so simplify-rtx stops when it sees a second one. Under certain
10752 ;; conditions this is safe on x86, so help combine not create
10760 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10761 [(reg FLAGS_REG) (const_int 0)])
10763 (label_ref (match_operand 1 "" ""))
10767 (if_then_else (match_dup 0)
10768 (label_ref (match_dup 1))
10770 "PUT_MODE (operands[0], VOIDmode);")
10774 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10775 [(reg FLAGS_REG) (const_int 0)])
10777 (label_ref (match_operand 1 "" ""))
10781 (if_then_else (match_dup 0)
10782 (label_ref (match_dup 1))
10785 rtx new_op0 = copy_rtx (operands[0]);
10786 operands[0] = new_op0;
10787 PUT_MODE (new_op0, VOIDmode);
10788 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10789 GET_MODE (XEXP (new_op0, 0))));
10791 /* Make sure that (a) the CCmode we have for the flags is strong
10792 enough for the reversed compare or (b) we have a valid FP compare. */
10793 if (! ix86_comparison_operator (new_op0, VOIDmode))
10797 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10798 ;; pass generates from shift insn with QImode operand. Actually, the mode
10799 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10800 ;; appropriate modulo of the bit offset value.
10802 (define_insn_and_split "*jcc_bt<mode>"
10804 (if_then_else (match_operator 0 "bt_comparison_operator"
10805 [(zero_extract:SWI48
10806 (match_operand:SWI48 1 "register_operand" "r")
10809 (match_operand:QI 2 "register_operand" "r")))
10811 (label_ref (match_operand 3 "" ""))
10813 (clobber (reg:CC FLAGS_REG))]
10814 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10817 [(set (reg:CCC FLAGS_REG)
10819 (zero_extract:SWI48
10825 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10826 (label_ref (match_dup 3))
10829 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10831 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10834 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10835 ;; also for DImode, this is what combine produces.
10836 (define_insn_and_split "*jcc_bt<mode>_mask"
10838 (if_then_else (match_operator 0 "bt_comparison_operator"
10839 [(zero_extract:SWI48
10840 (match_operand:SWI48 1 "register_operand" "r")
10843 (match_operand:SI 2 "register_operand" "r")
10844 (match_operand:SI 3 "const_int_operand" "n")))])
10845 (label_ref (match_operand 4 "" ""))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10849 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10850 == GET_MODE_BITSIZE (<MODE>mode)-1"
10853 [(set (reg:CCC FLAGS_REG)
10855 (zero_extract:SWI48
10861 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10862 (label_ref (match_dup 4))
10865 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10867 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10870 (define_insn_and_split "*jcc_btsi_1"
10872 (if_then_else (match_operator 0 "bt_comparison_operator"
10875 (match_operand:SI 1 "register_operand" "r")
10876 (match_operand:QI 2 "register_operand" "r"))
10879 (label_ref (match_operand 3 "" ""))
10881 (clobber (reg:CC FLAGS_REG))]
10882 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10885 [(set (reg:CCC FLAGS_REG)
10893 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10894 (label_ref (match_dup 3))
10897 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10899 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10902 ;; avoid useless masking of bit offset operand
10903 (define_insn_and_split "*jcc_btsi_mask_1"
10906 (match_operator 0 "bt_comparison_operator"
10909 (match_operand:SI 1 "register_operand" "r")
10912 (match_operand:SI 2 "register_operand" "r")
10913 (match_operand:SI 3 "const_int_operand" "n")) 0))
10916 (label_ref (match_operand 4 "" ""))
10918 (clobber (reg:CC FLAGS_REG))]
10919 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10920 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10923 [(set (reg:CCC FLAGS_REG)
10931 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10932 (label_ref (match_dup 4))
10934 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10936 ;; Define combination compare-and-branch fp compare instructions to help
10939 (define_insn "*fp_jcc_1_387"
10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942 [(match_operand 1 "register_operand" "f")
10943 (match_operand 2 "nonimmediate_operand" "fm")])
10944 (label_ref (match_operand 3 "" ""))
10946 (clobber (reg:CCFP FPSR_REG))
10947 (clobber (reg:CCFP FLAGS_REG))
10948 (clobber (match_scratch:HI 4 "=a"))]
10950 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10951 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10952 && SELECT_CC_MODE (GET_CODE (operands[0]),
10953 operands[1], operands[2]) == CCFPmode
10957 (define_insn "*fp_jcc_1r_387"
10959 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10960 [(match_operand 1 "register_operand" "f")
10961 (match_operand 2 "nonimmediate_operand" "fm")])
10963 (label_ref (match_operand 3 "" ""))))
10964 (clobber (reg:CCFP FPSR_REG))
10965 (clobber (reg:CCFP FLAGS_REG))
10966 (clobber (match_scratch:HI 4 "=a"))]
10968 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10969 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970 && SELECT_CC_MODE (GET_CODE (operands[0]),
10971 operands[1], operands[2]) == CCFPmode
10975 (define_insn "*fp_jcc_2_387"
10977 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978 [(match_operand 1 "register_operand" "f")
10979 (match_operand 2 "register_operand" "f")])
10980 (label_ref (match_operand 3 "" ""))
10982 (clobber (reg:CCFP FPSR_REG))
10983 (clobber (reg:CCFP FLAGS_REG))
10984 (clobber (match_scratch:HI 4 "=a"))]
10985 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10990 (define_insn "*fp_jcc_2r_387"
10992 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10993 [(match_operand 1 "register_operand" "f")
10994 (match_operand 2 "register_operand" "f")])
10996 (label_ref (match_operand 3 "" ""))))
10997 (clobber (reg:CCFP FPSR_REG))
10998 (clobber (reg:CCFP FLAGS_REG))
10999 (clobber (match_scratch:HI 4 "=a"))]
11000 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11001 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11005 (define_insn "*fp_jcc_3_387"
11007 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11008 [(match_operand 1 "register_operand" "f")
11009 (match_operand 2 "const0_operand" "")])
11010 (label_ref (match_operand 3 "" ""))
11012 (clobber (reg:CCFP FPSR_REG))
11013 (clobber (reg:CCFP FLAGS_REG))
11014 (clobber (match_scratch:HI 4 "=a"))]
11015 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11017 && SELECT_CC_MODE (GET_CODE (operands[0]),
11018 operands[1], operands[2]) == CCFPmode
11024 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11025 [(match_operand 1 "register_operand" "")
11026 (match_operand 2 "nonimmediate_operand" "")])
11027 (match_operand 3 "" "")
11028 (match_operand 4 "" "")))
11029 (clobber (reg:CCFP FPSR_REG))
11030 (clobber (reg:CCFP FLAGS_REG))]
11034 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11035 operands[3], operands[4], NULL_RTX, NULL_RTX);
11041 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11042 [(match_operand 1 "register_operand" "")
11043 (match_operand 2 "general_operand" "")])
11044 (match_operand 3 "" "")
11045 (match_operand 4 "" "")))
11046 (clobber (reg:CCFP FPSR_REG))
11047 (clobber (reg:CCFP FLAGS_REG))
11048 (clobber (match_scratch:HI 5 "=a"))]
11052 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11053 operands[3], operands[4], operands[5], NULL_RTX);
11057 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11058 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11059 ;; with a precedence over other operators and is always put in the first
11060 ;; place. Swap condition and operands to match ficom instruction.
11062 (define_insn "*fp_jcc_4_<mode>_387"
11065 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11066 [(match_operator 1 "float_operator"
11067 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11068 (match_operand 3 "register_operand" "f,f")])
11069 (label_ref (match_operand 4 "" ""))
11071 (clobber (reg:CCFP FPSR_REG))
11072 (clobber (reg:CCFP FLAGS_REG))
11073 (clobber (match_scratch:HI 5 "=a,a"))]
11074 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11075 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11076 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11077 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11084 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11085 [(match_operator 1 "float_operator"
11086 [(match_operand:SWI24 2 "memory_operand" "")])
11087 (match_operand 3 "register_operand" "")])
11088 (match_operand 4 "" "")
11089 (match_operand 5 "" "")))
11090 (clobber (reg:CCFP FPSR_REG))
11091 (clobber (reg:CCFP FLAGS_REG))
11092 (clobber (match_scratch:HI 6 "=a"))]
11096 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11098 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11099 operands[3], operands[7],
11100 operands[4], operands[5], operands[6], NULL_RTX);
11104 ;; %%% Kill this when reload knows how to do it.
11108 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11109 [(match_operator 1 "float_operator"
11110 [(match_operand:SWI24 2 "register_operand" "")])
11111 (match_operand 3 "register_operand" "")])
11112 (match_operand 4 "" "")
11113 (match_operand 5 "" "")))
11114 (clobber (reg:CCFP FPSR_REG))
11115 (clobber (reg:CCFP FLAGS_REG))
11116 (clobber (match_scratch:HI 6 "=a"))]
11120 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11121 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11123 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11124 operands[3], operands[7],
11125 operands[4], operands[5], operands[6], operands[2]);
11129 ;; Unconditional and other jump instructions
11131 (define_insn "jump"
11133 (label_ref (match_operand 0 "" "")))]
11136 [(set_attr "type" "ibr")
11137 (set (attr "length")
11138 (if_then_else (and (ge (minus (match_dup 0) (pc))
11140 (lt (minus (match_dup 0) (pc))
11144 (set_attr "modrm" "0")])
11146 (define_expand "indirect_jump"
11147 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11149 (define_insn "*indirect_jump"
11150 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11153 [(set_attr "type" "ibr")
11154 (set_attr "length_immediate" "0")])
11156 (define_expand "tablejump"
11157 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11158 (use (label_ref (match_operand 1 "" "")))])]
11161 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11162 relative. Convert the relative address to an absolute address. */
11166 enum rtx_code code;
11168 /* We can't use @GOTOFF for text labels on VxWorks;
11169 see gotoff_operand. */
11170 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11174 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11176 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11180 op1 = pic_offset_table_rtx;
11185 op0 = pic_offset_table_rtx;
11189 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11192 else if (TARGET_X32)
11193 operands[0] = convert_memory_address (Pmode, operands[0]);
11196 (define_insn "*tablejump_1"
11197 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11198 (use (label_ref (match_operand 1 "" "")))]
11201 [(set_attr "type" "ibr")
11202 (set_attr "length_immediate" "0")])
11204 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11207 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11208 (set (match_operand:QI 1 "register_operand" "")
11209 (match_operator:QI 2 "ix86_comparison_operator"
11210 [(reg FLAGS_REG) (const_int 0)]))
11211 (set (match_operand 3 "q_regs_operand" "")
11212 (zero_extend (match_dup 1)))]
11213 "(peep2_reg_dead_p (3, operands[1])
11214 || operands_match_p (operands[1], operands[3]))
11215 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11216 [(set (match_dup 4) (match_dup 0))
11217 (set (strict_low_part (match_dup 5))
11220 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11221 operands[5] = gen_lowpart (QImode, operands[3]);
11222 ix86_expand_clear (operands[3]);
11225 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11228 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11229 (set (match_operand:QI 1 "register_operand" "")
11230 (match_operator:QI 2 "ix86_comparison_operator"
11231 [(reg FLAGS_REG) (const_int 0)]))
11232 (parallel [(set (match_operand 3 "q_regs_operand" "")
11233 (zero_extend (match_dup 1)))
11234 (clobber (reg:CC FLAGS_REG))])]
11235 "(peep2_reg_dead_p (3, operands[1])
11236 || operands_match_p (operands[1], operands[3]))
11237 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11238 [(set (match_dup 4) (match_dup 0))
11239 (set (strict_low_part (match_dup 5))
11242 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11243 operands[5] = gen_lowpart (QImode, operands[3]);
11244 ix86_expand_clear (operands[3]);
11247 ;; Call instructions.
11249 ;; The predicates normally associated with named expanders are not properly
11250 ;; checked for calls. This is a bug in the generic code, but it isn't that
11251 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11253 ;; P6 processors will jump to the address after the decrement when %esp
11254 ;; is used as a call operand, so they will execute return address as a code.
11255 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11257 ;; Register constraint for call instruction.
11258 (define_mode_attr c [(SI "l") (DI "r")])
11260 ;; Call subroutine returning no value.
11262 (define_expand "call"
11263 [(call (match_operand:QI 0 "" "")
11264 (match_operand 1 "" ""))
11265 (use (match_operand 2 "" ""))]
11268 ix86_expand_call (NULL, operands[0], operands[1],
11269 operands[2], NULL, false);
11273 (define_expand "sibcall"
11274 [(call (match_operand:QI 0 "" "")
11275 (match_operand 1 "" ""))
11276 (use (match_operand 2 "" ""))]
11279 ix86_expand_call (NULL, operands[0], operands[1],
11280 operands[2], NULL, true);
11284 (define_insn_and_split "*call_vzeroupper"
11285 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11286 (match_operand 1 "" ""))
11287 (unspec [(match_operand 2 "const_int_operand" "")]
11288 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11289 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11291 "&& reload_completed"
11293 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11294 [(set_attr "type" "call")])
11296 (define_insn "*call"
11297 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11298 (match_operand 1 "" ""))]
11299 "!SIBLING_CALL_P (insn)"
11300 "* return ix86_output_call_insn (insn, operands[0]);"
11301 [(set_attr "type" "call")])
11303 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11304 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11305 (match_operand 1 "" ""))
11306 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11307 (clobber (reg:TI XMM6_REG))
11308 (clobber (reg:TI XMM7_REG))
11309 (clobber (reg:TI XMM8_REG))
11310 (clobber (reg:TI XMM9_REG))
11311 (clobber (reg:TI XMM10_REG))
11312 (clobber (reg:TI XMM11_REG))
11313 (clobber (reg:TI XMM12_REG))
11314 (clobber (reg:TI XMM13_REG))
11315 (clobber (reg:TI XMM14_REG))
11316 (clobber (reg:TI XMM15_REG))
11317 (clobber (reg:DI SI_REG))
11318 (clobber (reg:DI DI_REG))
11319 (unspec [(match_operand 2 "const_int_operand" "")]
11320 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11321 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11323 "&& reload_completed"
11325 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11326 [(set_attr "type" "call")])
11328 (define_insn "*call_rex64_ms_sysv"
11329 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11330 (match_operand 1 "" ""))
11331 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11332 (clobber (reg:TI XMM6_REG))
11333 (clobber (reg:TI XMM7_REG))
11334 (clobber (reg:TI XMM8_REG))
11335 (clobber (reg:TI XMM9_REG))
11336 (clobber (reg:TI XMM10_REG))
11337 (clobber (reg:TI XMM11_REG))
11338 (clobber (reg:TI XMM12_REG))
11339 (clobber (reg:TI XMM13_REG))
11340 (clobber (reg:TI XMM14_REG))
11341 (clobber (reg:TI XMM15_REG))
11342 (clobber (reg:DI SI_REG))
11343 (clobber (reg:DI DI_REG))]
11344 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11345 "* return ix86_output_call_insn (insn, operands[0]);"
11346 [(set_attr "type" "call")])
11348 (define_insn_and_split "*sibcall_vzeroupper"
11349 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11350 (match_operand 1 "" ""))
11351 (unspec [(match_operand 2 "const_int_operand" "")]
11352 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11353 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11355 "&& reload_completed"
11357 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11358 [(set_attr "type" "call")])
11360 (define_insn "*sibcall"
11361 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11362 (match_operand 1 "" ""))]
11363 "SIBLING_CALL_P (insn)"
11364 "* return ix86_output_call_insn (insn, operands[0]);"
11365 [(set_attr "type" "call")])
11367 (define_expand "call_pop"
11368 [(parallel [(call (match_operand:QI 0 "" "")
11369 (match_operand:SI 1 "" ""))
11370 (set (reg:SI SP_REG)
11371 (plus:SI (reg:SI SP_REG)
11372 (match_operand:SI 3 "" "")))])]
11375 ix86_expand_call (NULL, operands[0], operands[1],
11376 operands[2], operands[3], false);
11380 (define_insn_and_split "*call_pop_vzeroupper"
11381 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11382 (match_operand:SI 1 "" ""))
11383 (set (reg:SI SP_REG)
11384 (plus:SI (reg:SI SP_REG)
11385 (match_operand:SI 2 "immediate_operand" "i")))
11386 (unspec [(match_operand 3 "const_int_operand" "")]
11387 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11388 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11390 "&& reload_completed"
11392 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11393 [(set_attr "type" "call")])
11395 (define_insn "*call_pop"
11396 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11397 (match_operand 1 "" ""))
11398 (set (reg:SI SP_REG)
11399 (plus:SI (reg:SI SP_REG)
11400 (match_operand:SI 2 "immediate_operand" "i")))]
11401 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11402 "* return ix86_output_call_insn (insn, operands[0]);"
11403 [(set_attr "type" "call")])
11405 (define_insn_and_split "*sibcall_pop_vzeroupper"
11406 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11407 (match_operand 1 "" ""))
11408 (set (reg:SI SP_REG)
11409 (plus:SI (reg:SI SP_REG)
11410 (match_operand:SI 2 "immediate_operand" "i")))
11411 (unspec [(match_operand 3 "const_int_operand" "")]
11412 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11413 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11415 "&& reload_completed"
11417 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11418 [(set_attr "type" "call")])
11420 (define_insn "*sibcall_pop"
11421 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11422 (match_operand 1 "" ""))
11423 (set (reg:SI SP_REG)
11424 (plus:SI (reg:SI SP_REG)
11425 (match_operand:SI 2 "immediate_operand" "i")))]
11426 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11427 "* return ix86_output_call_insn (insn, operands[0]);"
11428 [(set_attr "type" "call")])
11430 ;; Call subroutine, returning value in operand 0
11432 (define_expand "call_value"
11433 [(set (match_operand 0 "" "")
11434 (call (match_operand:QI 1 "" "")
11435 (match_operand 2 "" "")))
11436 (use (match_operand 3 "" ""))]
11439 ix86_expand_call (operands[0], operands[1], operands[2],
11440 operands[3], NULL, false);
11444 (define_expand "sibcall_value"
11445 [(set (match_operand 0 "" "")
11446 (call (match_operand:QI 1 "" "")
11447 (match_operand 2 "" "")))
11448 (use (match_operand 3 "" ""))]
11451 ix86_expand_call (operands[0], operands[1], operands[2],
11452 operands[3], NULL, true);
11456 (define_insn_and_split "*call_value_vzeroupper"
11457 [(set (match_operand 0 "" "")
11458 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11459 (match_operand 2 "" "")))
11460 (unspec [(match_operand 3 "const_int_operand" "")]
11461 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11462 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11464 "&& reload_completed"
11466 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11467 [(set_attr "type" "callv")])
11469 (define_insn "*call_value"
11470 [(set (match_operand 0 "" "")
11471 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11472 (match_operand 2 "" "")))]
11473 "!SIBLING_CALL_P (insn)"
11474 "* return ix86_output_call_insn (insn, operands[1]);"
11475 [(set_attr "type" "callv")])
11477 (define_insn_and_split "*sibcall_value_vzeroupper"
11478 [(set (match_operand 0 "" "")
11479 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11480 (match_operand 2 "" "")))
11481 (unspec [(match_operand 3 "const_int_operand" "")]
11482 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11483 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11485 "&& reload_completed"
11487 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11488 [(set_attr "type" "callv")])
11490 (define_insn "*sibcall_value"
11491 [(set (match_operand 0 "" "")
11492 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11493 (match_operand 2 "" "")))]
11494 "SIBLING_CALL_P (insn)"
11495 "* return ix86_output_call_insn (insn, operands[1]);"
11496 [(set_attr "type" "callv")])
11498 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11499 [(set (match_operand 0 "" "")
11500 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11501 (match_operand 2 "" "")))
11502 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11503 (clobber (reg:TI XMM6_REG))
11504 (clobber (reg:TI XMM7_REG))
11505 (clobber (reg:TI XMM8_REG))
11506 (clobber (reg:TI XMM9_REG))
11507 (clobber (reg:TI XMM10_REG))
11508 (clobber (reg:TI XMM11_REG))
11509 (clobber (reg:TI XMM12_REG))
11510 (clobber (reg:TI XMM13_REG))
11511 (clobber (reg:TI XMM14_REG))
11512 (clobber (reg:TI XMM15_REG))
11513 (clobber (reg:DI SI_REG))
11514 (clobber (reg:DI DI_REG))
11515 (unspec [(match_operand 3 "const_int_operand" "")]
11516 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11517 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519 "&& reload_completed"
11521 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11522 [(set_attr "type" "callv")])
11524 (define_insn "*call_value_rex64_ms_sysv"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11527 (match_operand 2 "" "")))
11528 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11529 (clobber (reg:TI XMM6_REG))
11530 (clobber (reg:TI XMM7_REG))
11531 (clobber (reg:TI XMM8_REG))
11532 (clobber (reg:TI XMM9_REG))
11533 (clobber (reg:TI XMM10_REG))
11534 (clobber (reg:TI XMM11_REG))
11535 (clobber (reg:TI XMM12_REG))
11536 (clobber (reg:TI XMM13_REG))
11537 (clobber (reg:TI XMM14_REG))
11538 (clobber (reg:TI XMM15_REG))
11539 (clobber (reg:DI SI_REG))
11540 (clobber (reg:DI DI_REG))]
11541 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11542 "* return ix86_output_call_insn (insn, operands[1]);"
11543 [(set_attr "type" "callv")])
11545 (define_expand "call_value_pop"
11546 [(parallel [(set (match_operand 0 "" "")
11547 (call (match_operand:QI 1 "" "")
11548 (match_operand:SI 2 "" "")))
11549 (set (reg:SI SP_REG)
11550 (plus:SI (reg:SI SP_REG)
11551 (match_operand:SI 4 "" "")))])]
11554 ix86_expand_call (operands[0], operands[1], operands[2],
11555 operands[3], operands[4], false);
11559 (define_insn_and_split "*call_value_pop_vzeroupper"
11560 [(set (match_operand 0 "" "")
11561 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11562 (match_operand 2 "" "")))
11563 (set (reg:SI SP_REG)
11564 (plus:SI (reg:SI SP_REG)
11565 (match_operand:SI 3 "immediate_operand" "i")))
11566 (unspec [(match_operand 4 "const_int_operand" "")]
11567 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11568 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11570 "&& reload_completed"
11572 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11573 [(set_attr "type" "callv")])
11575 (define_insn "*call_value_pop"
11576 [(set (match_operand 0 "" "")
11577 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11578 (match_operand 2 "" "")))
11579 (set (reg:SI SP_REG)
11580 (plus:SI (reg:SI SP_REG)
11581 (match_operand:SI 3 "immediate_operand" "i")))]
11582 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11583 "* return ix86_output_call_insn (insn, operands[1]);"
11584 [(set_attr "type" "callv")])
11586 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11587 [(set (match_operand 0 "" "")
11588 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11589 (match_operand 2 "" "")))
11590 (set (reg:SI SP_REG)
11591 (plus:SI (reg:SI SP_REG)
11592 (match_operand:SI 3 "immediate_operand" "i")))
11593 (unspec [(match_operand 4 "const_int_operand" "")]
11594 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11595 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11597 "&& reload_completed"
11599 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11600 [(set_attr "type" "callv")])
11602 (define_insn "*sibcall_value_pop"
11603 [(set (match_operand 0 "" "")
11604 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11605 (match_operand 2 "" "")))
11606 (set (reg:SI SP_REG)
11607 (plus:SI (reg:SI SP_REG)
11608 (match_operand:SI 3 "immediate_operand" "i")))]
11609 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11610 "* return ix86_output_call_insn (insn, operands[1]);"
11611 [(set_attr "type" "callv")])
11613 ;; Call subroutine returning any type.
11615 (define_expand "untyped_call"
11616 [(parallel [(call (match_operand 0 "" "")
11618 (match_operand 1 "" "")
11619 (match_operand 2 "" "")])]
11624 /* In order to give reg-stack an easier job in validating two
11625 coprocessor registers as containing a possible return value,
11626 simply pretend the untyped call returns a complex long double
11629 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11630 and should have the default ABI. */
11632 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11633 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11634 operands[0], const0_rtx,
11635 GEN_INT ((TARGET_64BIT
11636 ? (ix86_abi == SYSV_ABI
11637 ? X86_64_SSE_REGPARM_MAX
11638 : X86_64_MS_SSE_REGPARM_MAX)
11639 : X86_32_SSE_REGPARM_MAX)
11643 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11645 rtx set = XVECEXP (operands[2], 0, i);
11646 emit_move_insn (SET_DEST (set), SET_SRC (set));
11649 /* The optimizer does not know that the call sets the function value
11650 registers we stored in the result block. We avoid problems by
11651 claiming that all hard registers are used and clobbered at this
11653 emit_insn (gen_blockage ());
11658 ;; Prologue and epilogue instructions
11660 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11661 ;; all of memory. This blocks insns from being moved across this point.
11663 (define_insn "blockage"
11664 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11667 [(set_attr "length" "0")])
11669 ;; Do not schedule instructions accessing memory across this point.
11671 (define_expand "memory_blockage"
11672 [(set (match_dup 0)
11673 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11676 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11677 MEM_VOLATILE_P (operands[0]) = 1;
11680 (define_insn "*memory_blockage"
11681 [(set (match_operand:BLK 0 "" "")
11682 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11685 [(set_attr "length" "0")])
11687 ;; As USE insns aren't meaningful after reload, this is used instead
11688 ;; to prevent deleting instructions setting registers for PIC code
11689 (define_insn "prologue_use"
11690 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11693 [(set_attr "length" "0")])
11695 ;; Insn emitted into the body of a function to return from a function.
11696 ;; This is only done if the function's epilogue is known to be simple.
11697 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11699 (define_expand "return"
11701 "ix86_can_use_return_insn_p ()"
11703 if (crtl->args.pops_args)
11705 rtx popc = GEN_INT (crtl->args.pops_args);
11706 emit_jump_insn (gen_simple_return_pop_internal (popc));
11711 (define_expand "simple_return"
11715 if (crtl->args.pops_args)
11717 rtx popc = GEN_INT (crtl->args.pops_args);
11718 emit_jump_insn (gen_simple_return_pop_internal (popc));
11723 (define_insn "simple_return_internal"
11727 [(set_attr "length" "1")
11728 (set_attr "atom_unit" "jeu")
11729 (set_attr "length_immediate" "0")
11730 (set_attr "modrm" "0")])
11732 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11733 ;; instruction Athlon and K8 have.
11735 (define_insn "simple_return_internal_long"
11737 (unspec [(const_int 0)] UNSPEC_REP)]
11740 [(set_attr "length" "2")
11741 (set_attr "atom_unit" "jeu")
11742 (set_attr "length_immediate" "0")
11743 (set_attr "prefix_rep" "1")
11744 (set_attr "modrm" "0")])
11746 (define_insn "simple_return_pop_internal"
11748 (use (match_operand:SI 0 "const_int_operand" ""))]
11751 [(set_attr "length" "3")
11752 (set_attr "atom_unit" "jeu")
11753 (set_attr "length_immediate" "2")
11754 (set_attr "modrm" "0")])
11756 (define_insn "simple_return_indirect_internal"
11758 (use (match_operand:SI 0 "register_operand" "r"))]
11761 [(set_attr "type" "ibr")
11762 (set_attr "length_immediate" "0")])
11768 [(set_attr "length" "1")
11769 (set_attr "length_immediate" "0")
11770 (set_attr "modrm" "0")])
11772 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11773 (define_insn "nops"
11774 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11778 int num = INTVAL (operands[0]);
11780 gcc_assert (num >= 1 && num <= 8);
11783 fputs ("\tnop\n", asm_out_file);
11787 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11788 (set_attr "length_immediate" "0")
11789 (set_attr "modrm" "0")])
11791 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11792 ;; branch prediction penalty for the third jump in a 16-byte
11796 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11799 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11800 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11802 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11803 The align insn is used to avoid 3 jump instructions in the row to improve
11804 branch prediction and the benefits hardly outweigh the cost of extra 8
11805 nops on the average inserted by full alignment pseudo operation. */
11809 [(set_attr "length" "16")])
11811 (define_expand "prologue"
11814 "ix86_expand_prologue (); DONE;")
11816 (define_insn "set_got"
11817 [(set (match_operand:SI 0 "register_operand" "=r")
11818 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11819 (clobber (reg:CC FLAGS_REG))]
11821 "* return output_set_got (operands[0], NULL_RTX);"
11822 [(set_attr "type" "multi")
11823 (set_attr "length" "12")])
11825 (define_insn "set_got_labelled"
11826 [(set (match_operand:SI 0 "register_operand" "=r")
11827 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11829 (clobber (reg:CC FLAGS_REG))]
11831 "* return output_set_got (operands[0], operands[1]);"
11832 [(set_attr "type" "multi")
11833 (set_attr "length" "12")])
11835 (define_insn "set_got_rex64"
11836 [(set (match_operand:DI 0 "register_operand" "=r")
11837 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11839 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11840 [(set_attr "type" "lea")
11841 (set_attr "length_address" "4")
11842 (set_attr "mode" "DI")])
11844 (define_insn "set_rip_rex64"
11845 [(set (match_operand:DI 0 "register_operand" "=r")
11846 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11848 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11849 [(set_attr "type" "lea")
11850 (set_attr "length_address" "4")
11851 (set_attr "mode" "DI")])
11853 (define_insn "set_got_offset_rex64"
11854 [(set (match_operand:DI 0 "register_operand" "=r")
11856 [(label_ref (match_operand 1 "" ""))]
11857 UNSPEC_SET_GOT_OFFSET))]
11859 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11860 [(set_attr "type" "imov")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "length_address" "8")
11863 (set_attr "mode" "DI")])
11865 (define_expand "epilogue"
11868 "ix86_expand_epilogue (1); DONE;")
11870 (define_expand "sibcall_epilogue"
11873 "ix86_expand_epilogue (0); DONE;")
11875 (define_expand "eh_return"
11876 [(use (match_operand 0 "register_operand" ""))]
11879 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11881 /* Tricky bit: we write the address of the handler to which we will
11882 be returning into someone else's stack frame, one word below the
11883 stack address we wish to restore. */
11884 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11885 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11886 tmp = gen_rtx_MEM (Pmode, tmp);
11887 emit_move_insn (tmp, ra);
11889 emit_jump_insn (gen_eh_return_internal ());
11894 (define_insn_and_split "eh_return_internal"
11898 "epilogue_completed"
11900 "ix86_expand_epilogue (2); DONE;")
11902 (define_insn "leave"
11903 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11904 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11905 (clobber (mem:BLK (scratch)))]
11908 [(set_attr "type" "leave")])
11910 (define_insn "leave_rex64"
11911 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11912 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11913 (clobber (mem:BLK (scratch)))]
11916 [(set_attr "type" "leave")])
11918 ;; Handle -fsplit-stack.
11920 (define_expand "split_stack_prologue"
11924 ix86_expand_split_stack_prologue ();
11928 ;; In order to support the call/return predictor, we use a return
11929 ;; instruction which the middle-end doesn't see.
11930 (define_insn "split_stack_return"
11931 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11932 UNSPECV_SPLIT_STACK_RETURN)]
11935 if (operands[0] == const0_rtx)
11940 [(set_attr "atom_unit" "jeu")
11941 (set_attr "modrm" "0")
11942 (set (attr "length")
11943 (if_then_else (match_operand:SI 0 "const0_operand" "")
11946 (set (attr "length_immediate")
11947 (if_then_else (match_operand:SI 0 "const0_operand" "")
11951 ;; If there are operand 0 bytes available on the stack, jump to
11954 (define_expand "split_stack_space_check"
11955 [(set (pc) (if_then_else
11956 (ltu (minus (reg SP_REG)
11957 (match_operand 0 "register_operand" ""))
11958 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11959 (label_ref (match_operand 1 "" ""))
11963 rtx reg, size, limit;
11965 reg = gen_reg_rtx (Pmode);
11966 size = force_reg (Pmode, operands[0]);
11967 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11968 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11969 UNSPEC_STACK_CHECK);
11970 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11971 ix86_expand_branch (GEU, reg, limit, operands[1]);
11976 ;; Bit manipulation instructions.
11978 (define_expand "ffs<mode>2"
11979 [(set (match_dup 2) (const_int -1))
11980 (parallel [(set (reg:CCZ FLAGS_REG)
11982 (match_operand:SWI48 1 "nonimmediate_operand" "")
11984 (set (match_operand:SWI48 0 "register_operand" "")
11985 (ctz:SWI48 (match_dup 1)))])
11986 (set (match_dup 0) (if_then_else:SWI48
11987 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11990 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11991 (clobber (reg:CC FLAGS_REG))])]
11994 if (<MODE>mode == SImode && !TARGET_CMOVE)
11996 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11999 operands[2] = gen_reg_rtx (<MODE>mode);
12002 (define_insn_and_split "ffssi2_no_cmove"
12003 [(set (match_operand:SI 0 "register_operand" "=r")
12004 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12005 (clobber (match_scratch:SI 2 "=&q"))
12006 (clobber (reg:CC FLAGS_REG))]
12009 "&& reload_completed"
12010 [(parallel [(set (reg:CCZ FLAGS_REG)
12011 (compare:CCZ (match_dup 1) (const_int 0)))
12012 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12013 (set (strict_low_part (match_dup 3))
12014 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12015 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12016 (clobber (reg:CC FLAGS_REG))])
12017 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12019 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12020 (clobber (reg:CC FLAGS_REG))])]
12022 operands[3] = gen_lowpart (QImode, operands[2]);
12023 ix86_expand_clear (operands[2]);
12026 (define_insn "*ffs<mode>_1"
12027 [(set (reg:CCZ FLAGS_REG)
12028 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12030 (set (match_operand:SWI48 0 "register_operand" "=r")
12031 (ctz:SWI48 (match_dup 1)))]
12033 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12034 [(set_attr "type" "alu1")
12035 (set_attr "prefix_0f" "1")
12036 (set_attr "mode" "<MODE>")])
12038 (define_insn "ctz<mode>2"
12039 [(set (match_operand:SWI248 0 "register_operand" "=r")
12040 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12041 (clobber (reg:CC FLAGS_REG))]
12045 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12047 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12049 [(set_attr "type" "alu1")
12050 (set_attr "prefix_0f" "1")
12051 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12052 (set_attr "mode" "<MODE>")])
12054 (define_expand "clz<mode>2"
12056 [(set (match_operand:SWI248 0 "register_operand" "")
12059 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12060 (clobber (reg:CC FLAGS_REG))])
12062 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12063 (clobber (reg:CC FLAGS_REG))])]
12068 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12071 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12074 (define_insn "clz<mode>2_lzcnt"
12075 [(set (match_operand:SWI248 0 "register_operand" "=r")
12076 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12077 (clobber (reg:CC FLAGS_REG))]
12079 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12080 [(set_attr "prefix_rep" "1")
12081 (set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12084 ;; BMI instructions.
12085 (define_insn "*bmi_andn_<mode>"
12086 [(set (match_operand:SWI48 0 "register_operand" "=r")
12089 (match_operand:SWI48 1 "register_operand" "r"))
12090 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12091 (clobber (reg:CC FLAGS_REG))]
12093 "andn\t{%2, %1, %0|%0, %1, %2}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "bmi_bextr_<mode>"
12098 [(set (match_operand:SWI48 0 "register_operand" "=r")
12099 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12100 (match_operand:SWI48 2 "register_operand" "r")]
12102 (clobber (reg:CC FLAGS_REG))]
12104 "bextr\t{%2, %1, %0|%0, %1, %2}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "mode" "<MODE>")])
12108 (define_insn "*bmi_blsi_<mode>"
12109 [(set (match_operand:SWI48 0 "register_operand" "=r")
12112 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12114 (clobber (reg:CC FLAGS_REG))]
12116 "blsi\t{%1, %0|%0, %1}"
12117 [(set_attr "type" "bitmanip")
12118 (set_attr "mode" "<MODE>")])
12120 (define_insn "*bmi_blsmsk_<mode>"
12121 [(set (match_operand:SWI48 0 "register_operand" "=r")
12124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12127 (clobber (reg:CC FLAGS_REG))]
12129 "blsmsk\t{%1, %0|%0, %1}"
12130 [(set_attr "type" "bitmanip")
12131 (set_attr "mode" "<MODE>")])
12133 (define_insn "*bmi_blsr_<mode>"
12134 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140 (clobber (reg:CC FLAGS_REG))]
12142 "blsr\t{%1, %0|%0, %1}"
12143 [(set_attr "type" "bitmanip")
12144 (set_attr "mode" "<MODE>")])
12146 ;; BMI2 instructions.
12147 (define_insn "bmi2_bzhi_<mode>3"
12148 [(set (match_operand:SWI48 0 "register_operand" "=r")
12149 (and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12150 (lshiftrt:SWI48 (const_int -1)
12151 (match_operand:SWI48 2 "register_operand" "r"))))
12152 (clobber (reg:CC FLAGS_REG))]
12154 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12155 [(set_attr "type" "bitmanip")
12156 (set_attr "prefix" "vex")
12157 (set_attr "mode" "<MODE>")])
12159 (define_insn "bmi2_pdep_<mode>3"
12160 [(set (match_operand:SWI48 0 "register_operand" "=r")
12161 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12162 (match_operand:SWI48 2 "register_operand" "r")]
12165 "pdep\t{%2, %1, %0|%0, %1, %2}"
12166 [(set_attr "type" "bitmanip")
12167 (set_attr "prefix" "vex")
12168 (set_attr "mode" "<MODE>")])
12170 (define_insn "bmi2_pext_<mode>3"
12171 [(set (match_operand:SWI48 0 "register_operand" "=r")
12172 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12173 (match_operand:SWI48 2 "register_operand" "r")]
12176 "pext\t{%2, %1, %0|%0, %1, %2}"
12177 [(set_attr "type" "bitmanip")
12178 (set_attr "prefix" "vex")
12179 (set_attr "mode" "<MODE>")])
12181 ;; TBM instructions.
12182 (define_insn "tbm_bextri_<mode>"
12183 [(set (match_operand:SWI48 0 "register_operand" "=r")
12184 (zero_extract:SWI48
12185 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12186 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12187 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12188 (clobber (reg:CC FLAGS_REG))]
12191 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12192 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "mode" "<MODE>")])
12197 (define_insn "*tbm_blcfill_<mode>"
12198 [(set (match_operand:SWI48 0 "register_operand" "=r")
12201 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204 (clobber (reg:CC FLAGS_REG))]
12206 "blcfill\t{%1, %0|%0, %1}"
12207 [(set_attr "type" "bitmanip")
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "*tbm_blci_<mode>"
12211 [(set (match_operand:SWI48 0 "register_operand" "=r")
12215 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218 (clobber (reg:CC FLAGS_REG))]
12220 "blci\t{%1, %0|%0, %1}"
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "mode" "<MODE>")])
12224 (define_insn "*tbm_blcic_<mode>"
12225 [(set (match_operand:SWI48 0 "register_operand" "=r")
12228 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12232 (clobber (reg:CC FLAGS_REG))]
12234 "blcic\t{%1, %0|%0, %1}"
12235 [(set_attr "type" "bitmanip")
12236 (set_attr "mode" "<MODE>")])
12238 (define_insn "*tbm_blcmsk_<mode>"
12239 [(set (match_operand:SWI48 0 "register_operand" "=r")
12242 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12245 (clobber (reg:CC FLAGS_REG))]
12247 "blcmsk\t{%1, %0|%0, %1}"
12248 [(set_attr "type" "bitmanip")
12249 (set_attr "mode" "<MODE>")])
12251 (define_insn "*tbm_blcs_<mode>"
12252 [(set (match_operand:SWI48 0 "register_operand" "=r")
12255 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258 (clobber (reg:CC FLAGS_REG))]
12260 "blcs\t{%1, %0|%0, %1}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "mode" "<MODE>")])
12264 (define_insn "*tbm_blsfill_<mode>"
12265 [(set (match_operand:SWI48 0 "register_operand" "=r")
12268 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271 (clobber (reg:CC FLAGS_REG))]
12273 "blsfill\t{%1, %0|%0, %1}"
12274 [(set_attr "type" "bitmanip")
12275 (set_attr "mode" "<MODE>")])
12277 (define_insn "*tbm_blsic_<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 "blsic\t{%1, %0|%0, %1}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*tbm_t1mskc_<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 "t1mskc\t{%1, %0|%0, %1}"
12302 [(set_attr "type" "bitmanip")
12303 (set_attr "mode" "<MODE>")])
12305 (define_insn "*tbm_tzmsk_<mode>"
12306 [(set (match_operand:SWI48 0 "register_operand" "=r")
12309 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313 (clobber (reg:CC FLAGS_REG))]
12315 "tzmsk\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "bitmanip")
12317 (set_attr "mode" "<MODE>")])
12319 (define_insn "bsr_rex64"
12320 [(set (match_operand:DI 0 "register_operand" "=r")
12321 (minus:DI (const_int 63)
12322 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12323 (clobber (reg:CC FLAGS_REG))]
12325 "bsr{q}\t{%1, %0|%0, %1}"
12326 [(set_attr "type" "alu1")
12327 (set_attr "prefix_0f" "1")
12328 (set_attr "mode" "DI")])
12331 [(set (match_operand:SI 0 "register_operand" "=r")
12332 (minus:SI (const_int 31)
12333 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12334 (clobber (reg:CC FLAGS_REG))]
12336 "bsr{l}\t{%1, %0|%0, %1}"
12337 [(set_attr "type" "alu1")
12338 (set_attr "prefix_0f" "1")
12339 (set_attr "mode" "SI")])
12341 (define_insn "*bsrhi"
12342 [(set (match_operand:HI 0 "register_operand" "=r")
12343 (minus:HI (const_int 15)
12344 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12345 (clobber (reg:CC FLAGS_REG))]
12347 "bsr{w}\t{%1, %0|%0, %1}"
12348 [(set_attr "type" "alu1")
12349 (set_attr "prefix_0f" "1")
12350 (set_attr "mode" "HI")])
12352 (define_insn "popcount<mode>2"
12353 [(set (match_operand:SWI248 0 "register_operand" "=r")
12355 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12356 (clobber (reg:CC FLAGS_REG))]
12360 return "popcnt\t{%1, %0|%0, %1}";
12362 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12365 [(set_attr "prefix_rep" "1")
12366 (set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "*popcount<mode>2_cmp"
12370 [(set (reg FLAGS_REG)
12373 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12375 (set (match_operand:SWI248 0 "register_operand" "=r")
12376 (popcount:SWI248 (match_dup 1)))]
12377 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12380 return "popcnt\t{%1, %0|%0, %1}";
12382 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12385 [(set_attr "prefix_rep" "1")
12386 (set_attr "type" "bitmanip")
12387 (set_attr "mode" "<MODE>")])
12389 (define_insn "*popcountsi2_cmp_zext"
12390 [(set (reg FLAGS_REG)
12392 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12394 (set (match_operand:DI 0 "register_operand" "=r")
12395 (zero_extend:DI(popcount:SI (match_dup 1))))]
12396 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12399 return "popcnt\t{%1, %0|%0, %1}";
12401 return "popcnt{l}\t{%1, %0|%0, %1}";
12404 [(set_attr "prefix_rep" "1")
12405 (set_attr "type" "bitmanip")
12406 (set_attr "mode" "SI")])
12408 (define_expand "bswap<mode>2"
12409 [(set (match_operand:SWI48 0 "register_operand" "")
12410 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12413 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12415 rtx x = operands[0];
12417 emit_move_insn (x, operands[1]);
12418 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12419 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12420 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12425 (define_insn "*bswap<mode>2_movbe"
12426 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12427 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12429 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12432 movbe\t{%1, %0|%0, %1}
12433 movbe\t{%1, %0|%0, %1}"
12434 [(set_attr "type" "bitmanip,imov,imov")
12435 (set_attr "modrm" "0,1,1")
12436 (set_attr "prefix_0f" "*,1,1")
12437 (set_attr "prefix_extra" "*,1,1")
12438 (set_attr "mode" "<MODE>")])
12440 (define_insn "*bswap<mode>2_1"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12445 [(set_attr "type" "bitmanip")
12446 (set_attr "modrm" "0")
12447 (set_attr "mode" "<MODE>")])
12449 (define_insn "*bswaphi_lowpart_1"
12450 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12451 (bswap:HI (match_dup 0)))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12455 xchg{b}\t{%h0, %b0|%b0, %h0}
12456 rol{w}\t{$8, %0|%0, 8}"
12457 [(set_attr "length" "2,4")
12458 (set_attr "mode" "QI,HI")])
12460 (define_insn "bswaphi_lowpart"
12461 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12462 (bswap:HI (match_dup 0)))
12463 (clobber (reg:CC FLAGS_REG))]
12465 "rol{w}\t{$8, %0|%0, 8}"
12466 [(set_attr "length" "4")
12467 (set_attr "mode" "HI")])
12469 (define_expand "paritydi2"
12470 [(set (match_operand:DI 0 "register_operand" "")
12471 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12474 rtx scratch = gen_reg_rtx (QImode);
12477 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12478 NULL_RTX, operands[1]));
12480 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12481 gen_rtx_REG (CCmode, FLAGS_REG),
12483 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12486 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12489 rtx tmp = gen_reg_rtx (SImode);
12491 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12492 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12497 (define_expand "paritysi2"
12498 [(set (match_operand:SI 0 "register_operand" "")
12499 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12502 rtx scratch = gen_reg_rtx (QImode);
12505 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12507 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12508 gen_rtx_REG (CCmode, FLAGS_REG),
12510 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12512 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12516 (define_insn_and_split "paritydi2_cmp"
12517 [(set (reg:CC FLAGS_REG)
12518 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12520 (clobber (match_scratch:DI 0 "=r"))
12521 (clobber (match_scratch:SI 1 "=&r"))
12522 (clobber (match_scratch:HI 2 "=Q"))]
12525 "&& reload_completed"
12527 [(set (match_dup 1)
12528 (xor:SI (match_dup 1) (match_dup 4)))
12529 (clobber (reg:CC FLAGS_REG))])
12531 [(set (reg:CC FLAGS_REG)
12532 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12533 (clobber (match_dup 1))
12534 (clobber (match_dup 2))])]
12536 operands[4] = gen_lowpart (SImode, operands[3]);
12540 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12541 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12544 operands[1] = gen_highpart (SImode, operands[3]);
12547 (define_insn_and_split "paritysi2_cmp"
12548 [(set (reg:CC FLAGS_REG)
12549 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12551 (clobber (match_scratch:SI 0 "=r"))
12552 (clobber (match_scratch:HI 1 "=&Q"))]
12555 "&& reload_completed"
12557 [(set (match_dup 1)
12558 (xor:HI (match_dup 1) (match_dup 3)))
12559 (clobber (reg:CC FLAGS_REG))])
12561 [(set (reg:CC FLAGS_REG)
12562 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12563 (clobber (match_dup 1))])]
12565 operands[3] = gen_lowpart (HImode, operands[2]);
12567 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12568 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12571 (define_insn "*parityhi2_cmp"
12572 [(set (reg:CC FLAGS_REG)
12573 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12575 (clobber (match_scratch:HI 0 "=Q"))]
12577 "xor{b}\t{%h0, %b0|%b0, %h0}"
12578 [(set_attr "length" "2")
12579 (set_attr "mode" "HI")])
12582 ;; Thread-local storage patterns for ELF.
12584 ;; Note that these code sequences must appear exactly as shown
12585 ;; in order to allow linker relaxation.
12587 (define_insn "*tls_global_dynamic_32_gnu"
12588 [(set (match_operand:SI 0 "register_operand" "=a")
12590 [(match_operand:SI 1 "register_operand" "b")
12591 (match_operand:SI 2 "tls_symbolic_operand" "")
12592 (match_operand:SI 3 "constant_call_address_operand" "z")]
12594 (clobber (match_scratch:SI 4 "=d"))
12595 (clobber (match_scratch:SI 5 "=c"))
12596 (clobber (reg:CC FLAGS_REG))]
12597 "!TARGET_64BIT && TARGET_GNU_TLS"
12600 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12601 if (TARGET_SUN_TLS)
12602 #ifdef HAVE_AS_IX86_TLSGDPLT
12603 return "call\t%a2@tlsgdplt";
12605 return "call\t%p3@plt";
12607 return "call\t%P3";
12609 [(set_attr "type" "multi")
12610 (set_attr "length" "12")])
12612 (define_expand "tls_global_dynamic_32"
12614 [(set (match_operand:SI 0 "register_operand" "")
12615 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12616 (match_operand:SI 1 "tls_symbolic_operand" "")
12617 (match_operand:SI 3 "constant_call_address_operand" "")]
12619 (clobber (match_scratch:SI 4 ""))
12620 (clobber (match_scratch:SI 5 ""))
12621 (clobber (reg:CC FLAGS_REG))])])
12623 (define_insn "*tls_global_dynamic_64"
12624 [(set (match_operand:DI 0 "register_operand" "=a")
12626 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12627 (match_operand:DI 3 "" "")))
12628 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12633 fputs (ASM_BYTE "0x66\n", asm_out_file);
12635 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12636 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12637 fputs ("\trex64\n", asm_out_file);
12638 if (TARGET_SUN_TLS)
12639 return "call\t%p2@plt";
12640 return "call\t%P2";
12642 [(set_attr "type" "multi")
12643 (set (attr "length")
12644 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12646 (define_expand "tls_global_dynamic_64"
12648 [(set (match_operand:DI 0 "register_operand" "")
12650 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12652 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12655 (define_insn "*tls_local_dynamic_base_32_gnu"
12656 [(set (match_operand:SI 0 "register_operand" "=a")
12658 [(match_operand:SI 1 "register_operand" "b")
12659 (match_operand:SI 2 "constant_call_address_operand" "z")]
12660 UNSPEC_TLS_LD_BASE))
12661 (clobber (match_scratch:SI 3 "=d"))
12662 (clobber (match_scratch:SI 4 "=c"))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "!TARGET_64BIT && TARGET_GNU_TLS"
12667 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12668 if (TARGET_SUN_TLS)
12669 #ifdef HAVE_AS_IX86_TLSLDMPLT
12670 return "call\t%&@tlsldmplt";
12672 return "call\t%p2@plt";
12674 return "call\t%P2";
12676 [(set_attr "type" "multi")
12677 (set_attr "length" "11")])
12679 (define_expand "tls_local_dynamic_base_32"
12681 [(set (match_operand:SI 0 "register_operand" "")
12683 [(match_operand:SI 1 "register_operand" "")
12684 (match_operand:SI 2 "constant_call_address_operand" "")]
12685 UNSPEC_TLS_LD_BASE))
12686 (clobber (match_scratch:SI 3 ""))
12687 (clobber (match_scratch:SI 4 ""))
12688 (clobber (reg:CC FLAGS_REG))])])
12690 (define_insn "*tls_local_dynamic_base_64"
12691 [(set (match_operand:DI 0 "register_operand" "=a")
12693 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12694 (match_operand:DI 2 "" "")))
12695 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12699 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12700 if (TARGET_SUN_TLS)
12701 return "call\t%p1@plt";
12702 return "call\t%P1";
12704 [(set_attr "type" "multi")
12705 (set_attr "length" "12")])
12707 (define_expand "tls_local_dynamic_base_64"
12709 [(set (match_operand:DI 0 "register_operand" "")
12711 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12713 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12715 ;; Local dynamic of a single variable is a lose. Show combine how
12716 ;; to convert that back to global dynamic.
12718 (define_insn_and_split "*tls_local_dynamic_32_once"
12719 [(set (match_operand:SI 0 "register_operand" "=a")
12721 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12722 (match_operand:SI 2 "constant_call_address_operand" "z")]
12723 UNSPEC_TLS_LD_BASE)
12724 (const:SI (unspec:SI
12725 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12727 (clobber (match_scratch:SI 4 "=d"))
12728 (clobber (match_scratch:SI 5 "=c"))
12729 (clobber (reg:CC FLAGS_REG))]
12734 [(set (match_dup 0)
12735 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12737 (clobber (match_dup 4))
12738 (clobber (match_dup 5))
12739 (clobber (reg:CC FLAGS_REG))])])
12741 ;; Segment register for the thread base ptr load
12742 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12744 ;; Load and add the thread base pointer from %<tp_seg>:0.
12745 (define_insn "*load_tp_x32"
12746 [(set (match_operand:SI 0 "register_operand" "=r")
12747 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12749 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12750 [(set_attr "type" "imov")
12751 (set_attr "modrm" "0")
12752 (set_attr "length" "7")
12753 (set_attr "memory" "load")
12754 (set_attr "imm_disp" "false")])
12756 (define_insn "*load_tp_x32_zext"
12757 [(set (match_operand:DI 0 "register_operand" "=r")
12758 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12760 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12761 [(set_attr "type" "imov")
12762 (set_attr "modrm" "0")
12763 (set_attr "length" "7")
12764 (set_attr "memory" "load")
12765 (set_attr "imm_disp" "false")])
12767 (define_insn "*load_tp_<mode>"
12768 [(set (match_operand:P 0 "register_operand" "=r")
12769 (unspec:P [(const_int 0)] UNSPEC_TP))]
12771 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12772 [(set_attr "type" "imov")
12773 (set_attr "modrm" "0")
12774 (set_attr "length" "7")
12775 (set_attr "memory" "load")
12776 (set_attr "imm_disp" "false")])
12778 (define_insn "*add_tp_x32"
12779 [(set (match_operand:SI 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, %0|%0, 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_x32_zext"
12792 [(set (match_operand:DI 0 "register_operand" "=r")
12794 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12795 (match_operand:SI 1 "register_operand" "0"))))
12796 (clobber (reg:CC FLAGS_REG))]
12798 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12799 [(set_attr "type" "alu")
12800 (set_attr "modrm" "0")
12801 (set_attr "length" "7")
12802 (set_attr "memory" "load")
12803 (set_attr "imm_disp" "false")])
12805 (define_insn "*add_tp_<mode>"
12806 [(set (match_operand:P 0 "register_operand" "=r")
12807 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12808 (match_operand:P 1 "register_operand" "0")))
12809 (clobber (reg:CC FLAGS_REG))]
12811 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12812 [(set_attr "type" "alu")
12813 (set_attr "modrm" "0")
12814 (set_attr "length" "7")
12815 (set_attr "memory" "load")
12816 (set_attr "imm_disp" "false")])
12818 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12819 ;; %rax as destination of the initial executable code sequence.
12820 (define_insn "tls_initial_exec_64_sun"
12821 [(set (match_operand:DI 0 "register_operand" "=a")
12823 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12824 UNSPEC_TLS_IE_SUN))
12825 (clobber (reg:CC FLAGS_REG))]
12826 "TARGET_64BIT && TARGET_SUN_TLS"
12829 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12830 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12832 [(set_attr "type" "multi")])
12834 ;; GNU2 TLS patterns can be split.
12836 (define_expand "tls_dynamic_gnu2_32"
12837 [(set (match_dup 3)
12838 (plus:SI (match_operand:SI 2 "register_operand" "")
12840 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12843 [(set (match_operand:SI 0 "register_operand" "")
12844 (unspec:SI [(match_dup 1) (match_dup 3)
12845 (match_dup 2) (reg:SI SP_REG)]
12847 (clobber (reg:CC FLAGS_REG))])]
12848 "!TARGET_64BIT && TARGET_GNU2_TLS"
12850 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12851 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12854 (define_insn "*tls_dynamic_gnu2_lea_32"
12855 [(set (match_operand:SI 0 "register_operand" "=r")
12856 (plus:SI (match_operand:SI 1 "register_operand" "b")
12858 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12859 UNSPEC_TLSDESC))))]
12860 "!TARGET_64BIT && TARGET_GNU2_TLS"
12861 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12862 [(set_attr "type" "lea")
12863 (set_attr "mode" "SI")
12864 (set_attr "length" "6")
12865 (set_attr "length_address" "4")])
12867 (define_insn "*tls_dynamic_gnu2_call_32"
12868 [(set (match_operand:SI 0 "register_operand" "=a")
12869 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12870 (match_operand:SI 2 "register_operand" "0")
12871 ;; we have to make sure %ebx still points to the GOT
12872 (match_operand:SI 3 "register_operand" "b")
12875 (clobber (reg:CC FLAGS_REG))]
12876 "!TARGET_64BIT && TARGET_GNU2_TLS"
12877 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12878 [(set_attr "type" "call")
12879 (set_attr "length" "2")
12880 (set_attr "length_address" "0")])
12882 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12883 [(set (match_operand:SI 0 "register_operand" "=&a")
12885 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12886 (match_operand:SI 4 "" "")
12887 (match_operand:SI 2 "register_operand" "b")
12890 (const:SI (unspec:SI
12891 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12893 (clobber (reg:CC FLAGS_REG))]
12894 "!TARGET_64BIT && TARGET_GNU2_TLS"
12897 [(set (match_dup 0) (match_dup 5))]
12899 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12900 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12903 (define_expand "tls_dynamic_gnu2_64"
12904 [(set (match_dup 2)
12905 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12908 [(set (match_operand:DI 0 "register_operand" "")
12909 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12911 (clobber (reg:CC FLAGS_REG))])]
12912 "TARGET_64BIT && TARGET_GNU2_TLS"
12914 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12915 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12918 (define_insn "*tls_dynamic_gnu2_lea_64"
12919 [(set (match_operand:DI 0 "register_operand" "=r")
12920 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12922 "TARGET_64BIT && TARGET_GNU2_TLS"
12923 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12924 [(set_attr "type" "lea")
12925 (set_attr "mode" "DI")
12926 (set_attr "length" "7")
12927 (set_attr "length_address" "4")])
12929 (define_insn "*tls_dynamic_gnu2_call_64"
12930 [(set (match_operand:DI 0 "register_operand" "=a")
12931 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12932 (match_operand:DI 2 "register_operand" "0")
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && TARGET_GNU2_TLS"
12937 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12938 [(set_attr "type" "call")
12939 (set_attr "length" "2")
12940 (set_attr "length_address" "0")])
12942 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12943 [(set (match_operand:DI 0 "register_operand" "=&a")
12945 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12946 (match_operand:DI 3 "" "")
12949 (const:DI (unspec:DI
12950 [(match_operand 1 "tls_symbolic_operand" "")]
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_64BIT && TARGET_GNU2_TLS"
12956 [(set (match_dup 0) (match_dup 4))]
12958 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12959 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12962 ;; These patterns match the binary 387 instructions for addM3, subM3,
12963 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12964 ;; SFmode. The first is the normal insn, the second the same insn but
12965 ;; with one operand a conversion, and the third the same insn but with
12966 ;; the other operand a conversion. The conversion may be SFmode or
12967 ;; SImode if the target mode DFmode, but only SImode if the target mode
12970 ;; Gcc is slightly more smart about handling normal two address instructions
12971 ;; so use special patterns for add and mull.
12973 (define_insn "*fop_<mode>_comm_mixed"
12974 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12975 (match_operator:MODEF 3 "binary_fp_operator"
12976 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12977 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12979 && COMMUTATIVE_ARITH_P (operands[3])
12980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12981 "* return output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (if_then_else (eq_attr "alternative" "1,2")
12984 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12985 (const_string "ssemul")
12986 (const_string "sseadd"))
12987 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12988 (const_string "fmul")
12989 (const_string "fop"))))
12990 (set_attr "isa" "*,noavx,avx")
12991 (set_attr "prefix" "orig,orig,vex")
12992 (set_attr "mode" "<MODE>")])
12994 (define_insn "*fop_<mode>_comm_sse"
12995 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12996 (match_operator:MODEF 3 "binary_fp_operator"
12997 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12998 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12999 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13000 && COMMUTATIVE_ARITH_P (operands[3])
13001 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13002 "* return output_387_binary_op (insn, operands);"
13003 [(set (attr "type")
13004 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13005 (const_string "ssemul")
13006 (const_string "sseadd")))
13007 (set_attr "isa" "noavx,avx")
13008 (set_attr "prefix" "orig,vex")
13009 (set_attr "mode" "<MODE>")])
13011 (define_insn "*fop_<mode>_comm_i387"
13012 [(set (match_operand:MODEF 0 "register_operand" "=f")
13013 (match_operator:MODEF 3 "binary_fp_operator"
13014 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13015 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13016 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13017 && COMMUTATIVE_ARITH_P (operands[3])
13018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13019 "* return output_387_binary_op (insn, operands);"
13020 [(set (attr "type")
13021 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13022 (const_string "fmul")
13023 (const_string "fop")))
13024 (set_attr "mode" "<MODE>")])
13026 (define_insn "*fop_<mode>_1_mixed"
13027 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13028 (match_operator:MODEF 3 "binary_fp_operator"
13029 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13030 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13031 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13032 && !COMMUTATIVE_ARITH_P (operands[3])
13033 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13034 "* return output_387_binary_op (insn, operands);"
13035 [(set (attr "type")
13036 (cond [(and (eq_attr "alternative" "2,3")
13037 (match_operand:MODEF 3 "mult_operator" ""))
13038 (const_string "ssemul")
13039 (and (eq_attr "alternative" "2,3")
13040 (match_operand:MODEF 3 "div_operator" ""))
13041 (const_string "ssediv")
13042 (eq_attr "alternative" "2,3")
13043 (const_string "sseadd")
13044 (match_operand:MODEF 3 "mult_operator" "")
13045 (const_string "fmul")
13046 (match_operand:MODEF 3 "div_operator" "")
13047 (const_string "fdiv")
13049 (const_string "fop")))
13050 (set_attr "isa" "*,*,noavx,avx")
13051 (set_attr "prefix" "orig,orig,orig,vex")
13052 (set_attr "mode" "<MODE>")])
13054 (define_insn "*rcpsf2_sse"
13055 [(set (match_operand:SF 0 "register_operand" "=x")
13056 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13059 "%vrcpss\t{%1, %d0|%d0, %1}"
13060 [(set_attr "type" "sse")
13061 (set_attr "atom_sse_attr" "rcp")
13062 (set_attr "prefix" "maybe_vex")
13063 (set_attr "mode" "SF")])
13065 (define_insn "*fop_<mode>_1_sse"
13066 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13067 (match_operator:MODEF 3 "binary_fp_operator"
13068 [(match_operand:MODEF 1 "register_operand" "0,x")
13069 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13070 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13071 && !COMMUTATIVE_ARITH_P (operands[3])"
13072 "* return output_387_binary_op (insn, operands);"
13073 [(set (attr "type")
13074 (cond [(match_operand:MODEF 3 "mult_operator" "")
13075 (const_string "ssemul")
13076 (match_operand:MODEF 3 "div_operator" "")
13077 (const_string "ssediv")
13079 (const_string "sseadd")))
13080 (set_attr "isa" "noavx,avx")
13081 (set_attr "prefix" "orig,vex")
13082 (set_attr "mode" "<MODE>")])
13084 ;; This pattern is not fully shadowed by the pattern above.
13085 (define_insn "*fop_<mode>_1_i387"
13086 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13087 (match_operator:MODEF 3 "binary_fp_operator"
13088 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13089 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13090 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13091 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13092 && !COMMUTATIVE_ARITH_P (operands[3])
13093 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13094 "* return output_387_binary_op (insn, operands);"
13095 [(set (attr "type")
13096 (cond [(match_operand:MODEF 3 "mult_operator" "")
13097 (const_string "fmul")
13098 (match_operand:MODEF 3 "div_operator" "")
13099 (const_string "fdiv")
13101 (const_string "fop")))
13102 (set_attr "mode" "<MODE>")])
13104 ;; ??? Add SSE splitters for these!
13105 (define_insn "*fop_<MODEF:mode>_2_i387"
13106 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13107 (match_operator:MODEF 3 "binary_fp_operator"
13109 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13110 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13111 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13112 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13113 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13114 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13115 [(set (attr "type")
13116 (cond [(match_operand:MODEF 3 "mult_operator" "")
13117 (const_string "fmul")
13118 (match_operand:MODEF 3 "div_operator" "")
13119 (const_string "fdiv")
13121 (const_string "fop")))
13122 (set_attr "fp_int_src" "true")
13123 (set_attr "mode" "<SWI24:MODE>")])
13125 (define_insn "*fop_<MODEF:mode>_3_i387"
13126 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13127 (match_operator:MODEF 3 "binary_fp_operator"
13128 [(match_operand:MODEF 1 "register_operand" "0,0")
13130 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13131 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13132 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13133 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13134 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13135 [(set (attr "type")
13136 (cond [(match_operand:MODEF 3 "mult_operator" "")
13137 (const_string "fmul")
13138 (match_operand:MODEF 3 "div_operator" "")
13139 (const_string "fdiv")
13141 (const_string "fop")))
13142 (set_attr "fp_int_src" "true")
13143 (set_attr "mode" "<MODE>")])
13145 (define_insn "*fop_df_4_i387"
13146 [(set (match_operand:DF 0 "register_operand" "=f,f")
13147 (match_operator:DF 3 "binary_fp_operator"
13149 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13150 (match_operand:DF 2 "register_operand" "0,f")]))]
13151 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13152 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13153 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13154 "* return output_387_binary_op (insn, operands);"
13155 [(set (attr "type")
13156 (cond [(match_operand:DF 3 "mult_operator" "")
13157 (const_string "fmul")
13158 (match_operand:DF 3 "div_operator" "")
13159 (const_string "fdiv")
13161 (const_string "fop")))
13162 (set_attr "mode" "SF")])
13164 (define_insn "*fop_df_5_i387"
13165 [(set (match_operand:DF 0 "register_operand" "=f,f")
13166 (match_operator:DF 3 "binary_fp_operator"
13167 [(match_operand:DF 1 "register_operand" "0,f")
13169 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13170 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13171 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13172 "* return output_387_binary_op (insn, operands);"
13173 [(set (attr "type")
13174 (cond [(match_operand:DF 3 "mult_operator" "")
13175 (const_string "fmul")
13176 (match_operand:DF 3 "div_operator" "")
13177 (const_string "fdiv")
13179 (const_string "fop")))
13180 (set_attr "mode" "SF")])
13182 (define_insn "*fop_df_6_i387"
13183 [(set (match_operand:DF 0 "register_operand" "=f,f")
13184 (match_operator:DF 3 "binary_fp_operator"
13186 (match_operand:SF 1 "register_operand" "0,f"))
13188 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13189 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13190 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13191 "* return output_387_binary_op (insn, operands);"
13192 [(set (attr "type")
13193 (cond [(match_operand:DF 3 "mult_operator" "")
13194 (const_string "fmul")
13195 (match_operand:DF 3 "div_operator" "")
13196 (const_string "fdiv")
13198 (const_string "fop")))
13199 (set_attr "mode" "SF")])
13201 (define_insn "*fop_xf_comm_i387"
13202 [(set (match_operand:XF 0 "register_operand" "=f")
13203 (match_operator:XF 3 "binary_fp_operator"
13204 [(match_operand:XF 1 "register_operand" "%0")
13205 (match_operand:XF 2 "register_operand" "f")]))]
13207 && COMMUTATIVE_ARITH_P (operands[3])"
13208 "* return output_387_binary_op (insn, operands);"
13209 [(set (attr "type")
13210 (if_then_else (match_operand:XF 3 "mult_operator" "")
13211 (const_string "fmul")
13212 (const_string "fop")))
13213 (set_attr "mode" "XF")])
13215 (define_insn "*fop_xf_1_i387"
13216 [(set (match_operand:XF 0 "register_operand" "=f,f")
13217 (match_operator:XF 3 "binary_fp_operator"
13218 [(match_operand:XF 1 "register_operand" "0,f")
13219 (match_operand:XF 2 "register_operand" "f,0")]))]
13221 && !COMMUTATIVE_ARITH_P (operands[3])"
13222 "* return output_387_binary_op (insn, operands);"
13223 [(set (attr "type")
13224 (cond [(match_operand:XF 3 "mult_operator" "")
13225 (const_string "fmul")
13226 (match_operand:XF 3 "div_operator" "")
13227 (const_string "fdiv")
13229 (const_string "fop")))
13230 (set_attr "mode" "XF")])
13232 (define_insn "*fop_xf_2_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f,f")
13234 (match_operator:XF 3 "binary_fp_operator"
13236 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13237 (match_operand:XF 2 "register_operand" "0,0")]))]
13238 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13239 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13240 [(set (attr "type")
13241 (cond [(match_operand:XF 3 "mult_operator" "")
13242 (const_string "fmul")
13243 (match_operand:XF 3 "div_operator" "")
13244 (const_string "fdiv")
13246 (const_string "fop")))
13247 (set_attr "fp_int_src" "true")
13248 (set_attr "mode" "<MODE>")])
13250 (define_insn "*fop_xf_3_i387"
13251 [(set (match_operand:XF 0 "register_operand" "=f,f")
13252 (match_operator:XF 3 "binary_fp_operator"
13253 [(match_operand:XF 1 "register_operand" "0,0")
13255 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13256 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13257 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13258 [(set (attr "type")
13259 (cond [(match_operand:XF 3 "mult_operator" "")
13260 (const_string "fmul")
13261 (match_operand:XF 3 "div_operator" "")
13262 (const_string "fdiv")
13264 (const_string "fop")))
13265 (set_attr "fp_int_src" "true")
13266 (set_attr "mode" "<MODE>")])
13268 (define_insn "*fop_xf_4_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f,f")
13270 (match_operator:XF 3 "binary_fp_operator"
13272 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13273 (match_operand:XF 2 "register_operand" "0,f")]))]
13275 "* return output_387_binary_op (insn, operands);"
13276 [(set (attr "type")
13277 (cond [(match_operand:XF 3 "mult_operator" "")
13278 (const_string "fmul")
13279 (match_operand:XF 3 "div_operator" "")
13280 (const_string "fdiv")
13282 (const_string "fop")))
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_xf_5_i387"
13286 [(set (match_operand:XF 0 "register_operand" "=f,f")
13287 (match_operator:XF 3 "binary_fp_operator"
13288 [(match_operand:XF 1 "register_operand" "0,f")
13290 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13292 "* return output_387_binary_op (insn, operands);"
13293 [(set (attr "type")
13294 (cond [(match_operand:XF 3 "mult_operator" "")
13295 (const_string "fmul")
13296 (match_operand:XF 3 "div_operator" "")
13297 (const_string "fdiv")
13299 (const_string "fop")))
13300 (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_xf_6_i387"
13303 [(set (match_operand:XF 0 "register_operand" "=f,f")
13304 (match_operator:XF 3 "binary_fp_operator"
13306 (match_operand:MODEF 1 "register_operand" "0,f"))
13308 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (cond [(match_operand:XF 3 "mult_operator" "")
13313 (const_string "fmul")
13314 (match_operand:XF 3 "div_operator" "")
13315 (const_string "fdiv")
13317 (const_string "fop")))
13318 (set_attr "mode" "<MODE>")])
13321 [(set (match_operand 0 "register_operand" "")
13322 (match_operator 3 "binary_fp_operator"
13323 [(float (match_operand:SWI24 1 "register_operand" ""))
13324 (match_operand 2 "register_operand" "")]))]
13326 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13327 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13330 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13331 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13332 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13333 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13334 GET_MODE (operands[3]),
13337 ix86_free_from_memory (GET_MODE (operands[1]));
13342 [(set (match_operand 0 "register_operand" "")
13343 (match_operator 3 "binary_fp_operator"
13344 [(match_operand 1 "register_operand" "")
13345 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13347 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13348 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13351 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13352 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13353 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13354 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13355 GET_MODE (operands[3]),
13358 ix86_free_from_memory (GET_MODE (operands[2]));
13362 ;; FPU special functions.
13364 ;; This pattern implements a no-op XFmode truncation for
13365 ;; all fancy i386 XFmode math functions.
13367 (define_insn "truncxf<mode>2_i387_noop_unspec"
13368 [(set (match_operand:MODEF 0 "register_operand" "=f")
13369 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13370 UNSPEC_TRUNC_NOOP))]
13371 "TARGET_USE_FANCY_MATH_387"
13372 "* return output_387_reg_move (insn, operands);"
13373 [(set_attr "type" "fmov")
13374 (set_attr "mode" "<MODE>")])
13376 (define_insn "sqrtxf2"
13377 [(set (match_operand:XF 0 "register_operand" "=f")
13378 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13379 "TARGET_USE_FANCY_MATH_387"
13381 [(set_attr "type" "fpspc")
13382 (set_attr "mode" "XF")
13383 (set_attr "athlon_decode" "direct")
13384 (set_attr "amdfam10_decode" "direct")
13385 (set_attr "bdver1_decode" "direct")])
13387 (define_insn "sqrt_extend<mode>xf2_i387"
13388 [(set (match_operand:XF 0 "register_operand" "=f")
13391 (match_operand:MODEF 1 "register_operand" "0"))))]
13392 "TARGET_USE_FANCY_MATH_387"
13394 [(set_attr "type" "fpspc")
13395 (set_attr "mode" "XF")
13396 (set_attr "athlon_decode" "direct")
13397 (set_attr "amdfam10_decode" "direct")
13398 (set_attr "bdver1_decode" "direct")])
13400 (define_insn "*rsqrtsf2_sse"
13401 [(set (match_operand:SF 0 "register_operand" "=x")
13402 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13405 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13406 [(set_attr "type" "sse")
13407 (set_attr "atom_sse_attr" "rcp")
13408 (set_attr "prefix" "maybe_vex")
13409 (set_attr "mode" "SF")])
13411 (define_expand "rsqrtsf2"
13412 [(set (match_operand:SF 0 "register_operand" "")
13413 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13417 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13421 (define_insn "*sqrt<mode>2_sse"
13422 [(set (match_operand:MODEF 0 "register_operand" "=x")
13424 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13426 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13427 [(set_attr "type" "sse")
13428 (set_attr "atom_sse_attr" "sqrt")
13429 (set_attr "prefix" "maybe_vex")
13430 (set_attr "mode" "<MODE>")
13431 (set_attr "athlon_decode" "*")
13432 (set_attr "amdfam10_decode" "*")
13433 (set_attr "bdver1_decode" "*")])
13435 (define_expand "sqrt<mode>2"
13436 [(set (match_operand:MODEF 0 "register_operand" "")
13438 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13439 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13440 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13442 if (<MODE>mode == SFmode
13444 && TARGET_RECIP_SQRT
13445 && !optimize_function_for_size_p (cfun)
13446 && flag_finite_math_only && !flag_trapping_math
13447 && flag_unsafe_math_optimizations)
13449 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13453 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13455 rtx op0 = gen_reg_rtx (XFmode);
13456 rtx op1 = force_reg (<MODE>mode, operands[1]);
13458 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13459 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13464 (define_insn "fpremxf4_i387"
13465 [(set (match_operand:XF 0 "register_operand" "=f")
13466 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13467 (match_operand:XF 3 "register_operand" "1")]
13469 (set (match_operand:XF 1 "register_operand" "=u")
13470 (unspec:XF [(match_dup 2) (match_dup 3)]
13472 (set (reg:CCFP FPSR_REG)
13473 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13475 "TARGET_USE_FANCY_MATH_387"
13477 [(set_attr "type" "fpspc")
13478 (set_attr "mode" "XF")])
13480 (define_expand "fmodxf3"
13481 [(use (match_operand:XF 0 "register_operand" ""))
13482 (use (match_operand:XF 1 "general_operand" ""))
13483 (use (match_operand:XF 2 "general_operand" ""))]
13484 "TARGET_USE_FANCY_MATH_387"
13486 rtx label = gen_label_rtx ();
13488 rtx op1 = gen_reg_rtx (XFmode);
13489 rtx op2 = gen_reg_rtx (XFmode);
13491 emit_move_insn (op2, operands[2]);
13492 emit_move_insn (op1, operands[1]);
13494 emit_label (label);
13495 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13496 ix86_emit_fp_unordered_jump (label);
13497 LABEL_NUSES (label) = 1;
13499 emit_move_insn (operands[0], op1);
13503 (define_expand "fmod<mode>3"
13504 [(use (match_operand:MODEF 0 "register_operand" ""))
13505 (use (match_operand:MODEF 1 "general_operand" ""))
13506 (use (match_operand:MODEF 2 "general_operand" ""))]
13507 "TARGET_USE_FANCY_MATH_387"
13509 rtx (*gen_truncxf) (rtx, rtx);
13511 rtx label = gen_label_rtx ();
13513 rtx op1 = gen_reg_rtx (XFmode);
13514 rtx op2 = gen_reg_rtx (XFmode);
13516 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13519 emit_label (label);
13520 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13521 ix86_emit_fp_unordered_jump (label);
13522 LABEL_NUSES (label) = 1;
13524 /* Truncate the result properly for strict SSE math. */
13525 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13526 && !TARGET_MIX_SSE_I387)
13527 gen_truncxf = gen_truncxf<mode>2;
13529 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13531 emit_insn (gen_truncxf (operands[0], op1));
13535 (define_insn "fprem1xf4_i387"
13536 [(set (match_operand:XF 0 "register_operand" "=f")
13537 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13538 (match_operand:XF 3 "register_operand" "1")]
13540 (set (match_operand:XF 1 "register_operand" "=u")
13541 (unspec:XF [(match_dup 2) (match_dup 3)]
13543 (set (reg:CCFP FPSR_REG)
13544 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13546 "TARGET_USE_FANCY_MATH_387"
13548 [(set_attr "type" "fpspc")
13549 (set_attr "mode" "XF")])
13551 (define_expand "remainderxf3"
13552 [(use (match_operand:XF 0 "register_operand" ""))
13553 (use (match_operand:XF 1 "general_operand" ""))
13554 (use (match_operand:XF 2 "general_operand" ""))]
13555 "TARGET_USE_FANCY_MATH_387"
13557 rtx label = gen_label_rtx ();
13559 rtx op1 = gen_reg_rtx (XFmode);
13560 rtx op2 = gen_reg_rtx (XFmode);
13562 emit_move_insn (op2, operands[2]);
13563 emit_move_insn (op1, operands[1]);
13565 emit_label (label);
13566 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13567 ix86_emit_fp_unordered_jump (label);
13568 LABEL_NUSES (label) = 1;
13570 emit_move_insn (operands[0], op1);
13574 (define_expand "remainder<mode>3"
13575 [(use (match_operand:MODEF 0 "register_operand" ""))
13576 (use (match_operand:MODEF 1 "general_operand" ""))
13577 (use (match_operand:MODEF 2 "general_operand" ""))]
13578 "TARGET_USE_FANCY_MATH_387"
13580 rtx (*gen_truncxf) (rtx, rtx);
13582 rtx label = gen_label_rtx ();
13584 rtx op1 = gen_reg_rtx (XFmode);
13585 rtx op2 = gen_reg_rtx (XFmode);
13587 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13590 emit_label (label);
13592 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13593 ix86_emit_fp_unordered_jump (label);
13594 LABEL_NUSES (label) = 1;
13596 /* Truncate the result properly for strict SSE math. */
13597 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13598 && !TARGET_MIX_SSE_I387)
13599 gen_truncxf = gen_truncxf<mode>2;
13601 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13603 emit_insn (gen_truncxf (operands[0], op1));
13607 (define_insn "*sinxf2_i387"
13608 [(set (match_operand:XF 0 "register_operand" "=f")
13609 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13610 "TARGET_USE_FANCY_MATH_387
13611 && flag_unsafe_math_optimizations"
13613 [(set_attr "type" "fpspc")
13614 (set_attr "mode" "XF")])
13616 (define_insn "*sin_extend<mode>xf2_i387"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(float_extend:XF
13619 (match_operand:MODEF 1 "register_operand" "0"))]
13621 "TARGET_USE_FANCY_MATH_387
13622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13623 || TARGET_MIX_SSE_I387)
13624 && flag_unsafe_math_optimizations"
13626 [(set_attr "type" "fpspc")
13627 (set_attr "mode" "XF")])
13629 (define_insn "*cosxf2_i387"
13630 [(set (match_operand:XF 0 "register_operand" "=f")
13631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13632 "TARGET_USE_FANCY_MATH_387
13633 && flag_unsafe_math_optimizations"
13635 [(set_attr "type" "fpspc")
13636 (set_attr "mode" "XF")])
13638 (define_insn "*cos_extend<mode>xf2_i387"
13639 [(set (match_operand:XF 0 "register_operand" "=f")
13640 (unspec:XF [(float_extend:XF
13641 (match_operand:MODEF 1 "register_operand" "0"))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13645 || TARGET_MIX_SSE_I387)
13646 && flag_unsafe_math_optimizations"
13648 [(set_attr "type" "fpspc")
13649 (set_attr "mode" "XF")])
13651 ;; When sincos pattern is defined, sin and cos builtin functions will be
13652 ;; expanded to sincos pattern with one of its outputs left unused.
13653 ;; CSE pass will figure out if two sincos patterns can be combined,
13654 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13655 ;; depending on the unused output.
13657 (define_insn "sincosxf3"
13658 [(set (match_operand:XF 0 "register_operand" "=f")
13659 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13660 UNSPEC_SINCOS_COS))
13661 (set (match_operand:XF 1 "register_operand" "=u")
13662 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13663 "TARGET_USE_FANCY_MATH_387
13664 && flag_unsafe_math_optimizations"
13666 [(set_attr "type" "fpspc")
13667 (set_attr "mode" "XF")])
13670 [(set (match_operand:XF 0 "register_operand" "")
13671 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13672 UNSPEC_SINCOS_COS))
13673 (set (match_operand:XF 1 "register_operand" "")
13674 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13675 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13676 && can_create_pseudo_p ()"
13677 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13680 [(set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13682 UNSPEC_SINCOS_COS))
13683 (set (match_operand:XF 1 "register_operand" "")
13684 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13685 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13686 && can_create_pseudo_p ()"
13687 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13689 (define_insn "sincos_extend<mode>xf3_i387"
13690 [(set (match_operand:XF 0 "register_operand" "=f")
13691 (unspec:XF [(float_extend:XF
13692 (match_operand:MODEF 2 "register_operand" "0"))]
13693 UNSPEC_SINCOS_COS))
13694 (set (match_operand:XF 1 "register_operand" "=u")
13695 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13698 || TARGET_MIX_SSE_I387)
13699 && flag_unsafe_math_optimizations"
13701 [(set_attr "type" "fpspc")
13702 (set_attr "mode" "XF")])
13705 [(set (match_operand:XF 0 "register_operand" "")
13706 (unspec:XF [(float_extend:XF
13707 (match_operand:MODEF 2 "register_operand" ""))]
13708 UNSPEC_SINCOS_COS))
13709 (set (match_operand:XF 1 "register_operand" "")
13710 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13711 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13712 && can_create_pseudo_p ()"
13713 [(set (match_dup 1)
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13717 [(set (match_operand:XF 0 "register_operand" "")
13718 (unspec:XF [(float_extend:XF
13719 (match_operand:MODEF 2 "register_operand" ""))]
13720 UNSPEC_SINCOS_COS))
13721 (set (match_operand:XF 1 "register_operand" "")
13722 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13723 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13724 && can_create_pseudo_p ()"
13725 [(set (match_dup 0)
13726 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13728 (define_expand "sincos<mode>3"
13729 [(use (match_operand:MODEF 0 "register_operand" ""))
13730 (use (match_operand:MODEF 1 "register_operand" ""))
13731 (use (match_operand:MODEF 2 "register_operand" ""))]
13732 "TARGET_USE_FANCY_MATH_387
13733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734 || TARGET_MIX_SSE_I387)
13735 && flag_unsafe_math_optimizations"
13737 rtx op0 = gen_reg_rtx (XFmode);
13738 rtx op1 = gen_reg_rtx (XFmode);
13740 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13746 (define_insn "fptanxf4_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (match_operand:XF 3 "const_double_operand" "F"))
13749 (set (match_operand:XF 1 "register_operand" "=u")
13750 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13752 "TARGET_USE_FANCY_MATH_387
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_insn "fptan_extend<mode>xf4_i387"
13760 [(set (match_operand:MODEF 0 "register_operand" "=f")
13761 (match_operand:MODEF 3 "const_double_operand" "F"))
13762 (set (match_operand:XF 1 "register_operand" "=u")
13763 (unspec:XF [(float_extend:XF
13764 (match_operand:MODEF 2 "register_operand" "0"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations
13770 && standard_80387_constant_p (operands[3]) == 2"
13772 [(set_attr "type" "fpspc")
13773 (set_attr "mode" "XF")])
13775 (define_expand "tanxf2"
13776 [(use (match_operand:XF 0 "register_operand" ""))
13777 (use (match_operand:XF 1 "register_operand" ""))]
13778 "TARGET_USE_FANCY_MATH_387
13779 && flag_unsafe_math_optimizations"
13781 rtx one = gen_reg_rtx (XFmode);
13782 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13784 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13788 (define_expand "tan<mode>2"
13789 [(use (match_operand:MODEF 0 "register_operand" ""))
13790 (use (match_operand:MODEF 1 "register_operand" ""))]
13791 "TARGET_USE_FANCY_MATH_387
13792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13793 || TARGET_MIX_SSE_I387)
13794 && flag_unsafe_math_optimizations"
13796 rtx op0 = gen_reg_rtx (XFmode);
13798 rtx one = gen_reg_rtx (<MODE>mode);
13799 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13801 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13802 operands[1], op2));
13803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807 (define_insn "*fpatanxf3_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13810 (match_operand:XF 2 "register_operand" "u")]
13812 (clobber (match_scratch:XF 3 "=2"))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && flag_unsafe_math_optimizations"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13819 (define_insn "fpatan_extend<mode>xf3_i387"
13820 [(set (match_operand:XF 0 "register_operand" "=f")
13821 (unspec:XF [(float_extend:XF
13822 (match_operand:MODEF 1 "register_operand" "0"))
13824 (match_operand:MODEF 2 "register_operand" "u"))]
13826 (clobber (match_scratch:XF 3 "=2"))]
13827 "TARGET_USE_FANCY_MATH_387
13828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13829 || TARGET_MIX_SSE_I387)
13830 && flag_unsafe_math_optimizations"
13832 [(set_attr "type" "fpspc")
13833 (set_attr "mode" "XF")])
13835 (define_expand "atan2xf3"
13836 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13838 (match_operand:XF 1 "register_operand" "")]
13840 (clobber (match_scratch:XF 3 ""))])]
13841 "TARGET_USE_FANCY_MATH_387
13842 && flag_unsafe_math_optimizations")
13844 (define_expand "atan2<mode>3"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))
13847 (use (match_operand:MODEF 2 "register_operand" ""))]
13848 "TARGET_USE_FANCY_MATH_387
13849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850 || TARGET_MIX_SSE_I387)
13851 && flag_unsafe_math_optimizations"
13853 rtx op0 = gen_reg_rtx (XFmode);
13855 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13860 (define_expand "atanxf2"
13861 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13862 (unspec:XF [(match_dup 2)
13863 (match_operand:XF 1 "register_operand" "")]
13865 (clobber (match_scratch:XF 3 ""))])]
13866 "TARGET_USE_FANCY_MATH_387
13867 && flag_unsafe_math_optimizations"
13869 operands[2] = gen_reg_rtx (XFmode);
13870 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13873 (define_expand "atan<mode>2"
13874 [(use (match_operand:MODEF 0 "register_operand" ""))
13875 (use (match_operand:MODEF 1 "register_operand" ""))]
13876 "TARGET_USE_FANCY_MATH_387
13877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13878 || TARGET_MIX_SSE_I387)
13879 && flag_unsafe_math_optimizations"
13881 rtx op0 = gen_reg_rtx (XFmode);
13883 rtx op2 = gen_reg_rtx (<MODE>mode);
13884 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13886 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13891 (define_expand "asinxf2"
13892 [(set (match_dup 2)
13893 (mult:XF (match_operand:XF 1 "register_operand" "")
13895 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13896 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13897 (parallel [(set (match_operand:XF 0 "register_operand" "")
13898 (unspec:XF [(match_dup 5) (match_dup 1)]
13900 (clobber (match_scratch:XF 6 ""))])]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations"
13906 if (optimize_insn_for_size_p ())
13909 for (i = 2; i < 6; i++)
13910 operands[i] = gen_reg_rtx (XFmode);
13912 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13915 (define_expand "asin<mode>2"
13916 [(use (match_operand:MODEF 0 "register_operand" ""))
13917 (use (match_operand:MODEF 1 "general_operand" ""))]
13918 "TARGET_USE_FANCY_MATH_387
13919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920 || TARGET_MIX_SSE_I387)
13921 && flag_unsafe_math_optimizations"
13923 rtx op0 = gen_reg_rtx (XFmode);
13924 rtx op1 = gen_reg_rtx (XFmode);
13926 if (optimize_insn_for_size_p ())
13929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13930 emit_insn (gen_asinxf2 (op0, op1));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13935 (define_expand "acosxf2"
13936 [(set (match_dup 2)
13937 (mult:XF (match_operand:XF 1 "register_operand" "")
13939 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13940 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13941 (parallel [(set (match_operand:XF 0 "register_operand" "")
13942 (unspec:XF [(match_dup 1) (match_dup 5)]
13944 (clobber (match_scratch:XF 6 ""))])]
13945 "TARGET_USE_FANCY_MATH_387
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 for (i = 2; i < 6; i++)
13954 operands[i] = gen_reg_rtx (XFmode);
13956 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13959 (define_expand "acos<mode>2"
13960 [(use (match_operand:MODEF 0 "register_operand" ""))
13961 (use (match_operand:MODEF 1 "general_operand" ""))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 rtx op0 = gen_reg_rtx (XFmode);
13968 rtx op1 = gen_reg_rtx (XFmode);
13970 if (optimize_insn_for_size_p ())
13973 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13974 emit_insn (gen_acosxf2 (op0, op1));
13975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13979 (define_insn "fyl2xxf3_i387"
13980 [(set (match_operand:XF 0 "register_operand" "=f")
13981 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13982 (match_operand:XF 2 "register_operand" "u")]
13984 (clobber (match_scratch:XF 3 "=2"))]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13988 [(set_attr "type" "fpspc")
13989 (set_attr "mode" "XF")])
13991 (define_insn "fyl2x_extend<mode>xf3_i387"
13992 [(set (match_operand:XF 0 "register_operand" "=f")
13993 (unspec:XF [(float_extend:XF
13994 (match_operand:MODEF 1 "register_operand" "0"))
13995 (match_operand:XF 2 "register_operand" "u")]
13997 (clobber (match_scratch:XF 3 "=2"))]
13998 "TARGET_USE_FANCY_MATH_387
13999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14000 || TARGET_MIX_SSE_I387)
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_expand "logxf2"
14007 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14008 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14009 (match_dup 2)] UNSPEC_FYL2X))
14010 (clobber (match_scratch:XF 3 ""))])]
14011 "TARGET_USE_FANCY_MATH_387
14012 && flag_unsafe_math_optimizations"
14014 operands[2] = gen_reg_rtx (XFmode);
14015 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14018 (define_expand "log<mode>2"
14019 [(use (match_operand:MODEF 0 "register_operand" ""))
14020 (use (match_operand:MODEF 1 "register_operand" ""))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14023 || TARGET_MIX_SSE_I387)
14024 && flag_unsafe_math_optimizations"
14026 rtx op0 = gen_reg_rtx (XFmode);
14028 rtx op2 = gen_reg_rtx (XFmode);
14029 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14031 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14032 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14036 (define_expand "log10xf2"
14037 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14038 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14039 (match_dup 2)] UNSPEC_FYL2X))
14040 (clobber (match_scratch:XF 3 ""))])]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 operands[2] = gen_reg_rtx (XFmode);
14045 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14048 (define_expand "log10<mode>2"
14049 [(use (match_operand:MODEF 0 "register_operand" ""))
14050 (use (match_operand:MODEF 1 "register_operand" ""))]
14051 "TARGET_USE_FANCY_MATH_387
14052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14053 || TARGET_MIX_SSE_I387)
14054 && flag_unsafe_math_optimizations"
14056 rtx op0 = gen_reg_rtx (XFmode);
14058 rtx op2 = gen_reg_rtx (XFmode);
14059 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14061 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 (define_expand "log2xf2"
14067 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14068 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14069 (match_dup 2)] UNSPEC_FYL2X))
14070 (clobber (match_scratch:XF 3 ""))])]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 operands[2] = gen_reg_rtx (XFmode);
14075 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14078 (define_expand "log2<mode>2"
14079 [(use (match_operand:MODEF 0 "register_operand" ""))
14080 (use (match_operand:MODEF 1 "register_operand" ""))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083 || TARGET_MIX_SSE_I387)
14084 && flag_unsafe_math_optimizations"
14086 rtx op0 = gen_reg_rtx (XFmode);
14088 rtx op2 = gen_reg_rtx (XFmode);
14089 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14091 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_insn "fyl2xp1xf3_i387"
14097 [(set (match_operand:XF 0 "register_operand" "=f")
14098 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099 (match_operand:XF 2 "register_operand" "u")]
14101 (clobber (match_scratch:XF 3 "=2"))]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "XF")])
14108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14109 [(set (match_operand:XF 0 "register_operand" "=f")
14110 (unspec:XF [(float_extend:XF
14111 (match_operand:MODEF 1 "register_operand" "0"))
14112 (match_operand:XF 2 "register_operand" "u")]
14114 (clobber (match_scratch:XF 3 "=2"))]
14115 "TARGET_USE_FANCY_MATH_387
14116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117 || TARGET_MIX_SSE_I387)
14118 && flag_unsafe_math_optimizations"
14120 [(set_attr "type" "fpspc")
14121 (set_attr "mode" "XF")])
14123 (define_expand "log1pxf2"
14124 [(use (match_operand:XF 0 "register_operand" ""))
14125 (use (match_operand:XF 1 "register_operand" ""))]
14126 "TARGET_USE_FANCY_MATH_387
14127 && flag_unsafe_math_optimizations"
14129 if (optimize_insn_for_size_p ())
14132 ix86_emit_i387_log1p (operands[0], operands[1]);
14136 (define_expand "log1p<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand" ""))
14138 (use (match_operand:MODEF 1 "register_operand" ""))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14146 if (optimize_insn_for_size_p ())
14149 op0 = gen_reg_rtx (XFmode);
14151 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14153 ix86_emit_i387_log1p (op0, operands[1]);
14154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 (define_insn "fxtractxf3_i387"
14159 [(set (match_operand:XF 0 "register_operand" "=f")
14160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14161 UNSPEC_XTRACT_FRACT))
14162 (set (match_operand:XF 1 "register_operand" "=u")
14163 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14167 [(set_attr "type" "fpspc")
14168 (set_attr "mode" "XF")])
14170 (define_insn "fxtract_extend<mode>xf3_i387"
14171 [(set (match_operand:XF 0 "register_operand" "=f")
14172 (unspec:XF [(float_extend:XF
14173 (match_operand:MODEF 2 "register_operand" "0"))]
14174 UNSPEC_XTRACT_FRACT))
14175 (set (match_operand:XF 1 "register_operand" "=u")
14176 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "XF")])
14185 (define_expand "logbxf2"
14186 [(parallel [(set (match_dup 2)
14187 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14188 UNSPEC_XTRACT_FRACT))
14189 (set (match_operand:XF 0 "register_operand" "")
14190 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14191 "TARGET_USE_FANCY_MATH_387
14192 && flag_unsafe_math_optimizations"
14193 "operands[2] = gen_reg_rtx (XFmode);")
14195 (define_expand "logb<mode>2"
14196 [(use (match_operand:MODEF 0 "register_operand" ""))
14197 (use (match_operand:MODEF 1 "register_operand" ""))]
14198 "TARGET_USE_FANCY_MATH_387
14199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200 || TARGET_MIX_SSE_I387)
14201 && flag_unsafe_math_optimizations"
14203 rtx op0 = gen_reg_rtx (XFmode);
14204 rtx op1 = gen_reg_rtx (XFmode);
14206 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14211 (define_expand "ilogbxf2"
14212 [(use (match_operand:SI 0 "register_operand" ""))
14213 (use (match_operand:XF 1 "register_operand" ""))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && flag_unsafe_math_optimizations"
14219 if (optimize_insn_for_size_p ())
14222 op0 = gen_reg_rtx (XFmode);
14223 op1 = gen_reg_rtx (XFmode);
14225 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14226 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14230 (define_expand "ilogb<mode>2"
14231 [(use (match_operand:SI 0 "register_operand" ""))
14232 (use (match_operand:MODEF 1 "register_operand" ""))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235 || TARGET_MIX_SSE_I387)
14236 && flag_unsafe_math_optimizations"
14240 if (optimize_insn_for_size_p ())
14243 op0 = gen_reg_rtx (XFmode);
14244 op1 = gen_reg_rtx (XFmode);
14246 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14247 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14251 (define_insn "*f2xm1xf2_i387"
14252 [(set (match_operand:XF 0 "register_operand" "=f")
14253 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14255 "TARGET_USE_FANCY_MATH_387
14256 && flag_unsafe_math_optimizations"
14258 [(set_attr "type" "fpspc")
14259 (set_attr "mode" "XF")])
14261 (define_insn "*fscalexf4_i387"
14262 [(set (match_operand:XF 0 "register_operand" "=f")
14263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14264 (match_operand:XF 3 "register_operand" "1")]
14265 UNSPEC_FSCALE_FRACT))
14266 (set (match_operand:XF 1 "register_operand" "=u")
14267 (unspec:XF [(match_dup 2) (match_dup 3)]
14268 UNSPEC_FSCALE_EXP))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && flag_unsafe_math_optimizations"
14272 [(set_attr "type" "fpspc")
14273 (set_attr "mode" "XF")])
14275 (define_expand "expNcorexf3"
14276 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14277 (match_operand:XF 2 "register_operand" "")))
14278 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14279 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14280 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14281 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14282 (parallel [(set (match_operand:XF 0 "register_operand" "")
14283 (unspec:XF [(match_dup 8) (match_dup 4)]
14284 UNSPEC_FSCALE_FRACT))
14286 (unspec:XF [(match_dup 8) (match_dup 4)]
14287 UNSPEC_FSCALE_EXP))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14293 if (optimize_insn_for_size_p ())
14296 for (i = 3; i < 10; i++)
14297 operands[i] = gen_reg_rtx (XFmode);
14299 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14302 (define_expand "expxf2"
14303 [(use (match_operand:XF 0 "register_operand" ""))
14304 (use (match_operand:XF 1 "register_operand" ""))]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14310 if (optimize_insn_for_size_p ())
14313 op2 = gen_reg_rtx (XFmode);
14314 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14316 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14320 (define_expand "exp<mode>2"
14321 [(use (match_operand:MODEF 0 "register_operand" ""))
14322 (use (match_operand:MODEF 1 "general_operand" ""))]
14323 "TARGET_USE_FANCY_MATH_387
14324 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14325 || TARGET_MIX_SSE_I387)
14326 && flag_unsafe_math_optimizations"
14330 if (optimize_insn_for_size_p ())
14333 op0 = gen_reg_rtx (XFmode);
14334 op1 = gen_reg_rtx (XFmode);
14336 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14337 emit_insn (gen_expxf2 (op0, op1));
14338 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14342 (define_expand "exp10xf2"
14343 [(use (match_operand:XF 0 "register_operand" ""))
14344 (use (match_operand:XF 1 "register_operand" ""))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14350 if (optimize_insn_for_size_p ())
14353 op2 = gen_reg_rtx (XFmode);
14354 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14356 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14360 (define_expand "exp10<mode>2"
14361 [(use (match_operand:MODEF 0 "register_operand" ""))
14362 (use (match_operand:MODEF 1 "general_operand" ""))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14365 || TARGET_MIX_SSE_I387)
14366 && flag_unsafe_math_optimizations"
14370 if (optimize_insn_for_size_p ())
14373 op0 = gen_reg_rtx (XFmode);
14374 op1 = gen_reg_rtx (XFmode);
14376 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14377 emit_insn (gen_exp10xf2 (op0, op1));
14378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14382 (define_expand "exp2xf2"
14383 [(use (match_operand:XF 0 "register_operand" ""))
14384 (use (match_operand:XF 1 "register_operand" ""))]
14385 "TARGET_USE_FANCY_MATH_387
14386 && flag_unsafe_math_optimizations"
14390 if (optimize_insn_for_size_p ())
14393 op2 = gen_reg_rtx (XFmode);
14394 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14396 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14400 (define_expand "exp2<mode>2"
14401 [(use (match_operand:MODEF 0 "register_operand" ""))
14402 (use (match_operand:MODEF 1 "general_operand" ""))]
14403 "TARGET_USE_FANCY_MATH_387
14404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14405 || TARGET_MIX_SSE_I387)
14406 && flag_unsafe_math_optimizations"
14410 if (optimize_insn_for_size_p ())
14413 op0 = gen_reg_rtx (XFmode);
14414 op1 = gen_reg_rtx (XFmode);
14416 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14417 emit_insn (gen_exp2xf2 (op0, op1));
14418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14422 (define_expand "expm1xf2"
14423 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14425 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14426 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14427 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14428 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14429 (parallel [(set (match_dup 7)
14430 (unspec:XF [(match_dup 6) (match_dup 4)]
14431 UNSPEC_FSCALE_FRACT))
14433 (unspec:XF [(match_dup 6) (match_dup 4)]
14434 UNSPEC_FSCALE_EXP))])
14435 (parallel [(set (match_dup 10)
14436 (unspec:XF [(match_dup 9) (match_dup 8)]
14437 UNSPEC_FSCALE_FRACT))
14438 (set (match_dup 11)
14439 (unspec:XF [(match_dup 9) (match_dup 8)]
14440 UNSPEC_FSCALE_EXP))])
14441 (set (match_dup 12) (minus:XF (match_dup 10)
14442 (float_extend:XF (match_dup 13))))
14443 (set (match_operand:XF 0 "register_operand" "")
14444 (plus:XF (match_dup 12) (match_dup 7)))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && flag_unsafe_math_optimizations"
14450 if (optimize_insn_for_size_p ())
14453 for (i = 2; i < 13; i++)
14454 operands[i] = gen_reg_rtx (XFmode);
14457 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14459 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14462 (define_expand "expm1<mode>2"
14463 [(use (match_operand:MODEF 0 "register_operand" ""))
14464 (use (match_operand:MODEF 1 "general_operand" ""))]
14465 "TARGET_USE_FANCY_MATH_387
14466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14467 || TARGET_MIX_SSE_I387)
14468 && flag_unsafe_math_optimizations"
14472 if (optimize_insn_for_size_p ())
14475 op0 = gen_reg_rtx (XFmode);
14476 op1 = gen_reg_rtx (XFmode);
14478 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14479 emit_insn (gen_expm1xf2 (op0, op1));
14480 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14484 (define_expand "ldexpxf3"
14485 [(set (match_dup 3)
14486 (float:XF (match_operand:SI 2 "register_operand" "")))
14487 (parallel [(set (match_operand:XF 0 " register_operand" "")
14488 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14490 UNSPEC_FSCALE_FRACT))
14492 (unspec:XF [(match_dup 1) (match_dup 3)]
14493 UNSPEC_FSCALE_EXP))])]
14494 "TARGET_USE_FANCY_MATH_387
14495 && flag_unsafe_math_optimizations"
14497 if (optimize_insn_for_size_p ())
14500 operands[3] = gen_reg_rtx (XFmode);
14501 operands[4] = gen_reg_rtx (XFmode);
14504 (define_expand "ldexp<mode>3"
14505 [(use (match_operand:MODEF 0 "register_operand" ""))
14506 (use (match_operand:MODEF 1 "general_operand" ""))
14507 (use (match_operand:SI 2 "register_operand" ""))]
14508 "TARGET_USE_FANCY_MATH_387
14509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14510 || TARGET_MIX_SSE_I387)
14511 && flag_unsafe_math_optimizations"
14515 if (optimize_insn_for_size_p ())
14518 op0 = gen_reg_rtx (XFmode);
14519 op1 = gen_reg_rtx (XFmode);
14521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14522 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14527 (define_expand "scalbxf3"
14528 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14530 (match_operand:XF 2 "register_operand" "")]
14531 UNSPEC_FSCALE_FRACT))
14533 (unspec:XF [(match_dup 1) (match_dup 2)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14538 if (optimize_insn_for_size_p ())
14541 operands[3] = gen_reg_rtx (XFmode);
14544 (define_expand "scalb<mode>3"
14545 [(use (match_operand:MODEF 0 "register_operand" ""))
14546 (use (match_operand:MODEF 1 "general_operand" ""))
14547 (use (match_operand:MODEF 2 "general_operand" ""))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550 || TARGET_MIX_SSE_I387)
14551 && flag_unsafe_math_optimizations"
14555 if (optimize_insn_for_size_p ())
14558 op0 = gen_reg_rtx (XFmode);
14559 op1 = gen_reg_rtx (XFmode);
14560 op2 = gen_reg_rtx (XFmode);
14562 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14563 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14564 emit_insn (gen_scalbxf3 (op0, op1, op2));
14565 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14569 (define_expand "significandxf2"
14570 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14571 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14572 UNSPEC_XTRACT_FRACT))
14574 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14575 "TARGET_USE_FANCY_MATH_387
14576 && flag_unsafe_math_optimizations"
14577 "operands[2] = gen_reg_rtx (XFmode);")
14579 (define_expand "significand<mode>2"
14580 [(use (match_operand:MODEF 0 "register_operand" ""))
14581 (use (match_operand:MODEF 1 "register_operand" ""))]
14582 "TARGET_USE_FANCY_MATH_387
14583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14584 || TARGET_MIX_SSE_I387)
14585 && flag_unsafe_math_optimizations"
14587 rtx op0 = gen_reg_rtx (XFmode);
14588 rtx op1 = gen_reg_rtx (XFmode);
14590 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14591 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14596 (define_insn "sse4_1_round<mode>2"
14597 [(set (match_operand:MODEF 0 "register_operand" "=x")
14598 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14599 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14602 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14603 [(set_attr "type" "ssecvt")
14604 (set_attr "prefix_extra" "1")
14605 (set_attr "prefix" "maybe_vex")
14606 (set_attr "mode" "<MODE>")])
14608 (define_insn "rintxf2"
14609 [(set (match_operand:XF 0 "register_operand" "=f")
14610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14612 "TARGET_USE_FANCY_MATH_387
14613 && flag_unsafe_math_optimizations"
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "XF")])
14618 (define_expand "rint<mode>2"
14619 [(use (match_operand:MODEF 0 "register_operand" ""))
14620 (use (match_operand:MODEF 1 "register_operand" ""))]
14621 "(TARGET_USE_FANCY_MATH_387
14622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14623 || TARGET_MIX_SSE_I387)
14624 && flag_unsafe_math_optimizations)
14625 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14626 && !flag_trapping_math)"
14628 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14629 && !flag_trapping_math)
14632 emit_insn (gen_sse4_1_round<mode>2
14633 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14634 else if (optimize_insn_for_size_p ())
14637 ix86_expand_rint (operand0, operand1);
14641 rtx op0 = gen_reg_rtx (XFmode);
14642 rtx op1 = gen_reg_rtx (XFmode);
14644 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14645 emit_insn (gen_rintxf2 (op0, op1));
14647 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14652 (define_expand "round<mode>2"
14653 [(match_operand:X87MODEF 0 "register_operand" "")
14654 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14655 "(TARGET_USE_FANCY_MATH_387
14656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14657 || TARGET_MIX_SSE_I387)
14658 && flag_unsafe_math_optimizations)
14659 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14660 && !flag_trapping_math && !flag_rounding_math)"
14662 if (optimize_insn_for_size_p ())
14665 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14666 && !flag_trapping_math && !flag_rounding_math)
14670 operands[1] = force_reg (<MODE>mode, operands[1]);
14671 ix86_expand_round_sse4 (operands[0], operands[1]);
14673 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14674 ix86_expand_round (operands[0], operands[1]);
14676 ix86_expand_rounddf_32 (operands[0], operands[1]);
14680 operands[1] = force_reg (<MODE>mode, operands[1]);
14681 ix86_emit_i387_round (operands[0], operands[1]);
14686 (define_insn_and_split "*fistdi2_1"
14687 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14688 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14690 "TARGET_USE_FANCY_MATH_387
14691 && can_create_pseudo_p ()"
14696 if (memory_operand (operands[0], VOIDmode))
14697 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14700 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14701 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "DI")])
14709 (define_insn "fistdi2"
14710 [(set (match_operand:DI 0 "memory_operand" "=m")
14711 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14713 (clobber (match_scratch:XF 2 "=&1f"))]
14714 "TARGET_USE_FANCY_MATH_387"
14715 "* return output_fix_trunc (insn, operands, false);"
14716 [(set_attr "type" "fpspc")
14717 (set_attr "mode" "DI")])
14719 (define_insn "fistdi2_with_temp"
14720 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14721 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14723 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14724 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14725 "TARGET_USE_FANCY_MATH_387"
14727 [(set_attr "type" "fpspc")
14728 (set_attr "mode" "DI")])
14731 [(set (match_operand:DI 0 "register_operand" "")
14732 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14734 (clobber (match_operand:DI 2 "memory_operand" ""))
14735 (clobber (match_scratch 3 ""))]
14737 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14738 (clobber (match_dup 3))])
14739 (set (match_dup 0) (match_dup 2))])
14742 [(set (match_operand:DI 0 "memory_operand" "")
14743 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14745 (clobber (match_operand:DI 2 "memory_operand" ""))
14746 (clobber (match_scratch 3 ""))]
14748 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14749 (clobber (match_dup 3))])])
14751 (define_insn_and_split "*fist<mode>2_1"
14752 [(set (match_operand:SWI24 0 "register_operand" "")
14753 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14755 "TARGET_USE_FANCY_MATH_387
14756 && can_create_pseudo_p ()"
14761 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14762 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14766 [(set_attr "type" "fpspc")
14767 (set_attr "mode" "<MODE>")])
14769 (define_insn "fist<mode>2"
14770 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14771 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14773 "TARGET_USE_FANCY_MATH_387"
14774 "* return output_fix_trunc (insn, operands, false);"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "<MODE>")])
14778 (define_insn "fist<mode>2_with_temp"
14779 [(set (match_operand:SWI24 0 "register_operand" "=r")
14780 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14782 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14783 "TARGET_USE_FANCY_MATH_387"
14785 [(set_attr "type" "fpspc")
14786 (set_attr "mode" "<MODE>")])
14789 [(set (match_operand:SWI24 0 "register_operand" "")
14790 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14792 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14794 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14795 (set (match_dup 0) (match_dup 2))])
14798 [(set (match_operand:SWI24 0 "memory_operand" "")
14799 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14801 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14803 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14805 (define_expand "lrintxf<mode>2"
14806 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14807 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14809 "TARGET_USE_FANCY_MATH_387")
14811 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14812 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14813 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14814 UNSPEC_FIX_NOTRUNC))]
14815 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14816 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14818 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14819 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14820 (match_operand:X87MODEF 1 "register_operand" "")]
14821 "(TARGET_USE_FANCY_MATH_387
14822 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14823 || TARGET_MIX_SSE_I387)
14824 && flag_unsafe_math_optimizations)
14825 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14826 && <SWI248x:MODE>mode != HImode
14827 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14828 && !flag_trapping_math && !flag_rounding_math)"
14830 if (optimize_insn_for_size_p ())
14833 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14834 && <SWI248x:MODE>mode != HImode
14835 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14836 && !flag_trapping_math && !flag_rounding_math)
14837 ix86_expand_lround (operand0, operand1);
14839 ix86_emit_i387_round (operands[0], operands[1]);
14843 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14844 (define_insn_and_split "frndintxf2_floor"
14845 [(set (match_operand:XF 0 "register_operand" "")
14846 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14847 UNSPEC_FRNDINT_FLOOR))
14848 (clobber (reg:CC FLAGS_REG))]
14849 "TARGET_USE_FANCY_MATH_387
14850 && flag_unsafe_math_optimizations
14851 && can_create_pseudo_p ()"
14856 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14858 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14859 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14861 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14862 operands[2], operands[3]));
14865 [(set_attr "type" "frndint")
14866 (set_attr "i387_cw" "floor")
14867 (set_attr "mode" "XF")])
14869 (define_insn "frndintxf2_floor_i387"
14870 [(set (match_operand:XF 0 "register_operand" "=f")
14871 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14872 UNSPEC_FRNDINT_FLOOR))
14873 (use (match_operand:HI 2 "memory_operand" "m"))
14874 (use (match_operand:HI 3 "memory_operand" "m"))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14877 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14878 [(set_attr "type" "frndint")
14879 (set_attr "i387_cw" "floor")
14880 (set_attr "mode" "XF")])
14882 (define_expand "floorxf2"
14883 [(use (match_operand:XF 0 "register_operand" ""))
14884 (use (match_operand:XF 1 "register_operand" ""))]
14885 "TARGET_USE_FANCY_MATH_387
14886 && flag_unsafe_math_optimizations"
14888 if (optimize_insn_for_size_p ())
14890 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14894 (define_expand "floor<mode>2"
14895 [(use (match_operand:MODEF 0 "register_operand" ""))
14896 (use (match_operand:MODEF 1 "register_operand" ""))]
14897 "(TARGET_USE_FANCY_MATH_387
14898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899 || TARGET_MIX_SSE_I387)
14900 && flag_unsafe_math_optimizations)
14901 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14902 && !flag_trapping_math)"
14904 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905 && !flag_trapping_math)
14908 emit_insn (gen_sse4_1_round<mode>2
14909 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14910 else if (optimize_insn_for_size_p ())
14912 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14913 ix86_expand_floorceil (operand0, operand1, true);
14915 ix86_expand_floorceildf_32 (operand0, operand1, true);
14921 if (optimize_insn_for_size_p ())
14924 op0 = gen_reg_rtx (XFmode);
14925 op1 = gen_reg_rtx (XFmode);
14926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14927 emit_insn (gen_frndintxf2_floor (op0, op1));
14929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14934 (define_insn_and_split "*fist<mode>2_floor_1"
14935 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14936 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14937 UNSPEC_FIST_FLOOR))
14938 (clobber (reg:CC FLAGS_REG))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations
14941 && can_create_pseudo_p ()"
14946 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14948 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14949 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14950 if (memory_operand (operands[0], VOIDmode))
14951 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14952 operands[2], operands[3]));
14955 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14956 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14957 operands[2], operands[3],
14962 [(set_attr "type" "fistp")
14963 (set_attr "i387_cw" "floor")
14964 (set_attr "mode" "<MODE>")])
14966 (define_insn "fistdi2_floor"
14967 [(set (match_operand:DI 0 "memory_operand" "=m")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_operand:HI 2 "memory_operand" "m"))
14971 (use (match_operand:HI 3 "memory_operand" "m"))
14972 (clobber (match_scratch:XF 4 "=&1f"))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && flag_unsafe_math_optimizations"
14975 "* return output_fix_trunc (insn, operands, false);"
14976 [(set_attr "type" "fistp")
14977 (set_attr "i387_cw" "floor")
14978 (set_attr "mode" "DI")])
14980 (define_insn "fistdi2_floor_with_temp"
14981 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14982 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14983 UNSPEC_FIST_FLOOR))
14984 (use (match_operand:HI 2 "memory_operand" "m,m"))
14985 (use (match_operand:HI 3 "memory_operand" "m,m"))
14986 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14987 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14991 [(set_attr "type" "fistp")
14992 (set_attr "i387_cw" "floor")
14993 (set_attr "mode" "DI")])
14996 [(set (match_operand:DI 0 "register_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 4)
15005 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15006 (use (match_dup 2))
15007 (use (match_dup 3))
15008 (clobber (match_dup 5))])
15009 (set (match_dup 0) (match_dup 4))])
15012 [(set (match_operand:DI 0 "memory_operand" "")
15013 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FIST_FLOOR))
15015 (use (match_operand:HI 2 "memory_operand" ""))
15016 (use (match_operand:HI 3 "memory_operand" ""))
15017 (clobber (match_operand:DI 4 "memory_operand" ""))
15018 (clobber (match_scratch 5 ""))]
15020 [(parallel [(set (match_dup 0)
15021 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15022 (use (match_dup 2))
15023 (use (match_dup 3))
15024 (clobber (match_dup 5))])])
15026 (define_insn "fist<mode>2_floor"
15027 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15029 UNSPEC_FIST_FLOOR))
15030 (use (match_operand:HI 2 "memory_operand" "m"))
15031 (use (match_operand:HI 3 "memory_operand" "m"))]
15032 "TARGET_USE_FANCY_MATH_387
15033 && flag_unsafe_math_optimizations"
15034 "* return output_fix_trunc (insn, operands, false);"
15035 [(set_attr "type" "fistp")
15036 (set_attr "i387_cw" "floor")
15037 (set_attr "mode" "<MODE>")])
15039 (define_insn "fist<mode>2_floor_with_temp"
15040 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15041 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15042 UNSPEC_FIST_FLOOR))
15043 (use (match_operand:HI 2 "memory_operand" "m,m"))
15044 (use (match_operand:HI 3 "memory_operand" "m,m"))
15045 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15046 "TARGET_USE_FANCY_MATH_387
15047 && flag_unsafe_math_optimizations"
15049 [(set_attr "type" "fistp")
15050 (set_attr "i387_cw" "floor")
15051 (set_attr "mode" "<MODE>")])
15054 [(set (match_operand:SWI24 0 "register_operand" "")
15055 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15056 UNSPEC_FIST_FLOOR))
15057 (use (match_operand:HI 2 "memory_operand" ""))
15058 (use (match_operand:HI 3 "memory_operand" ""))
15059 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15061 [(parallel [(set (match_dup 4)
15062 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15063 (use (match_dup 2))
15064 (use (match_dup 3))])
15065 (set (match_dup 0) (match_dup 4))])
15068 [(set (match_operand:SWI24 0 "memory_operand" "")
15069 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15070 UNSPEC_FIST_FLOOR))
15071 (use (match_operand:HI 2 "memory_operand" ""))
15072 (use (match_operand:HI 3 "memory_operand" ""))
15073 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15075 [(parallel [(set (match_dup 0)
15076 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15077 (use (match_dup 2))
15078 (use (match_dup 3))])])
15080 (define_expand "lfloorxf<mode>2"
15081 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15082 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15083 UNSPEC_FIST_FLOOR))
15084 (clobber (reg:CC FLAGS_REG))])]
15085 "TARGET_USE_FANCY_MATH_387
15086 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15087 && flag_unsafe_math_optimizations")
15089 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15090 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15091 (match_operand:MODEF 1 "register_operand" "")]
15092 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15093 && !flag_trapping_math"
15095 if (TARGET_64BIT && optimize_insn_for_size_p ())
15097 ix86_expand_lfloorceil (operand0, operand1, true);
15101 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15102 (define_insn_and_split "frndintxf2_ceil"
15103 [(set (match_operand:XF 0 "register_operand" "")
15104 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15105 UNSPEC_FRNDINT_CEIL))
15106 (clobber (reg:CC FLAGS_REG))]
15107 "TARGET_USE_FANCY_MATH_387
15108 && flag_unsafe_math_optimizations
15109 && can_create_pseudo_p ()"
15114 ix86_optimize_mode_switching[I387_CEIL] = 1;
15116 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15117 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15119 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15120 operands[2], operands[3]));
15123 [(set_attr "type" "frndint")
15124 (set_attr "i387_cw" "ceil")
15125 (set_attr "mode" "XF")])
15127 (define_insn "frndintxf2_ceil_i387"
15128 [(set (match_operand:XF 0 "register_operand" "=f")
15129 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15130 UNSPEC_FRNDINT_CEIL))
15131 (use (match_operand:HI 2 "memory_operand" "m"))
15132 (use (match_operand:HI 3 "memory_operand" "m"))]
15133 "TARGET_USE_FANCY_MATH_387
15134 && flag_unsafe_math_optimizations"
15135 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15136 [(set_attr "type" "frndint")
15137 (set_attr "i387_cw" "ceil")
15138 (set_attr "mode" "XF")])
15140 (define_expand "ceilxf2"
15141 [(use (match_operand:XF 0 "register_operand" ""))
15142 (use (match_operand:XF 1 "register_operand" ""))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations"
15146 if (optimize_insn_for_size_p ())
15148 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15152 (define_expand "ceil<mode>2"
15153 [(use (match_operand:MODEF 0 "register_operand" ""))
15154 (use (match_operand:MODEF 1 "register_operand" ""))]
15155 "(TARGET_USE_FANCY_MATH_387
15156 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15157 || TARGET_MIX_SSE_I387)
15158 && flag_unsafe_math_optimizations)
15159 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15160 && !flag_trapping_math)"
15162 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15163 && !flag_trapping_math)
15166 emit_insn (gen_sse4_1_round<mode>2
15167 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15168 else if (optimize_insn_for_size_p ())
15170 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15171 ix86_expand_floorceil (operand0, operand1, false);
15173 ix86_expand_floorceildf_32 (operand0, operand1, false);
15179 if (optimize_insn_for_size_p ())
15182 op0 = gen_reg_rtx (XFmode);
15183 op1 = gen_reg_rtx (XFmode);
15184 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15185 emit_insn (gen_frndintxf2_ceil (op0, op1));
15187 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15192 (define_insn_and_split "*fist<mode>2_ceil_1"
15193 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15194 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15196 (clobber (reg:CC FLAGS_REG))]
15197 "TARGET_USE_FANCY_MATH_387
15198 && flag_unsafe_math_optimizations
15199 && can_create_pseudo_p ()"
15204 ix86_optimize_mode_switching[I387_CEIL] = 1;
15206 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15207 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15208 if (memory_operand (operands[0], VOIDmode))
15209 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15210 operands[2], operands[3]));
15213 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15214 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15215 operands[2], operands[3],
15220 [(set_attr "type" "fistp")
15221 (set_attr "i387_cw" "ceil")
15222 (set_attr "mode" "<MODE>")])
15224 (define_insn "fistdi2_ceil"
15225 [(set (match_operand:DI 0 "memory_operand" "=m")
15226 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15228 (use (match_operand:HI 2 "memory_operand" "m"))
15229 (use (match_operand:HI 3 "memory_operand" "m"))
15230 (clobber (match_scratch:XF 4 "=&1f"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && flag_unsafe_math_optimizations"
15233 "* return output_fix_trunc (insn, operands, false);"
15234 [(set_attr "type" "fistp")
15235 (set_attr "i387_cw" "ceil")
15236 (set_attr "mode" "DI")])
15238 (define_insn "fistdi2_ceil_with_temp"
15239 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15240 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15242 (use (match_operand:HI 2 "memory_operand" "m,m"))
15243 (use (match_operand:HI 3 "memory_operand" "m,m"))
15244 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15245 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15246 "TARGET_USE_FANCY_MATH_387
15247 && flag_unsafe_math_optimizations"
15249 [(set_attr "type" "fistp")
15250 (set_attr "i387_cw" "ceil")
15251 (set_attr "mode" "DI")])
15254 [(set (match_operand:DI 0 "register_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 4)
15263 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15264 (use (match_dup 2))
15265 (use (match_dup 3))
15266 (clobber (match_dup 5))])
15267 (set (match_dup 0) (match_dup 4))])
15270 [(set (match_operand:DI 0 "memory_operand" "")
15271 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15273 (use (match_operand:HI 2 "memory_operand" ""))
15274 (use (match_operand:HI 3 "memory_operand" ""))
15275 (clobber (match_operand:DI 4 "memory_operand" ""))
15276 (clobber (match_scratch 5 ""))]
15278 [(parallel [(set (match_dup 0)
15279 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15280 (use (match_dup 2))
15281 (use (match_dup 3))
15282 (clobber (match_dup 5))])])
15284 (define_insn "fist<mode>2_ceil"
15285 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15286 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15288 (use (match_operand:HI 2 "memory_operand" "m"))
15289 (use (match_operand:HI 3 "memory_operand" "m"))]
15290 "TARGET_USE_FANCY_MATH_387
15291 && flag_unsafe_math_optimizations"
15292 "* return output_fix_trunc (insn, operands, false);"
15293 [(set_attr "type" "fistp")
15294 (set_attr "i387_cw" "ceil")
15295 (set_attr "mode" "<MODE>")])
15297 (define_insn "fist<mode>2_ceil_with_temp"
15298 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15299 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15301 (use (match_operand:HI 2 "memory_operand" "m,m"))
15302 (use (match_operand:HI 3 "memory_operand" "m,m"))
15303 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15304 "TARGET_USE_FANCY_MATH_387
15305 && flag_unsafe_math_optimizations"
15307 [(set_attr "type" "fistp")
15308 (set_attr "i387_cw" "ceil")
15309 (set_attr "mode" "<MODE>")])
15312 [(set (match_operand:SWI24 0 "register_operand" "")
15313 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15315 (use (match_operand:HI 2 "memory_operand" ""))
15316 (use (match_operand:HI 3 "memory_operand" ""))
15317 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15319 [(parallel [(set (match_dup 4)
15320 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15321 (use (match_dup 2))
15322 (use (match_dup 3))])
15323 (set (match_dup 0) (match_dup 4))])
15326 [(set (match_operand:SWI24 0 "memory_operand" "")
15327 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15329 (use (match_operand:HI 2 "memory_operand" ""))
15330 (use (match_operand:HI 3 "memory_operand" ""))
15331 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15333 [(parallel [(set (match_dup 0)
15334 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15335 (use (match_dup 2))
15336 (use (match_dup 3))])])
15338 (define_expand "lceilxf<mode>2"
15339 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15340 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15342 (clobber (reg:CC FLAGS_REG))])]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15345 && flag_unsafe_math_optimizations")
15347 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15348 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15349 (match_operand:MODEF 1 "register_operand" "")]
15350 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15351 && !flag_trapping_math"
15353 ix86_expand_lfloorceil (operand0, operand1, false);
15357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15358 (define_insn_and_split "frndintxf2_trunc"
15359 [(set (match_operand:XF 0 "register_operand" "")
15360 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15361 UNSPEC_FRNDINT_TRUNC))
15362 (clobber (reg:CC FLAGS_REG))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations
15365 && can_create_pseudo_p ()"
15370 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15372 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15373 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15375 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15376 operands[2], operands[3]));
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "trunc")
15381 (set_attr "mode" "XF")])
15383 (define_insn "frndintxf2_trunc_i387"
15384 [(set (match_operand:XF 0 "register_operand" "=f")
15385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15386 UNSPEC_FRNDINT_TRUNC))
15387 (use (match_operand:HI 2 "memory_operand" "m"))
15388 (use (match_operand:HI 3 "memory_operand" "m"))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15391 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15392 [(set_attr "type" "frndint")
15393 (set_attr "i387_cw" "trunc")
15394 (set_attr "mode" "XF")])
15396 (define_expand "btruncxf2"
15397 [(use (match_operand:XF 0 "register_operand" ""))
15398 (use (match_operand:XF 1 "register_operand" ""))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && flag_unsafe_math_optimizations"
15402 if (optimize_insn_for_size_p ())
15404 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15408 (define_expand "btrunc<mode>2"
15409 [(use (match_operand:MODEF 0 "register_operand" ""))
15410 (use (match_operand:MODEF 1 "register_operand" ""))]
15411 "(TARGET_USE_FANCY_MATH_387
15412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15413 || TARGET_MIX_SSE_I387)
15414 && flag_unsafe_math_optimizations)
15415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15416 && !flag_trapping_math)"
15418 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15419 && !flag_trapping_math)
15422 emit_insn (gen_sse4_1_round<mode>2
15423 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15424 else if (optimize_insn_for_size_p ())
15426 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15427 ix86_expand_trunc (operand0, operand1);
15429 ix86_expand_truncdf_32 (operand0, operand1);
15435 if (optimize_insn_for_size_p ())
15438 op0 = gen_reg_rtx (XFmode);
15439 op1 = gen_reg_rtx (XFmode);
15440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15441 emit_insn (gen_frndintxf2_trunc (op0, op1));
15443 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15448 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15449 (define_insn_and_split "frndintxf2_mask_pm"
15450 [(set (match_operand:XF 0 "register_operand" "")
15451 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15452 UNSPEC_FRNDINT_MASK_PM))
15453 (clobber (reg:CC FLAGS_REG))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations
15456 && can_create_pseudo_p ()"
15461 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15463 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15464 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15466 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15467 operands[2], operands[3]));
15470 [(set_attr "type" "frndint")
15471 (set_attr "i387_cw" "mask_pm")
15472 (set_attr "mode" "XF")])
15474 (define_insn "frndintxf2_mask_pm_i387"
15475 [(set (match_operand:XF 0 "register_operand" "=f")
15476 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15477 UNSPEC_FRNDINT_MASK_PM))
15478 (use (match_operand:HI 2 "memory_operand" "m"))
15479 (use (match_operand:HI 3 "memory_operand" "m"))]
15480 "TARGET_USE_FANCY_MATH_387
15481 && flag_unsafe_math_optimizations"
15482 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15483 [(set_attr "type" "frndint")
15484 (set_attr "i387_cw" "mask_pm")
15485 (set_attr "mode" "XF")])
15487 (define_expand "nearbyintxf2"
15488 [(use (match_operand:XF 0 "register_operand" ""))
15489 (use (match_operand:XF 1 "register_operand" ""))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && flag_unsafe_math_optimizations"
15493 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15497 (define_expand "nearbyint<mode>2"
15498 [(use (match_operand:MODEF 0 "register_operand" ""))
15499 (use (match_operand:MODEF 1 "register_operand" ""))]
15500 "TARGET_USE_FANCY_MATH_387
15501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15502 || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15505 rtx op0 = gen_reg_rtx (XFmode);
15506 rtx op1 = gen_reg_rtx (XFmode);
15508 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15509 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15515 (define_insn "fxam<mode>2_i387"
15516 [(set (match_operand:HI 0 "register_operand" "=a")
15518 [(match_operand:X87MODEF 1 "register_operand" "f")]
15520 "TARGET_USE_FANCY_MATH_387"
15521 "fxam\n\tfnstsw\t%0"
15522 [(set_attr "type" "multi")
15523 (set_attr "length" "4")
15524 (set_attr "unit" "i387")
15525 (set_attr "mode" "<MODE>")])
15527 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15528 [(set (match_operand:HI 0 "register_operand" "")
15530 [(match_operand:MODEF 1 "memory_operand" "")]
15532 "TARGET_USE_FANCY_MATH_387
15533 && can_create_pseudo_p ()"
15536 [(set (match_dup 2)(match_dup 1))
15538 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15540 operands[2] = gen_reg_rtx (<MODE>mode);
15542 MEM_VOLATILE_P (operands[1]) = 1;
15544 [(set_attr "type" "multi")
15545 (set_attr "unit" "i387")
15546 (set_attr "mode" "<MODE>")])
15548 (define_expand "isinfxf2"
15549 [(use (match_operand:SI 0 "register_operand" ""))
15550 (use (match_operand:XF 1 "register_operand" ""))]
15551 "TARGET_USE_FANCY_MATH_387
15552 && TARGET_C99_FUNCTIONS"
15554 rtx mask = GEN_INT (0x45);
15555 rtx val = GEN_INT (0x05);
15559 rtx scratch = gen_reg_rtx (HImode);
15560 rtx res = gen_reg_rtx (QImode);
15562 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15564 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15565 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15566 cond = gen_rtx_fmt_ee (EQ, QImode,
15567 gen_rtx_REG (CCmode, FLAGS_REG),
15569 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15570 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15574 (define_expand "isinf<mode>2"
15575 [(use (match_operand:SI 0 "register_operand" ""))
15576 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && TARGET_C99_FUNCTIONS
15579 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15581 rtx mask = GEN_INT (0x45);
15582 rtx val = GEN_INT (0x05);
15586 rtx scratch = gen_reg_rtx (HImode);
15587 rtx res = gen_reg_rtx (QImode);
15589 /* Remove excess precision by forcing value through memory. */
15590 if (memory_operand (operands[1], VOIDmode))
15591 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15594 enum ix86_stack_slot slot = (virtuals_instantiated
15597 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15599 emit_move_insn (temp, operands[1]);
15600 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15603 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15604 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15605 cond = gen_rtx_fmt_ee (EQ, QImode,
15606 gen_rtx_REG (CCmode, FLAGS_REG),
15608 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15609 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15613 (define_expand "signbitxf2"
15614 [(use (match_operand:SI 0 "register_operand" ""))
15615 (use (match_operand:XF 1 "register_operand" ""))]
15616 "TARGET_USE_FANCY_MATH_387"
15618 rtx scratch = gen_reg_rtx (HImode);
15620 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15621 emit_insn (gen_andsi3 (operands[0],
15622 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15626 (define_insn "movmsk_df"
15627 [(set (match_operand:SI 0 "register_operand" "=r")
15629 [(match_operand:DF 1 "register_operand" "x")]
15631 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15632 "%vmovmskpd\t{%1, %0|%0, %1}"
15633 [(set_attr "type" "ssemov")
15634 (set_attr "prefix" "maybe_vex")
15635 (set_attr "mode" "DF")])
15637 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15638 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15639 (define_expand "signbitdf2"
15640 [(use (match_operand:SI 0 "register_operand" ""))
15641 (use (match_operand:DF 1 "register_operand" ""))]
15642 "TARGET_USE_FANCY_MATH_387
15643 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15645 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15647 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15648 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15652 rtx scratch = gen_reg_rtx (HImode);
15654 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15655 emit_insn (gen_andsi3 (operands[0],
15656 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15661 (define_expand "signbitsf2"
15662 [(use (match_operand:SI 0 "register_operand" ""))
15663 (use (match_operand:SF 1 "register_operand" ""))]
15664 "TARGET_USE_FANCY_MATH_387
15665 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15667 rtx scratch = gen_reg_rtx (HImode);
15669 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15670 emit_insn (gen_andsi3 (operands[0],
15671 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15675 ;; Block operation instructions
15678 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15681 [(set_attr "length" "1")
15682 (set_attr "length_immediate" "0")
15683 (set_attr "modrm" "0")])
15685 (define_expand "movmem<mode>"
15686 [(use (match_operand:BLK 0 "memory_operand" ""))
15687 (use (match_operand:BLK 1 "memory_operand" ""))
15688 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15689 (use (match_operand:SWI48 3 "const_int_operand" ""))
15690 (use (match_operand:SI 4 "const_int_operand" ""))
15691 (use (match_operand:SI 5 "const_int_operand" ""))]
15694 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15695 operands[4], operands[5]))
15701 ;; Most CPUs don't like single string operations
15702 ;; Handle this case here to simplify previous expander.
15704 (define_expand "strmov"
15705 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15706 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15707 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15708 (clobber (reg:CC FLAGS_REG))])
15709 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15710 (clobber (reg:CC FLAGS_REG))])]
15713 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15715 /* If .md ever supports :P for Pmode, these can be directly
15716 in the pattern above. */
15717 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15718 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15720 /* Can't use this if the user has appropriated esi or edi. */
15721 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15722 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15724 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15725 operands[2], operands[3],
15726 operands[5], operands[6]));
15730 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15733 (define_expand "strmov_singleop"
15734 [(parallel [(set (match_operand 1 "memory_operand" "")
15735 (match_operand 3 "memory_operand" ""))
15736 (set (match_operand 0 "register_operand" "")
15737 (match_operand 4 "" ""))
15738 (set (match_operand 2 "register_operand" "")
15739 (match_operand 5 "" ""))])]
15741 "ix86_current_function_needs_cld = 1;")
15743 (define_insn "*strmovdi_rex_1"
15744 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15745 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15746 (set (match_operand:DI 0 "register_operand" "=D")
15747 (plus:DI (match_dup 2)
15749 (set (match_operand:DI 1 "register_operand" "=S")
15750 (plus:DI (match_dup 3)
15753 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "both")
15757 (set_attr "mode" "DI")])
15759 (define_insn "*strmovsi_1"
15760 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15761 (mem:SI (match_operand:P 3 "register_operand" "1")))
15762 (set (match_operand:P 0 "register_operand" "=D")
15763 (plus:P (match_dup 2)
15765 (set (match_operand:P 1 "register_operand" "=S")
15766 (plus:P (match_dup 3)
15768 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15770 [(set_attr "type" "str")
15771 (set_attr "memory" "both")
15772 (set_attr "mode" "SI")])
15774 (define_insn "*strmovhi_1"
15775 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15776 (mem:HI (match_operand:P 3 "register_operand" "1")))
15777 (set (match_operand:P 0 "register_operand" "=D")
15778 (plus:P (match_dup 2)
15780 (set (match_operand:P 1 "register_operand" "=S")
15781 (plus:P (match_dup 3)
15783 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15785 [(set_attr "type" "str")
15786 (set_attr "memory" "both")
15787 (set_attr "mode" "HI")])
15789 (define_insn "*strmovqi_1"
15790 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15791 (mem:QI (match_operand:P 3 "register_operand" "1")))
15792 (set (match_operand:P 0 "register_operand" "=D")
15793 (plus:P (match_dup 2)
15795 (set (match_operand:P 1 "register_operand" "=S")
15796 (plus:P (match_dup 3)
15798 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15800 [(set_attr "type" "str")
15801 (set_attr "memory" "both")
15802 (set (attr "prefix_rex")
15804 (match_test "<P:MODE>mode == DImode")
15806 (const_string "*")))
15807 (set_attr "mode" "QI")])
15809 (define_expand "rep_mov"
15810 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15811 (set (match_operand 0 "register_operand" "")
15812 (match_operand 5 "" ""))
15813 (set (match_operand 2 "register_operand" "")
15814 (match_operand 6 "" ""))
15815 (set (match_operand 1 "memory_operand" "")
15816 (match_operand 3 "memory_operand" ""))
15817 (use (match_dup 4))])]
15819 "ix86_current_function_needs_cld = 1;")
15821 (define_insn "*rep_movdi_rex64"
15822 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15823 (set (match_operand:DI 0 "register_operand" "=D")
15824 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15826 (match_operand:DI 3 "register_operand" "0")))
15827 (set (match_operand:DI 1 "register_operand" "=S")
15828 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15829 (match_operand:DI 4 "register_operand" "1")))
15830 (set (mem:BLK (match_dup 3))
15831 (mem:BLK (match_dup 4)))
15832 (use (match_dup 5))]
15834 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15836 [(set_attr "type" "str")
15837 (set_attr "prefix_rep" "1")
15838 (set_attr "memory" "both")
15839 (set_attr "mode" "DI")])
15841 (define_insn "*rep_movsi"
15842 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15843 (set (match_operand:P 0 "register_operand" "=D")
15844 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15846 (match_operand:P 3 "register_operand" "0")))
15847 (set (match_operand:P 1 "register_operand" "=S")
15848 (plus:P (ashift:P (match_dup 5) (const_int 2))
15849 (match_operand:P 4 "register_operand" "1")))
15850 (set (mem:BLK (match_dup 3))
15851 (mem:BLK (match_dup 4)))
15852 (use (match_dup 5))]
15853 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15854 "rep{%;} movs{l|d}"
15855 [(set_attr "type" "str")
15856 (set_attr "prefix_rep" "1")
15857 (set_attr "memory" "both")
15858 (set_attr "mode" "SI")])
15860 (define_insn "*rep_movqi"
15861 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15862 (set (match_operand:P 0 "register_operand" "=D")
15863 (plus:P (match_operand:P 3 "register_operand" "0")
15864 (match_operand:P 5 "register_operand" "2")))
15865 (set (match_operand:P 1 "register_operand" "=S")
15866 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15867 (set (mem:BLK (match_dup 3))
15868 (mem:BLK (match_dup 4)))
15869 (use (match_dup 5))]
15870 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15872 [(set_attr "type" "str")
15873 (set_attr "prefix_rep" "1")
15874 (set_attr "memory" "both")
15875 (set_attr "mode" "QI")])
15877 (define_expand "setmem<mode>"
15878 [(use (match_operand:BLK 0 "memory_operand" ""))
15879 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15880 (use (match_operand:QI 2 "nonmemory_operand" ""))
15881 (use (match_operand 3 "const_int_operand" ""))
15882 (use (match_operand:SI 4 "const_int_operand" ""))
15883 (use (match_operand:SI 5 "const_int_operand" ""))]
15886 if (ix86_expand_setmem (operands[0], operands[1],
15887 operands[2], operands[3],
15888 operands[4], operands[5]))
15894 ;; Most CPUs don't like single string operations
15895 ;; Handle this case here to simplify previous expander.
15897 (define_expand "strset"
15898 [(set (match_operand 1 "memory_operand" "")
15899 (match_operand 2 "register_operand" ""))
15900 (parallel [(set (match_operand 0 "register_operand" "")
15902 (clobber (reg:CC FLAGS_REG))])]
15905 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15906 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15908 /* If .md ever supports :P for Pmode, this can be directly
15909 in the pattern above. */
15910 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15911 GEN_INT (GET_MODE_SIZE (GET_MODE
15913 /* Can't use this if the user has appropriated eax or edi. */
15914 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15915 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15917 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15923 (define_expand "strset_singleop"
15924 [(parallel [(set (match_operand 1 "memory_operand" "")
15925 (match_operand 2 "register_operand" ""))
15926 (set (match_operand 0 "register_operand" "")
15927 (match_operand 3 "" ""))])]
15929 "ix86_current_function_needs_cld = 1;")
15931 (define_insn "*strsetdi_rex_1"
15932 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15933 (match_operand:DI 2 "register_operand" "a"))
15934 (set (match_operand:DI 0 "register_operand" "=D")
15935 (plus:DI (match_dup 1)
15938 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15940 [(set_attr "type" "str")
15941 (set_attr "memory" "store")
15942 (set_attr "mode" "DI")])
15944 (define_insn "*strsetsi_1"
15945 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15946 (match_operand:SI 2 "register_operand" "a"))
15947 (set (match_operand:P 0 "register_operand" "=D")
15948 (plus:P (match_dup 1)
15950 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "memory" "store")
15954 (set_attr "mode" "SI")])
15956 (define_insn "*strsethi_1"
15957 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15958 (match_operand:HI 2 "register_operand" "a"))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (match_dup 1)
15962 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15964 [(set_attr "type" "str")
15965 (set_attr "memory" "store")
15966 (set_attr "mode" "HI")])
15968 (define_insn "*strsetqi_1"
15969 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15970 (match_operand:QI 2 "register_operand" "a"))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (match_dup 1)
15974 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15976 [(set_attr "type" "str")
15977 (set_attr "memory" "store")
15978 (set (attr "prefix_rex")
15980 (match_test "<P:MODE>mode == DImode")
15982 (const_string "*")))
15983 (set_attr "mode" "QI")])
15985 (define_expand "rep_stos"
15986 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15987 (set (match_operand 0 "register_operand" "")
15988 (match_operand 4 "" ""))
15989 (set (match_operand 2 "memory_operand" "") (const_int 0))
15990 (use (match_operand 3 "register_operand" ""))
15991 (use (match_dup 1))])]
15993 "ix86_current_function_needs_cld = 1;")
15995 (define_insn "*rep_stosdi_rex64"
15996 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15997 (set (match_operand:DI 0 "register_operand" "=D")
15998 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16000 (match_operand:DI 3 "register_operand" "0")))
16001 (set (mem:BLK (match_dup 3))
16003 (use (match_operand:DI 2 "register_operand" "a"))
16004 (use (match_dup 4))]
16006 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008 [(set_attr "type" "str")
16009 (set_attr "prefix_rep" "1")
16010 (set_attr "memory" "store")
16011 (set_attr "mode" "DI")])
16013 (define_insn "*rep_stossi"
16014 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16015 (set (match_operand:P 0 "register_operand" "=D")
16016 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16018 (match_operand:P 3 "register_operand" "0")))
16019 (set (mem:BLK (match_dup 3))
16021 (use (match_operand:SI 2 "register_operand" "a"))
16022 (use (match_dup 4))]
16023 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024 "rep{%;} stos{l|d}"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "SI")])
16030 (define_insn "*rep_stosqi"
16031 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032 (set (match_operand:P 0 "register_operand" "=D")
16033 (plus:P (match_operand:P 3 "register_operand" "0")
16034 (match_operand:P 4 "register_operand" "1")))
16035 (set (mem:BLK (match_dup 3))
16037 (use (match_operand:QI 2 "register_operand" "a"))
16038 (use (match_dup 4))]
16039 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041 [(set_attr "type" "str")
16042 (set_attr "prefix_rep" "1")
16043 (set_attr "memory" "store")
16044 (set (attr "prefix_rex")
16046 (match_test "<P:MODE>mode == DImode")
16048 (const_string "*")))
16049 (set_attr "mode" "QI")])
16051 (define_expand "cmpstrnsi"
16052 [(set (match_operand:SI 0 "register_operand" "")
16053 (compare:SI (match_operand:BLK 1 "general_operand" "")
16054 (match_operand:BLK 2 "general_operand" "")))
16055 (use (match_operand 3 "general_operand" ""))
16056 (use (match_operand 4 "immediate_operand" ""))]
16059 rtx addr1, addr2, out, outlow, count, countreg, align;
16061 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16064 /* Can't use this if the user has appropriated ecx, esi or edi. */
16065 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16070 out = gen_reg_rtx (SImode);
16072 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16073 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16074 if (addr1 != XEXP (operands[1], 0))
16075 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16076 if (addr2 != XEXP (operands[2], 0))
16077 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16079 count = operands[3];
16080 countreg = ix86_zero_extend_to_Pmode (count);
16082 /* %%% Iff we are testing strict equality, we can use known alignment
16083 to good advantage. This may be possible with combine, particularly
16084 once cc0 is dead. */
16085 align = operands[4];
16087 if (CONST_INT_P (count))
16089 if (INTVAL (count) == 0)
16091 emit_move_insn (operands[0], const0_rtx);
16094 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16095 operands[1], operands[2]));
16099 rtx (*gen_cmp) (rtx, rtx);
16101 gen_cmp = (TARGET_64BIT
16102 ? gen_cmpdi_1 : gen_cmpsi_1);
16104 emit_insn (gen_cmp (countreg, countreg));
16105 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16106 operands[1], operands[2]));
16109 outlow = gen_lowpart (QImode, out);
16110 emit_insn (gen_cmpintqi (outlow));
16111 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16113 if (operands[0] != out)
16114 emit_move_insn (operands[0], out);
16119 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16121 (define_expand "cmpintqi"
16122 [(set (match_dup 1)
16123 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16125 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16126 (parallel [(set (match_operand:QI 0 "register_operand" "")
16127 (minus:QI (match_dup 1)
16129 (clobber (reg:CC FLAGS_REG))])]
16132 operands[1] = gen_reg_rtx (QImode);
16133 operands[2] = gen_reg_rtx (QImode);
16136 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16137 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16139 (define_expand "cmpstrnqi_nz_1"
16140 [(parallel [(set (reg:CC FLAGS_REG)
16141 (compare:CC (match_operand 4 "memory_operand" "")
16142 (match_operand 5 "memory_operand" "")))
16143 (use (match_operand 2 "register_operand" ""))
16144 (use (match_operand:SI 3 "immediate_operand" ""))
16145 (clobber (match_operand 0 "register_operand" ""))
16146 (clobber (match_operand 1 "register_operand" ""))
16147 (clobber (match_dup 2))])]
16149 "ix86_current_function_needs_cld = 1;")
16151 (define_insn "*cmpstrnqi_nz_1"
16152 [(set (reg:CC FLAGS_REG)
16153 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16154 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16155 (use (match_operand:P 6 "register_operand" "2"))
16156 (use (match_operand:SI 3 "immediate_operand" "i"))
16157 (clobber (match_operand:P 0 "register_operand" "=S"))
16158 (clobber (match_operand:P 1 "register_operand" "=D"))
16159 (clobber (match_operand:P 2 "register_operand" "=c"))]
16160 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16162 [(set_attr "type" "str")
16163 (set_attr "mode" "QI")
16164 (set (attr "prefix_rex")
16166 (match_test "<P:MODE>mode == DImode")
16168 (const_string "*")))
16169 (set_attr "prefix_rep" "1")])
16171 ;; The same, but the count is not known to not be zero.
16173 (define_expand "cmpstrnqi_1"
16174 [(parallel [(set (reg:CC FLAGS_REG)
16175 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16177 (compare:CC (match_operand 4 "memory_operand" "")
16178 (match_operand 5 "memory_operand" ""))
16180 (use (match_operand:SI 3 "immediate_operand" ""))
16181 (use (reg:CC FLAGS_REG))
16182 (clobber (match_operand 0 "register_operand" ""))
16183 (clobber (match_operand 1 "register_operand" ""))
16184 (clobber (match_dup 2))])]
16186 "ix86_current_function_needs_cld = 1;")
16188 (define_insn "*cmpstrnqi_1"
16189 [(set (reg:CC FLAGS_REG)
16190 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16192 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16193 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16195 (use (match_operand:SI 3 "immediate_operand" "i"))
16196 (use (reg:CC FLAGS_REG))
16197 (clobber (match_operand:P 0 "register_operand" "=S"))
16198 (clobber (match_operand:P 1 "register_operand" "=D"))
16199 (clobber (match_operand:P 2 "register_operand" "=c"))]
16200 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16202 [(set_attr "type" "str")
16203 (set_attr "mode" "QI")
16204 (set (attr "prefix_rex")
16206 (match_test "<P:MODE>mode == DImode")
16208 (const_string "*")))
16209 (set_attr "prefix_rep" "1")])
16211 (define_expand "strlen<mode>"
16212 [(set (match_operand:P 0 "register_operand" "")
16213 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16214 (match_operand:QI 2 "immediate_operand" "")
16215 (match_operand 3 "immediate_operand" "")]
16219 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16225 (define_expand "strlenqi_1"
16226 [(parallel [(set (match_operand 0 "register_operand" "")
16227 (match_operand 2 "" ""))
16228 (clobber (match_operand 1 "register_operand" ""))
16229 (clobber (reg:CC FLAGS_REG))])]
16231 "ix86_current_function_needs_cld = 1;")
16233 (define_insn "*strlenqi_1"
16234 [(set (match_operand:P 0 "register_operand" "=&c")
16235 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16236 (match_operand:QI 2 "register_operand" "a")
16237 (match_operand:P 3 "immediate_operand" "i")
16238 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16239 (clobber (match_operand:P 1 "register_operand" "=D"))
16240 (clobber (reg:CC FLAGS_REG))]
16241 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16243 [(set_attr "type" "str")
16244 (set_attr "mode" "QI")
16245 (set (attr "prefix_rex")
16247 (match_test "<P:MODE>mode == DImode")
16249 (const_string "*")))
16250 (set_attr "prefix_rep" "1")])
16252 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16253 ;; handled in combine, but it is not currently up to the task.
16254 ;; When used for their truth value, the cmpstrn* expanders generate
16263 ;; The intermediate three instructions are unnecessary.
16265 ;; This one handles cmpstrn*_nz_1...
16268 (set (reg:CC FLAGS_REG)
16269 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16270 (mem:BLK (match_operand 5 "register_operand" ""))))
16271 (use (match_operand 6 "register_operand" ""))
16272 (use (match_operand:SI 3 "immediate_operand" ""))
16273 (clobber (match_operand 0 "register_operand" ""))
16274 (clobber (match_operand 1 "register_operand" ""))
16275 (clobber (match_operand 2 "register_operand" ""))])
16276 (set (match_operand:QI 7 "register_operand" "")
16277 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16278 (set (match_operand:QI 8 "register_operand" "")
16279 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16280 (set (reg FLAGS_REG)
16281 (compare (match_dup 7) (match_dup 8)))
16283 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16285 (set (reg:CC FLAGS_REG)
16286 (compare:CC (mem:BLK (match_dup 4))
16287 (mem:BLK (match_dup 5))))
16288 (use (match_dup 6))
16289 (use (match_dup 3))
16290 (clobber (match_dup 0))
16291 (clobber (match_dup 1))
16292 (clobber (match_dup 2))])])
16294 ;; ...and this one handles cmpstrn*_1.
16297 (set (reg:CC FLAGS_REG)
16298 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16300 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16301 (mem:BLK (match_operand 5 "register_operand" "")))
16303 (use (match_operand:SI 3 "immediate_operand" ""))
16304 (use (reg:CC FLAGS_REG))
16305 (clobber (match_operand 0 "register_operand" ""))
16306 (clobber (match_operand 1 "register_operand" ""))
16307 (clobber (match_operand 2 "register_operand" ""))])
16308 (set (match_operand:QI 7 "register_operand" "")
16309 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16310 (set (match_operand:QI 8 "register_operand" "")
16311 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16312 (set (reg FLAGS_REG)
16313 (compare (match_dup 7) (match_dup 8)))
16315 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16317 (set (reg:CC FLAGS_REG)
16318 (if_then_else:CC (ne (match_dup 6)
16320 (compare:CC (mem:BLK (match_dup 4))
16321 (mem:BLK (match_dup 5)))
16323 (use (match_dup 3))
16324 (use (reg:CC FLAGS_REG))
16325 (clobber (match_dup 0))
16326 (clobber (match_dup 1))
16327 (clobber (match_dup 2))])])
16329 ;; Conditional move instructions.
16331 (define_expand "mov<mode>cc"
16332 [(set (match_operand:SWIM 0 "register_operand" "")
16333 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16334 (match_operand:SWIM 2 "<general_operand>" "")
16335 (match_operand:SWIM 3 "<general_operand>" "")))]
16337 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16339 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16340 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16341 ;; So just document what we're doing explicitly.
16343 (define_expand "x86_mov<mode>cc_0_m1"
16345 [(set (match_operand:SWI48 0 "register_operand" "")
16346 (if_then_else:SWI48
16347 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16348 [(match_operand 1 "flags_reg_operand" "")
16352 (clobber (reg:CC FLAGS_REG))])])
16354 (define_insn "*x86_mov<mode>cc_0_m1"
16355 [(set (match_operand:SWI48 0 "register_operand" "=r")
16356 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16357 [(reg FLAGS_REG) (const_int 0)])
16360 (clobber (reg:CC FLAGS_REG))]
16362 "sbb{<imodesuffix>}\t%0, %0"
16363 ; Since we don't have the proper number of operands for an alu insn,
16364 ; fill in all the blanks.
16365 [(set_attr "type" "alu")
16366 (set_attr "use_carry" "1")
16367 (set_attr "pent_pair" "pu")
16368 (set_attr "memory" "none")
16369 (set_attr "imm_disp" "false")
16370 (set_attr "mode" "<MODE>")
16371 (set_attr "length_immediate" "0")])
16373 (define_insn "*x86_mov<mode>cc_0_m1_se"
16374 [(set (match_operand:SWI48 0 "register_operand" "=r")
16375 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16376 [(reg FLAGS_REG) (const_int 0)])
16379 (clobber (reg:CC FLAGS_REG))]
16381 "sbb{<imodesuffix>}\t%0, %0"
16382 [(set_attr "type" "alu")
16383 (set_attr "use_carry" "1")
16384 (set_attr "pent_pair" "pu")
16385 (set_attr "memory" "none")
16386 (set_attr "imm_disp" "false")
16387 (set_attr "mode" "<MODE>")
16388 (set_attr "length_immediate" "0")])
16390 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16391 [(set (match_operand:SWI48 0 "register_operand" "=r")
16392 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393 [(reg FLAGS_REG) (const_int 0)])))]
16395 "sbb{<imodesuffix>}\t%0, %0"
16396 [(set_attr "type" "alu")
16397 (set_attr "use_carry" "1")
16398 (set_attr "pent_pair" "pu")
16399 (set_attr "memory" "none")
16400 (set_attr "imm_disp" "false")
16401 (set_attr "mode" "<MODE>")
16402 (set_attr "length_immediate" "0")])
16404 (define_insn "*mov<mode>cc_noc"
16405 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16406 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16409 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16410 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16412 cmov%O2%C1\t{%2, %0|%0, %2}
16413 cmov%O2%c1\t{%3, %0|%0, %3}"
16414 [(set_attr "type" "icmov")
16415 (set_attr "mode" "<MODE>")])
16417 (define_insn_and_split "*movqicc_noc"
16418 [(set (match_operand:QI 0 "register_operand" "=r,r")
16419 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16420 [(match_operand 4 "flags_reg_operand" "")
16422 (match_operand:QI 2 "register_operand" "r,0")
16423 (match_operand:QI 3 "register_operand" "0,r")))]
16424 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16426 "&& reload_completed"
16427 [(set (match_dup 0)
16428 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16431 "operands[0] = gen_lowpart (SImode, operands[0]);
16432 operands[2] = gen_lowpart (SImode, operands[2]);
16433 operands[3] = gen_lowpart (SImode, operands[3]);"
16434 [(set_attr "type" "icmov")
16435 (set_attr "mode" "SI")])
16437 (define_expand "mov<mode>cc"
16438 [(set (match_operand:X87MODEF 0 "register_operand" "")
16439 (if_then_else:X87MODEF
16440 (match_operand 1 "ix86_fp_comparison_operator" "")
16441 (match_operand:X87MODEF 2 "register_operand" "")
16442 (match_operand:X87MODEF 3 "register_operand" "")))]
16443 "(TARGET_80387 && TARGET_CMOVE)
16444 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16445 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16447 (define_insn "*movxfcc_1"
16448 [(set (match_operand:XF 0 "register_operand" "=f,f")
16449 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16450 [(reg FLAGS_REG) (const_int 0)])
16451 (match_operand:XF 2 "register_operand" "f,0")
16452 (match_operand:XF 3 "register_operand" "0,f")))]
16453 "TARGET_80387 && TARGET_CMOVE"
16455 fcmov%F1\t{%2, %0|%0, %2}
16456 fcmov%f1\t{%3, %0|%0, %3}"
16457 [(set_attr "type" "fcmov")
16458 (set_attr "mode" "XF")])
16460 (define_insn "*movdfcc_1_rex64"
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}
16471 cmov%O2%C1\t{%2, %0|%0, %2}
16472 cmov%O2%c1\t{%3, %0|%0, %3}"
16473 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16474 (set_attr "mode" "DF,DF,DI,DI")])
16476 (define_insn "*movdfcc_1"
16477 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16478 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16479 [(reg FLAGS_REG) (const_int 0)])
16480 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16481 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16482 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16483 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16485 fcmov%F1\t{%2, %0|%0, %2}
16486 fcmov%f1\t{%3, %0|%0, %3}
16489 [(set_attr "type" "fcmov,fcmov,multi,multi")
16490 (set_attr "mode" "DF,DF,DI,DI")])
16493 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16494 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16495 [(match_operand 4 "flags_reg_operand" "")
16497 (match_operand:DF 2 "nonimmediate_operand" "")
16498 (match_operand:DF 3 "nonimmediate_operand" "")))]
16499 "!TARGET_64BIT && reload_completed"
16500 [(set (match_dup 2)
16501 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16505 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16509 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16510 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16513 (define_insn "*movsfcc_1_387"
16514 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16515 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16516 [(reg FLAGS_REG) (const_int 0)])
16517 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16518 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16519 "TARGET_80387 && TARGET_CMOVE
16520 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16522 fcmov%F1\t{%2, %0|%0, %2}
16523 fcmov%f1\t{%3, %0|%0, %3}
16524 cmov%O2%C1\t{%2, %0|%0, %2}
16525 cmov%O2%c1\t{%3, %0|%0, %3}"
16526 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16527 (set_attr "mode" "SF,SF,SI,SI")])
16529 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16530 ;; the scalar versions to have only XMM registers as operands.
16532 ;; XOP conditional move
16533 (define_insn "*xop_pcmov_<mode>"
16534 [(set (match_operand:MODEF 0 "register_operand" "=x")
16535 (if_then_else:MODEF
16536 (match_operand:MODEF 1 "register_operand" "x")
16537 (match_operand:MODEF 2 "register_operand" "x")
16538 (match_operand:MODEF 3 "register_operand" "x")))]
16540 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16541 [(set_attr "type" "sse4arg")])
16543 ;; These versions of the min/max patterns are intentionally ignorant of
16544 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16545 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16546 ;; are undefined in this condition, we're certain this is correct.
16548 (define_insn "<code><mode>3"
16549 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16551 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16552 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16553 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16555 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16556 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16557 [(set_attr "isa" "noavx,avx")
16558 (set_attr "prefix" "orig,vex")
16559 (set_attr "type" "sseadd")
16560 (set_attr "mode" "<MODE>")])
16562 ;; These versions of the min/max patterns implement exactly the operations
16563 ;; min = (op1 < op2 ? op1 : op2)
16564 ;; max = (!(op1 < op2) ? op1 : op2)
16565 ;; Their operands are not commutative, and thus they may be used in the
16566 ;; presence of -0.0 and NaN.
16568 (define_insn "*ieee_smin<mode>3"
16569 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16571 [(match_operand:MODEF 1 "register_operand" "0,x")
16572 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16574 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16576 min<ssemodesuffix>\t{%2, %0|%0, %2}
16577 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16578 [(set_attr "isa" "noavx,avx")
16579 (set_attr "prefix" "orig,vex")
16580 (set_attr "type" "sseadd")
16581 (set_attr "mode" "<MODE>")])
16583 (define_insn "*ieee_smax<mode>3"
16584 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16586 [(match_operand:MODEF 1 "register_operand" "0,x")
16587 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16589 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16591 max<ssemodesuffix>\t{%2, %0|%0, %2}
16592 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16593 [(set_attr "isa" "noavx,avx")
16594 (set_attr "prefix" "orig,vex")
16595 (set_attr "type" "sseadd")
16596 (set_attr "mode" "<MODE>")])
16598 ;; Make two stack loads independent:
16600 ;; fld %st(0) -> fld bb
16601 ;; fmul bb fmul %st(1), %st
16603 ;; Actually we only match the last two instructions for simplicity.
16605 [(set (match_operand 0 "fp_register_operand" "")
16606 (match_operand 1 "fp_register_operand" ""))
16608 (match_operator 2 "binary_fp_operator"
16610 (match_operand 3 "memory_operand" "")]))]
16611 "REGNO (operands[0]) != REGNO (operands[1])"
16612 [(set (match_dup 0) (match_dup 3))
16613 (set (match_dup 0) (match_dup 4))]
16615 ;; The % modifier is not operational anymore in peephole2's, so we have to
16616 ;; swap the operands manually in the case of addition and multiplication.
16617 "if (COMMUTATIVE_ARITH_P (operands[2]))
16618 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16619 GET_MODE (operands[2]),
16620 operands[0], operands[1]);
16622 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16623 GET_MODE (operands[2]),
16624 operands[1], operands[0]);")
16626 ;; Conditional addition patterns
16627 (define_expand "add<mode>cc"
16628 [(match_operand:SWI 0 "register_operand" "")
16629 (match_operand 1 "ordered_comparison_operator" "")
16630 (match_operand:SWI 2 "register_operand" "")
16631 (match_operand:SWI 3 "const_int_operand" "")]
16633 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16635 ;; Misc patterns (?)
16637 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16638 ;; Otherwise there will be nothing to keep
16640 ;; [(set (reg ebp) (reg esp))]
16641 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16642 ;; (clobber (eflags)]
16643 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16645 ;; in proper program order.
16647 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16648 [(set (match_operand:P 0 "register_operand" "=r,r")
16649 (plus:P (match_operand:P 1 "register_operand" "0,r")
16650 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16651 (clobber (reg:CC FLAGS_REG))
16652 (clobber (mem:BLK (scratch)))]
16655 switch (get_attr_type (insn))
16658 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16662 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16663 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16665 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16668 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16669 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16672 [(set (attr "type")
16673 (cond [(and (eq_attr "alternative" "0")
16674 (not (match_test "TARGET_OPT_AGU")))
16675 (const_string "alu")
16676 (match_operand:<MODE> 2 "const0_operand" "")
16677 (const_string "imov")
16679 (const_string "lea")))
16680 (set (attr "length_immediate")
16681 (cond [(eq_attr "type" "imov")
16683 (and (eq_attr "type" "alu")
16684 (match_operand 2 "const128_operand" ""))
16687 (const_string "*")))
16688 (set_attr "mode" "<MODE>")])
16690 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16691 [(set (match_operand:P 0 "register_operand" "=r")
16692 (minus:P (match_operand:P 1 "register_operand" "0")
16693 (match_operand:P 2 "register_operand" "r")))
16694 (clobber (reg:CC FLAGS_REG))
16695 (clobber (mem:BLK (scratch)))]
16697 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16698 [(set_attr "type" "alu")
16699 (set_attr "mode" "<MODE>")])
16701 (define_insn "allocate_stack_worker_probe_<mode>"
16702 [(set (match_operand:P 0 "register_operand" "=a")
16703 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16704 UNSPECV_STACK_PROBE))
16705 (clobber (reg:CC FLAGS_REG))]
16706 "ix86_target_stack_probe ()"
16707 "call\t___chkstk_ms"
16708 [(set_attr "type" "multi")
16709 (set_attr "length" "5")])
16711 (define_expand "allocate_stack"
16712 [(match_operand 0 "register_operand" "")
16713 (match_operand 1 "general_operand" "")]
16714 "ix86_target_stack_probe ()"
16718 #ifndef CHECK_STACK_LIMIT
16719 #define CHECK_STACK_LIMIT 0
16722 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16723 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16725 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16726 stack_pointer_rtx, 0, OPTAB_DIRECT);
16727 if (x != stack_pointer_rtx)
16728 emit_move_insn (stack_pointer_rtx, x);
16732 x = copy_to_mode_reg (Pmode, operands[1]);
16734 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16736 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16737 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16738 stack_pointer_rtx, 0, OPTAB_DIRECT);
16739 if (x != stack_pointer_rtx)
16740 emit_move_insn (stack_pointer_rtx, x);
16743 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16747 ;; Use IOR for stack probes, this is shorter.
16748 (define_expand "probe_stack"
16749 [(match_operand 0 "memory_operand" "")]
16752 rtx (*gen_ior3) (rtx, rtx, rtx);
16754 gen_ior3 = (GET_MODE (operands[0]) == DImode
16755 ? gen_iordi3 : gen_iorsi3);
16757 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16761 (define_insn "adjust_stack_and_probe<mode>"
16762 [(set (match_operand:P 0 "register_operand" "=r")
16763 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16764 UNSPECV_PROBE_STACK_RANGE))
16765 (set (reg:P SP_REG)
16766 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16767 (clobber (reg:CC FLAGS_REG))
16768 (clobber (mem:BLK (scratch)))]
16770 "* return output_adjust_stack_and_probe (operands[0]);"
16771 [(set_attr "type" "multi")])
16773 (define_insn "probe_stack_range<mode>"
16774 [(set (match_operand:P 0 "register_operand" "=r")
16775 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16776 (match_operand:P 2 "const_int_operand" "n")]
16777 UNSPECV_PROBE_STACK_RANGE))
16778 (clobber (reg:CC FLAGS_REG))]
16780 "* return output_probe_stack_range (operands[0], operands[2]);"
16781 [(set_attr "type" "multi")])
16783 (define_expand "builtin_setjmp_receiver"
16784 [(label_ref (match_operand 0 "" ""))]
16785 "!TARGET_64BIT && flag_pic"
16791 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16792 rtx label_rtx = gen_label_rtx ();
16793 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16794 xops[0] = xops[1] = picreg;
16795 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16796 ix86_expand_binary_operator (MINUS, SImode, xops);
16800 emit_insn (gen_set_got (pic_offset_table_rtx));
16804 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16807 [(set (match_operand 0 "register_operand" "")
16808 (match_operator 3 "promotable_binary_operator"
16809 [(match_operand 1 "register_operand" "")
16810 (match_operand 2 "aligned_operand" "")]))
16811 (clobber (reg:CC FLAGS_REG))]
16812 "! TARGET_PARTIAL_REG_STALL && reload_completed
16813 && ((GET_MODE (operands[0]) == HImode
16814 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16815 /* ??? next two lines just !satisfies_constraint_K (...) */
16816 || !CONST_INT_P (operands[2])
16817 || satisfies_constraint_K (operands[2])))
16818 || (GET_MODE (operands[0]) == QImode
16819 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16820 [(parallel [(set (match_dup 0)
16821 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16822 (clobber (reg:CC FLAGS_REG))])]
16823 "operands[0] = gen_lowpart (SImode, operands[0]);
16824 operands[1] = gen_lowpart (SImode, operands[1]);
16825 if (GET_CODE (operands[3]) != ASHIFT)
16826 operands[2] = gen_lowpart (SImode, operands[2]);
16827 PUT_MODE (operands[3], SImode);")
16829 ; Promote the QImode tests, as i386 has encoding of the AND
16830 ; instruction with 32-bit sign-extended immediate and thus the
16831 ; instruction size is unchanged, except in the %eax case for
16832 ; which it is increased by one byte, hence the ! optimize_size.
16834 [(set (match_operand 0 "flags_reg_operand" "")
16835 (match_operator 2 "compare_operator"
16836 [(and (match_operand 3 "aligned_operand" "")
16837 (match_operand 4 "const_int_operand" ""))
16839 (set (match_operand 1 "register_operand" "")
16840 (and (match_dup 3) (match_dup 4)))]
16841 "! TARGET_PARTIAL_REG_STALL && reload_completed
16842 && optimize_insn_for_speed_p ()
16843 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16844 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16845 /* Ensure that the operand will remain sign-extended immediate. */
16846 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16847 [(parallel [(set (match_dup 0)
16848 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16851 (and:SI (match_dup 3) (match_dup 4)))])]
16854 = gen_int_mode (INTVAL (operands[4])
16855 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16856 operands[1] = gen_lowpart (SImode, operands[1]);
16857 operands[3] = gen_lowpart (SImode, operands[3]);
16860 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16861 ; the TEST instruction with 32-bit sign-extended immediate and thus
16862 ; the instruction size would at least double, which is not what we
16863 ; want even with ! optimize_size.
16865 [(set (match_operand 0 "flags_reg_operand" "")
16866 (match_operator 1 "compare_operator"
16867 [(and (match_operand:HI 2 "aligned_operand" "")
16868 (match_operand:HI 3 "const_int_operand" ""))
16870 "! TARGET_PARTIAL_REG_STALL && reload_completed
16871 && ! TARGET_FAST_PREFIX
16872 && optimize_insn_for_speed_p ()
16873 /* Ensure that the operand will remain sign-extended immediate. */
16874 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16875 [(set (match_dup 0)
16876 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16880 = gen_int_mode (INTVAL (operands[3])
16881 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16882 operands[2] = gen_lowpart (SImode, operands[2]);
16886 [(set (match_operand 0 "register_operand" "")
16887 (neg (match_operand 1 "register_operand" "")))
16888 (clobber (reg:CC FLAGS_REG))]
16889 "! TARGET_PARTIAL_REG_STALL && reload_completed
16890 && (GET_MODE (operands[0]) == HImode
16891 || (GET_MODE (operands[0]) == QImode
16892 && (TARGET_PROMOTE_QImode
16893 || optimize_insn_for_size_p ())))"
16894 [(parallel [(set (match_dup 0)
16895 (neg:SI (match_dup 1)))
16896 (clobber (reg:CC FLAGS_REG))])]
16897 "operands[0] = gen_lowpart (SImode, operands[0]);
16898 operands[1] = gen_lowpart (SImode, operands[1]);")
16901 [(set (match_operand 0 "register_operand" "")
16902 (not (match_operand 1 "register_operand" "")))]
16903 "! TARGET_PARTIAL_REG_STALL && reload_completed
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 (not:SI (match_dup 1)))]
16910 "operands[0] = gen_lowpart (SImode, operands[0]);
16911 operands[1] = gen_lowpart (SImode, operands[1]);")
16914 [(set (match_operand 0 "register_operand" "")
16915 (if_then_else (match_operator 1 "ordered_comparison_operator"
16916 [(reg FLAGS_REG) (const_int 0)])
16917 (match_operand 2 "register_operand" "")
16918 (match_operand 3 "register_operand" "")))]
16919 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16920 && (GET_MODE (operands[0]) == HImode
16921 || (GET_MODE (operands[0]) == QImode
16922 && (TARGET_PROMOTE_QImode
16923 || optimize_insn_for_size_p ())))"
16924 [(set (match_dup 0)
16925 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16926 "operands[0] = gen_lowpart (SImode, operands[0]);
16927 operands[2] = gen_lowpart (SImode, operands[2]);
16928 operands[3] = gen_lowpart (SImode, operands[3]);")
16930 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16931 ;; transform a complex memory operation into two memory to register operations.
16933 ;; Don't push memory operands
16935 [(set (match_operand:SWI 0 "push_operand" "")
16936 (match_operand:SWI 1 "memory_operand" ""))
16937 (match_scratch:SWI 2 "<r>")]
16938 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16939 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16940 [(set (match_dup 2) (match_dup 1))
16941 (set (match_dup 0) (match_dup 2))])
16943 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16946 [(set (match_operand:SF 0 "push_operand" "")
16947 (match_operand:SF 1 "memory_operand" ""))
16948 (match_scratch:SF 2 "r")]
16949 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16950 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16951 [(set (match_dup 2) (match_dup 1))
16952 (set (match_dup 0) (match_dup 2))])
16954 ;; Don't move an immediate directly to memory when the instruction
16957 [(match_scratch:SWI124 1 "<r>")
16958 (set (match_operand:SWI124 0 "memory_operand" "")
16960 "optimize_insn_for_speed_p ()
16961 && !TARGET_USE_MOV0
16962 && TARGET_SPLIT_LONG_MOVES
16963 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 2) (const_int 0))
16966 (clobber (reg:CC FLAGS_REG))])
16967 (set (match_dup 0) (match_dup 1))]
16968 "operands[2] = gen_lowpart (SImode, operands[1]);")
16971 [(match_scratch:SWI124 2 "<r>")
16972 (set (match_operand:SWI124 0 "memory_operand" "")
16973 (match_operand:SWI124 1 "immediate_operand" ""))]
16974 "optimize_insn_for_speed_p ()
16975 && TARGET_SPLIT_LONG_MOVES
16976 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16977 [(set (match_dup 2) (match_dup 1))
16978 (set (match_dup 0) (match_dup 2))])
16980 ;; Don't compare memory with zero, load and use a test instead.
16982 [(set (match_operand 0 "flags_reg_operand" "")
16983 (match_operator 1 "compare_operator"
16984 [(match_operand:SI 2 "memory_operand" "")
16986 (match_scratch:SI 3 "r")]
16987 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16988 [(set (match_dup 3) (match_dup 2))
16989 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16991 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16992 ;; Don't split NOTs with a displacement operand, because resulting XOR
16993 ;; will not be pairable anyway.
16995 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16996 ;; represented using a modRM byte. The XOR replacement is long decoded,
16997 ;; so this split helps here as well.
16999 ;; Note: Can't do this as a regular split because we can't get proper
17000 ;; lifetime information then.
17003 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17004 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17005 "optimize_insn_for_speed_p ()
17006 && ((TARGET_NOT_UNPAIRABLE
17007 && (!MEM_P (operands[0])
17008 || !memory_displacement_operand (operands[0], <MODE>mode)))
17009 || (TARGET_NOT_VECTORMODE
17010 && long_memory_operand (operands[0], <MODE>mode)))
17011 && peep2_regno_dead_p (0, FLAGS_REG)"
17012 [(parallel [(set (match_dup 0)
17013 (xor:SWI124 (match_dup 1) (const_int -1)))
17014 (clobber (reg:CC FLAGS_REG))])])
17016 ;; Non pairable "test imm, reg" instructions can be translated to
17017 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17018 ;; byte opcode instead of two, have a short form for byte operands),
17019 ;; so do it for other CPUs as well. Given that the value was dead,
17020 ;; this should not create any new dependencies. Pass on the sub-word
17021 ;; versions if we're concerned about partial register stalls.
17024 [(set (match_operand 0 "flags_reg_operand" "")
17025 (match_operator 1 "compare_operator"
17026 [(and:SI (match_operand:SI 2 "register_operand" "")
17027 (match_operand:SI 3 "immediate_operand" ""))
17029 "ix86_match_ccmode (insn, CCNOmode)
17030 && (true_regnum (operands[2]) != AX_REG
17031 || satisfies_constraint_K (operands[3]))
17032 && peep2_reg_dead_p (1, operands[2])"
17034 [(set (match_dup 0)
17035 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17038 (and:SI (match_dup 2) (match_dup 3)))])])
17040 ;; We don't need to handle HImode case, because it will be promoted to SImode
17041 ;; on ! TARGET_PARTIAL_REG_STALL
17044 [(set (match_operand 0 "flags_reg_operand" "")
17045 (match_operator 1 "compare_operator"
17046 [(and:QI (match_operand:QI 2 "register_operand" "")
17047 (match_operand:QI 3 "immediate_operand" ""))
17049 "! TARGET_PARTIAL_REG_STALL
17050 && ix86_match_ccmode (insn, CCNOmode)
17051 && true_regnum (operands[2]) != AX_REG
17052 && peep2_reg_dead_p (1, operands[2])"
17054 [(set (match_dup 0)
17055 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17058 (and:QI (match_dup 2) (match_dup 3)))])])
17061 [(set (match_operand 0 "flags_reg_operand" "")
17062 (match_operator 1 "compare_operator"
17065 (match_operand 2 "ext_register_operand" "")
17068 (match_operand 3 "const_int_operand" ""))
17070 "! TARGET_PARTIAL_REG_STALL
17071 && ix86_match_ccmode (insn, CCNOmode)
17072 && true_regnum (operands[2]) != AX_REG
17073 && peep2_reg_dead_p (1, operands[2])"
17074 [(parallel [(set (match_dup 0)
17083 (set (zero_extract:SI (match_dup 2)
17091 (match_dup 3)))])])
17093 ;; Don't do logical operations with memory inputs.
17095 [(match_scratch:SI 2 "r")
17096 (parallel [(set (match_operand:SI 0 "register_operand" "")
17097 (match_operator:SI 3 "arith_or_logical_operator"
17099 (match_operand:SI 1 "memory_operand" "")]))
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17102 [(set (match_dup 2) (match_dup 1))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17105 (clobber (reg:CC FLAGS_REG))])])
17108 [(match_scratch:SI 2 "r")
17109 (parallel [(set (match_operand:SI 0 "register_operand" "")
17110 (match_operator:SI 3 "arith_or_logical_operator"
17111 [(match_operand:SI 1 "memory_operand" "")
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17115 [(set (match_dup 2) (match_dup 1))
17116 (parallel [(set (match_dup 0)
17117 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17118 (clobber (reg:CC FLAGS_REG))])])
17120 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17121 ;; refers to the destination of the load!
17124 [(set (match_operand:SI 0 "register_operand" "")
17125 (match_operand:SI 1 "register_operand" ""))
17126 (parallel [(set (match_dup 0)
17127 (match_operator:SI 3 "commutative_operator"
17129 (match_operand:SI 2 "memory_operand" "")]))
17130 (clobber (reg:CC FLAGS_REG))])]
17131 "REGNO (operands[0]) != REGNO (operands[1])
17132 && GENERAL_REGNO_P (REGNO (operands[0]))
17133 && GENERAL_REGNO_P (REGNO (operands[1]))"
17134 [(set (match_dup 0) (match_dup 4))
17135 (parallel [(set (match_dup 0)
17136 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17141 [(set (match_operand 0 "register_operand" "")
17142 (match_operand 1 "register_operand" ""))
17144 (match_operator 3 "commutative_operator"
17146 (match_operand 2 "memory_operand" "")]))]
17147 "REGNO (operands[0]) != REGNO (operands[1])
17148 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17149 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17150 [(set (match_dup 0) (match_dup 2))
17152 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17154 ; Don't do logical operations with memory outputs
17156 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17157 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17158 ; the same decoder scheduling characteristics as the original.
17161 [(match_scratch:SI 2 "r")
17162 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17163 (match_operator:SI 3 "arith_or_logical_operator"
17165 (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 2) (match_dup 1)]))
17173 (clobber (reg:CC FLAGS_REG))])
17174 (set (match_dup 0) (match_dup 2))])
17177 [(match_scratch:SI 2 "r")
17178 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17179 (match_operator:SI 3 "arith_or_logical_operator"
17180 [(match_operand:SI 1 "nonmemory_operand" "")
17182 (clobber (reg:CC FLAGS_REG))])]
17183 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17184 /* Do not split stack checking probes. */
17185 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17186 [(set (match_dup 2) (match_dup 0))
17187 (parallel [(set (match_dup 2)
17188 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17189 (clobber (reg:CC FLAGS_REG))])
17190 (set (match_dup 0) (match_dup 2))])
17192 ;; Attempt to use arith or logical operations with memory outputs with
17193 ;; setting of flags.
17195 [(set (match_operand:SWI 0 "register_operand" "")
17196 (match_operand:SWI 1 "memory_operand" ""))
17197 (parallel [(set (match_dup 0)
17198 (match_operator:SWI 3 "plusminuslogic_operator"
17200 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17201 (clobber (reg:CC FLAGS_REG))])
17202 (set (match_dup 1) (match_dup 0))
17203 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17204 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17205 && peep2_reg_dead_p (4, operands[0])
17206 && !reg_overlap_mentioned_p (operands[0], operands[1])
17207 && ix86_match_ccmode (peep2_next_insn (3),
17208 (GET_CODE (operands[3]) == PLUS
17209 || GET_CODE (operands[3]) == MINUS)
17210 ? CCGOCmode : CCNOmode)"
17211 [(parallel [(set (match_dup 4) (match_dup 5))
17212 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17213 (match_dup 2)]))])]
17214 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17215 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17216 copy_rtx (operands[1]),
17217 copy_rtx (operands[2]));
17218 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17219 operands[5], const0_rtx);")
17222 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17223 (match_operator:SWI 2 "plusminuslogic_operator"
17225 (match_operand:SWI 1 "memory_operand" "")]))
17226 (clobber (reg:CC FLAGS_REG))])
17227 (set (match_dup 1) (match_dup 0))
17228 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17229 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17230 && GET_CODE (operands[2]) != MINUS
17231 && peep2_reg_dead_p (3, operands[0])
17232 && !reg_overlap_mentioned_p (operands[0], operands[1])
17233 && ix86_match_ccmode (peep2_next_insn (2),
17234 GET_CODE (operands[2]) == PLUS
17235 ? CCGOCmode : CCNOmode)"
17236 [(parallel [(set (match_dup 3) (match_dup 4))
17237 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17238 (match_dup 0)]))])]
17239 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17240 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17241 copy_rtx (operands[1]),
17242 copy_rtx (operands[0]));
17243 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17244 operands[4], const0_rtx);")
17247 [(set (match_operand:SWI12 0 "register_operand" "")
17248 (match_operand:SWI12 1 "memory_operand" ""))
17249 (parallel [(set (match_operand:SI 4 "register_operand" "")
17250 (match_operator:SI 3 "plusminuslogic_operator"
17252 (match_operand:SI 2 "nonmemory_operand" "")]))
17253 (clobber (reg:CC FLAGS_REG))])
17254 (set (match_dup 1) (match_dup 0))
17255 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17256 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17257 && REG_P (operands[0]) && REG_P (operands[4])
17258 && REGNO (operands[0]) == REGNO (operands[4])
17259 && peep2_reg_dead_p (4, operands[0])
17260 && !reg_overlap_mentioned_p (operands[0], operands[1])
17261 && ix86_match_ccmode (peep2_next_insn (3),
17262 (GET_CODE (operands[3]) == PLUS
17263 || GET_CODE (operands[3]) == MINUS)
17264 ? CCGOCmode : CCNOmode)"
17265 [(parallel [(set (match_dup 4) (match_dup 5))
17266 (set (match_dup 1) (match_dup 6))])]
17267 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17268 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17269 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17270 copy_rtx (operands[1]), operands[2]);
17271 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17272 operands[5], const0_rtx);
17273 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17274 copy_rtx (operands[1]),
17275 copy_rtx (operands[2]));")
17277 ;; Attempt to always use XOR for zeroing registers.
17279 [(set (match_operand 0 "register_operand" "")
17280 (match_operand 1 "const0_operand" ""))]
17281 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17282 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17283 && GENERAL_REG_P (operands[0])
17284 && peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (const_int 0))
17286 (clobber (reg:CC FLAGS_REG))])]
17287 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17290 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17292 "(GET_MODE (operands[0]) == QImode
17293 || GET_MODE (operands[0]) == HImode)
17294 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17295 && peep2_regno_dead_p (0, FLAGS_REG)"
17296 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17297 (clobber (reg:CC FLAGS_REG))])])
17299 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17301 [(set (match_operand:SWI248 0 "register_operand" "")
17303 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17304 && peep2_regno_dead_p (0, FLAGS_REG)"
17305 [(parallel [(set (match_dup 0) (const_int -1))
17306 (clobber (reg:CC FLAGS_REG))])]
17308 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17309 operands[0] = gen_lowpart (SImode, operands[0]);
17312 ;; Attempt to convert simple lea to add/shift.
17313 ;; These can be created by move expanders.
17316 [(set (match_operand:SWI48 0 "register_operand" "")
17317 (plus:SWI48 (match_dup 0)
17318 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17319 "peep2_regno_dead_p (0, FLAGS_REG)"
17320 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17321 (clobber (reg:CC FLAGS_REG))])])
17324 [(set (match_operand:SI 0 "register_operand" "")
17325 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17326 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17328 && peep2_regno_dead_p (0, FLAGS_REG)
17329 && REGNO (operands[0]) == REGNO (operands[1])"
17330 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17331 (clobber (reg:CC FLAGS_REG))])]
17332 "operands[2] = gen_lowpart (SImode, operands[2]);")
17335 [(set (match_operand:SWI48 0 "register_operand" "")
17336 (mult:SWI48 (match_dup 0)
17337 (match_operand:SWI48 1 "const_int_operand" "")))]
17338 "exact_log2 (INTVAL (operands[1])) >= 0
17339 && peep2_regno_dead_p (0, FLAGS_REG)"
17340 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17341 (clobber (reg:CC FLAGS_REG))])]
17342 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17345 [(set (match_operand:SI 0 "register_operand" "")
17346 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17347 (match_operand:DI 2 "const_int_operand" "")) 0))]
17349 && exact_log2 (INTVAL (operands[2])) >= 0
17350 && REGNO (operands[0]) == REGNO (operands[1])
17351 && peep2_regno_dead_p (0, FLAGS_REG)"
17352 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17356 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17357 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17358 ;; On many CPUs it is also faster, since special hardware to avoid esp
17359 ;; dependencies is present.
17361 ;; While some of these conversions may be done using splitters, we use
17362 ;; peepholes in order to allow combine_stack_adjustments pass to see
17363 ;; nonobfuscated RTL.
17365 ;; Convert prologue esp subtractions to push.
17366 ;; We need register to push. In order to keep verify_flow_info happy we have
17368 ;; - use scratch and clobber it in order to avoid dependencies
17369 ;; - use already live register
17370 ;; We can't use the second way right now, since there is no reliable way how to
17371 ;; verify that given register is live. First choice will also most likely in
17372 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17373 ;; call clobbered registers are dead. We may want to use base pointer as an
17374 ;; alternative when no register is available later.
17377 [(match_scratch:P 1 "r")
17378 (parallel [(set (reg:P SP_REG)
17379 (plus:P (reg:P SP_REG)
17380 (match_operand:P 0 "const_int_operand" "")))
17381 (clobber (reg:CC FLAGS_REG))
17382 (clobber (mem:BLK (scratch)))])]
17383 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17384 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17385 [(clobber (match_dup 1))
17386 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17387 (clobber (mem:BLK (scratch)))])])
17390 [(match_scratch:P 1 "r")
17391 (parallel [(set (reg:P SP_REG)
17392 (plus:P (reg:P SP_REG)
17393 (match_operand:P 0 "const_int_operand" "")))
17394 (clobber (reg:CC FLAGS_REG))
17395 (clobber (mem:BLK (scratch)))])]
17396 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17397 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17398 [(clobber (match_dup 1))
17399 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17400 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17401 (clobber (mem:BLK (scratch)))])])
17403 ;; Convert esp subtractions to push.
17405 [(match_scratch:P 1 "r")
17406 (parallel [(set (reg:P SP_REG)
17407 (plus:P (reg:P SP_REG)
17408 (match_operand:P 0 "const_int_operand" "")))
17409 (clobber (reg:CC FLAGS_REG))])]
17410 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17411 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17412 [(clobber (match_dup 1))
17413 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17416 [(match_scratch:P 1 "r")
17417 (parallel [(set (reg:P SP_REG)
17418 (plus:P (reg:P SP_REG)
17419 (match_operand:P 0 "const_int_operand" "")))
17420 (clobber (reg:CC FLAGS_REG))])]
17421 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17422 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17423 [(clobber (match_dup 1))
17424 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17425 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17427 ;; Convert epilogue deallocator to pop.
17429 [(match_scratch:P 1 "r")
17430 (parallel [(set (reg:P SP_REG)
17431 (plus:P (reg:P SP_REG)
17432 (match_operand:P 0 "const_int_operand" "")))
17433 (clobber (reg:CC FLAGS_REG))
17434 (clobber (mem:BLK (scratch)))])]
17435 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17436 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17437 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17438 (clobber (mem:BLK (scratch)))])])
17440 ;; Two pops case is tricky, since pop causes dependency
17441 ;; on destination register. We use two registers if available.
17443 [(match_scratch:P 1 "r")
17444 (match_scratch:P 2 "r")
17445 (parallel [(set (reg:P SP_REG)
17446 (plus:P (reg:P SP_REG)
17447 (match_operand:P 0 "const_int_operand" "")))
17448 (clobber (reg:CC FLAGS_REG))
17449 (clobber (mem:BLK (scratch)))])]
17450 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17451 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17452 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17453 (clobber (mem:BLK (scratch)))])
17454 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17457 [(match_scratch:P 1 "r")
17458 (parallel [(set (reg:P SP_REG)
17459 (plus:P (reg:P SP_REG)
17460 (match_operand:P 0 "const_int_operand" "")))
17461 (clobber (reg:CC FLAGS_REG))
17462 (clobber (mem:BLK (scratch)))])]
17463 "optimize_insn_for_size_p ()
17464 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17465 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17466 (clobber (mem:BLK (scratch)))])
17467 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17469 ;; Convert esp additions to pop.
17471 [(match_scratch:P 1 "r")
17472 (parallel [(set (reg:P SP_REG)
17473 (plus:P (reg:P SP_REG)
17474 (match_operand:P 0 "const_int_operand" "")))
17475 (clobber (reg:CC FLAGS_REG))])]
17476 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17477 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17479 ;; Two pops case is tricky, since pop causes dependency
17480 ;; on destination register. We use two registers if available.
17482 [(match_scratch:P 1 "r")
17483 (match_scratch:P 2 "r")
17484 (parallel [(set (reg:P SP_REG)
17485 (plus:P (reg:P SP_REG)
17486 (match_operand:P 0 "const_int_operand" "")))
17487 (clobber (reg:CC FLAGS_REG))])]
17488 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17489 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17490 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17493 [(match_scratch:P 1 "r")
17494 (parallel [(set (reg:P SP_REG)
17495 (plus:P (reg:P SP_REG)
17496 (match_operand:P 0 "const_int_operand" "")))
17497 (clobber (reg:CC FLAGS_REG))])]
17498 "optimize_insn_for_size_p ()
17499 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17500 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17501 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17503 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17504 ;; required and register dies. Similarly for 128 to -128.
17506 [(set (match_operand 0 "flags_reg_operand" "")
17507 (match_operator 1 "compare_operator"
17508 [(match_operand 2 "register_operand" "")
17509 (match_operand 3 "const_int_operand" "")]))]
17510 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17511 && incdec_operand (operands[3], GET_MODE (operands[3])))
17512 || (!TARGET_FUSE_CMP_AND_BRANCH
17513 && INTVAL (operands[3]) == 128))
17514 && ix86_match_ccmode (insn, CCGCmode)
17515 && peep2_reg_dead_p (1, operands[2])"
17516 [(parallel [(set (match_dup 0)
17517 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17518 (clobber (match_dup 2))])])
17520 ;; Convert imul by three, five and nine into lea
17523 [(set (match_operand:SWI48 0 "register_operand" "")
17524 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17525 (match_operand:SWI48 2 "const359_operand" "")))
17526 (clobber (reg:CC FLAGS_REG))])]
17527 "!TARGET_PARTIAL_REG_STALL
17528 || <MODE>mode == SImode
17529 || optimize_function_for_size_p (cfun)"
17530 [(set (match_dup 0)
17531 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17533 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17537 [(set (match_operand:SWI48 0 "register_operand" "")
17538 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17539 (match_operand:SWI48 2 "const359_operand" "")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "optimize_insn_for_speed_p ()
17542 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17543 [(set (match_dup 0) (match_dup 1))
17545 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17547 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17549 ;; imul $32bit_imm, mem, reg is vector decoded, while
17550 ;; imul $32bit_imm, reg, reg is direct decoded.
17552 [(match_scratch:SWI48 3 "r")
17553 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17554 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17555 (match_operand:SWI48 2 "immediate_operand" "")))
17556 (clobber (reg:CC FLAGS_REG))])]
17557 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17558 && !satisfies_constraint_K (operands[2])"
17559 [(set (match_dup 3) (match_dup 1))
17560 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17561 (clobber (reg:CC FLAGS_REG))])])
17564 [(match_scratch:SI 3 "r")
17565 (parallel [(set (match_operand:DI 0 "register_operand" "")
17567 (mult:SI (match_operand:SI 1 "memory_operand" "")
17568 (match_operand:SI 2 "immediate_operand" ""))))
17569 (clobber (reg:CC FLAGS_REG))])]
17571 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17572 && !satisfies_constraint_K (operands[2])"
17573 [(set (match_dup 3) (match_dup 1))
17574 (parallel [(set (match_dup 0)
17575 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17576 (clobber (reg:CC FLAGS_REG))])])
17578 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17579 ;; Convert it into imul reg, reg
17580 ;; It would be better to force assembler to encode instruction using long
17581 ;; immediate, but there is apparently no way to do so.
17583 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17585 (match_operand:SWI248 1 "nonimmediate_operand" "")
17586 (match_operand:SWI248 2 "const_int_operand" "")))
17587 (clobber (reg:CC FLAGS_REG))])
17588 (match_scratch:SWI248 3 "r")]
17589 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17590 && satisfies_constraint_K (operands[2])"
17591 [(set (match_dup 3) (match_dup 2))
17592 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17593 (clobber (reg:CC FLAGS_REG))])]
17595 if (!rtx_equal_p (operands[0], operands[1]))
17596 emit_move_insn (operands[0], operands[1]);
17599 ;; After splitting up read-modify operations, array accesses with memory
17600 ;; operands might end up in form:
17602 ;; movl 4(%esp), %edx
17604 ;; instead of pre-splitting:
17606 ;; addl 4(%esp), %eax
17608 ;; movl 4(%esp), %edx
17609 ;; leal (%edx,%eax,4), %eax
17612 [(match_scratch:P 5 "r")
17613 (parallel [(set (match_operand 0 "register_operand" "")
17614 (ashift (match_operand 1 "register_operand" "")
17615 (match_operand 2 "const_int_operand" "")))
17616 (clobber (reg:CC FLAGS_REG))])
17617 (parallel [(set (match_operand 3 "register_operand" "")
17618 (plus (match_dup 0)
17619 (match_operand 4 "x86_64_general_operand" "")))
17620 (clobber (reg:CC FLAGS_REG))])]
17621 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17622 /* Validate MODE for lea. */
17623 && ((!TARGET_PARTIAL_REG_STALL
17624 && (GET_MODE (operands[0]) == QImode
17625 || GET_MODE (operands[0]) == HImode))
17626 || GET_MODE (operands[0]) == SImode
17627 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17628 && (rtx_equal_p (operands[0], operands[3])
17629 || peep2_reg_dead_p (2, operands[0]))
17630 /* We reorder load and the shift. */
17631 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17632 [(set (match_dup 5) (match_dup 4))
17633 (set (match_dup 0) (match_dup 1))]
17635 enum machine_mode op1mode = GET_MODE (operands[1]);
17636 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17637 int scale = 1 << INTVAL (operands[2]);
17638 rtx index = gen_lowpart (Pmode, operands[1]);
17639 rtx base = gen_lowpart (Pmode, operands[5]);
17640 rtx dest = gen_lowpart (mode, operands[3]);
17642 operands[1] = gen_rtx_PLUS (Pmode, base,
17643 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17644 operands[5] = base;
17646 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17647 if (op1mode != Pmode)
17648 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17649 operands[0] = dest;
17652 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17653 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17654 ;; caught for use by garbage collectors and the like. Using an insn that
17655 ;; maps to SIGILL makes it more likely the program will rightfully die.
17656 ;; Keeping with tradition, "6" is in honor of #UD.
17657 (define_insn "trap"
17658 [(trap_if (const_int 1) (const_int 6))]
17660 { return ASM_SHORT "0x0b0f"; }
17661 [(set_attr "length" "2")])
17663 (define_expand "prefetch"
17664 [(prefetch (match_operand 0 "address_operand" "")
17665 (match_operand:SI 1 "const_int_operand" "")
17666 (match_operand:SI 2 "const_int_operand" ""))]
17667 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17669 int rw = INTVAL (operands[1]);
17670 int locality = INTVAL (operands[2]);
17672 gcc_assert (rw == 0 || rw == 1);
17673 gcc_assert (locality >= 0 && locality <= 3);
17674 gcc_assert (GET_MODE (operands[0]) == Pmode
17675 || GET_MODE (operands[0]) == VOIDmode);
17677 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17678 supported by SSE counterpart or the SSE prefetch is not available
17679 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17681 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17682 operands[2] = GEN_INT (3);
17684 operands[1] = const0_rtx;
17687 (define_insn "*prefetch_sse_<mode>"
17688 [(prefetch (match_operand:P 0 "address_operand" "p")
17690 (match_operand:SI 1 "const_int_operand" ""))]
17691 "TARGET_PREFETCH_SSE"
17693 static const char * const patterns[4] = {
17694 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17697 int locality = INTVAL (operands[1]);
17698 gcc_assert (locality >= 0 && locality <= 3);
17700 return patterns[locality];
17702 [(set_attr "type" "sse")
17703 (set_attr "atom_sse_attr" "prefetch")
17704 (set (attr "length_address")
17705 (symbol_ref "memory_address_length (operands[0])"))
17706 (set_attr "memory" "none")])
17708 (define_insn "*prefetch_3dnow_<mode>"
17709 [(prefetch (match_operand:P 0 "address_operand" "p")
17710 (match_operand:SI 1 "const_int_operand" "n")
17714 if (INTVAL (operands[1]) == 0)
17715 return "prefetch\t%a0";
17717 return "prefetchw\t%a0";
17719 [(set_attr "type" "mmx")
17720 (set (attr "length_address")
17721 (symbol_ref "memory_address_length (operands[0])"))
17722 (set_attr "memory" "none")])
17724 (define_expand "stack_protect_set"
17725 [(match_operand 0 "memory_operand" "")
17726 (match_operand 1 "memory_operand" "")]
17729 rtx (*insn)(rtx, rtx);
17731 #ifdef TARGET_THREAD_SSP_OFFSET
17732 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17733 insn = (TARGET_LP64
17734 ? gen_stack_tls_protect_set_di
17735 : gen_stack_tls_protect_set_si);
17737 insn = (TARGET_LP64
17738 ? gen_stack_protect_set_di
17739 : gen_stack_protect_set_si);
17742 emit_insn (insn (operands[0], operands[1]));
17746 (define_insn "stack_protect_set_<mode>"
17747 [(set (match_operand:PTR 0 "memory_operand" "=m")
17748 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17750 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17751 (clobber (reg:CC FLAGS_REG))]
17753 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17754 [(set_attr "type" "multi")])
17756 (define_insn "stack_tls_protect_set_<mode>"
17757 [(set (match_operand:PTR 0 "memory_operand" "=m")
17758 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17759 UNSPEC_SP_TLS_SET))
17760 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17761 (clobber (reg:CC FLAGS_REG))]
17763 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17764 [(set_attr "type" "multi")])
17766 (define_expand "stack_protect_test"
17767 [(match_operand 0 "memory_operand" "")
17768 (match_operand 1 "memory_operand" "")
17769 (match_operand 2 "" "")]
17772 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17774 rtx (*insn)(rtx, rtx, rtx);
17776 #ifdef TARGET_THREAD_SSP_OFFSET
17777 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17778 insn = (TARGET_LP64
17779 ? gen_stack_tls_protect_test_di
17780 : gen_stack_tls_protect_test_si);
17782 insn = (TARGET_LP64
17783 ? gen_stack_protect_test_di
17784 : gen_stack_protect_test_si);
17787 emit_insn (insn (flags, operands[0], operands[1]));
17789 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17790 flags, const0_rtx, operands[2]));
17794 (define_insn "stack_protect_test_<mode>"
17795 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17796 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17797 (match_operand:PTR 2 "memory_operand" "m")]
17799 (clobber (match_scratch:PTR 3 "=&r"))]
17801 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17802 [(set_attr "type" "multi")])
17804 (define_insn "stack_tls_protect_test_<mode>"
17805 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17806 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17807 (match_operand:PTR 2 "const_int_operand" "i")]
17808 UNSPEC_SP_TLS_TEST))
17809 (clobber (match_scratch:PTR 3 "=r"))]
17811 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17812 [(set_attr "type" "multi")])
17814 (define_insn "sse4_2_crc32<mode>"
17815 [(set (match_operand:SI 0 "register_operand" "=r")
17817 [(match_operand:SI 1 "register_operand" "0")
17818 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17820 "TARGET_SSE4_2 || TARGET_CRC32"
17821 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17822 [(set_attr "type" "sselog1")
17823 (set_attr "prefix_rep" "1")
17824 (set_attr "prefix_extra" "1")
17825 (set (attr "prefix_data16")
17826 (if_then_else (match_operand:HI 2 "" "")
17828 (const_string "*")))
17829 (set (attr "prefix_rex")
17830 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17832 (const_string "*")))
17833 (set_attr "mode" "SI")])
17835 (define_insn "sse4_2_crc32di"
17836 [(set (match_operand:DI 0 "register_operand" "=r")
17838 [(match_operand:DI 1 "register_operand" "0")
17839 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17841 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17842 "crc32{q}\t{%2, %0|%0, %2}"
17843 [(set_attr "type" "sselog1")
17844 (set_attr "prefix_rep" "1")
17845 (set_attr "prefix_extra" "1")
17846 (set_attr "mode" "DI")])
17848 (define_expand "rdpmc"
17849 [(match_operand:DI 0 "register_operand" "")
17850 (match_operand:SI 1 "register_operand" "")]
17853 rtx reg = gen_reg_rtx (DImode);
17856 /* Force operand 1 into ECX. */
17857 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17858 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17859 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17864 rtvec vec = rtvec_alloc (2);
17865 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17866 rtx upper = gen_reg_rtx (DImode);
17867 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17868 gen_rtvec (1, const0_rtx),
17870 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17871 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17873 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17874 NULL, 1, OPTAB_DIRECT);
17875 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17879 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17884 (define_insn "*rdpmc"
17885 [(set (match_operand:DI 0 "register_operand" "=A")
17886 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17890 [(set_attr "type" "other")
17891 (set_attr "length" "2")])
17893 (define_insn "*rdpmc_rex64"
17894 [(set (match_operand:DI 0 "register_operand" "=a")
17895 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17897 (set (match_operand:DI 1 "register_operand" "=d")
17898 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17901 [(set_attr "type" "other")
17902 (set_attr "length" "2")])
17904 (define_expand "rdtsc"
17905 [(set (match_operand:DI 0 "register_operand" "")
17906 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17911 rtvec vec = rtvec_alloc (2);
17912 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17913 rtx upper = gen_reg_rtx (DImode);
17914 rtx lower = gen_reg_rtx (DImode);
17915 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17916 gen_rtvec (1, const0_rtx),
17918 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17919 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17921 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17922 NULL, 1, OPTAB_DIRECT);
17923 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17925 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17930 (define_insn "*rdtsc"
17931 [(set (match_operand:DI 0 "register_operand" "=A")
17932 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17935 [(set_attr "type" "other")
17936 (set_attr "length" "2")])
17938 (define_insn "*rdtsc_rex64"
17939 [(set (match_operand:DI 0 "register_operand" "=a")
17940 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17941 (set (match_operand:DI 1 "register_operand" "=d")
17942 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17945 [(set_attr "type" "other")
17946 (set_attr "length" "2")])
17948 (define_expand "rdtscp"
17949 [(match_operand:DI 0 "register_operand" "")
17950 (match_operand:SI 1 "memory_operand" "")]
17953 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17954 gen_rtvec (1, const0_rtx),
17956 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17957 gen_rtvec (1, const0_rtx),
17959 rtx reg = gen_reg_rtx (DImode);
17960 rtx tmp = gen_reg_rtx (SImode);
17964 rtvec vec = rtvec_alloc (3);
17965 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17966 rtx upper = gen_reg_rtx (DImode);
17967 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17968 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17969 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17971 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17972 NULL, 1, OPTAB_DIRECT);
17973 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17978 rtvec vec = rtvec_alloc (2);
17979 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17980 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17981 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17985 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17989 (define_insn "*rdtscp"
17990 [(set (match_operand:DI 0 "register_operand" "=A")
17991 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17992 (set (match_operand:SI 1 "register_operand" "=c")
17993 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17996 [(set_attr "type" "other")
17997 (set_attr "length" "3")])
17999 (define_insn "*rdtscp_rex64"
18000 [(set (match_operand:DI 0 "register_operand" "=a")
18001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18002 (set (match_operand:DI 1 "register_operand" "=d")
18003 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18004 (set (match_operand:SI 2 "register_operand" "=c")
18005 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18008 [(set_attr "type" "other")
18009 (set_attr "length" "3")])
18011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18013 ;; LWP instructions
18015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18017 (define_expand "lwp_llwpcb"
18018 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18019 UNSPECV_LLWP_INTRINSIC)]
18022 (define_insn "*lwp_llwpcb<mode>1"
18023 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18024 UNSPECV_LLWP_INTRINSIC)]
18027 [(set_attr "type" "lwp")
18028 (set_attr "mode" "<MODE>")
18029 (set_attr "length" "5")])
18031 (define_expand "lwp_slwpcb"
18032 [(set (match_operand 0 "register_operand" "=r")
18033 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18038 insn = (TARGET_64BIT
18040 : gen_lwp_slwpcbsi);
18042 emit_insn (insn (operands[0]));
18046 (define_insn "lwp_slwpcb<mode>"
18047 [(set (match_operand:P 0 "register_operand" "=r")
18048 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18051 [(set_attr "type" "lwp")
18052 (set_attr "mode" "<MODE>")
18053 (set_attr "length" "5")])
18055 (define_expand "lwp_lwpval<mode>3"
18056 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18057 (match_operand:SI 2 "nonimmediate_operand" "rm")
18058 (match_operand:SI 3 "const_int_operand" "i")]
18059 UNSPECV_LWPVAL_INTRINSIC)]
18061 "/* Avoid unused variable warning. */
18064 (define_insn "*lwp_lwpval<mode>3_1"
18065 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18066 (match_operand:SI 1 "nonimmediate_operand" "rm")
18067 (match_operand:SI 2 "const_int_operand" "i")]
18068 UNSPECV_LWPVAL_INTRINSIC)]
18070 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18071 [(set_attr "type" "lwp")
18072 (set_attr "mode" "<MODE>")
18073 (set (attr "length")
18074 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18076 (define_expand "lwp_lwpins<mode>3"
18077 [(set (reg:CCC FLAGS_REG)
18078 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18079 (match_operand:SI 2 "nonimmediate_operand" "rm")
18080 (match_operand:SI 3 "const_int_operand" "i")]
18081 UNSPECV_LWPINS_INTRINSIC))
18082 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18083 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18086 (define_insn "*lwp_lwpins<mode>3_1"
18087 [(set (reg:CCC FLAGS_REG)
18088 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18089 (match_operand:SI 1 "nonimmediate_operand" "rm")
18090 (match_operand:SI 2 "const_int_operand" "i")]
18091 UNSPECV_LWPINS_INTRINSIC))]
18093 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18094 [(set_attr "type" "lwp")
18095 (set_attr "mode" "<MODE>")
18096 (set (attr "length")
18097 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18099 (define_insn "rdfsbase<mode>"
18100 [(set (match_operand:SWI48 0 "register_operand" "=r")
18101 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18102 "TARGET_64BIT && TARGET_FSGSBASE"
18104 [(set_attr "type" "other")
18105 (set_attr "prefix_extra" "2")])
18107 (define_insn "rdgsbase<mode>"
18108 [(set (match_operand:SWI48 0 "register_operand" "=r")
18109 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18110 "TARGET_64BIT && TARGET_FSGSBASE"
18112 [(set_attr "type" "other")
18113 (set_attr "prefix_extra" "2")])
18115 (define_insn "wrfsbase<mode>"
18116 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18118 "TARGET_64BIT && TARGET_FSGSBASE"
18120 [(set_attr "type" "other")
18121 (set_attr "prefix_extra" "2")])
18123 (define_insn "wrgsbase<mode>"
18124 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18126 "TARGET_64BIT && TARGET_FSGSBASE"
18128 [(set_attr "type" "other")
18129 (set_attr "prefix_extra" "2")])
18131 (define_insn "rdrand<mode>_1"
18132 [(set (match_operand:SWI248 0 "register_operand" "=r")
18133 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18134 (set (reg:CCC FLAGS_REG)
18135 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18138 [(set_attr "type" "other")
18139 (set_attr "prefix_extra" "1")])
18141 (define_expand "pause"
18142 [(set (match_dup 0)
18143 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18146 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18147 MEM_VOLATILE_P (operands[0]) = 1;
18150 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18151 ;; They have the same encoding.
18152 (define_insn "*pause"
18153 [(set (match_operand:BLK 0 "" "")
18154 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18157 [(set_attr "length" "2")
18158 (set_attr "memory" "unknown")])
18162 (include "sync.md")