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 logic-shift operators
776 (define_code_iterator any_lshift [ashift lshiftrt])
778 ;; Mapping of shift-right operators
779 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
781 ;; Base name for define_insn
782 (define_code_attr shift_insn
783 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
785 ;; Base name for insn mnemonic.
786 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
787 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
789 ;; Mapping of rotate operators
790 (define_code_iterator any_rotate [rotate rotatert])
792 ;; Base name for define_insn
793 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
795 ;; Base name for insn mnemonic.
796 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
798 ;; Mapping of abs neg operators
799 (define_code_iterator absneg [abs neg])
801 ;; Base name for x87 insn mnemonic.
802 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
804 ;; Used in signed and unsigned widening multiplications.
805 (define_code_iterator any_extend [sign_extend zero_extend])
807 ;; Prefix for insn menmonic.
808 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
810 ;; Prefix for define_insn
811 (define_code_attr u [(sign_extend "") (zero_extend "u")])
812 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
814 ;; All integer modes.
815 (define_mode_iterator SWI1248x [QI HI SI DI])
817 ;; All integer modes without QImode.
818 (define_mode_iterator SWI248x [HI SI DI])
820 ;; All integer modes without QImode and HImode.
821 (define_mode_iterator SWI48x [SI DI])
823 ;; All integer modes without SImode and DImode.
824 (define_mode_iterator SWI12 [QI HI])
826 ;; All integer modes without DImode.
827 (define_mode_iterator SWI124 [QI HI SI])
829 ;; All integer modes without QImode and DImode.
830 (define_mode_iterator SWI24 [HI SI])
832 ;; Single word integer modes.
833 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
835 ;; Single word integer modes without QImode.
836 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
838 ;; Single word integer modes without QImode and HImode.
839 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
841 ;; All math-dependant single and double word integer modes.
842 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
843 (HI "TARGET_HIMODE_MATH")
844 SI DI (TI "TARGET_64BIT")])
846 ;; Math-dependant single word integer modes.
847 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
848 (HI "TARGET_HIMODE_MATH")
849 SI (DI "TARGET_64BIT")])
851 ;; Math-dependant integer modes without DImode.
852 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
853 (HI "TARGET_HIMODE_MATH")
856 ;; Math-dependant single word integer modes without QImode.
857 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
858 SI (DI "TARGET_64BIT")])
860 ;; Double word integer modes.
861 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
862 (TI "TARGET_64BIT")])
864 ;; Double word integer modes as mode attribute.
865 (define_mode_attr DWI [(SI "DI") (DI "TI")])
866 (define_mode_attr dwi [(SI "di") (DI "ti")])
868 ;; Half mode for double word integer modes.
869 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
870 (DI "TARGET_64BIT")])
872 ;; Instruction suffix for integer modes.
873 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
875 ;; Pointer size prefix for integer modes (Intel asm dialect)
876 (define_mode_attr iptrsize [(QI "BYTE")
881 ;; Register class for integer modes.
882 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
884 ;; Immediate operand constraint for integer modes.
885 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
887 ;; General operand constraint for word modes.
888 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
890 ;; Immediate operand constraint for double integer modes.
891 (define_mode_attr di [(SI "nF") (DI "e")])
893 ;; Immediate operand constraint for shifts.
894 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
896 ;; General operand predicate for integer modes.
897 (define_mode_attr general_operand
898 [(QI "general_operand")
899 (HI "general_operand")
900 (SI "x86_64_general_operand")
901 (DI "x86_64_general_operand")
902 (TI "x86_64_general_operand")])
904 ;; General sign/zero extend operand predicate for integer modes.
905 (define_mode_attr general_szext_operand
906 [(QI "general_operand")
907 (HI "general_operand")
908 (SI "x86_64_szext_general_operand")
909 (DI "x86_64_szext_general_operand")])
911 ;; Immediate operand predicate for integer modes.
912 (define_mode_attr immediate_operand
913 [(QI "immediate_operand")
914 (HI "immediate_operand")
915 (SI "x86_64_immediate_operand")
916 (DI "x86_64_immediate_operand")])
918 ;; Nonmemory operand predicate for integer modes.
919 (define_mode_attr nonmemory_operand
920 [(QI "nonmemory_operand")
921 (HI "nonmemory_operand")
922 (SI "x86_64_nonmemory_operand")
923 (DI "x86_64_nonmemory_operand")])
925 ;; Operand predicate for shifts.
926 (define_mode_attr shift_operand
927 [(QI "nonimmediate_operand")
928 (HI "nonimmediate_operand")
929 (SI "nonimmediate_operand")
930 (DI "shiftdi_operand")
931 (TI "register_operand")])
933 ;; Operand predicate for shift argument.
934 (define_mode_attr shift_immediate_operand
935 [(QI "const_1_to_31_operand")
936 (HI "const_1_to_31_operand")
937 (SI "const_1_to_31_operand")
938 (DI "const_1_to_63_operand")])
940 ;; Input operand predicate for arithmetic left shifts.
941 (define_mode_attr ashl_input_operand
942 [(QI "nonimmediate_operand")
943 (HI "nonimmediate_operand")
944 (SI "nonimmediate_operand")
945 (DI "ashldi_input_operand")
946 (TI "reg_or_pm1_operand")])
948 ;; SSE and x87 SFmode and DFmode floating point modes
949 (define_mode_iterator MODEF [SF DF])
951 ;; All x87 floating point modes
952 (define_mode_iterator X87MODEF [SF DF XF])
954 ;; SSE instruction suffix for various modes
955 (define_mode_attr ssemodesuffix
957 (V8SF "ps") (V4DF "pd")
958 (V4SF "ps") (V2DF "pd")
959 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
960 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
962 ;; SSE vector suffix for floating point modes
963 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
965 ;; SSE vector mode corresponding to a scalar mode
966 (define_mode_attr ssevecmode
967 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
969 ;; Instruction suffix for REX 64bit operators.
970 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
972 ;; This mode iterator allows :P to be used for patterns that operate on
973 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
974 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
976 ;; This mode iterator allows :PTR to be used for patterns that operate on
977 ;; ptr_mode sized quantities.
978 (define_mode_iterator PTR
979 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
981 ;; Scheduling descriptions
983 (include "pentium.md")
986 (include "athlon.md")
987 (include "bdver1.md")
993 ;; Operand and operator predicates and constraints
995 (include "predicates.md")
996 (include "constraints.md")
999 ;; Compare and branch/compare and store instructions.
1001 (define_expand "cbranch<mode>4"
1002 [(set (reg:CC FLAGS_REG)
1003 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1004 (match_operand:SDWIM 2 "<general_operand>" "")))
1005 (set (pc) (if_then_else
1006 (match_operator 0 "ordered_comparison_operator"
1007 [(reg:CC FLAGS_REG) (const_int 0)])
1008 (label_ref (match_operand 3 "" ""))
1012 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1013 operands[1] = force_reg (<MODE>mode, operands[1]);
1014 ix86_expand_branch (GET_CODE (operands[0]),
1015 operands[1], operands[2], operands[3]);
1019 (define_expand "cstore<mode>4"
1020 [(set (reg:CC FLAGS_REG)
1021 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1022 (match_operand:SWIM 3 "<general_operand>" "")))
1023 (set (match_operand:QI 0 "register_operand" "")
1024 (match_operator 1 "ordered_comparison_operator"
1025 [(reg:CC FLAGS_REG) (const_int 0)]))]
1028 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1029 operands[2] = force_reg (<MODE>mode, operands[2]);
1030 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1031 operands[2], operands[3]);
1035 (define_expand "cmp<mode>_1"
1036 [(set (reg:CC FLAGS_REG)
1037 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1038 (match_operand:SWI48 1 "<general_operand>" "")))])
1040 (define_insn "*cmp<mode>_ccno_1"
1041 [(set (reg FLAGS_REG)
1042 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1043 (match_operand:SWI 1 "const0_operand" "")))]
1044 "ix86_match_ccmode (insn, CCNOmode)"
1046 test{<imodesuffix>}\t%0, %0
1047 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1048 [(set_attr "type" "test,icmp")
1049 (set_attr "length_immediate" "0,1")
1050 (set_attr "mode" "<MODE>")])
1052 (define_insn "*cmp<mode>_1"
1053 [(set (reg FLAGS_REG)
1054 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1055 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1056 "ix86_match_ccmode (insn, CCmode)"
1057 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1058 [(set_attr "type" "icmp")
1059 (set_attr "mode" "<MODE>")])
1061 (define_insn "*cmp<mode>_minus_1"
1062 [(set (reg FLAGS_REG)
1064 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1065 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1067 "ix86_match_ccmode (insn, CCGOCmode)"
1068 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1069 [(set_attr "type" "icmp")
1070 (set_attr "mode" "<MODE>")])
1072 (define_insn "*cmpqi_ext_1"
1073 [(set (reg FLAGS_REG)
1075 (match_operand:QI 0 "general_operand" "Qm")
1078 (match_operand 1 "ext_register_operand" "Q")
1080 (const_int 8)) 0)))]
1081 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1082 "cmp{b}\t{%h1, %0|%0, %h1}"
1083 [(set_attr "type" "icmp")
1084 (set_attr "mode" "QI")])
1086 (define_insn "*cmpqi_ext_1_rex64"
1087 [(set (reg FLAGS_REG)
1089 (match_operand:QI 0 "register_operand" "Q")
1092 (match_operand 1 "ext_register_operand" "Q")
1094 (const_int 8)) 0)))]
1095 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1096 "cmp{b}\t{%h1, %0|%0, %h1}"
1097 [(set_attr "type" "icmp")
1098 (set_attr "mode" "QI")])
1100 (define_insn "*cmpqi_ext_2"
1101 [(set (reg FLAGS_REG)
1105 (match_operand 0 "ext_register_operand" "Q")
1108 (match_operand:QI 1 "const0_operand" "")))]
1109 "ix86_match_ccmode (insn, CCNOmode)"
1111 [(set_attr "type" "test")
1112 (set_attr "length_immediate" "0")
1113 (set_attr "mode" "QI")])
1115 (define_expand "cmpqi_ext_3"
1116 [(set (reg:CC FLAGS_REG)
1120 (match_operand 0 "ext_register_operand" "")
1123 (match_operand:QI 1 "immediate_operand" "")))])
1125 (define_insn "*cmpqi_ext_3_insn"
1126 [(set (reg FLAGS_REG)
1130 (match_operand 0 "ext_register_operand" "Q")
1133 (match_operand:QI 1 "general_operand" "Qmn")))]
1134 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1135 "cmp{b}\t{%1, %h0|%h0, %1}"
1136 [(set_attr "type" "icmp")
1137 (set_attr "modrm" "1")
1138 (set_attr "mode" "QI")])
1140 (define_insn "*cmpqi_ext_3_insn_rex64"
1141 [(set (reg FLAGS_REG)
1145 (match_operand 0 "ext_register_operand" "Q")
1148 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1149 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1150 "cmp{b}\t{%1, %h0|%h0, %1}"
1151 [(set_attr "type" "icmp")
1152 (set_attr "modrm" "1")
1153 (set_attr "mode" "QI")])
1155 (define_insn "*cmpqi_ext_4"
1156 [(set (reg FLAGS_REG)
1160 (match_operand 0 "ext_register_operand" "Q")
1165 (match_operand 1 "ext_register_operand" "Q")
1167 (const_int 8)) 0)))]
1168 "ix86_match_ccmode (insn, CCmode)"
1169 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1170 [(set_attr "type" "icmp")
1171 (set_attr "mode" "QI")])
1173 ;; These implement float point compares.
1174 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1175 ;; which would allow mix and match FP modes on the compares. Which is what
1176 ;; the old patterns did, but with many more of them.
1178 (define_expand "cbranchxf4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1181 (match_operand:XF 2 "nonmemory_operand" "")))
1182 (set (pc) (if_then_else
1183 (match_operator 0 "ix86_fp_comparison_operator"
1186 (label_ref (match_operand 3 "" ""))
1190 ix86_expand_branch (GET_CODE (operands[0]),
1191 operands[1], operands[2], operands[3]);
1195 (define_expand "cstorexf4"
1196 [(set (reg:CC FLAGS_REG)
1197 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1198 (match_operand:XF 3 "nonmemory_operand" "")))
1199 (set (match_operand:QI 0 "register_operand" "")
1200 (match_operator 1 "ix86_fp_comparison_operator"
1205 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1206 operands[2], operands[3]);
1210 (define_expand "cbranch<mode>4"
1211 [(set (reg:CC FLAGS_REG)
1212 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1213 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1214 (set (pc) (if_then_else
1215 (match_operator 0 "ix86_fp_comparison_operator"
1218 (label_ref (match_operand 3 "" ""))
1220 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1222 ix86_expand_branch (GET_CODE (operands[0]),
1223 operands[1], operands[2], operands[3]);
1227 (define_expand "cstore<mode>4"
1228 [(set (reg:CC FLAGS_REG)
1229 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1230 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1231 (set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "ix86_fp_comparison_operator"
1235 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1242 (define_expand "cbranchcc4"
1243 [(set (pc) (if_then_else
1244 (match_operator 0 "comparison_operator"
1245 [(match_operand 1 "flags_reg_operand" "")
1246 (match_operand 2 "const0_operand" "")])
1247 (label_ref (match_operand 3 "" ""))
1251 ix86_expand_branch (GET_CODE (operands[0]),
1252 operands[1], operands[2], operands[3]);
1256 (define_expand "cstorecc4"
1257 [(set (match_operand:QI 0 "register_operand" "")
1258 (match_operator 1 "comparison_operator"
1259 [(match_operand 2 "flags_reg_operand" "")
1260 (match_operand 3 "const0_operand" "")]))]
1263 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1264 operands[2], operands[3]);
1269 ;; FP compares, step 1:
1270 ;; Set the FP condition codes.
1272 ;; CCFPmode compare with exceptions
1273 ;; CCFPUmode compare with no exceptions
1275 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1276 ;; used to manage the reg stack popping would not be preserved.
1278 (define_insn "*cmpfp_0"
1279 [(set (match_operand:HI 0 "register_operand" "=a")
1282 (match_operand 1 "register_operand" "f")
1283 (match_operand 2 "const0_operand" ""))]
1285 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1286 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1291 (cond [(match_operand:SF 1 "" "")
1293 (match_operand:DF 1 "" "")
1296 (const_string "XF")))])
1298 (define_insn_and_split "*cmpfp_0_cc"
1299 [(set (reg:CCFP FLAGS_REG)
1301 (match_operand 1 "register_operand" "f")
1302 (match_operand 2 "const0_operand" "")))
1303 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1305 && TARGET_SAHF && !TARGET_CMOVE
1306 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1308 "&& reload_completed"
1311 [(compare:CCFP (match_dup 1)(match_dup 2))]
1313 (set (reg:CC FLAGS_REG)
1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1319 (cond [(match_operand:SF 1 "" "")
1321 (match_operand:DF 1 "" "")
1324 (const_string "XF")))])
1326 (define_insn "*cmpfp_xf"
1327 [(set (match_operand:HI 0 "register_operand" "=a")
1330 (match_operand:XF 1 "register_operand" "f")
1331 (match_operand:XF 2 "register_operand" "f"))]
1334 "* return output_fp_compare (insn, operands, false, false);"
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "XF")])
1339 (define_insn_and_split "*cmpfp_xf_cc"
1340 [(set (reg:CCFP FLAGS_REG)
1342 (match_operand:XF 1 "register_operand" "f")
1343 (match_operand:XF 2 "register_operand" "f")))
1344 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346 && TARGET_SAHF && !TARGET_CMOVE"
1348 "&& reload_completed"
1351 [(compare:CCFP (match_dup 1)(match_dup 2))]
1353 (set (reg:CC FLAGS_REG)
1354 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1356 [(set_attr "type" "multi")
1357 (set_attr "unit" "i387")
1358 (set_attr "mode" "XF")])
1360 (define_insn "*cmpfp_<mode>"
1361 [(set (match_operand:HI 0 "register_operand" "=a")
1364 (match_operand:MODEF 1 "register_operand" "f")
1365 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1368 "* return output_fp_compare (insn, operands, false, false);"
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1371 (set_attr "mode" "<MODE>")])
1373 (define_insn_and_split "*cmpfp_<mode>_cc"
1374 [(set (reg:CCFP FLAGS_REG)
1376 (match_operand:MODEF 1 "register_operand" "f")
1377 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1378 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1380 && TARGET_SAHF && !TARGET_CMOVE"
1382 "&& reload_completed"
1385 [(compare:CCFP (match_dup 1)(match_dup 2))]
1387 (set (reg:CC FLAGS_REG)
1388 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1390 [(set_attr "type" "multi")
1391 (set_attr "unit" "i387")
1392 (set_attr "mode" "<MODE>")])
1394 (define_insn "*cmpfp_u"
1395 [(set (match_operand:HI 0 "register_operand" "=a")
1398 (match_operand 1 "register_operand" "f")
1399 (match_operand 2 "register_operand" "f"))]
1401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1402 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1403 "* return output_fp_compare (insn, operands, false, true);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1407 (cond [(match_operand:SF 1 "" "")
1409 (match_operand:DF 1 "" "")
1412 (const_string "XF")))])
1414 (define_insn_and_split "*cmpfp_u_cc"
1415 [(set (reg:CCFPU FLAGS_REG)
1417 (match_operand 1 "register_operand" "f")
1418 (match_operand 2 "register_operand" "f")))
1419 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1420 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1421 && TARGET_SAHF && !TARGET_CMOVE
1422 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1424 "&& reload_completed"
1427 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1429 (set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1432 [(set_attr "type" "multi")
1433 (set_attr "unit" "i387")
1435 (cond [(match_operand:SF 1 "" "")
1437 (match_operand:DF 1 "" "")
1440 (const_string "XF")))])
1442 (define_insn "*cmpfp_<mode>"
1443 [(set (match_operand:HI 0 "register_operand" "=a")
1446 (match_operand 1 "register_operand" "f")
1447 (match_operator 3 "float_operator"
1448 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1450 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1451 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1452 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1453 "* return output_fp_compare (insn, operands, false, false);"
1454 [(set_attr "type" "multi")
1455 (set_attr "unit" "i387")
1456 (set_attr "fp_int_src" "true")
1457 (set_attr "mode" "<MODE>")])
1459 (define_insn_and_split "*cmpfp_<mode>_cc"
1460 [(set (reg:CCFP FLAGS_REG)
1462 (match_operand 1 "register_operand" "f")
1463 (match_operator 3 "float_operator"
1464 [(match_operand:SWI24 2 "memory_operand" "m")])))
1465 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1466 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1467 && TARGET_SAHF && !TARGET_CMOVE
1468 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1469 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1471 "&& reload_completed"
1476 (match_op_dup 3 [(match_dup 2)]))]
1478 (set (reg:CC FLAGS_REG)
1479 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1481 [(set_attr "type" "multi")
1482 (set_attr "unit" "i387")
1483 (set_attr "fp_int_src" "true")
1484 (set_attr "mode" "<MODE>")])
1486 ;; FP compares, step 2
1487 ;; Move the fpsw to ax.
1489 (define_insn "x86_fnstsw_1"
1490 [(set (match_operand:HI 0 "register_operand" "=a")
1491 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1494 [(set (attr "length")
1495 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1496 (set_attr "mode" "SI")
1497 (set_attr "unit" "i387")])
1499 ;; FP compares, step 3
1500 ;; Get ax into flags, general case.
1502 (define_insn "x86_sahf_1"
1503 [(set (reg:CC FLAGS_REG)
1504 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1508 #ifndef HAVE_AS_IX86_SAHF
1510 return ASM_BYTE "0x9e";
1515 [(set_attr "length" "1")
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")
1518 (set_attr "bdver1_decode" "direct")
1519 (set_attr "mode" "SI")])
1521 ;; Pentium Pro can do steps 1 through 3 in one go.
1522 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1523 ;; (these i387 instructions set flags directly)
1524 (define_insn "*cmpfp_i_mixed"
1525 [(set (reg:CCFP FLAGS_REG)
1526 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1527 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1528 "TARGET_MIX_SSE_I387
1529 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1530 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1531 "* return output_fp_compare (insn, operands, true, false);"
1532 [(set_attr "type" "fcmp,ssecomi")
1533 (set_attr "prefix" "orig,maybe_vex")
1535 (if_then_else (match_operand:SF 1 "" "")
1537 (const_string "DF")))
1538 (set (attr "prefix_rep")
1539 (if_then_else (eq_attr "type" "ssecomi")
1541 (const_string "*")))
1542 (set (attr "prefix_data16")
1543 (cond [(eq_attr "type" "fcmp")
1545 (eq_attr "mode" "DF")
1548 (const_string "0")))
1549 (set_attr "athlon_decode" "vector")
1550 (set_attr "amdfam10_decode" "direct")
1551 (set_attr "bdver1_decode" "double")])
1553 (define_insn "*cmpfp_i_sse"
1554 [(set (reg:CCFP FLAGS_REG)
1555 (compare:CCFP (match_operand 0 "register_operand" "x")
1556 (match_operand 1 "nonimmediate_operand" "xm")))]
1558 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1559 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560 "* return output_fp_compare (insn, operands, true, false);"
1561 [(set_attr "type" "ssecomi")
1562 (set_attr "prefix" "maybe_vex")
1564 (if_then_else (match_operand:SF 1 "" "")
1566 (const_string "DF")))
1567 (set_attr "prefix_rep" "0")
1568 (set (attr "prefix_data16")
1569 (if_then_else (eq_attr "mode" "DF")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpfp_i_i387"
1577 [(set (reg:CCFP FLAGS_REG)
1578 (compare:CCFP (match_operand 0 "register_operand" "f")
1579 (match_operand 1 "register_operand" "f")))]
1580 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1583 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1584 "* return output_fp_compare (insn, operands, true, false);"
1585 [(set_attr "type" "fcmp")
1587 (cond [(match_operand:SF 1 "" "")
1589 (match_operand:DF 1 "" "")
1592 (const_string "XF")))
1593 (set_attr "athlon_decode" "vector")
1594 (set_attr "amdfam10_decode" "direct")
1595 (set_attr "bdver1_decode" "double")])
1597 (define_insn "*cmpfp_iu_mixed"
1598 [(set (reg:CCFPU FLAGS_REG)
1599 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1600 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1601 "TARGET_MIX_SSE_I387
1602 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1603 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1604 "* return output_fp_compare (insn, operands, true, true);"
1605 [(set_attr "type" "fcmp,ssecomi")
1606 (set_attr "prefix" "orig,maybe_vex")
1608 (if_then_else (match_operand:SF 1 "" "")
1610 (const_string "DF")))
1611 (set (attr "prefix_rep")
1612 (if_then_else (eq_attr "type" "ssecomi")
1614 (const_string "*")))
1615 (set (attr "prefix_data16")
1616 (cond [(eq_attr "type" "fcmp")
1618 (eq_attr "mode" "DF")
1621 (const_string "0")))
1622 (set_attr "athlon_decode" "vector")
1623 (set_attr "amdfam10_decode" "direct")
1624 (set_attr "bdver1_decode" "double")])
1626 (define_insn "*cmpfp_iu_sse"
1627 [(set (reg:CCFPU FLAGS_REG)
1628 (compare:CCFPU (match_operand 0 "register_operand" "x")
1629 (match_operand 1 "nonimmediate_operand" "xm")))]
1631 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1632 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633 "* return output_fp_compare (insn, operands, true, true);"
1634 [(set_attr "type" "ssecomi")
1635 (set_attr "prefix" "maybe_vex")
1637 (if_then_else (match_operand:SF 1 "" "")
1639 (const_string "DF")))
1640 (set_attr "prefix_rep" "0")
1641 (set (attr "prefix_data16")
1642 (if_then_else (eq_attr "mode" "DF")
1644 (const_string "0")))
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "direct")
1647 (set_attr "bdver1_decode" "double")])
1649 (define_insn "*cmpfp_iu_387"
1650 [(set (reg:CCFPU FLAGS_REG)
1651 (compare:CCFPU (match_operand 0 "register_operand" "f")
1652 (match_operand 1 "register_operand" "f")))]
1653 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1655 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1656 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1657 "* return output_fp_compare (insn, operands, true, true);"
1658 [(set_attr "type" "fcmp")
1660 (cond [(match_operand:SF 1 "" "")
1662 (match_operand:DF 1 "" "")
1665 (const_string "XF")))
1666 (set_attr "athlon_decode" "vector")
1667 (set_attr "amdfam10_decode" "direct")
1668 (set_attr "bdver1_decode" "direct")])
1670 ;; Push/pop instructions.
1672 (define_insn "*push<mode>2"
1673 [(set (match_operand:DWI 0 "push_operand" "=<")
1674 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1677 [(set_attr "type" "multi")
1678 (set_attr "mode" "<MODE>")])
1681 [(set (match_operand:TI 0 "push_operand" "")
1682 (match_operand:TI 1 "general_operand" ""))]
1683 "TARGET_64BIT && reload_completed
1684 && !SSE_REG_P (operands[1])"
1686 "ix86_split_long_move (operands); DONE;")
1688 (define_insn "*pushdi2_rex64"
1689 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1690 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1695 [(set_attr "type" "push,multi")
1696 (set_attr "mode" "DI")])
1698 ;; Convert impossible pushes of immediate to existing instructions.
1699 ;; First try to get scratch register and go through it. In case this
1700 ;; fails, push sign extended lower part first and then overwrite
1701 ;; upper part by 32bit move.
1703 [(match_scratch:DI 2 "r")
1704 (set (match_operand:DI 0 "push_operand" "")
1705 (match_operand:DI 1 "immediate_operand" ""))]
1706 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1707 && !x86_64_immediate_operand (operands[1], DImode)"
1708 [(set (match_dup 2) (match_dup 1))
1709 (set (match_dup 0) (match_dup 2))])
1711 ;; We need to define this as both peepholer and splitter for case
1712 ;; peephole2 pass is not run.
1713 ;; "&& 1" is needed to keep it from matching the previous pattern.
1715 [(set (match_operand:DI 0 "push_operand" "")
1716 (match_operand:DI 1 "immediate_operand" ""))]
1717 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1718 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1719 [(set (match_dup 0) (match_dup 1))
1720 (set (match_dup 2) (match_dup 3))]
1722 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1724 operands[1] = gen_lowpart (DImode, operands[2]);
1725 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1730 [(set (match_operand:DI 0 "push_operand" "")
1731 (match_operand:DI 1 "immediate_operand" ""))]
1732 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1733 ? epilogue_completed : reload_completed)
1734 && !symbolic_operand (operands[1], DImode)
1735 && !x86_64_immediate_operand (operands[1], DImode)"
1736 [(set (match_dup 0) (match_dup 1))
1737 (set (match_dup 2) (match_dup 3))]
1739 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1741 operands[1] = gen_lowpart (DImode, operands[2]);
1742 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1747 [(set (match_operand:DI 0 "push_operand" "")
1748 (match_operand:DI 1 "general_operand" ""))]
1749 "!TARGET_64BIT && reload_completed
1750 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1752 "ix86_split_long_move (operands); DONE;")
1754 (define_insn "*pushsi2"
1755 [(set (match_operand:SI 0 "push_operand" "=<")
1756 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "SI")])
1762 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1763 ;; "push a byte/word". But actually we use pushl, which has the effect
1764 ;; of rounding the amount pushed up to a word.
1766 ;; For TARGET_64BIT we always round up to 8 bytes.
1767 (define_insn "*push<mode>2_rex64"
1768 [(set (match_operand:SWI124 0 "push_operand" "=X")
1769 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1772 [(set_attr "type" "push")
1773 (set_attr "mode" "DI")])
1775 (define_insn "*push<mode>2"
1776 [(set (match_operand:SWI12 0 "push_operand" "=X")
1777 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1780 [(set_attr "type" "push")
1781 (set_attr "mode" "SI")])
1783 (define_insn "*push<mode>2_prologue"
1784 [(set (match_operand:P 0 "push_operand" "=<")
1785 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1786 (clobber (mem:BLK (scratch)))]
1788 "push{<imodesuffix>}\t%1"
1789 [(set_attr "type" "push")
1790 (set_attr "mode" "<MODE>")])
1792 (define_insn "*pop<mode>1"
1793 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1794 (match_operand:P 1 "pop_operand" ">"))]
1796 "pop{<imodesuffix>}\t%0"
1797 [(set_attr "type" "pop")
1798 (set_attr "mode" "<MODE>")])
1800 (define_insn "*pop<mode>1_epilogue"
1801 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1802 (match_operand:P 1 "pop_operand" ">"))
1803 (clobber (mem:BLK (scratch)))]
1805 "pop{<imodesuffix>}\t%0"
1806 [(set_attr "type" "pop")
1807 (set_attr "mode" "<MODE>")])
1809 ;; Move instructions.
1811 (define_expand "movoi"
1812 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1813 (match_operand:OI 1 "general_operand" ""))]
1815 "ix86_expand_move (OImode, operands); DONE;")
1817 (define_expand "movti"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1819 (match_operand:TI 1 "nonimmediate_operand" ""))]
1820 "TARGET_64BIT || TARGET_SSE"
1823 ix86_expand_move (TImode, operands);
1824 else if (push_operand (operands[0], TImode))
1825 ix86_expand_push (TImode, operands[1]);
1827 ix86_expand_vector_move (TImode, operands);
1831 ;; This expands to what emit_move_complex would generate if we didn't
1832 ;; have a movti pattern. Having this avoids problems with reload on
1833 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1834 ;; to have around all the time.
1835 (define_expand "movcdi"
1836 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1837 (match_operand:CDI 1 "general_operand" ""))]
1840 if (push_operand (operands[0], CDImode))
1841 emit_move_complex_push (CDImode, operands[0], operands[1]);
1843 emit_move_complex_parts (operands[0], operands[1]);
1847 (define_expand "mov<mode>"
1848 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1849 (match_operand:SWI1248x 1 "general_operand" ""))]
1851 "ix86_expand_move (<MODE>mode, operands); DONE;")
1853 (define_insn "*mov<mode>_xor"
1854 [(set (match_operand:SWI48 0 "register_operand" "=r")
1855 (match_operand:SWI48 1 "const0_operand" ""))
1856 (clobber (reg:CC FLAGS_REG))]
1859 [(set_attr "type" "alu1")
1860 (set_attr "mode" "SI")
1861 (set_attr "length_immediate" "0")])
1863 (define_insn "*mov<mode>_or"
1864 [(set (match_operand:SWI48 0 "register_operand" "=r")
1865 (match_operand:SWI48 1 "const_int_operand" ""))
1866 (clobber (reg:CC FLAGS_REG))]
1868 && operands[1] == constm1_rtx"
1869 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1870 [(set_attr "type" "alu1")
1871 (set_attr "mode" "<MODE>")
1872 (set_attr "length_immediate" "1")])
1874 (define_insn "*movoi_internal_avx"
1875 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1876 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1877 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879 switch (which_alternative)
1882 return standard_sse_constant_opcode (insn, operands[1]);
1885 if (misaligned_operand (operands[0], OImode)
1886 || misaligned_operand (operands[1], OImode))
1887 return "vmovdqu\t{%1, %0|%0, %1}";
1889 return "vmovdqa\t{%1, %0|%0, %1}";
1894 [(set_attr "type" "sselog1,ssemov,ssemov")
1895 (set_attr "prefix" "vex")
1896 (set_attr "mode" "OI")])
1898 (define_insn "*movti_internal_rex64"
1899 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1900 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1901 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1903 switch (which_alternative)
1909 return standard_sse_constant_opcode (insn, operands[1]);
1912 /* TDmode values are passed as TImode on the stack. Moving them
1913 to stack may result in unaligned memory access. */
1914 if (misaligned_operand (operands[0], TImode)
1915 || misaligned_operand (operands[1], TImode))
1917 if (get_attr_mode (insn) == MODE_V4SF)
1918 return "%vmovups\t{%1, %0|%0, %1}";
1920 return "%vmovdqu\t{%1, %0|%0, %1}";
1924 if (get_attr_mode (insn) == MODE_V4SF)
1925 return "%vmovaps\t{%1, %0|%0, %1}";
1927 return "%vmovdqa\t{%1, %0|%0, %1}";
1933 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1934 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1936 (cond [(eq_attr "alternative" "2,3")
1938 (match_test "optimize_function_for_size_p (cfun)")
1939 (const_string "V4SF")
1940 (const_string "TI"))
1941 (eq_attr "alternative" "4")
1943 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1944 (match_test "optimize_function_for_size_p (cfun)"))
1945 (const_string "V4SF")
1946 (const_string "TI"))]
1947 (const_string "DI")))])
1950 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1951 (match_operand:TI 1 "general_operand" ""))]
1953 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1955 "ix86_split_long_move (operands); DONE;")
1957 (define_insn "*movti_internal_sse"
1958 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1959 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1960 "TARGET_SSE && !TARGET_64BIT
1961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1963 switch (which_alternative)
1966 return standard_sse_constant_opcode (insn, operands[1]);
1969 /* TDmode values are passed as TImode on the stack. Moving them
1970 to stack may result in unaligned memory access. */
1971 if (misaligned_operand (operands[0], TImode)
1972 || misaligned_operand (operands[1], TImode))
1974 if (get_attr_mode (insn) == MODE_V4SF)
1975 return "%vmovups\t{%1, %0|%0, %1}";
1977 return "%vmovdqu\t{%1, %0|%0, %1}";
1981 if (get_attr_mode (insn) == MODE_V4SF)
1982 return "%vmovaps\t{%1, %0|%0, %1}";
1984 return "%vmovdqa\t{%1, %0|%0, %1}";
1990 [(set_attr "type" "sselog1,ssemov,ssemov")
1991 (set_attr "prefix" "maybe_vex")
1993 (cond [(ior (not (match_test "TARGET_SSE2"))
1994 (match_test "optimize_function_for_size_p (cfun)"))
1995 (const_string "V4SF")
1996 (and (eq_attr "alternative" "2")
1997 (match_test "TARGET_SSE_TYPELESS_STORES"))
1998 (const_string "V4SF")]
1999 (const_string "TI")))])
2001 (define_insn "*movdi_internal_rex64"
2002 [(set (match_operand:DI 0 "nonimmediate_operand"
2003 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2004 (match_operand:DI 1 "general_operand"
2005 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2006 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008 switch (get_attr_type (insn))
2011 if (SSE_REG_P (operands[0]))
2012 return "movq2dq\t{%1, %0|%0, %1}";
2014 return "movdq2q\t{%1, %0|%0, %1}";
2017 if (get_attr_mode (insn) == MODE_TI)
2018 return "%vmovdqa\t{%1, %0|%0, %1}";
2019 /* Handle broken assemblers that require movd instead of movq. */
2020 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2021 return "%vmovd\t{%1, %0|%0, %1}";
2023 return "%vmovq\t{%1, %0|%0, %1}";
2026 /* Handle broken assemblers that require movd instead of movq. */
2027 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2028 return "movd\t{%1, %0|%0, %1}";
2030 return "movq\t{%1, %0|%0, %1}";
2033 return standard_sse_constant_opcode (insn, operands[1]);
2036 return "pxor\t%0, %0";
2042 return "lea{q}\t{%a1, %0|%0, %a1}";
2045 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2046 if (get_attr_mode (insn) == MODE_SI)
2047 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2048 else if (which_alternative == 2)
2049 return "movabs{q}\t{%1, %0|%0, %1}";
2051 return "mov{q}\t{%1, %0|%0, %1}";
2055 (cond [(eq_attr "alternative" "4")
2056 (const_string "multi")
2057 (eq_attr "alternative" "5")
2058 (const_string "mmx")
2059 (eq_attr "alternative" "6,7,8,9")
2060 (const_string "mmxmov")
2061 (eq_attr "alternative" "10")
2062 (const_string "sselog1")
2063 (eq_attr "alternative" "11,12,13,14,15")
2064 (const_string "ssemov")
2065 (eq_attr "alternative" "16,17")
2066 (const_string "ssecvt")
2067 (match_operand 1 "pic_32bit_operand" "")
2068 (const_string "lea")
2070 (const_string "imov")))
2073 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2075 (const_string "*")))
2076 (set (attr "length_immediate")
2078 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2080 (const_string "*")))
2081 (set (attr "prefix_rex")
2082 (if_then_else (eq_attr "alternative" "8,9")
2084 (const_string "*")))
2085 (set (attr "prefix_data16")
2086 (if_then_else (eq_attr "alternative" "11")
2088 (const_string "*")))
2089 (set (attr "prefix")
2090 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2091 (const_string "maybe_vex")
2092 (const_string "orig")))
2093 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2095 ;; Reload patterns to support multi-word load/store
2096 ;; with non-offsetable address.
2097 (define_expand "reload_noff_store"
2098 [(parallel [(match_operand 0 "memory_operand" "=m")
2099 (match_operand 1 "register_operand" "r")
2100 (match_operand:DI 2 "register_operand" "=&r")])]
2103 rtx mem = operands[0];
2104 rtx addr = XEXP (mem, 0);
2106 emit_move_insn (operands[2], addr);
2107 mem = replace_equiv_address_nv (mem, operands[2]);
2109 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2113 (define_expand "reload_noff_load"
2114 [(parallel [(match_operand 0 "register_operand" "=r")
2115 (match_operand 1 "memory_operand" "m")
2116 (match_operand:DI 2 "register_operand" "=r")])]
2119 rtx mem = operands[1];
2120 rtx addr = XEXP (mem, 0);
2122 emit_move_insn (operands[2], addr);
2123 mem = replace_equiv_address_nv (mem, operands[2]);
2125 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2129 ;; Convert impossible stores of immediate to existing instructions.
2130 ;; First try to get scratch register and go through it. In case this
2131 ;; fails, move by 32bit parts.
2133 [(match_scratch:DI 2 "r")
2134 (set (match_operand:DI 0 "memory_operand" "")
2135 (match_operand:DI 1 "immediate_operand" ""))]
2136 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2137 && !x86_64_immediate_operand (operands[1], DImode)"
2138 [(set (match_dup 2) (match_dup 1))
2139 (set (match_dup 0) (match_dup 2))])
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2145 [(set (match_operand:DI 0 "memory_operand" "")
2146 (match_operand:DI 1 "immediate_operand" ""))]
2147 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149 [(set (match_dup 2) (match_dup 3))
2150 (set (match_dup 4) (match_dup 5))]
2151 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2154 [(set (match_operand:DI 0 "memory_operand" "")
2155 (match_operand:DI 1 "immediate_operand" ""))]
2156 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157 ? epilogue_completed : reload_completed)
2158 && !symbolic_operand (operands[1], DImode)
2159 && !x86_64_immediate_operand (operands[1], DImode)"
2160 [(set (match_dup 2) (match_dup 3))
2161 (set (match_dup 4) (match_dup 5))]
2162 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2164 (define_insn "*movdi_internal"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2171 switch (get_attr_type (insn))
2174 if (SSE_REG_P (operands[0]))
2175 return "movq2dq\t{%1, %0|%0, %1}";
2177 return "movdq2q\t{%1, %0|%0, %1}";
2180 switch (get_attr_mode (insn))
2183 return "%vmovdqa\t{%1, %0|%0, %1}";
2185 return "%vmovq\t{%1, %0|%0, %1}";
2187 return "movaps\t{%1, %0|%0, %1}";
2189 return "movlps\t{%1, %0|%0, %1}";
2195 return "movq\t{%1, %0|%0, %1}";
2198 return standard_sse_constant_opcode (insn, operands[1]);
2201 return "pxor\t%0, %0";
2211 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2212 (const_string "sse2")
2213 (eq_attr "alternative" "9,10,11,12")
2214 (const_string "noavx")
2216 (const_string "*")))
2218 (cond [(eq_attr "alternative" "0,1")
2219 (const_string "multi")
2220 (eq_attr "alternative" "2")
2221 (const_string "mmx")
2222 (eq_attr "alternative" "3,4")
2223 (const_string "mmxmov")
2224 (eq_attr "alternative" "5,9")
2225 (const_string "sselog1")
2226 (eq_attr "alternative" "13,14")
2227 (const_string "ssecvt")
2229 (const_string "ssemov")))
2230 (set (attr "prefix")
2231 (if_then_else (eq_attr "alternative" "5,6,7,8")
2232 (const_string "maybe_vex")
2233 (const_string "orig")))
2234 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2237 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2238 (match_operand:DI 1 "general_operand" ""))]
2239 "!TARGET_64BIT && reload_completed
2240 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2241 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2243 "ix86_split_long_move (operands); DONE;")
2245 (define_insn "*movsi_internal"
2246 [(set (match_operand:SI 0 "nonimmediate_operand"
2247 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2248 (match_operand:SI 1 "general_operand"
2249 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2252 switch (get_attr_type (insn))
2255 return standard_sse_constant_opcode (insn, operands[1]);
2258 switch (get_attr_mode (insn))
2261 return "%vmovdqa\t{%1, %0|%0, %1}";
2263 return "%vmovaps\t{%1, %0|%0, %1}";
2265 return "%vmovd\t{%1, %0|%0, %1}";
2267 return "%vmovss\t{%1, %0|%0, %1}";
2273 return "pxor\t%0, %0";
2276 if (get_attr_mode (insn) == MODE_DI)
2277 return "movq\t{%1, %0|%0, %1}";
2278 return "movd\t{%1, %0|%0, %1}";
2281 return "lea{l}\t{%a1, %0|%0, %a1}";
2284 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2285 return "mov{l}\t{%1, %0|%0, %1}";
2289 (cond [(eq_attr "alternative" "2")
2290 (const_string "mmx")
2291 (eq_attr "alternative" "3,4,5")
2292 (const_string "mmxmov")
2293 (eq_attr "alternative" "6")
2294 (const_string "sselog1")
2295 (eq_attr "alternative" "7,8,9,10,11")
2296 (const_string "ssemov")
2297 (match_operand 1 "pic_32bit_operand" "")
2298 (const_string "lea")
2300 (const_string "imov")))
2301 (set (attr "prefix")
2302 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2303 (const_string "orig")
2304 (const_string "maybe_vex")))
2305 (set (attr "prefix_data16")
2306 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2308 (const_string "*")))
2310 (cond [(eq_attr "alternative" "2,3")
2312 (eq_attr "alternative" "6,7")
2314 (not (match_test "TARGET_SSE2"))
2315 (const_string "V4SF")
2316 (const_string "TI"))
2317 (and (eq_attr "alternative" "8,9,10,11")
2318 (not (match_test "TARGET_SSE2")))
2321 (const_string "SI")))])
2323 (define_insn "*movhi_internal"
2324 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2325 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328 switch (get_attr_type (insn))
2331 /* movzwl is faster than movw on p2 due to partial word stalls,
2332 though not as fast as an aligned movl. */
2333 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2335 if (get_attr_mode (insn) == MODE_SI)
2336 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2338 return "mov{w}\t{%1, %0|%0, %1}";
2342 (cond [(match_test "optimize_function_for_size_p (cfun)")
2343 (const_string "imov")
2344 (and (eq_attr "alternative" "0")
2345 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2346 (not (match_test "TARGET_HIMODE_MATH"))))
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "1,2")
2349 (match_operand:HI 1 "aligned_operand" ""))
2350 (const_string "imov")
2351 (and (match_test "TARGET_MOVX")
2352 (eq_attr "alternative" "0,2"))
2353 (const_string "imovx")
2355 (const_string "imov")))
2357 (cond [(eq_attr "type" "imovx")
2359 (and (eq_attr "alternative" "1,2")
2360 (match_operand:HI 1 "aligned_operand" ""))
2362 (and (eq_attr "alternative" "0")
2363 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2364 (not (match_test "TARGET_HIMODE_MATH"))))
2367 (const_string "HI")))])
2369 ;; Situation is quite tricky about when to choose full sized (SImode) move
2370 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2371 ;; partial register dependency machines (such as AMD Athlon), where QImode
2372 ;; moves issue extra dependency and for partial register stalls machines
2373 ;; that don't use QImode patterns (and QImode move cause stall on the next
2376 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2377 ;; register stall machines with, where we use QImode instructions, since
2378 ;; partial register stall can be caused there. Then we use movzx.
2379 (define_insn "*movqi_internal"
2380 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2381 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2382 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2384 switch (get_attr_type (insn))
2387 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2388 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2390 if (get_attr_mode (insn) == MODE_SI)
2391 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2393 return "mov{b}\t{%1, %0|%0, %1}";
2397 (cond [(and (eq_attr "alternative" "5")
2398 (not (match_operand:QI 1 "aligned_operand" "")))
2399 (const_string "imovx")
2400 (match_test "optimize_function_for_size_p (cfun)")
2401 (const_string "imov")
2402 (and (eq_attr "alternative" "3")
2403 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2404 (not (match_test "TARGET_QIMODE_MATH"))))
2405 (const_string "imov")
2406 (eq_attr "alternative" "3,5")
2407 (const_string "imovx")
2408 (and (match_test "TARGET_MOVX")
2409 (eq_attr "alternative" "2"))
2410 (const_string "imovx")
2412 (const_string "imov")))
2414 (cond [(eq_attr "alternative" "3,4,5")
2416 (eq_attr "alternative" "6")
2418 (eq_attr "type" "imovx")
2420 (and (eq_attr "type" "imov")
2421 (and (eq_attr "alternative" "0,1")
2422 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2423 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2424 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2426 ;; Avoid partial register stalls when not using QImode arithmetic
2427 (and (eq_attr "type" "imov")
2428 (and (eq_attr "alternative" "0,1")
2429 (and (match_test "TARGET_PARTIAL_REG_STALL")
2430 (not (match_test "TARGET_QIMODE_MATH")))))
2433 (const_string "QI")))])
2435 ;; Stores and loads of ax to arbitrary constant address.
2436 ;; We fake an second form of instruction to force reload to load address
2437 ;; into register when rax is not available
2438 (define_insn "*movabs<mode>_1"
2439 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2440 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2441 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2443 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2444 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2445 [(set_attr "type" "imov")
2446 (set_attr "modrm" "0,*")
2447 (set_attr "length_address" "8,0")
2448 (set_attr "length_immediate" "0,*")
2449 (set_attr "memory" "store")
2450 (set_attr "mode" "<MODE>")])
2452 (define_insn "*movabs<mode>_2"
2453 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2454 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2455 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2457 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2458 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2459 [(set_attr "type" "imov")
2460 (set_attr "modrm" "0,*")
2461 (set_attr "length_address" "8,0")
2462 (set_attr "length_immediate" "0")
2463 (set_attr "memory" "load")
2464 (set_attr "mode" "<MODE>")])
2466 (define_insn "*swap<mode>"
2467 [(set (match_operand:SWI48 0 "register_operand" "+r")
2468 (match_operand:SWI48 1 "register_operand" "+r"))
2472 "xchg{<imodesuffix>}\t%1, %0"
2473 [(set_attr "type" "imov")
2474 (set_attr "mode" "<MODE>")
2475 (set_attr "pent_pair" "np")
2476 (set_attr "athlon_decode" "vector")
2477 (set_attr "amdfam10_decode" "double")
2478 (set_attr "bdver1_decode" "double")])
2480 (define_insn "*swap<mode>_1"
2481 [(set (match_operand:SWI12 0 "register_operand" "+r")
2482 (match_operand:SWI12 1 "register_operand" "+r"))
2485 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2487 [(set_attr "type" "imov")
2488 (set_attr "mode" "SI")
2489 (set_attr "pent_pair" "np")
2490 (set_attr "athlon_decode" "vector")
2491 (set_attr "amdfam10_decode" "double")
2492 (set_attr "bdver1_decode" "double")])
2494 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2495 ;; is disabled for AMDFAM10
2496 (define_insn "*swap<mode>_2"
2497 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2498 (match_operand:SWI12 1 "register_operand" "+<r>"))
2501 "TARGET_PARTIAL_REG_STALL"
2502 "xchg{<imodesuffix>}\t%1, %0"
2503 [(set_attr "type" "imov")
2504 (set_attr "mode" "<MODE>")
2505 (set_attr "pent_pair" "np")
2506 (set_attr "athlon_decode" "vector")])
2508 (define_expand "movstrict<mode>"
2509 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2510 (match_operand:SWI12 1 "general_operand" ""))]
2513 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2515 if (GET_CODE (operands[0]) == SUBREG
2516 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2518 /* Don't generate memory->memory moves, go through a register */
2519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2520 operands[1] = force_reg (<MODE>mode, operands[1]);
2523 (define_insn "*movstrict<mode>_1"
2524 [(set (strict_low_part
2525 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2526 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2527 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2530 [(set_attr "type" "imov")
2531 (set_attr "mode" "<MODE>")])
2533 (define_insn "*movstrict<mode>_xor"
2534 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2535 (match_operand:SWI12 1 "const0_operand" ""))
2536 (clobber (reg:CC FLAGS_REG))]
2538 "xor{<imodesuffix>}\t%0, %0"
2539 [(set_attr "type" "alu1")
2540 (set_attr "mode" "<MODE>")
2541 (set_attr "length_immediate" "0")])
2543 (define_insn "*mov<mode>_extv_1"
2544 [(set (match_operand:SWI24 0 "register_operand" "=R")
2545 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2549 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2550 [(set_attr "type" "imovx")
2551 (set_attr "mode" "SI")])
2553 (define_insn "*movqi_extv_1_rex64"
2554 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2555 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2560 switch (get_attr_type (insn))
2563 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2565 return "mov{b}\t{%h1, %0|%0, %h1}";
2569 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2570 (match_test "TARGET_MOVX"))
2571 (const_string "imovx")
2572 (const_string "imov")))
2574 (if_then_else (eq_attr "type" "imovx")
2576 (const_string "QI")))])
2578 (define_insn "*movqi_extv_1"
2579 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2580 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2585 switch (get_attr_type (insn))
2588 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2590 return "mov{b}\t{%h1, %0|%0, %h1}";
2594 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2595 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2596 (match_test "TARGET_MOVX")))
2597 (const_string "imovx")
2598 (const_string "imov")))
2600 (if_then_else (eq_attr "type" "imovx")
2602 (const_string "QI")))])
2604 (define_insn "*mov<mode>_extzv_1"
2605 [(set (match_operand:SWI48 0 "register_operand" "=R")
2606 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2610 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2611 [(set_attr "type" "imovx")
2612 (set_attr "mode" "SI")])
2614 (define_insn "*movqi_extzv_2_rex64"
2615 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2617 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2622 switch (get_attr_type (insn))
2625 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2627 return "mov{b}\t{%h1, %0|%0, %h1}";
2631 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2632 (match_test "TARGET_MOVX"))
2633 (const_string "imovx")
2634 (const_string "imov")))
2636 (if_then_else (eq_attr "type" "imovx")
2638 (const_string "QI")))])
2640 (define_insn "*movqi_extzv_2"
2641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2643 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2648 switch (get_attr_type (insn))
2651 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2653 return "mov{b}\t{%h1, %0|%0, %h1}";
2657 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2658 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2659 (match_test "TARGET_MOVX")))
2660 (const_string "imovx")
2661 (const_string "imov")))
2663 (if_then_else (eq_attr "type" "imovx")
2665 (const_string "QI")))])
2667 (define_expand "mov<mode>_insv_1"
2668 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2671 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2673 (define_insn "*mov<mode>_insv_1_rex64"
2674 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2677 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2679 "mov{b}\t{%b1, %h0|%h0, %b1}"
2680 [(set_attr "type" "imov")
2681 (set_attr "mode" "QI")])
2683 (define_insn "*movsi_insv_1"
2684 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2687 (match_operand:SI 1 "general_operand" "Qmn"))]
2689 "mov{b}\t{%b1, %h0|%h0, %b1}"
2690 [(set_attr "type" "imov")
2691 (set_attr "mode" "QI")])
2693 (define_insn "*movqi_insv_2"
2694 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2697 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2700 "mov{b}\t{%h1, %h0|%h0, %h1}"
2701 [(set_attr "type" "imov")
2702 (set_attr "mode" "QI")])
2704 ;; Floating point push instructions.
2706 (define_insn "*pushtf"
2707 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2708 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2711 /* This insn should be already split before reg-stack. */
2714 [(set_attr "type" "multi")
2715 (set_attr "unit" "sse,*,*")
2716 (set_attr "mode" "TF,SI,SI")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:TF 0 "push_operand" "")
2721 (match_operand:TF 1 "sse_reg_operand" ""))]
2722 "TARGET_SSE2 && reload_completed"
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2724 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2726 (define_insn "*pushxf"
2727 [(set (match_operand:XF 0 "push_operand" "=<,<")
2728 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2729 "optimize_function_for_speed_p (cfun)"
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*")
2736 (set_attr "mode" "XF,SI")])
2738 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2739 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2740 ;; Pushing using integer instructions is longer except for constants
2741 ;; and direct memory references (assuming that any given constant is pushed
2742 ;; only once, but this ought to be handled elsewhere).
2744 (define_insn "*pushxf_nointeger"
2745 [(set (match_operand:XF 0 "push_operand" "=<,<")
2746 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2747 "optimize_function_for_size_p (cfun)"
2749 /* This insn should be already split before reg-stack. */
2752 [(set_attr "type" "multi")
2753 (set_attr "unit" "i387,*")
2754 (set_attr "mode" "XF,SI")])
2756 ;; %%% Kill this when call knows how to work this out.
2758 [(set (match_operand:XF 0 "push_operand" "")
2759 (match_operand:XF 1 "fp_register_operand" ""))]
2761 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2762 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2763 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2765 (define_insn "*pushdf_rex64"
2766 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2767 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2770 /* This insn should be already split before reg-stack. */
2773 [(set_attr "type" "multi")
2774 (set_attr "unit" "i387,*,*")
2775 (set_attr "mode" "DF,DI,DF")])
2777 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2778 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2779 ;; On the average, pushdf using integers can be still shorter.
2781 (define_insn "*pushdf"
2782 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2783 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2786 /* This insn should be already split before reg-stack. */
2789 [(set_attr "isa" "*,*,sse2")
2790 (set_attr "type" "multi")
2791 (set_attr "unit" "i387,*,*")
2792 (set_attr "mode" "DF,DI,DF")])
2794 ;; %%% Kill this when call knows how to work this out.
2796 [(set (match_operand:DF 0 "push_operand" "")
2797 (match_operand:DF 1 "any_fp_register_operand" ""))]
2799 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2800 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2802 (define_insn "*pushsf_rex64"
2803 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2804 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2807 /* Anything else should be already split before reg-stack. */
2808 gcc_assert (which_alternative == 1);
2809 return "push{q}\t%q1";
2811 [(set_attr "type" "multi,push,multi")
2812 (set_attr "unit" "i387,*,*")
2813 (set_attr "mode" "SF,DI,SF")])
2815 (define_insn "*pushsf"
2816 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2817 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2820 /* Anything else should be already split before reg-stack. */
2821 gcc_assert (which_alternative == 1);
2822 return "push{l}\t%1";
2824 [(set_attr "type" "multi,push,multi")
2825 (set_attr "unit" "i387,*,*")
2826 (set_attr "mode" "SF,SI,SF")])
2828 ;; %%% Kill this when call knows how to work this out.
2830 [(set (match_operand:SF 0 "push_operand" "")
2831 (match_operand:SF 1 "any_fp_register_operand" ""))]
2833 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2834 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2835 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2838 [(set (match_operand:SF 0 "push_operand" "")
2839 (match_operand:SF 1 "memory_operand" ""))]
2841 && (operands[2] = find_constant_src (insn))"
2842 [(set (match_dup 0) (match_dup 2))])
2845 [(set (match_operand 0 "push_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2848 && (GET_MODE (operands[0]) == TFmode
2849 || GET_MODE (operands[0]) == XFmode
2850 || GET_MODE (operands[0]) == DFmode)
2851 && !ANY_FP_REG_P (operands[1])"
2853 "ix86_split_long_move (operands); DONE;")
2855 ;; Floating point move instructions.
2857 (define_expand "movtf"
2858 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2859 (match_operand:TF 1 "nonimmediate_operand" ""))]
2862 ix86_expand_move (TFmode, operands);
2866 (define_expand "mov<mode>"
2867 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2868 (match_operand:X87MODEF 1 "general_operand" ""))]
2870 "ix86_expand_move (<MODE>mode, operands); DONE;")
2872 (define_insn "*movtf_internal"
2873 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2874 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2876 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2877 && (!can_create_pseudo_p ()
2878 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2879 || GET_CODE (operands[1]) != CONST_DOUBLE
2880 || (optimize_function_for_size_p (cfun)
2881 && standard_sse_constant_p (operands[1])
2882 && !memory_operand (operands[0], TFmode))
2883 || (!TARGET_MEMORY_MISMATCH_STALL
2884 && memory_operand (operands[0], TFmode)))"
2886 switch (which_alternative)
2890 /* Handle misaligned load/store since we
2891 don't have movmisaligntf pattern. */
2892 if (misaligned_operand (operands[0], TFmode)
2893 || misaligned_operand (operands[1], TFmode))
2895 if (get_attr_mode (insn) == MODE_V4SF)
2896 return "%vmovups\t{%1, %0|%0, %1}";
2898 return "%vmovdqu\t{%1, %0|%0, %1}";
2902 if (get_attr_mode (insn) == MODE_V4SF)
2903 return "%vmovaps\t{%1, %0|%0, %1}";
2905 return "%vmovdqa\t{%1, %0|%0, %1}";
2909 return standard_sse_constant_opcode (insn, operands[1]);
2919 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2920 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2922 (cond [(eq_attr "alternative" "0,2")
2924 (match_test "optimize_function_for_size_p (cfun)")
2925 (const_string "V4SF")
2926 (const_string "TI"))
2927 (eq_attr "alternative" "1")
2929 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2930 (match_test "optimize_function_for_size_p (cfun)"))
2931 (const_string "V4SF")
2932 (const_string "TI"))]
2933 (const_string "DI")))])
2935 ;; Possible store forwarding (partial memory) stall in alternative 4.
2936 (define_insn "*movxf_internal"
2937 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2938 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2939 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2940 && (!can_create_pseudo_p ()
2941 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2942 || GET_CODE (operands[1]) != CONST_DOUBLE
2943 || (optimize_function_for_size_p (cfun)
2944 && standard_80387_constant_p (operands[1]) > 0
2945 && !memory_operand (operands[0], XFmode))
2946 || (!TARGET_MEMORY_MISMATCH_STALL
2947 && memory_operand (operands[0], XFmode)))"
2949 switch (which_alternative)
2953 return output_387_reg_move (insn, operands);
2956 return standard_80387_constant_opcode (operands[1]);
2966 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2967 (set_attr "mode" "XF,XF,XF,SI,SI")])
2969 (define_insn "*movdf_internal_rex64"
2970 [(set (match_operand:DF 0 "nonimmediate_operand"
2971 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2972 (match_operand:DF 1 "general_operand"
2973 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2974 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2975 && (!can_create_pseudo_p ()
2976 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (optimize_function_for_size_p (cfun)
2979 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2980 && standard_80387_constant_p (operands[1]) > 0)
2981 || (TARGET_SSE2 && TARGET_SSE_MATH
2982 && standard_sse_constant_p (operands[1]))))
2983 || memory_operand (operands[0], DFmode))"
2985 switch (which_alternative)
2989 return output_387_reg_move (insn, operands);
2992 return standard_80387_constant_opcode (operands[1]);
2996 return "mov{q}\t{%1, %0|%0, %1}";
2999 return "movabs{q}\t{%1, %0|%0, %1}";
3005 return standard_sse_constant_opcode (insn, operands[1]);
3010 switch (get_attr_mode (insn))
3013 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3014 return "%vmovapd\t{%1, %0|%0, %1}";
3016 return "%vmovaps\t{%1, %0|%0, %1}";
3019 return "%vmovq\t{%1, %0|%0, %1}";
3021 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3022 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3023 return "%vmovsd\t{%1, %0|%0, %1}";
3025 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3027 return "%vmovlps\t{%1, %d0|%d0, %1}";
3034 /* Handle broken assemblers that require movd instead of movq. */
3035 return "%vmovd\t{%1, %0|%0, %1}";
3042 (cond [(eq_attr "alternative" "0,1,2")
3043 (const_string "fmov")
3044 (eq_attr "alternative" "3,4,5")
3045 (const_string "imov")
3046 (eq_attr "alternative" "6")
3047 (const_string "multi")
3048 (eq_attr "alternative" "7")
3049 (const_string "sselog1")
3051 (const_string "ssemov")))
3054 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3056 (const_string "*")))
3057 (set (attr "length_immediate")
3059 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3061 (const_string "*")))
3062 (set (attr "prefix")
3063 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3064 (const_string "orig")
3065 (const_string "maybe_vex")))
3066 (set (attr "prefix_data16")
3067 (if_then_else (eq_attr "mode" "V1DF")
3069 (const_string "*")))
3071 (cond [(eq_attr "alternative" "0,1,2")
3073 (eq_attr "alternative" "3,4,5,6,11,12")
3076 /* xorps is one byte shorter. */
3077 (eq_attr "alternative" "7")
3078 (cond [(match_test "optimize_function_for_size_p (cfun)")
3079 (const_string "V4SF")
3080 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3083 (const_string "V2DF"))
3085 /* For architectures resolving dependencies on
3086 whole SSE registers use APD move to break dependency
3087 chains, otherwise use short move to avoid extra work.
3089 movaps encodes one byte shorter. */
3090 (eq_attr "alternative" "8")
3092 [(match_test "optimize_function_for_size_p (cfun)")
3093 (const_string "V4SF")
3094 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3095 (const_string "V2DF")
3097 (const_string "DF"))
3098 /* For architectures resolving dependencies on register
3099 parts we may avoid extra work to zero out upper part
3101 (eq_attr "alternative" "9")
3103 (match_test "TARGET_SSE_SPLIT_REGS")
3104 (const_string "V1DF")
3105 (const_string "DF"))
3107 (const_string "DF")))])
3109 ;; Possible store forwarding (partial memory) stall in alternative 4.
3110 (define_insn "*movdf_internal"
3111 [(set (match_operand:DF 0 "nonimmediate_operand"
3112 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3113 (match_operand:DF 1 "general_operand"
3114 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3115 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3116 && (!can_create_pseudo_p ()
3117 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3118 || GET_CODE (operands[1]) != CONST_DOUBLE
3119 || (optimize_function_for_size_p (cfun)
3120 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3121 && standard_80387_constant_p (operands[1]) > 0)
3122 || (TARGET_SSE2 && TARGET_SSE_MATH
3123 && standard_sse_constant_p (operands[1])))
3124 && !memory_operand (operands[0], DFmode))
3125 || (!TARGET_MEMORY_MISMATCH_STALL
3126 && memory_operand (operands[0], DFmode)))"
3128 switch (which_alternative)
3132 return output_387_reg_move (insn, operands);
3135 return standard_80387_constant_opcode (operands[1]);
3143 return standard_sse_constant_opcode (insn, operands[1]);
3151 switch (get_attr_mode (insn))
3154 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3155 return "%vmovapd\t{%1, %0|%0, %1}";
3157 return "%vmovaps\t{%1, %0|%0, %1}";
3160 return "%vmovq\t{%1, %0|%0, %1}";
3162 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3163 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3164 return "%vmovsd\t{%1, %0|%0, %1}";
3166 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3168 return "%vmovlps\t{%1, %d0|%d0, %1}";
3178 (if_then_else (eq_attr "alternative" "5,6,7,8")
3179 (const_string "sse2")
3180 (const_string "*")))
3182 (cond [(eq_attr "alternative" "0,1,2")
3183 (const_string "fmov")
3184 (eq_attr "alternative" "3,4")
3185 (const_string "multi")
3186 (eq_attr "alternative" "5,9")
3187 (const_string "sselog1")
3189 (const_string "ssemov")))
3190 (set (attr "prefix")
3191 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3192 (const_string "orig")
3193 (const_string "maybe_vex")))
3194 (set (attr "prefix_data16")
3195 (if_then_else (eq_attr "mode" "V1DF")
3197 (const_string "*")))
3199 (cond [(eq_attr "alternative" "0,1,2")
3201 (eq_attr "alternative" "3,4")
3204 /* For SSE1, we have many fewer alternatives. */
3205 (not (match_test "TARGET_SSE2"))
3207 (eq_attr "alternative" "5,6,9,10")
3208 (const_string "V4SF")
3209 (const_string "V2SF"))
3211 /* xorps is one byte shorter. */
3212 (eq_attr "alternative" "5,9")
3213 (cond [(match_test "optimize_function_for_size_p (cfun)")
3214 (const_string "V4SF")
3215 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3218 (const_string "V2DF"))
3220 /* For architectures resolving dependencies on
3221 whole SSE registers use APD move to break dependency
3222 chains, otherwise use short move to avoid extra work.
3224 movaps encodes one byte shorter. */
3225 (eq_attr "alternative" "6,10")
3227 [(match_test "optimize_function_for_size_p (cfun)")
3228 (const_string "V4SF")
3229 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3230 (const_string "V2DF")
3232 (const_string "DF"))
3233 /* For architectures resolving dependencies on register
3234 parts we may avoid extra work to zero out upper part
3236 (eq_attr "alternative" "7,11")
3238 (match_test "TARGET_SSE_SPLIT_REGS")
3239 (const_string "V1DF")
3240 (const_string "DF"))
3242 (const_string "DF")))])
3244 (define_insn "*movsf_internal"
3245 [(set (match_operand:SF 0 "nonimmediate_operand"
3246 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3247 (match_operand:SF 1 "general_operand"
3248 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3249 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3250 && (!can_create_pseudo_p ()
3251 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3252 || GET_CODE (operands[1]) != CONST_DOUBLE
3253 || (optimize_function_for_size_p (cfun)
3254 && ((!TARGET_SSE_MATH
3255 && standard_80387_constant_p (operands[1]) > 0)
3257 && standard_sse_constant_p (operands[1]))))
3258 || memory_operand (operands[0], SFmode))"
3260 switch (which_alternative)
3264 return output_387_reg_move (insn, operands);
3267 return standard_80387_constant_opcode (operands[1]);
3271 return "mov{l}\t{%1, %0|%0, %1}";
3274 return standard_sse_constant_opcode (insn, operands[1]);
3277 if (get_attr_mode (insn) == MODE_V4SF)
3278 return "%vmovaps\t{%1, %0|%0, %1}";
3280 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3284 return "%vmovss\t{%1, %0|%0, %1}";
3290 return "movd\t{%1, %0|%0, %1}";
3293 return "movq\t{%1, %0|%0, %1}";
3297 return "%vmovd\t{%1, %0|%0, %1}";
3304 (cond [(eq_attr "alternative" "0,1,2")
3305 (const_string "fmov")
3306 (eq_attr "alternative" "3,4")
3307 (const_string "multi")
3308 (eq_attr "alternative" "5")
3309 (const_string "sselog1")
3310 (eq_attr "alternative" "9,10,11,14,15")
3311 (const_string "mmxmov")
3313 (const_string "ssemov")))
3314 (set (attr "prefix")
3315 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3316 (const_string "maybe_vex")
3317 (const_string "orig")))
3319 (cond [(eq_attr "alternative" "3,4,9,10")
3321 (eq_attr "alternative" "5")
3323 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3324 (match_test "TARGET_SSE2"))
3325 (not (match_test "optimize_function_for_size_p (cfun)")))
3327 (const_string "V4SF"))
3328 /* For architectures resolving dependencies on
3329 whole SSE registers use APS move to break dependency
3330 chains, otherwise use short move to avoid extra work.
3332 Do the same for architectures resolving dependencies on
3333 the parts. While in DF mode it is better to always handle
3334 just register parts, the SF mode is different due to lack
3335 of instructions to load just part of the register. It is
3336 better to maintain the whole registers in single format
3337 to avoid problems on using packed logical operations. */
3338 (eq_attr "alternative" "6")
3340 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3341 (match_test "TARGET_SSE_SPLIT_REGS"))
3342 (const_string "V4SF")
3343 (const_string "SF"))
3344 (eq_attr "alternative" "11")
3345 (const_string "DI")]
3346 (const_string "SF")))])
3349 [(set (match_operand 0 "any_fp_register_operand" "")
3350 (match_operand 1 "memory_operand" ""))]
3352 && (GET_MODE (operands[0]) == TFmode
3353 || GET_MODE (operands[0]) == XFmode
3354 || GET_MODE (operands[0]) == DFmode
3355 || GET_MODE (operands[0]) == SFmode)
3356 && (operands[2] = find_constant_src (insn))"
3357 [(set (match_dup 0) (match_dup 2))]
3359 rtx c = operands[2];
3360 int r = REGNO (operands[0]);
3362 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3363 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3368 [(set (match_operand 0 "any_fp_register_operand" "")
3369 (float_extend (match_operand 1 "memory_operand" "")))]
3371 && (GET_MODE (operands[0]) == TFmode
3372 || GET_MODE (operands[0]) == XFmode
3373 || GET_MODE (operands[0]) == DFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3385 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3387 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3388 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3390 && (standard_80387_constant_p (operands[1]) == 8
3391 || standard_80387_constant_p (operands[1]) == 9)"
3392 [(set (match_dup 0)(match_dup 1))
3394 (neg:X87MODEF (match_dup 0)))]
3398 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3399 if (real_isnegzero (&r))
3400 operands[1] = CONST0_RTX (<MODE>mode);
3402 operands[1] = CONST1_RTX (<MODE>mode);
3406 [(set (match_operand 0 "nonimmediate_operand" "")
3407 (match_operand 1 "general_operand" ""))]
3409 && (GET_MODE (operands[0]) == TFmode
3410 || GET_MODE (operands[0]) == XFmode
3411 || GET_MODE (operands[0]) == DFmode)
3412 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3414 "ix86_split_long_move (operands); DONE;")
3416 (define_insn "swapxf"
3417 [(set (match_operand:XF 0 "register_operand" "+f")
3418 (match_operand:XF 1 "register_operand" "+f"))
3423 if (STACK_TOP_P (operands[0]))
3428 [(set_attr "type" "fxch")
3429 (set_attr "mode" "XF")])
3431 (define_insn "*swap<mode>"
3432 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3433 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3436 "TARGET_80387 || reload_completed"
3438 if (STACK_TOP_P (operands[0]))
3443 [(set_attr "type" "fxch")
3444 (set_attr "mode" "<MODE>")])
3446 ;; Zero extension instructions
3448 (define_expand "zero_extendsidi2"
3449 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3450 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3455 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3460 (define_insn "*zero_extendsidi2_rex64"
3461 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3463 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3466 mov\t{%k1, %k0|%k0, %k1}
3468 movd\t{%1, %0|%0, %1}
3469 movd\t{%1, %0|%0, %1}
3470 %vmovd\t{%1, %0|%0, %1}
3471 %vmovd\t{%1, %0|%0, %1}"
3472 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3473 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3474 (set_attr "prefix_0f" "0,*,*,*,*,*")
3475 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3478 [(set (match_operand:DI 0 "memory_operand" "")
3479 (zero_extend:DI (match_dup 0)))]
3481 [(set (match_dup 4) (const_int 0))]
3482 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3484 ;; %%% Kill me once multi-word ops are sane.
3485 (define_insn "zero_extendsidi2_1"
3486 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3488 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3489 (clobber (reg:CC FLAGS_REG))]
3495 movd\t{%1, %0|%0, %1}
3496 movd\t{%1, %0|%0, %1}
3497 %vmovd\t{%1, %0|%0, %1}
3498 %vmovd\t{%1, %0|%0, %1}"
3499 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3500 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3501 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3502 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3505 [(set (match_operand:DI 0 "register_operand" "")
3506 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3507 (clobber (reg:CC FLAGS_REG))]
3508 "!TARGET_64BIT && reload_completed
3509 && true_regnum (operands[0]) == true_regnum (operands[1])"
3510 [(set (match_dup 4) (const_int 0))]
3511 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3514 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3515 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))]
3517 "!TARGET_64BIT && reload_completed
3518 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3519 [(set (match_dup 3) (match_dup 1))
3520 (set (match_dup 4) (const_int 0))]
3521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3523 (define_insn "zero_extend<mode>di2"
3524 [(set (match_operand:DI 0 "register_operand" "=r")
3526 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3528 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3529 [(set_attr "type" "imovx")
3530 (set_attr "mode" "SI")])
3532 (define_expand "zero_extendhisi2"
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3537 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3539 operands[1] = force_reg (HImode, operands[1]);
3540 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3545 (define_insn_and_split "zero_extendhisi2_and"
3546 [(set (match_operand:SI 0 "register_operand" "=r")
3547 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3548 (clobber (reg:CC FLAGS_REG))]
3549 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3551 "&& reload_completed"
3552 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3553 (clobber (reg:CC FLAGS_REG))])]
3555 [(set_attr "type" "alu1")
3556 (set_attr "mode" "SI")])
3558 (define_insn "*zero_extendhisi2_movzwl"
3559 [(set (match_operand:SI 0 "register_operand" "=r")
3560 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3561 "!TARGET_ZERO_EXTEND_WITH_AND
3562 || optimize_function_for_size_p (cfun)"
3563 "movz{wl|x}\t{%1, %0|%0, %1}"
3564 [(set_attr "type" "imovx")
3565 (set_attr "mode" "SI")])
3567 (define_expand "zero_extendqi<mode>2"
3569 [(set (match_operand:SWI24 0 "register_operand" "")
3570 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3571 (clobber (reg:CC FLAGS_REG))])])
3573 (define_insn "*zero_extendqi<mode>2_and"
3574 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3575 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3576 (clobber (reg:CC FLAGS_REG))]
3577 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "<MODE>")])
3582 ;; When source and destination does not overlap, clear destination
3583 ;; first and then do the movb
3585 [(set (match_operand:SWI24 0 "register_operand" "")
3586 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3587 (clobber (reg:CC FLAGS_REG))]
3589 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3590 && ANY_QI_REG_P (operands[0])
3591 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3592 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3593 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3595 operands[2] = gen_lowpart (QImode, operands[0]);
3596 ix86_expand_clear (operands[0]);
3599 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3600 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3601 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3602 (clobber (reg:CC FLAGS_REG))]
3603 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3605 [(set_attr "type" "imovx,alu1")
3606 (set_attr "mode" "<MODE>")])
3608 ;; For the movzbl case strip only the clobber
3610 [(set (match_operand:SWI24 0 "register_operand" "")
3611 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3614 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3615 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3617 (zero_extend:SWI24 (match_dup 1)))])
3619 ; zero extend to SImode to avoid partial register stalls
3620 (define_insn "*zero_extendqi<mode>2_movzbl"
3621 [(set (match_operand:SWI24 0 "register_operand" "=r")
3622 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3624 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3625 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3626 [(set_attr "type" "imovx")
3627 (set_attr "mode" "SI")])
3629 ;; Rest is handled by single and.
3631 [(set (match_operand:SWI24 0 "register_operand" "")
3632 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3633 (clobber (reg:CC FLAGS_REG))]
3635 && true_regnum (operands[0]) == true_regnum (operands[1])"
3636 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3637 (clobber (reg:CC FLAGS_REG))])])
3639 ;; Sign extension instructions
3641 (define_expand "extendsidi2"
3642 [(set (match_operand:DI 0 "register_operand" "")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3648 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3653 (define_insn "*extendsidi2_rex64"
3654 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3655 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3659 movs{lq|x}\t{%1, %0|%0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "DI")
3662 (set_attr "prefix_0f" "0")
3663 (set_attr "modrm" "0,1")])
3665 (define_insn "extendsidi2_1"
3666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3668 (clobber (reg:CC FLAGS_REG))
3669 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3673 ;; Extend to memory case when source register does die.
3675 [(set (match_operand:DI 0 "memory_operand" "")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand" ""))]
3680 && dead_or_set_p (insn, operands[1])
3681 && !reg_mentioned_p (operands[1], operands[0]))"
3682 [(set (match_dup 3) (match_dup 1))
3683 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3684 (clobber (reg:CC FLAGS_REG))])
3685 (set (match_dup 4) (match_dup 1))]
3686 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3688 ;; Extend to memory case when source register does not die.
3690 [(set (match_operand:DI 0 "memory_operand" "")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_operand:SI 2 "register_operand" ""))]
3697 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3699 emit_move_insn (operands[3], operands[1]);
3701 /* Generate a cltd if possible and doing so it profitable. */
3702 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3703 && true_regnum (operands[1]) == AX_REG
3704 && true_regnum (operands[2]) == DX_REG)
3706 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3710 emit_move_insn (operands[2], operands[1]);
3711 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3713 emit_move_insn (operands[4], operands[2]);
3717 ;; Extend to register case. Optimize case where source and destination
3718 ;; registers match and cases where we can use cltd.
3720 [(set (match_operand:DI 0 "register_operand" "")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722 (clobber (reg:CC FLAGS_REG))
3723 (clobber (match_scratch:SI 2 ""))]
3727 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3729 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3730 emit_move_insn (operands[3], operands[1]);
3732 /* Generate a cltd if possible and doing so it profitable. */
3733 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3734 && true_regnum (operands[3]) == AX_REG
3735 && true_regnum (operands[4]) == DX_REG)
3737 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3741 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3742 emit_move_insn (operands[4], operands[1]);
3744 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3748 (define_insn "extend<mode>di2"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3753 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3757 (define_insn "extendhisi2"
3758 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3759 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3762 switch (get_attr_prefix_0f (insn))
3765 return "{cwtl|cwde}";
3767 return "movs{wl|x}\t{%1, %0|%0, %1}";
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "SI")
3772 (set (attr "prefix_0f")
3773 ;; movsx is short decodable while cwtl is vector decoded.
3774 (if_then_else (and (eq_attr "cpu" "!k6")
3775 (eq_attr "alternative" "0"))
3777 (const_string "1")))
3779 (if_then_else (eq_attr "prefix_0f" "0")
3781 (const_string "1")))])
3783 (define_insn "*extendhisi2_zext"
3784 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3787 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3790 switch (get_attr_prefix_0f (insn))
3793 return "{cwtl|cwde}";
3795 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "SI")
3800 (set (attr "prefix_0f")
3801 ;; movsx is short decodable while cwtl is vector decoded.
3802 (if_then_else (and (eq_attr "cpu" "!k6")
3803 (eq_attr "alternative" "0"))
3805 (const_string "1")))
3807 (if_then_else (eq_attr "prefix_0f" "0")
3809 (const_string "1")))])
3811 (define_insn "extendqisi2"
3812 [(set (match_operand:SI 0 "register_operand" "=r")
3813 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3815 "movs{bl|x}\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")])
3819 (define_insn "*extendqisi2_zext"
3820 [(set (match_operand:DI 0 "register_operand" "=r")
3822 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3824 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3825 [(set_attr "type" "imovx")
3826 (set_attr "mode" "SI")])
3828 (define_insn "extendqihi2"
3829 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3830 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3833 switch (get_attr_prefix_0f (insn))
3836 return "{cbtw|cbw}";
3838 return "movs{bw|x}\t{%1, %0|%0, %1}";
3841 [(set_attr "type" "imovx")
3842 (set_attr "mode" "HI")
3843 (set (attr "prefix_0f")
3844 ;; movsx is short decodable while cwtl is vector decoded.
3845 (if_then_else (and (eq_attr "cpu" "!k6")
3846 (eq_attr "alternative" "0"))
3848 (const_string "1")))
3850 (if_then_else (eq_attr "prefix_0f" "0")
3852 (const_string "1")))])
3854 ;; Conversions between float and double.
3856 ;; These are all no-ops in the model used for the 80387.
3857 ;; So just emit moves.
3859 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3861 [(set (match_operand:DF 0 "push_operand" "")
3862 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3864 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3865 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3868 [(set (match_operand:XF 0 "push_operand" "")
3869 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3871 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3872 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3873 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3875 (define_expand "extendsfdf2"
3876 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3877 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3878 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3880 /* ??? Needed for compress_float_constant since all fp constants
3881 are TARGET_LEGITIMATE_CONSTANT_P. */
3882 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3884 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3885 && standard_80387_constant_p (operands[1]) > 0)
3887 operands[1] = simplify_const_unary_operation
3888 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3889 emit_move_insn_1 (operands[0], operands[1]);
3892 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3896 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3898 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3900 We do the conversion post reload to avoid producing of 128bit spills
3901 that might lead to ICE on 32bit target. The sequence unlikely combine
3904 [(set (match_operand:DF 0 "register_operand" "")
3906 (match_operand:SF 1 "nonimmediate_operand" "")))]
3907 "TARGET_USE_VECTOR_FP_CONVERTS
3908 && optimize_insn_for_speed_p ()
3909 && reload_completed && SSE_REG_P (operands[0])"
3914 (parallel [(const_int 0) (const_int 1)]))))]
3916 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3917 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3918 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3919 Try to avoid move when unpacking can be done in source. */
3920 if (REG_P (operands[1]))
3922 /* If it is unsafe to overwrite upper half of source, we need
3923 to move to destination and unpack there. */
3924 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3925 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3926 && true_regnum (operands[0]) != true_regnum (operands[1]))
3928 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3929 emit_move_insn (tmp, operands[1]);
3932 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3933 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3937 emit_insn (gen_vec_setv4sf_0 (operands[3],
3938 CONST0_RTX (V4SFmode), operands[1]));
3941 (define_insn "*extendsfdf2_mixed"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3944 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3945 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3947 switch (which_alternative)
3951 return output_387_reg_move (insn, operands);
3954 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3960 [(set_attr "type" "fmov,fmov,ssecvt")
3961 (set_attr "prefix" "orig,orig,maybe_vex")
3962 (set_attr "mode" "SF,XF,DF")])
3964 (define_insn "*extendsfdf2_sse"
3965 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3966 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3967 "TARGET_SSE2 && TARGET_SSE_MATH"
3968 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3969 [(set_attr "type" "ssecvt")
3970 (set_attr "prefix" "maybe_vex")
3971 (set_attr "mode" "DF")])
3973 (define_insn "*extendsfdf2_i387"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3975 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3977 "* return output_387_reg_move (insn, operands);"
3978 [(set_attr "type" "fmov")
3979 (set_attr "mode" "SF,XF")])
3981 (define_expand "extend<mode>xf2"
3982 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3983 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3986 /* ??? Needed for compress_float_constant since all fp constants
3987 are TARGET_LEGITIMATE_CONSTANT_P. */
3988 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3990 if (standard_80387_constant_p (operands[1]) > 0)
3992 operands[1] = simplify_const_unary_operation
3993 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3994 emit_move_insn_1 (operands[0], operands[1]);
3997 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4001 (define_insn "*extend<mode>xf2_i387"
4002 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4004 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4006 "* return output_387_reg_move (insn, operands);"
4007 [(set_attr "type" "fmov")
4008 (set_attr "mode" "<MODE>,XF")])
4010 ;; %%% This seems bad bad news.
4011 ;; This cannot output into an f-reg because there is no way to be sure
4012 ;; of truncating in that case. Otherwise this is just like a simple move
4013 ;; insn. So we pretend we can output to a reg in order to get better
4014 ;; register preferencing, but we really use a stack slot.
4016 ;; Conversion from DFmode to SFmode.
4018 (define_expand "truncdfsf2"
4019 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4021 (match_operand:DF 1 "nonimmediate_operand" "")))]
4022 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4024 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4026 else if (flag_unsafe_math_optimizations)
4030 enum ix86_stack_slot slot = (virtuals_instantiated
4033 rtx temp = assign_386_stack_local (SFmode, slot);
4034 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4039 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4041 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4043 We do the conversion post reload to avoid producing of 128bit spills
4044 that might lead to ICE on 32bit target. The sequence unlikely combine
4047 [(set (match_operand:SF 0 "register_operand" "")
4049 (match_operand:DF 1 "nonimmediate_operand" "")))]
4050 "TARGET_USE_VECTOR_FP_CONVERTS
4051 && optimize_insn_for_speed_p ()
4052 && reload_completed && SSE_REG_P (operands[0])"
4055 (float_truncate:V2SF
4059 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4060 operands[3] = CONST0_RTX (V2SFmode);
4061 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4062 /* Use movsd for loading from memory, unpcklpd for registers.
4063 Try to avoid move when unpacking can be done in source, or SSE3
4064 movddup is available. */
4065 if (REG_P (operands[1]))
4068 && true_regnum (operands[0]) != true_regnum (operands[1])
4069 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4070 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4072 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4073 emit_move_insn (tmp, operands[1]);
4076 else if (!TARGET_SSE3)
4077 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4078 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4081 emit_insn (gen_sse2_loadlpd (operands[4],
4082 CONST0_RTX (V2DFmode), operands[1]));
4085 (define_expand "truncdfsf2_with_temp"
4086 [(parallel [(set (match_operand:SF 0 "" "")
4087 (float_truncate:SF (match_operand:DF 1 "" "")))
4088 (clobber (match_operand:SF 2 "" ""))])])
4090 (define_insn "*truncdfsf_fast_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4093 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4094 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4096 switch (which_alternative)
4099 return output_387_reg_move (insn, operands);
4101 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4106 [(set_attr "type" "fmov,ssecvt")
4107 (set_attr "prefix" "orig,maybe_vex")
4108 (set_attr "mode" "SF")])
4110 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4111 ;; because nothing we do here is unsafe.
4112 (define_insn "*truncdfsf_fast_sse"
4113 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4115 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4116 "TARGET_SSE2 && TARGET_SSE_MATH"
4117 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4118 [(set_attr "type" "ssecvt")
4119 (set_attr "prefix" "maybe_vex")
4120 (set_attr "mode" "SF")])
4122 (define_insn "*truncdfsf_fast_i387"
4123 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4125 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4126 "TARGET_80387 && flag_unsafe_math_optimizations"
4127 "* return output_387_reg_move (insn, operands);"
4128 [(set_attr "type" "fmov")
4129 (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf_mixed"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4135 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4136 "TARGET_MIX_SSE_I387"
4138 switch (which_alternative)
4141 return output_387_reg_move (insn, operands);
4143 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4149 [(set_attr "isa" "*,sse2,*,*,*")
4150 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4151 (set_attr "unit" "*,*,i387,i387,i387")
4152 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4153 (set_attr "mode" "SF")])
4155 (define_insn "*truncdfsf_i387"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4162 switch (which_alternative)
4165 return output_387_reg_move (insn, operands);
4171 [(set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf2_i387_1"
4176 [(set (match_operand:SF 0 "memory_operand" "=m")
4178 (match_operand:DF 1 "register_operand" "f")))]
4180 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4181 && !TARGET_MIX_SSE_I387"
4182 "* return output_387_reg_move (insn, operands);"
4183 [(set_attr "type" "fmov")
4184 (set_attr "mode" "SF")])
4187 [(set (match_operand:SF 0 "register_operand" "")
4189 (match_operand:DF 1 "fp_register_operand" "")))
4190 (clobber (match_operand 2 "" ""))]
4192 [(set (match_dup 2) (match_dup 1))
4193 (set (match_dup 0) (match_dup 2))]
4194 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4196 ;; Conversion from XFmode to {SF,DF}mode
4198 (define_expand "truncxf<mode>2"
4199 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4200 (float_truncate:MODEF
4201 (match_operand:XF 1 "register_operand" "")))
4202 (clobber (match_dup 2))])]
4205 if (flag_unsafe_math_optimizations)
4207 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4208 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4209 if (reg != operands[0])
4210 emit_move_insn (operands[0], reg);
4215 enum ix86_stack_slot slot = (virtuals_instantiated
4218 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4222 (define_insn "*truncxfsf2_mixed"
4223 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4225 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4226 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4229 gcc_assert (!which_alternative);
4230 return output_387_reg_move (insn, operands);
4232 [(set_attr "type" "fmov,multi,multi,multi")
4233 (set_attr "unit" "*,i387,i387,i387")
4234 (set_attr "mode" "SF")])
4236 (define_insn "*truncxfdf2_mixed"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4246 [(set_attr "isa" "*,*,sse2,*")
4247 (set_attr "type" "fmov,multi,multi,multi")
4248 (set_attr "unit" "*,i387,i387,i387")
4249 (set_attr "mode" "DF")])
4251 (define_insn "truncxf<mode>2_i387_noop"
4252 [(set (match_operand:MODEF 0 "register_operand" "=f")
4253 (float_truncate:MODEF
4254 (match_operand:XF 1 "register_operand" "f")))]
4255 "TARGET_80387 && flag_unsafe_math_optimizations"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "<MODE>")])
4260 (define_insn "*truncxf<mode>2_i387"
4261 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4262 (float_truncate:MODEF
4263 (match_operand:XF 1 "register_operand" "f")))]
4265 "* return output_387_reg_move (insn, operands);"
4266 [(set_attr "type" "fmov")
4267 (set_attr "mode" "<MODE>")])
4270 [(set (match_operand:MODEF 0 "register_operand" "")
4271 (float_truncate:MODEF
4272 (match_operand:XF 1 "register_operand" "")))
4273 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4274 "TARGET_80387 && reload_completed"
4275 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4276 (set (match_dup 0) (match_dup 2))])
4279 [(set (match_operand:MODEF 0 "memory_operand" "")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand" "")))
4282 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4284 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4286 ;; Signed conversion to DImode.
4288 (define_expand "fix_truncxfdi2"
4289 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4290 (fix:DI (match_operand:XF 1 "register_operand" "")))
4291 (clobber (reg:CC FLAGS_REG))])]
4296 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4301 (define_expand "fix_trunc<mode>di2"
4302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4303 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4304 (clobber (reg:CC FLAGS_REG))])]
4305 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4308 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4313 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4315 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4316 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4317 if (out != operands[0])
4318 emit_move_insn (operands[0], out);
4323 ;; Signed conversion to SImode.
4325 (define_expand "fix_truncxfsi2"
4326 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4327 (fix:SI (match_operand:XF 1 "register_operand" "")))
4328 (clobber (reg:CC FLAGS_REG))])]
4333 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4338 (define_expand "fix_trunc<mode>si2"
4339 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4340 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4341 (clobber (reg:CC FLAGS_REG))])]
4342 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4350 if (SSE_FLOAT_MODE_P (<MODE>mode))
4352 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4353 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4354 if (out != operands[0])
4355 emit_move_insn (operands[0], out);
4360 ;; Signed conversion to HImode.
4362 (define_expand "fix_trunc<mode>hi2"
4363 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4364 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4365 (clobber (reg:CC FLAGS_REG))])]
4367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4371 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4376 ;; Unsigned conversion to SImode.
4378 (define_expand "fixuns_trunc<mode>si2"
4380 [(set (match_operand:SI 0 "register_operand" "")
4382 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384 (clobber (match_scratch:<ssevecmode> 3 ""))
4385 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4388 enum machine_mode mode = <MODE>mode;
4389 enum machine_mode vecmode = <ssevecmode>mode;
4390 REAL_VALUE_TYPE TWO31r;
4393 if (optimize_insn_for_size_p ())
4396 real_ldexp (&TWO31r, &dconst1, 31);
4397 two31 = const_double_from_real_value (TWO31r, mode);
4398 two31 = ix86_build_const_vector (vecmode, true, two31);
4399 operands[2] = force_reg (vecmode, two31);
4402 (define_insn_and_split "*fixuns_trunc<mode>_1"
4403 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4405 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4406 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4407 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4408 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4409 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4410 && optimize_function_for_speed_p (cfun)"
4412 "&& reload_completed"
4415 ix86_split_convert_uns_si_sse (operands);
4419 ;; Unsigned conversion to HImode.
4420 ;; Without these patterns, we'll try the unsigned SI conversion which
4421 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4423 (define_expand "fixuns_trunc<mode>hi2"
4425 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4426 (set (match_operand:HI 0 "nonimmediate_operand" "")
4427 (subreg:HI (match_dup 2) 0))]
4428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4429 "operands[2] = gen_reg_rtx (SImode);")
4431 ;; When SSE is available, it is always faster to use it!
4432 (define_insn "fix_trunc<mode>di_sse"
4433 [(set (match_operand:DI 0 "register_operand" "=r,r")
4434 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4435 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4436 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4437 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4438 [(set_attr "type" "sseicvt")
4439 (set_attr "prefix" "maybe_vex")
4440 (set_attr "prefix_rex" "1")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "athlon_decode" "double,vector")
4443 (set_attr "amdfam10_decode" "double,double")
4444 (set_attr "bdver1_decode" "double,double")])
4446 (define_insn "fix_trunc<mode>si_sse"
4447 [(set (match_operand:SI 0 "register_operand" "=r,r")
4448 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "mode" "<MODE>")
4455 (set_attr "athlon_decode" "double,vector")
4456 (set_attr "amdfam10_decode" "double,double")
4457 (set_attr "bdver1_decode" "double,double")])
4459 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4461 [(set (match_operand:MODEF 0 "register_operand" "")
4462 (match_operand:MODEF 1 "memory_operand" ""))
4463 (set (match_operand:SWI48x 2 "register_operand" "")
4464 (fix:SWI48x (match_dup 0)))]
4465 "TARGET_SHORTEN_X87_SSE
4466 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4467 && peep2_reg_dead_p (2, operands[0])"
4468 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4470 ;; Avoid vector decoded forms of the instruction.
4472 [(match_scratch:DF 2 "x")
4473 (set (match_operand:SWI48x 0 "register_operand" "")
4474 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4475 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4480 [(match_scratch:SF 2 "x")
4481 (set (match_operand:SWI48x 0 "register_operand" "")
4482 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4483 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4484 [(set (match_dup 2) (match_dup 1))
4485 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4487 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4489 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4495 && can_create_pseudo_p ()"
4500 if (memory_operand (operands[0], VOIDmode))
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4504 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4505 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp"
4515 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4516 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4517 (clobber (match_scratch:XF 2 "=&1f"))]
4518 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4520 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && (TARGET_64BIT || <MODE>mode != DImode))
4522 && TARGET_SSE_MATH)"
4523 "* return output_fix_trunc (insn, operands, true);"
4524 [(set_attr "type" "fisttp")
4525 (set_attr "mode" "<MODE>")])
4527 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4528 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4529 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4530 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && (TARGET_64BIT || <MODE>mode != DImode))
4536 && TARGET_SSE_MATH)"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4542 [(set (match_operand:SWI248x 0 "register_operand" "")
4543 (fix:SWI248x (match_operand 1 "register_operand" "")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4545 (clobber (match_scratch 3 ""))]
4547 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4548 (clobber (match_dup 3))])
4549 (set (match_dup 0) (match_dup 2))])
4552 [(set (match_operand:SWI248x 0 "memory_operand" "")
4553 (fix:SWI248x (match_operand 1 "register_operand" "")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4555 (clobber (match_scratch 3 ""))]
4557 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4558 (clobber (match_dup 3))])])
4560 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4561 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4562 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4563 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4564 ;; function in i386.c.
4565 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4566 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4567 (fix:SWI248x (match_operand 1 "register_operand" "")))
4568 (clobber (reg:CC FLAGS_REG))]
4569 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4571 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4572 && (TARGET_64BIT || <MODE>mode != DImode))
4573 && can_create_pseudo_p ()"
4578 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4584 operands[2], operands[3]));
4587 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4588 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4589 operands[2], operands[3],
4594 [(set_attr "type" "fistp")
4595 (set_attr "i387_cw" "trunc")
4596 (set_attr "mode" "<MODE>")])
4598 (define_insn "fix_truncdi_i387"
4599 [(set (match_operand:DI 0 "memory_operand" "=m")
4600 (fix:DI (match_operand 1 "register_operand" "f")))
4601 (use (match_operand:HI 2 "memory_operand" "m"))
4602 (use (match_operand:HI 3 "memory_operand" "m"))
4603 (clobber (match_scratch:XF 4 "=&1f"))]
4604 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4607 "* return output_fix_trunc (insn, operands, false);"
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "DI")])
4612 (define_insn "fix_truncdi_i387_with_temp"
4613 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4614 (fix:DI (match_operand 1 "register_operand" "f,f")))
4615 (use (match_operand:HI 2 "memory_operand" "m,m"))
4616 (use (match_operand:HI 3 "memory_operand" "m,m"))
4617 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4618 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4619 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4623 [(set_attr "type" "fistp")
4624 (set_attr "i387_cw" "trunc")
4625 (set_attr "mode" "DI")])
4628 [(set (match_operand:DI 0 "register_operand" "")
4629 (fix:DI (match_operand 1 "register_operand" "")))
4630 (use (match_operand:HI 2 "memory_operand" ""))
4631 (use (match_operand:HI 3 "memory_operand" ""))
4632 (clobber (match_operand:DI 4 "memory_operand" ""))
4633 (clobber (match_scratch 5 ""))]
4635 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4638 (clobber (match_dup 5))])
4639 (set (match_dup 0) (match_dup 4))])
4642 [(set (match_operand:DI 0 "memory_operand" "")
4643 (fix:DI (match_operand 1 "register_operand" "")))
4644 (use (match_operand:HI 2 "memory_operand" ""))
4645 (use (match_operand:HI 3 "memory_operand" ""))
4646 (clobber (match_operand:DI 4 "memory_operand" ""))
4647 (clobber (match_scratch 5 ""))]
4649 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4652 (clobber (match_dup 5))])])
4654 (define_insn "fix_trunc<mode>_i387"
4655 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4656 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4657 (use (match_operand:HI 2 "memory_operand" "m"))
4658 (use (match_operand:HI 3 "memory_operand" "m"))]
4659 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4661 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4662 "* return output_fix_trunc (insn, operands, false);"
4663 [(set_attr "type" "fistp")
4664 (set_attr "i387_cw" "trunc")
4665 (set_attr "mode" "<MODE>")])
4667 (define_insn "fix_trunc<mode>_i387_with_temp"
4668 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4669 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4670 (use (match_operand:HI 2 "memory_operand" "m,m"))
4671 (use (match_operand:HI 3 "memory_operand" "m,m"))
4672 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4682 [(set (match_operand:SWI24 0 "register_operand" "")
4683 (fix:SWI24 (match_operand 1 "register_operand" "")))
4684 (use (match_operand:HI 2 "memory_operand" ""))
4685 (use (match_operand:HI 3 "memory_operand" ""))
4686 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4688 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4690 (use (match_dup 3))])
4691 (set (match_dup 0) (match_dup 4))])
4694 [(set (match_operand:SWI24 0 "memory_operand" "")
4695 (fix:SWI24 (match_operand 1 "register_operand" "")))
4696 (use (match_operand:HI 2 "memory_operand" ""))
4697 (use (match_operand:HI 3 "memory_operand" ""))
4698 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4700 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4702 (use (match_dup 3))])])
4704 (define_insn "x86_fnstcw_1"
4705 [(set (match_operand:HI 0 "memory_operand" "=m")
4706 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4709 [(set (attr "length")
4710 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4711 (set_attr "mode" "HI")
4712 (set_attr "unit" "i387")
4713 (set_attr "bdver1_decode" "vector")])
4715 (define_insn "x86_fldcw_1"
4716 [(set (reg:HI FPCR_REG)
4717 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4720 [(set (attr "length")
4721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722 (set_attr "mode" "HI")
4723 (set_attr "unit" "i387")
4724 (set_attr "athlon_decode" "vector")
4725 (set_attr "amdfam10_decode" "vector")
4726 (set_attr "bdver1_decode" "vector")])
4728 ;; Conversion between fixed point and floating point.
4730 ;; Even though we only accept memory inputs, the backend _really_
4731 ;; wants to be able to do this between registers.
4733 (define_expand "floathi<mode>2"
4734 [(set (match_operand:X87MODEF 0 "register_operand" "")
4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)")
4740 ;; Pre-reload splitter to add memory clobber to the pattern.
4741 (define_insn_and_split "*floathi<mode>2_1"
4742 [(set (match_operand:X87MODEF 0 "register_operand" "")
4743 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4746 || TARGET_MIX_SSE_I387)
4747 && can_create_pseudo_p ()"
4750 [(parallel [(set (match_dup 0)
4751 (float:X87MODEF (match_dup 1)))
4752 (clobber (match_dup 2))])]
4753 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4755 (define_insn "*floathi<mode>2_i387_with_temp"
4756 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4757 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4758 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387)"
4763 [(set_attr "type" "fmov,multi")
4764 (set_attr "mode" "<MODE>")
4765 (set_attr "unit" "*,i387")
4766 (set_attr "fp_int_src" "true")])
4768 (define_insn "*floathi<mode>2_i387"
4769 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773 || TARGET_MIX_SSE_I387)"
4775 [(set_attr "type" "fmov")
4776 (set_attr "mode" "<MODE>")
4777 (set_attr "fp_int_src" "true")])
4780 [(set (match_operand:X87MODEF 0 "register_operand" "")
4781 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4782 (clobber (match_operand:HI 2 "memory_operand" ""))]
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)
4786 && reload_completed"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4791 [(set (match_operand:X87MODEF 0 "register_operand" "")
4792 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4793 (clobber (match_operand:HI 2 "memory_operand" ""))]
4795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796 || TARGET_MIX_SSE_I387)
4797 && reload_completed"
4798 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4800 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4801 [(set (match_operand:X87MODEF 0 "register_operand" "")
4803 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4805 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4806 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4808 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4809 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4810 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4812 rtx reg = gen_reg_rtx (XFmode);
4813 rtx (*insn)(rtx, rtx);
4815 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4817 if (<X87MODEF:MODE>mode == SFmode)
4818 insn = gen_truncxfsf2;
4819 else if (<X87MODEF:MODE>mode == DFmode)
4820 insn = gen_truncxfdf2;
4824 emit_insn (insn (operands[0], reg));
4829 ;; Pre-reload splitter to add memory clobber to the pattern.
4830 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4831 [(set (match_operand:X87MODEF 0 "register_operand" "")
4832 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4834 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4835 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4837 || TARGET_MIX_SSE_I387))
4838 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4839 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4840 && ((<SWI48x:MODE>mode == SImode
4841 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4842 && optimize_function_for_speed_p (cfun)
4843 && flag_trapping_math)
4844 || !(TARGET_INTER_UNIT_CONVERSIONS
4845 || optimize_function_for_size_p (cfun)))))
4846 && can_create_pseudo_p ()"
4849 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4850 (clobber (match_dup 2))])]
4852 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4854 /* Avoid store forwarding (partial memory) stall penalty
4855 by passing DImode value through XMM registers. */
4856 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4857 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4858 && optimize_function_for_speed_p (cfun))
4860 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4867 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4868 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4870 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4871 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4872 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4873 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4875 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4876 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4877 (set_attr "unit" "*,i387,*,*,*")
4878 (set_attr "athlon_decode" "*,*,double,direct,double")
4879 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4880 (set_attr "bdver1_decode" "*,*,double,direct,double")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*floatsi<mode>2_vector_mixed"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "mode" "<MODE>,<ssevecmode>")
4893 (set_attr "unit" "i387,*")
4894 (set_attr "athlon_decode" "*,direct")
4895 (set_attr "amdfam10_decode" "*,double")
4896 (set_attr "bdver1_decode" "*,direct")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4900 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4902 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4903 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4904 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4907 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4908 (set_attr "mode" "<MODEF:MODE>")
4909 (set_attr "unit" "*,i387,*,*")
4910 (set_attr "athlon_decode" "*,*,double,direct")
4911 (set_attr "amdfam10_decode" "*,*,vector,double")
4912 (set_attr "bdver1_decode" "*,*,double,direct")
4913 (set_attr "fp_int_src" "true")])
4916 [(set (match_operand:MODEF 0 "register_operand" "")
4917 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4918 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4919 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4920 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4921 && TARGET_INTER_UNIT_CONVERSIONS
4923 && (SSE_REG_P (operands[0])
4924 || (GET_CODE (operands[0]) == SUBREG
4925 && SSE_REG_P (operands[0])))"
4926 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4929 [(set (match_operand:MODEF 0 "register_operand" "")
4930 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4931 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4932 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4933 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4934 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4936 && (SSE_REG_P (operands[0])
4937 || (GET_CODE (operands[0]) == SUBREG
4938 && SSE_REG_P (operands[0])))"
4939 [(set (match_dup 2) (match_dup 1))
4940 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4942 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4943 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4945 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4946 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4947 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4948 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4951 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4952 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4953 [(set_attr "type" "fmov,sseicvt,sseicvt")
4954 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4955 (set_attr "mode" "<MODEF:MODE>")
4956 (set (attr "prefix_rex")
4958 (and (eq_attr "prefix" "maybe_vex")
4959 (match_test "<SWI48x:MODE>mode == DImode"))
4961 (const_string "*")))
4962 (set_attr "unit" "i387,*,*")
4963 (set_attr "athlon_decode" "*,double,direct")
4964 (set_attr "amdfam10_decode" "*,vector,double")
4965 (set_attr "bdver1_decode" "*,double,direct")
4966 (set_attr "fp_int_src" "true")])
4968 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4969 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4971 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4972 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4973 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4974 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4977 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4978 [(set_attr "type" "fmov,sseicvt")
4979 (set_attr "prefix" "orig,maybe_vex")
4980 (set_attr "mode" "<MODEF:MODE>")
4981 (set (attr "prefix_rex")
4983 (and (eq_attr "prefix" "maybe_vex")
4984 (match_test "<SWI48x:MODE>mode == DImode"))
4986 (const_string "*")))
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "bdver1_decode" "*,direct")
4990 (set_attr "fp_int_src" "true")])
4992 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4993 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4995 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4996 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000 [(set_attr "type" "sseicvt")
5001 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5002 (set_attr "athlon_decode" "double,direct,double")
5003 (set_attr "amdfam10_decode" "vector,double,double")
5004 (set_attr "bdver1_decode" "double,direct,double")
5005 (set_attr "fp_int_src" "true")])
5007 (define_insn "*floatsi<mode>2_vector_sse"
5008 [(set (match_operand:MODEF 0 "register_operand" "=x")
5009 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5013 [(set_attr "type" "sseicvt")
5014 (set_attr "mode" "<MODE>")
5015 (set_attr "athlon_decode" "direct")
5016 (set_attr "amdfam10_decode" "double")
5017 (set_attr "bdver1_decode" "direct")
5018 (set_attr "fp_int_src" "true")])
5021 [(set (match_operand:MODEF 0 "register_operand" "")
5022 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5023 (clobber (match_operand:SI 2 "memory_operand" ""))]
5024 "TARGET_SSE2 && TARGET_SSE_MATH
5025 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5027 && (SSE_REG_P (operands[0])
5028 || (GET_CODE (operands[0]) == SUBREG
5029 && SSE_REG_P (operands[0])))"
5032 rtx op1 = operands[1];
5034 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5036 if (GET_CODE (op1) == SUBREG)
5037 op1 = SUBREG_REG (op1);
5039 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5041 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5042 emit_insn (gen_sse2_loadld (operands[4],
5043 CONST0_RTX (V4SImode), operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5052 emit_move_insn (operands[2], operands[1]);
5053 emit_insn (gen_sse2_loadld (operands[4],
5054 CONST0_RTX (V4SImode), operands[2]));
5056 if (<ssevecmode>mode == V4SImode)
5057 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5059 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5064 [(set (match_operand:MODEF 0 "register_operand" "")
5065 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5066 (clobber (match_operand:SI 2 "memory_operand" ""))]
5067 "TARGET_SSE2 && TARGET_SSE_MATH
5068 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5070 && (SSE_REG_P (operands[0])
5071 || (GET_CODE (operands[0]) == SUBREG
5072 && SSE_REG_P (operands[0])))"
5075 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5077 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5079 emit_insn (gen_sse2_loadld (operands[4],
5080 CONST0_RTX (V4SImode), operands[1]));
5081 if (<ssevecmode>mode == V4SFmode)
5082 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5084 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5089 [(set (match_operand:MODEF 0 "register_operand" "")
5090 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5094 && (SSE_REG_P (operands[0])
5095 || (GET_CODE (operands[0]) == SUBREG
5096 && SSE_REG_P (operands[0])))"
5099 rtx op1 = operands[1];
5101 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5103 if (GET_CODE (op1) == SUBREG)
5104 op1 = SUBREG_REG (op1);
5106 if (GENERAL_REG_P (op1))
5108 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5109 if (TARGET_INTER_UNIT_MOVES)
5110 emit_insn (gen_sse2_loadld (operands[4],
5111 CONST0_RTX (V4SImode), operands[1]));
5114 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5116 emit_insn (gen_sse2_loadld (operands[4],
5117 CONST0_RTX (V4SImode), operands[5]));
5118 ix86_free_from_memory (GET_MODE (operands[1]));
5121 /* We can ignore possible trapping value in the
5122 high part of SSE register for non-trapping math. */
5123 else if (SSE_REG_P (op1) && !flag_trapping_math)
5124 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5127 if (<ssevecmode>mode == V4SFmode)
5128 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5130 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5135 [(set (match_operand:MODEF 0 "register_operand" "")
5136 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5140 && (SSE_REG_P (operands[0])
5141 || (GET_CODE (operands[0]) == SUBREG
5142 && SSE_REG_P (operands[0])))"
5145 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5149 emit_insn (gen_sse2_loadld (operands[4],
5150 CONST0_RTX (V4SImode), operands[1]));
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5158 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5159 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5161 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5166 [(set_attr "type" "sseicvt")
5167 (set_attr "mode" "<MODEF:MODE>")
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5173 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5174 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5176 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5180 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5181 [(set_attr "type" "sseicvt")
5182 (set_attr "prefix" "maybe_vex")
5183 (set_attr "mode" "<MODEF:MODE>")
5184 (set (attr "prefix_rex")
5186 (and (eq_attr "prefix" "maybe_vex")
5187 (match_test "<SWI48x:MODE>mode == DImode"))
5189 (const_string "*")))
5190 (set_attr "athlon_decode" "double,direct")
5191 (set_attr "amdfam10_decode" "vector,double")
5192 (set_attr "bdver1_decode" "double,direct")
5193 (set_attr "fp_int_src" "true")])
5196 [(set (match_operand:MODEF 0 "register_operand" "")
5197 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5198 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
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))
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (operands[0])))"
5206 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5208 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5209 [(set (match_operand:MODEF 0 "register_operand" "=x")
5211 (match_operand:SWI48x 1 "memory_operand" "m")))]
5212 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5215 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5216 [(set_attr "type" "sseicvt")
5217 (set_attr "prefix" "maybe_vex")
5218 (set_attr "mode" "<MODEF:MODE>")
5219 (set (attr "prefix_rex")
5221 (and (eq_attr "prefix" "maybe_vex")
5222 (match_test "<SWI48x:MODE>mode == DImode"))
5224 (const_string "*")))
5225 (set_attr "athlon_decode" "direct")
5226 (set_attr "amdfam10_decode" "double")
5227 (set_attr "bdver1_decode" "direct")
5228 (set_attr "fp_int_src" "true")])
5231 [(set (match_operand:MODEF 0 "register_operand" "")
5232 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5233 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5234 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5238 && (SSE_REG_P (operands[0])
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && SSE_REG_P (operands[0])))"
5241 [(set (match_dup 2) (match_dup 1))
5242 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5245 [(set (match_operand:MODEF 0 "register_operand" "")
5246 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5247 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5248 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5249 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5251 && (SSE_REG_P (operands[0])
5252 || (GET_CODE (operands[0]) == SUBREG
5253 && SSE_REG_P (operands[0])))"
5254 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5256 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5257 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5259 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5260 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5262 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5266 [(set_attr "type" "fmov,multi")
5267 (set_attr "mode" "<X87MODEF:MODE>")
5268 (set_attr "unit" "*,i387")
5269 (set_attr "fp_int_src" "true")])
5271 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5274 (match_operand:SWI48x 1 "memory_operand" "m")))]
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5278 [(set_attr "type" "fmov")
5279 (set_attr "mode" "<X87MODEF:MODE>")
5280 (set_attr "fp_int_src" "true")])
5283 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5284 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5285 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5287 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5288 && reload_completed"
5289 [(set (match_dup 2) (match_dup 1))
5290 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5293 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5294 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5295 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5297 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5298 && reload_completed"
5299 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301 ;; Avoid store forwarding (partial memory) stall penalty
5302 ;; by passing DImode value through XMM registers. */
5304 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5307 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5308 (clobber (match_scratch:V4SI 3 "=X,x"))
5309 (clobber (match_scratch:V4SI 4 "=X,x"))
5310 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5311 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5313 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5315 [(set_attr "type" "multi")
5316 (set_attr "mode" "<X87MODEF:MODE>")
5317 (set_attr "unit" "i387")
5318 (set_attr "fp_int_src" "true")])
5321 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5322 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5323 (clobber (match_scratch:V4SI 3 ""))
5324 (clobber (match_scratch:V4SI 4 ""))
5325 (clobber (match_operand:DI 2 "memory_operand" ""))]
5326 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5328 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5329 && reload_completed"
5330 [(set (match_dup 2) (match_dup 3))
5331 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5334 Assemble the 64-bit DImode value in an xmm register. */
5335 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 0)));
5337 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5338 gen_rtx_SUBREG (SImode, operands[1], 4)));
5339 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5342 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5346 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5347 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5348 (clobber (match_scratch:V4SI 3 ""))
5349 (clobber (match_scratch:V4SI 4 ""))
5350 (clobber (match_operand:DI 2 "memory_operand" ""))]
5351 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5354 && reload_completed"
5355 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5357 ;; Avoid store forwarding (partial memory) stall penalty by extending
5358 ;; SImode value to DImode through XMM register instead of pushing two
5359 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5360 ;; targets benefit from this optimization. Also note that fild
5361 ;; loads from memory only.
5363 (define_insn "*floatunssi<mode>2_1"
5364 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5365 (unsigned_float:X87MODEF
5366 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5367 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5368 (clobber (match_scratch:SI 3 "=X,x"))]
5370 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5373 [(set_attr "type" "multi")
5374 (set_attr "mode" "<MODE>")])
5377 [(set (match_operand:X87MODEF 0 "register_operand" "")
5378 (unsigned_float:X87MODEF
5379 (match_operand:SI 1 "register_operand" "")))
5380 (clobber (match_operand:DI 2 "memory_operand" ""))
5381 (clobber (match_scratch:SI 3 ""))]
5383 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5385 && reload_completed"
5386 [(set (match_dup 2) (match_dup 1))
5388 (float:X87MODEF (match_dup 2)))]
5389 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5392 [(set (match_operand:X87MODEF 0 "register_operand" "")
5393 (unsigned_float:X87MODEF
5394 (match_operand:SI 1 "memory_operand" "")))
5395 (clobber (match_operand:DI 2 "memory_operand" ""))
5396 (clobber (match_scratch:SI 3 ""))]
5398 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && reload_completed"
5401 [(set (match_dup 2) (match_dup 3))
5403 (float:X87MODEF (match_dup 2)))]
5405 emit_move_insn (operands[3], operands[1]);
5406 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5409 (define_expand "floatunssi<mode>2"
5411 [(set (match_operand:X87MODEF 0 "register_operand" "")
5412 (unsigned_float:X87MODEF
5413 (match_operand:SI 1 "nonimmediate_operand" "")))
5414 (clobber (match_dup 2))
5415 (clobber (match_scratch:SI 3 ""))])]
5417 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5423 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5428 enum ix86_stack_slot slot = (virtuals_instantiated
5431 operands[2] = assign_386_stack_local (DImode, slot);
5435 (define_expand "floatunsdisf2"
5436 [(use (match_operand:SF 0 "register_operand" ""))
5437 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5438 "TARGET_64BIT && TARGET_SSE_MATH"
5439 "x86_emit_floatuns (operands); DONE;")
5441 (define_expand "floatunsdidf2"
5442 [(use (match_operand:DF 0 "register_operand" ""))
5443 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5444 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5445 && TARGET_SSE2 && TARGET_SSE_MATH"
5448 x86_emit_floatuns (operands);
5450 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5456 (define_expand "add<mode>3"
5457 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5458 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5459 (match_operand:SDWIM 2 "<general_operand>" "")))]
5461 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5463 (define_insn_and_split "*add<dwi>3_doubleword"
5464 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5466 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5467 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5472 [(parallel [(set (reg:CC FLAGS_REG)
5473 (unspec:CC [(match_dup 1) (match_dup 2)]
5476 (plus:DWIH (match_dup 1) (match_dup 2)))])
5477 (parallel [(set (match_dup 3)
5481 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5483 (clobber (reg:CC FLAGS_REG))])]
5484 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5486 (define_insn "*add<mode>3_cc"
5487 [(set (reg:CC FLAGS_REG)
5489 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5490 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5492 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5493 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5494 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5495 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "mode" "<MODE>")])
5499 (define_insn "addqi3_cc"
5500 [(set (reg:CC FLAGS_REG)
5502 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5503 (match_operand:QI 2 "general_operand" "qn,qm")]
5505 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5506 (plus:QI (match_dup 1) (match_dup 2)))]
5507 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5508 "add{b}\t{%2, %0|%0, %2}"
5509 [(set_attr "type" "alu")
5510 (set_attr "mode" "QI")])
5512 (define_insn_and_split "*lea_1"
5513 [(set (match_operand:SI 0 "register_operand" "=r")
5514 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5516 "lea{l}\t{%a1, %0|%0, %a1}"
5517 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5520 ix86_split_lea_for_addr (operands, SImode);
5523 [(set_attr "type" "lea")
5524 (set_attr "mode" "SI")])
5526 (define_insn_and_split "*lea<mode>_2"
5527 [(set (match_operand:SWI48 0 "register_operand" "=r")
5528 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5530 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5531 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5534 ix86_split_lea_for_addr (operands, <MODE>mode);
5537 [(set_attr "type" "lea")
5538 (set_attr "mode" "<MODE>")])
5540 (define_insn "*lea_3_zext"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5545 "lea{l}\t{%a1, %k0|%k0, %a1}"
5546 [(set_attr "type" "lea")
5547 (set_attr "mode" "SI")])
5549 (define_insn "*lea_4_zext"
5550 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (match_operand:SI 1 "lea_address_operand" "p")))]
5554 "lea{l}\t{%a1, %k0|%k0, %a1}"
5555 [(set_attr "type" "lea")
5556 (set_attr "mode" "SI")])
5558 (define_insn "*lea_5_zext"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5562 (match_operand:DI 2 "const_32bit_mask" "n")))]
5564 "lea{l}\t{%a1, %k0|%k0, %a1}"
5565 [(set_attr "type" "lea")
5566 (set_attr "mode" "SI")])
5568 (define_insn "*lea_6_zext"
5569 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (match_operand:DI 1 "lea_address_operand" "p")
5572 (match_operand:DI 2 "const_32bit_mask" "n")))]
5574 "lea{l}\t{%a1, %k0|%k0, %a1}"
5575 [(set_attr "type" "lea")
5576 (set_attr "mode" "SI")])
5578 (define_insn "*add<mode>_1"
5579 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5581 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5582 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5586 switch (get_attr_type (insn))
5592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593 if (operands[2] == const1_rtx)
5594 return "inc{<imodesuffix>}\t%0";
5597 gcc_assert (operands[2] == constm1_rtx);
5598 return "dec{<imodesuffix>}\t%0";
5602 /* For most processors, ADD is faster than LEA. This alternative
5603 was added to use ADD as much as possible. */
5604 if (which_alternative == 2)
5607 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5610 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5612 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5614 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5618 (cond [(eq_attr "alternative" "3")
5619 (const_string "lea")
5620 (match_operand:SWI48 2 "incdec_operand" "")
5621 (const_string "incdec")
5623 (const_string "alu")))
5624 (set (attr "length_immediate")
5626 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5628 (const_string "*")))
5629 (set_attr "mode" "<MODE>")])
5631 ;; It may seem that nonimmediate operand is proper one for operand 1.
5632 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5633 ;; we take care in ix86_binary_operator_ok to not allow two memory
5634 ;; operands so proper swapping will be done in reload. This allow
5635 ;; patterns constructed from addsi_1 to match.
5637 (define_insn "addsi_1_zext"
5638 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5640 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5641 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5642 (clobber (reg:CC FLAGS_REG))]
5643 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5645 switch (get_attr_type (insn))
5651 if (operands[2] == const1_rtx)
5652 return "inc{l}\t%k0";
5655 gcc_assert (operands[2] == constm1_rtx);
5656 return "dec{l}\t%k0";
5660 /* For most processors, ADD is faster than LEA. This alternative
5661 was added to use ADD as much as possible. */
5662 if (which_alternative == 1)
5665 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5668 if (x86_maybe_negate_const_int (&operands[2], SImode))
5669 return "sub{l}\t{%2, %k0|%k0, %2}";
5671 return "add{l}\t{%2, %k0|%k0, %2}";
5675 (cond [(eq_attr "alternative" "2")
5676 (const_string "lea")
5677 (match_operand:SI 2 "incdec_operand" "")
5678 (const_string "incdec")
5680 (const_string "alu")))
5681 (set (attr "length_immediate")
5683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5685 (const_string "*")))
5686 (set_attr "mode" "SI")])
5688 (define_insn "*addhi_1"
5689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5690 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5691 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5695 switch (get_attr_type (insn))
5701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 if (operands[2] == const1_rtx)
5703 return "inc{w}\t%0";
5706 gcc_assert (operands[2] == constm1_rtx);
5707 return "dec{w}\t%0";
5711 /* For most processors, ADD is faster than LEA. This alternative
5712 was added to use ADD as much as possible. */
5713 if (which_alternative == 2)
5716 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720 if (x86_maybe_negate_const_int (&operands[2], HImode))
5721 return "sub{w}\t{%2, %0|%0, %2}";
5723 return "add{w}\t{%2, %0|%0, %2}";
5727 (cond [(eq_attr "alternative" "3")
5728 (const_string "lea")
5729 (match_operand:HI 2 "incdec_operand" "")
5730 (const_string "incdec")
5732 (const_string "alu")))
5733 (set (attr "length_immediate")
5735 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5737 (const_string "*")))
5738 (set_attr "mode" "HI,HI,HI,SI")])
5740 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5741 (define_insn "*addqi_1"
5742 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5743 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5744 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5748 bool widen = (which_alternative == 3 || which_alternative == 4);
5750 switch (get_attr_type (insn))
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (operands[2] == const1_rtx)
5758 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5761 gcc_assert (operands[2] == constm1_rtx);
5762 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5766 /* For most processors, ADD is faster than LEA. These alternatives
5767 were added to use ADD as much as possible. */
5768 if (which_alternative == 2 || which_alternative == 4)
5771 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775 if (x86_maybe_negate_const_int (&operands[2], QImode))
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5780 return "sub{b}\t{%2, %0|%0, %2}";
5783 return "add{l}\t{%k2, %k0|%k0, %k2}";
5785 return "add{b}\t{%2, %0|%0, %2}";
5789 (cond [(eq_attr "alternative" "5")
5790 (const_string "lea")
5791 (match_operand:QI 2 "incdec_operand" "")
5792 (const_string "incdec")
5794 (const_string "alu")))
5795 (set (attr "length_immediate")
5797 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5799 (const_string "*")))
5800 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5802 (define_insn "*addqi_1_slp"
5803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5804 (plus:QI (match_dup 0)
5805 (match_operand:QI 1 "general_operand" "qn,qm")))
5806 (clobber (reg:CC FLAGS_REG))]
5807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5810 switch (get_attr_type (insn))
5813 if (operands[1] == const1_rtx)
5814 return "inc{b}\t%0";
5817 gcc_assert (operands[1] == constm1_rtx);
5818 return "dec{b}\t%0";
5822 if (x86_maybe_negate_const_int (&operands[1], QImode))
5823 return "sub{b}\t{%1, %0|%0, %1}";
5825 return "add{b}\t{%1, %0|%0, %1}";
5829 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5830 (const_string "incdec")
5831 (const_string "alu1")))
5832 (set (attr "memory")
5833 (if_then_else (match_operand 1 "memory_operand" "")
5834 (const_string "load")
5835 (const_string "none")))
5836 (set_attr "mode" "QI")])
5838 ;; Split non destructive adds if we cannot use lea.
5840 [(set (match_operand:SWI48 0 "register_operand" "")
5841 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5842 (match_operand:SWI48 2 "nonmemory_operand" "")))
5843 (clobber (reg:CC FLAGS_REG))]
5844 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845 [(set (match_dup 0) (match_dup 1))
5846 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5847 (clobber (reg:CC FLAGS_REG))])])
5849 ;; Convert add to the lea pattern to avoid flags dependency.
5851 [(set (match_operand:SWI 0 "register_operand" "")
5852 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5853 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5858 enum machine_mode mode = <MODE>mode;
5861 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5864 operands[0] = gen_lowpart (mode, operands[0]);
5865 operands[1] = gen_lowpart (mode, operands[1]);
5866 operands[2] = gen_lowpart (mode, operands[2]);
5869 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5871 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5875 ;; Convert add to the lea pattern to avoid flags dependency.
5877 [(set (match_operand:DI 0 "register_operand" "")
5879 (plus:SI (match_operand:SI 1 "register_operand" "")
5880 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5881 (clobber (reg:CC FLAGS_REG))]
5882 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5884 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5886 (define_insn "*add<mode>_2"
5887 [(set (reg FLAGS_REG)
5890 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5891 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5893 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5894 (plus:SWI (match_dup 1) (match_dup 2)))]
5895 "ix86_match_ccmode (insn, CCGOCmode)
5896 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5898 switch (get_attr_type (insn))
5901 if (operands[2] == const1_rtx)
5902 return "inc{<imodesuffix>}\t%0";
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{<imodesuffix>}\t%0";
5910 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5911 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5913 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5917 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set (attr "length_immediate")
5922 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5924 (const_string "*")))
5925 (set_attr "mode" "<MODE>")])
5927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5928 (define_insn "*addsi_2_zext"
5929 [(set (reg FLAGS_REG)
5931 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5932 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5934 (set (match_operand:DI 0 "register_operand" "=r")
5935 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5936 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5937 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939 switch (get_attr_type (insn))
5942 if (operands[2] == const1_rtx)
5943 return "inc{l}\t%k0";
5946 gcc_assert (operands[2] == constm1_rtx);
5947 return "dec{l}\t%k0";
5951 if (x86_maybe_negate_const_int (&operands[2], SImode))
5952 return "sub{l}\t{%2, %k0|%k0, %2}";
5954 return "add{l}\t{%2, %k0|%k0, %2}";
5958 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5959 (const_string "incdec")
5960 (const_string "alu")))
5961 (set (attr "length_immediate")
5963 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5965 (const_string "*")))
5966 (set_attr "mode" "SI")])
5968 (define_insn "*add<mode>_3"
5969 [(set (reg FLAGS_REG)
5971 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5972 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5973 (clobber (match_scratch:SWI 0 "=<r>"))]
5974 "ix86_match_ccmode (insn, CCZmode)
5975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5977 switch (get_attr_type (insn))
5980 if (operands[2] == const1_rtx)
5981 return "inc{<imodesuffix>}\t%0";
5984 gcc_assert (operands[2] == constm1_rtx);
5985 return "dec{<imodesuffix>}\t%0";
5989 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5990 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5992 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5996 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5997 (const_string "incdec")
5998 (const_string "alu")))
5999 (set (attr "length_immediate")
6001 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6003 (const_string "*")))
6004 (set_attr "mode" "<MODE>")])
6006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6007 (define_insn "*addsi_3_zext"
6008 [(set (reg FLAGS_REG)
6010 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
6011 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6012 (set (match_operand:DI 0 "register_operand" "=r")
6013 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6014 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6015 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6017 switch (get_attr_type (insn))
6020 if (operands[2] == const1_rtx)
6021 return "inc{l}\t%k0";
6024 gcc_assert (operands[2] == constm1_rtx);
6025 return "dec{l}\t%k0";
6029 if (x86_maybe_negate_const_int (&operands[2], SImode))
6030 return "sub{l}\t{%2, %k0|%k0, %2}";
6032 return "add{l}\t{%2, %k0|%k0, %2}";
6036 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6037 (const_string "incdec")
6038 (const_string "alu")))
6039 (set (attr "length_immediate")
6041 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6043 (const_string "*")))
6044 (set_attr "mode" "SI")])
6046 ; For comparisons against 1, -1 and 128, we may generate better code
6047 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6048 ; is matched then. We can't accept general immediate, because for
6049 ; case of overflows, the result is messed up.
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6053 (define_insn "*adddi_4"
6054 [(set (reg FLAGS_REG)
6056 (match_operand:DI 1 "nonimmediate_operand" "0")
6057 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6058 (clobber (match_scratch:DI 0 "=rm"))]
6060 && ix86_match_ccmode (insn, CCGCmode)"
6062 switch (get_attr_type (insn))
6065 if (operands[2] == constm1_rtx)
6066 return "inc{q}\t%0";
6069 gcc_assert (operands[2] == const1_rtx);
6070 return "dec{q}\t%0";
6074 if (x86_maybe_negate_const_int (&operands[2], DImode))
6075 return "add{q}\t{%2, %0|%0, %2}";
6077 return "sub{q}\t{%2, %0|%0, %2}";
6081 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6082 (const_string "incdec")
6083 (const_string "alu")))
6084 (set (attr "length_immediate")
6086 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6088 (const_string "*")))
6089 (set_attr "mode" "DI")])
6091 ; For comparisons against 1, -1 and 128, we may generate better code
6092 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6093 ; is matched then. We can't accept general immediate, because for
6094 ; case of overflows, the result is messed up.
6095 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6096 ; only for comparisons not depending on it.
6098 (define_insn "*add<mode>_4"
6099 [(set (reg FLAGS_REG)
6101 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6102 (match_operand:SWI124 2 "const_int_operand" "n")))
6103 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6104 "ix86_match_ccmode (insn, CCGCmode)"
6106 switch (get_attr_type (insn))
6109 if (operands[2] == constm1_rtx)
6110 return "inc{<imodesuffix>}\t%0";
6113 gcc_assert (operands[2] == const1_rtx);
6114 return "dec{<imodesuffix>}\t%0";
6118 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6119 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6121 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6125 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6126 (const_string "incdec")
6127 (const_string "alu")))
6128 (set (attr "length_immediate")
6130 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6132 (const_string "*")))
6133 (set_attr "mode" "<MODE>")])
6135 (define_insn "*add<mode>_5"
6136 [(set (reg FLAGS_REG)
6139 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6140 (match_operand:SWI 2 "<general_operand>" "<g>"))
6142 (clobber (match_scratch:SWI 0 "=<r>"))]
6143 "ix86_match_ccmode (insn, CCGOCmode)
6144 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6146 switch (get_attr_type (insn))
6149 if (operands[2] == const1_rtx)
6150 return "inc{<imodesuffix>}\t%0";
6153 gcc_assert (operands[2] == constm1_rtx);
6154 return "dec{<imodesuffix>}\t%0";
6158 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6159 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6161 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6165 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set (attr "length_immediate")
6170 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6172 (const_string "*")))
6173 (set_attr "mode" "<MODE>")])
6175 (define_insn "*addqi_ext_1_rex64"
6176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6181 (match_operand 1 "ext_register_operand" "0")
6184 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6185 (clobber (reg:CC FLAGS_REG))]
6188 switch (get_attr_type (insn))
6191 if (operands[2] == const1_rtx)
6192 return "inc{b}\t%h0";
6195 gcc_assert (operands[2] == constm1_rtx);
6196 return "dec{b}\t%h0";
6200 return "add{b}\t{%2, %h0|%h0, %2}";
6204 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6205 (const_string "incdec")
6206 (const_string "alu")))
6207 (set_attr "modrm" "1")
6208 (set_attr "mode" "QI")])
6210 (define_insn "addqi_ext_1"
6211 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6216 (match_operand 1 "ext_register_operand" "0")
6219 (match_operand:QI 2 "general_operand" "Qmn")))
6220 (clobber (reg:CC FLAGS_REG))]
6223 switch (get_attr_type (insn))
6226 if (operands[2] == const1_rtx)
6227 return "inc{b}\t%h0";
6230 gcc_assert (operands[2] == constm1_rtx);
6231 return "dec{b}\t%h0";
6235 return "add{b}\t{%2, %h0|%h0, %2}";
6239 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240 (const_string "incdec")
6241 (const_string "alu")))
6242 (set_attr "modrm" "1")
6243 (set_attr "mode" "QI")])
6245 (define_insn "*addqi_ext_2"
6246 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6251 (match_operand 1 "ext_register_operand" "%0")
6255 (match_operand 2 "ext_register_operand" "Q")
6258 (clobber (reg:CC FLAGS_REG))]
6260 "add{b}\t{%h2, %h0|%h0, %h2}"
6261 [(set_attr "type" "alu")
6262 (set_attr "mode" "QI")])
6264 ;; The lea patterns for modes less than 32 bits need to be matched by
6265 ;; several insns converted to real lea by splitters.
6267 (define_insn_and_split "*lea_general_1"
6268 [(set (match_operand 0 "register_operand" "=r")
6269 (plus (plus (match_operand 1 "index_register_operand" "l")
6270 (match_operand 2 "register_operand" "r"))
6271 (match_operand 3 "immediate_operand" "i")))]
6272 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6273 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6274 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6275 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6276 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6277 || GET_MODE (operands[3]) == VOIDmode)"
6279 "&& reload_completed"
6282 enum machine_mode mode = SImode;
6285 operands[0] = gen_lowpart (mode, operands[0]);
6286 operands[1] = gen_lowpart (mode, operands[1]);
6287 operands[2] = gen_lowpart (mode, operands[2]);
6288 operands[3] = gen_lowpart (mode, operands[3]);
6290 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6293 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6296 [(set_attr "type" "lea")
6297 (set_attr "mode" "SI")])
6299 (define_insn_and_split "*lea_general_2"
6300 [(set (match_operand 0 "register_operand" "=r")
6301 (plus (mult (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "const248_operand" "n"))
6303 (match_operand 3 "nonmemory_operand" "ri")))]
6304 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6308 || GET_MODE (operands[3]) == VOIDmode)"
6310 "&& reload_completed"
6313 enum machine_mode mode = SImode;
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[3] = gen_lowpart (mode, operands[3]);
6320 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6323 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6326 [(set_attr "type" "lea")
6327 (set_attr "mode" "SI")])
6329 (define_insn_and_split "*lea_general_3"
6330 [(set (match_operand 0 "register_operand" "=r")
6331 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6332 (match_operand 2 "const248_operand" "n"))
6333 (match_operand 3 "register_operand" "r"))
6334 (match_operand 4 "immediate_operand" "i")))]
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6336 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6337 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6338 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6340 "&& reload_completed"
6343 enum machine_mode mode = SImode;
6346 operands[0] = gen_lowpart (mode, operands[0]);
6347 operands[1] = gen_lowpart (mode, operands[1]);
6348 operands[3] = gen_lowpart (mode, operands[3]);
6349 operands[4] = gen_lowpart (mode, operands[4]);
6351 pat = gen_rtx_PLUS (mode,
6353 gen_rtx_MULT (mode, operands[1],
6358 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6361 [(set_attr "type" "lea")
6362 (set_attr "mode" "SI")])
6364 (define_insn_and_split "*lea_general_4"
6365 [(set (match_operand 0 "register_operand" "=r")
6367 (match_operand 1 "index_register_operand" "l")
6368 (match_operand 2 "const_int_operand" "n"))
6369 (match_operand 3 "const_int_operand" "n")))]
6370 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6371 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6372 || GET_MODE (operands[0]) == SImode
6373 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6374 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6375 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6376 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6377 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6379 "&& reload_completed"
6382 enum machine_mode mode = GET_MODE (operands[0]);
6385 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6388 operands[0] = gen_lowpart (mode, operands[0]);
6389 operands[1] = gen_lowpart (mode, operands[1]);
6392 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6394 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6395 INTVAL (operands[3]));
6397 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6400 [(set_attr "type" "lea")
6402 (if_then_else (match_operand:DI 0 "" "")
6404 (const_string "SI")))])
6406 ;; Subtract instructions
6408 (define_expand "sub<mode>3"
6409 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6410 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6411 (match_operand:SDWIM 2 "<general_operand>" "")))]
6413 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6415 (define_insn_and_split "*sub<dwi>3_doubleword"
6416 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6418 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6419 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6420 (clobber (reg:CC FLAGS_REG))]
6421 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6424 [(parallel [(set (reg:CC FLAGS_REG)
6425 (compare:CC (match_dup 1) (match_dup 2)))
6427 (minus:DWIH (match_dup 1) (match_dup 2)))])
6428 (parallel [(set (match_dup 3)
6432 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6434 (clobber (reg:CC FLAGS_REG))])]
6435 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6437 (define_insn "*sub<mode>_1"
6438 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6440 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6441 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6442 (clobber (reg:CC FLAGS_REG))]
6443 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6444 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "<MODE>")])
6448 (define_insn "*subsi_1_zext"
6449 [(set (match_operand:DI 0 "register_operand" "=r")
6451 (minus:SI (match_operand:SI 1 "register_operand" "0")
6452 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6453 (clobber (reg:CC FLAGS_REG))]
6454 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6455 "sub{l}\t{%2, %k0|%k0, %2}"
6456 [(set_attr "type" "alu")
6457 (set_attr "mode" "SI")])
6459 (define_insn "*subqi_1_slp"
6460 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6461 (minus:QI (match_dup 0)
6462 (match_operand:QI 1 "general_operand" "qn,qm")))
6463 (clobber (reg:CC FLAGS_REG))]
6464 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6465 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6466 "sub{b}\t{%1, %0|%0, %1}"
6467 [(set_attr "type" "alu1")
6468 (set_attr "mode" "QI")])
6470 (define_insn "*sub<mode>_2"
6471 [(set (reg FLAGS_REG)
6474 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6475 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6477 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478 (minus:SWI (match_dup 1) (match_dup 2)))]
6479 "ix86_match_ccmode (insn, CCGOCmode)
6480 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "<MODE>")])
6485 (define_insn "*subsi_2_zext"
6486 [(set (reg FLAGS_REG)
6488 (minus:SI (match_operand:SI 1 "register_operand" "0")
6489 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6491 (set (match_operand:DI 0 "register_operand" "=r")
6493 (minus:SI (match_dup 1)
6495 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6496 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6497 "sub{l}\t{%2, %k0|%k0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "mode" "SI")])
6501 (define_insn "*sub<mode>_3"
6502 [(set (reg FLAGS_REG)
6503 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6504 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6506 (minus:SWI (match_dup 1) (match_dup 2)))]
6507 "ix86_match_ccmode (insn, CCmode)
6508 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "<MODE>")])
6513 (define_insn "*subsi_3_zext"
6514 [(set (reg FLAGS_REG)
6515 (compare (match_operand:SI 1 "register_operand" "0")
6516 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6517 (set (match_operand:DI 0 "register_operand" "=r")
6519 (minus:SI (match_dup 1)
6521 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6522 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6523 "sub{l}\t{%2, %1|%1, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "mode" "SI")])
6527 ;; Add with carry and subtract with borrow
6529 (define_expand "<plusminus_insn><mode>3_carry"
6531 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6533 (match_operand:SWI 1 "nonimmediate_operand" "")
6534 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6535 [(match_operand 3 "flags_reg_operand" "")
6537 (match_operand:SWI 2 "<general_operand>" ""))))
6538 (clobber (reg:CC FLAGS_REG))])]
6539 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6541 (define_insn "*<plusminus_insn><mode>3_carry"
6542 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6544 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6546 (match_operator 3 "ix86_carry_flag_operator"
6547 [(reg FLAGS_REG) (const_int 0)])
6548 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6549 (clobber (reg:CC FLAGS_REG))]
6550 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6551 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6552 [(set_attr "type" "alu")
6553 (set_attr "use_carry" "1")
6554 (set_attr "pent_pair" "pu")
6555 (set_attr "mode" "<MODE>")])
6557 (define_insn "*addsi3_carry_zext"
6558 [(set (match_operand:DI 0 "register_operand" "=r")
6560 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6561 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6562 [(reg FLAGS_REG) (const_int 0)])
6563 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6564 (clobber (reg:CC FLAGS_REG))]
6565 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6566 "adc{l}\t{%2, %k0|%k0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "use_carry" "1")
6569 (set_attr "pent_pair" "pu")
6570 (set_attr "mode" "SI")])
6572 (define_insn "*subsi3_carry_zext"
6573 [(set (match_operand:DI 0 "register_operand" "=r")
6575 (minus:SI (match_operand:SI 1 "register_operand" "0")
6576 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6577 [(reg FLAGS_REG) (const_int 0)])
6578 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6581 "sbb{l}\t{%2, %k0|%k0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "SI")])
6586 ;; Overflow setting add and subtract instructions
6588 (define_insn "*add<mode>3_cconly_overflow"
6589 [(set (reg:CCC FLAGS_REG)
6592 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6593 (match_operand:SWI 2 "<general_operand>" "<g>"))
6595 (clobber (match_scratch:SWI 0 "=<r>"))]
6596 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6597 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "mode" "<MODE>")])
6601 (define_insn "*sub<mode>3_cconly_overflow"
6602 [(set (reg:CCC FLAGS_REG)
6605 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6606 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6609 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6610 [(set_attr "type" "icmp")
6611 (set_attr "mode" "<MODE>")])
6613 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6614 [(set (reg:CCC FLAGS_REG)
6617 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6618 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6620 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6621 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6622 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6623 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "mode" "<MODE>")])
6627 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6628 [(set (reg:CCC FLAGS_REG)
6631 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6632 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6634 (set (match_operand:DI 0 "register_operand" "=r")
6635 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6636 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6637 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6638 [(set_attr "type" "alu")
6639 (set_attr "mode" "SI")])
6641 ;; The patterns that match these are at the end of this file.
6643 (define_expand "<plusminus_insn>xf3"
6644 [(set (match_operand:XF 0 "register_operand" "")
6646 (match_operand:XF 1 "register_operand" "")
6647 (match_operand:XF 2 "register_operand" "")))]
6650 (define_expand "<plusminus_insn><mode>3"
6651 [(set (match_operand:MODEF 0 "register_operand" "")
6653 (match_operand:MODEF 1 "register_operand" "")
6654 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6655 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6656 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6658 ;; Multiply instructions
6660 (define_expand "mul<mode>3"
6661 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6663 (match_operand:SWIM248 1 "register_operand" "")
6664 (match_operand:SWIM248 2 "<general_operand>" "")))
6665 (clobber (reg:CC FLAGS_REG))])])
6667 (define_expand "mulqi3"
6668 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6670 (match_operand:QI 1 "register_operand" "")
6671 (match_operand:QI 2 "nonimmediate_operand" "")))
6672 (clobber (reg:CC FLAGS_REG))])]
6673 "TARGET_QIMODE_MATH")
6676 ;; IMUL reg32/64, reg32/64, imm8 Direct
6677 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6678 ;; IMUL reg32/64, reg32/64, imm32 Direct
6679 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6680 ;; IMUL reg32/64, reg32/64 Direct
6681 ;; IMUL reg32/64, mem32/64 Direct
6683 ;; On BDVER1, all above IMULs use DirectPath
6685 (define_insn "*mul<mode>3_1"
6686 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6688 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6689 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6690 (clobber (reg:CC FLAGS_REG))]
6691 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6694 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6695 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6696 [(set_attr "type" "imul")
6697 (set_attr "prefix_0f" "0,0,1")
6698 (set (attr "athlon_decode")
6699 (cond [(eq_attr "cpu" "athlon")
6700 (const_string "vector")
6701 (eq_attr "alternative" "1")
6702 (const_string "vector")
6703 (and (eq_attr "alternative" "2")
6704 (match_operand 1 "memory_operand" ""))
6705 (const_string "vector")]
6706 (const_string "direct")))
6707 (set (attr "amdfam10_decode")
6708 (cond [(and (eq_attr "alternative" "0,1")
6709 (match_operand 1 "memory_operand" ""))
6710 (const_string "vector")]
6711 (const_string "direct")))
6712 (set_attr "bdver1_decode" "direct")
6713 (set_attr "mode" "<MODE>")])
6715 (define_insn "*mulsi3_1_zext"
6716 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6718 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6719 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6720 (clobber (reg:CC FLAGS_REG))]
6722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6725 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6726 imul{l}\t{%2, %k0|%k0, %2}"
6727 [(set_attr "type" "imul")
6728 (set_attr "prefix_0f" "0,0,1")
6729 (set (attr "athlon_decode")
6730 (cond [(eq_attr "cpu" "athlon")
6731 (const_string "vector")
6732 (eq_attr "alternative" "1")
6733 (const_string "vector")
6734 (and (eq_attr "alternative" "2")
6735 (match_operand 1 "memory_operand" ""))
6736 (const_string "vector")]
6737 (const_string "direct")))
6738 (set (attr "amdfam10_decode")
6739 (cond [(and (eq_attr "alternative" "0,1")
6740 (match_operand 1 "memory_operand" ""))
6741 (const_string "vector")]
6742 (const_string "direct")))
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "SI")])
6747 ;; IMUL reg16, reg16, imm8 VectorPath
6748 ;; IMUL reg16, mem16, imm8 VectorPath
6749 ;; IMUL reg16, reg16, imm16 VectorPath
6750 ;; IMUL reg16, mem16, imm16 VectorPath
6751 ;; IMUL reg16, reg16 Direct
6752 ;; IMUL reg16, mem16 Direct
6754 ;; On BDVER1, all HI MULs use DoublePath
6756 (define_insn "*mulhi3_1"
6757 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6758 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6759 (match_operand:HI 2 "general_operand" "K,n,mr")))
6760 (clobber (reg:CC FLAGS_REG))]
6762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6764 imul{w}\t{%2, %1, %0|%0, %1, %2}
6765 imul{w}\t{%2, %1, %0|%0, %1, %2}
6766 imul{w}\t{%2, %0|%0, %2}"
6767 [(set_attr "type" "imul")
6768 (set_attr "prefix_0f" "0,0,1")
6769 (set (attr "athlon_decode")
6770 (cond [(eq_attr "cpu" "athlon")
6771 (const_string "vector")
6772 (eq_attr "alternative" "1,2")
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set (attr "amdfam10_decode")
6776 (cond [(eq_attr "alternative" "0,1")
6777 (const_string "vector")]
6778 (const_string "direct")))
6779 (set_attr "bdver1_decode" "double")
6780 (set_attr "mode" "HI")])
6782 ;;On AMDFAM10 and BDVER1
6786 (define_insn "*mulqi3_1"
6787 [(set (match_operand:QI 0 "register_operand" "=a")
6788 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6789 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6790 (clobber (reg:CC FLAGS_REG))]
6792 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6794 [(set_attr "type" "imul")
6795 (set_attr "length_immediate" "0")
6796 (set (attr "athlon_decode")
6797 (if_then_else (eq_attr "cpu" "athlon")
6798 (const_string "vector")
6799 (const_string "direct")))
6800 (set_attr "amdfam10_decode" "direct")
6801 (set_attr "bdver1_decode" "direct")
6802 (set_attr "mode" "QI")])
6804 (define_expand "<u>mul<mode><dwi>3"
6805 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6808 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6810 (match_operand:DWIH 2 "register_operand" ""))))
6811 (clobber (reg:CC FLAGS_REG))])])
6813 (define_expand "<u>mulqihi3"
6814 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6817 (match_operand:QI 1 "nonimmediate_operand" ""))
6819 (match_operand:QI 2 "register_operand" ""))))
6820 (clobber (reg:CC FLAGS_REG))])]
6821 "TARGET_QIMODE_MATH")
6823 (define_insn "*bmi2_umulditi3_1"
6824 [(set (match_operand:DI 0 "register_operand" "=r")
6826 (match_operand:DI 2 "nonimmediate_operand" "%d")
6827 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6828 (set (match_operand:DI 1 "register_operand" "=r")
6831 (mult:TI (zero_extend:TI (match_dup 2))
6832 (zero_extend:TI (match_dup 3)))
6834 "TARGET_64BIT && TARGET_BMI2
6835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6836 "mulx\t{%3, %0, %1|%1, %0, %3}"
6837 [(set_attr "type" "imulx")
6838 (set_attr "prefix" "vex")
6839 (set_attr "mode" "DI")])
6841 (define_insn "*bmi2_umulsidi3_1"
6842 [(set (match_operand:SI 0 "register_operand" "=r")
6844 (match_operand:SI 2 "nonimmediate_operand" "%d")
6845 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6846 (set (match_operand:SI 1 "register_operand" "=r")
6849 (mult:DI (zero_extend:DI (match_dup 2))
6850 (zero_extend:DI (match_dup 3)))
6852 "!TARGET_64BIT && TARGET_BMI2
6853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854 "mulx\t{%3, %0, %1|%1, %0, %3}"
6855 [(set_attr "type" "imulx")
6856 (set_attr "prefix" "vex")
6857 (set_attr "mode" "SI")])
6859 (define_insn "*umul<mode><dwi>3_1"
6860 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6863 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6865 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6866 (clobber (reg:CC FLAGS_REG))]
6867 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869 mul{<imodesuffix>}\t%2
6871 [(set_attr "isa" "*,bmi2")
6872 (set_attr "type" "imul,imulx")
6873 (set_attr "length_immediate" "0,*")
6874 (set (attr "athlon_decode")
6875 (cond [(eq_attr "alternative" "0")
6876 (if_then_else (eq_attr "cpu" "athlon")
6877 (const_string "vector")
6878 (const_string "double"))]
6879 (const_string "*")))
6880 (set_attr "amdfam10_decode" "double,*")
6881 (set_attr "bdver1_decode" "direct,*")
6882 (set_attr "prefix" "orig,vex")
6883 (set_attr "mode" "<MODE>")])
6885 ;; Convert mul to the mulx pattern to avoid flags dependency.
6887 [(set (match_operand:<DWI> 0 "register_operand" "")
6890 (match_operand:DWIH 1 "register_operand" ""))
6892 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6893 (clobber (reg:CC FLAGS_REG))]
6894 "TARGET_BMI2 && reload_completed
6895 && true_regnum (operands[1]) == DX_REG"
6896 [(parallel [(set (match_dup 3)
6897 (mult:DWIH (match_dup 1) (match_dup 2)))
6901 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6902 (zero_extend:<DWI> (match_dup 2)))
6905 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6907 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6910 (define_insn "*mul<mode><dwi>3_1"
6911 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6914 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6916 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6917 (clobber (reg:CC FLAGS_REG))]
6918 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919 "imul{<imodesuffix>}\t%2"
6920 [(set_attr "type" "imul")
6921 (set_attr "length_immediate" "0")
6922 (set (attr "athlon_decode")
6923 (if_then_else (eq_attr "cpu" "athlon")
6924 (const_string "vector")
6925 (const_string "double")))
6926 (set_attr "amdfam10_decode" "double")
6927 (set_attr "bdver1_decode" "direct")
6928 (set_attr "mode" "<MODE>")])
6930 (define_insn "*<u>mulqihi3_1"
6931 [(set (match_operand:HI 0 "register_operand" "=a")
6934 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6936 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6937 (clobber (reg:CC FLAGS_REG))]
6939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 "<sgnprefix>mul{b}\t%2"
6941 [(set_attr "type" "imul")
6942 (set_attr "length_immediate" "0")
6943 (set (attr "athlon_decode")
6944 (if_then_else (eq_attr "cpu" "athlon")
6945 (const_string "vector")
6946 (const_string "direct")))
6947 (set_attr "amdfam10_decode" "direct")
6948 (set_attr "bdver1_decode" "direct")
6949 (set_attr "mode" "QI")])
6951 (define_expand "<s>mul<mode>3_highpart"
6952 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6957 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6959 (match_operand:SWI48 2 "register_operand" "")))
6961 (clobber (match_scratch:SWI48 3 ""))
6962 (clobber (reg:CC FLAGS_REG))])]
6964 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6966 (define_insn "*<s>muldi3_highpart_1"
6967 [(set (match_operand:DI 0 "register_operand" "=d")
6972 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6974 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6976 (clobber (match_scratch:DI 3 "=1"))
6977 (clobber (reg:CC FLAGS_REG))]
6979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6980 "<sgnprefix>mul{q}\t%2"
6981 [(set_attr "type" "imul")
6982 (set_attr "length_immediate" "0")
6983 (set (attr "athlon_decode")
6984 (if_then_else (eq_attr "cpu" "athlon")
6985 (const_string "vector")
6986 (const_string "double")))
6987 (set_attr "amdfam10_decode" "double")
6988 (set_attr "bdver1_decode" "direct")
6989 (set_attr "mode" "DI")])
6991 (define_insn "*<s>mulsi3_highpart_1"
6992 [(set (match_operand:SI 0 "register_operand" "=d")
6997 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6999 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7001 (clobber (match_scratch:SI 3 "=1"))
7002 (clobber (reg:CC FLAGS_REG))]
7003 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7004 "<sgnprefix>mul{l}\t%2"
7005 [(set_attr "type" "imul")
7006 (set_attr "length_immediate" "0")
7007 (set (attr "athlon_decode")
7008 (if_then_else (eq_attr "cpu" "athlon")
7009 (const_string "vector")
7010 (const_string "double")))
7011 (set_attr "amdfam10_decode" "double")
7012 (set_attr "bdver1_decode" "direct")
7013 (set_attr "mode" "SI")])
7015 (define_insn "*<s>mulsi3_highpart_zext"
7016 [(set (match_operand:DI 0 "register_operand" "=d")
7017 (zero_extend:DI (truncate:SI
7019 (mult:DI (any_extend:DI
7020 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7022 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7024 (clobber (match_scratch:SI 3 "=1"))
7025 (clobber (reg:CC FLAGS_REG))]
7027 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7028 "<sgnprefix>mul{l}\t%2"
7029 [(set_attr "type" "imul")
7030 (set_attr "length_immediate" "0")
7031 (set (attr "athlon_decode")
7032 (if_then_else (eq_attr "cpu" "athlon")
7033 (const_string "vector")
7034 (const_string "double")))
7035 (set_attr "amdfam10_decode" "double")
7036 (set_attr "bdver1_decode" "direct")
7037 (set_attr "mode" "SI")])
7039 ;; The patterns that match these are at the end of this file.
7041 (define_expand "mulxf3"
7042 [(set (match_operand:XF 0 "register_operand" "")
7043 (mult:XF (match_operand:XF 1 "register_operand" "")
7044 (match_operand:XF 2 "register_operand" "")))]
7047 (define_expand "mul<mode>3"
7048 [(set (match_operand:MODEF 0 "register_operand" "")
7049 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7050 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7051 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7052 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7054 ;; Divide instructions
7056 ;; The patterns that match these are at the end of this file.
7058 (define_expand "divxf3"
7059 [(set (match_operand:XF 0 "register_operand" "")
7060 (div:XF (match_operand:XF 1 "register_operand" "")
7061 (match_operand:XF 2 "register_operand" "")))]
7064 (define_expand "divdf3"
7065 [(set (match_operand:DF 0 "register_operand" "")
7066 (div:DF (match_operand:DF 1 "register_operand" "")
7067 (match_operand:DF 2 "nonimmediate_operand" "")))]
7068 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7069 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7071 (define_expand "divsf3"
7072 [(set (match_operand:SF 0 "register_operand" "")
7073 (div:SF (match_operand:SF 1 "register_operand" "")
7074 (match_operand:SF 2 "nonimmediate_operand" "")))]
7075 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7080 && optimize_insn_for_speed_p ()
7081 && flag_finite_math_only && !flag_trapping_math
7082 && flag_unsafe_math_optimizations)
7084 ix86_emit_swdivsf (operands[0], operands[1],
7085 operands[2], SFmode);
7090 ;; Divmod instructions.
7092 (define_expand "divmod<mode>4"
7093 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7095 (match_operand:SWIM248 1 "register_operand" "")
7096 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7097 (set (match_operand:SWIM248 3 "register_operand" "")
7098 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7099 (clobber (reg:CC FLAGS_REG))])])
7101 ;; Split with 8bit unsigned divide:
7102 ;; if (dividend an divisor are in [0-255])
7103 ;; use 8bit unsigned integer divide
7105 ;; use original integer divide
7107 [(set (match_operand:SWI48 0 "register_operand" "")
7108 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7109 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7110 (set (match_operand:SWI48 1 "register_operand" "")
7111 (mod:SWI48 (match_dup 2) (match_dup 3)))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "TARGET_USE_8BIT_IDIV
7114 && TARGET_QIMODE_MATH
7115 && can_create_pseudo_p ()
7116 && !optimize_insn_for_size_p ()"
7118 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7120 (define_insn_and_split "divmod<mode>4_1"
7121 [(set (match_operand:SWI48 0 "register_operand" "=a")
7122 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7123 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7124 (set (match_operand:SWI48 1 "register_operand" "=&d")
7125 (mod:SWI48 (match_dup 2) (match_dup 3)))
7126 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7127 (clobber (reg:CC FLAGS_REG))]
7131 [(parallel [(set (match_dup 1)
7132 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7133 (clobber (reg:CC FLAGS_REG))])
7134 (parallel [(set (match_dup 0)
7135 (div:SWI48 (match_dup 2) (match_dup 3)))
7137 (mod:SWI48 (match_dup 2) (match_dup 3)))
7139 (clobber (reg:CC FLAGS_REG))])]
7141 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7143 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7144 operands[4] = operands[2];
7147 /* Avoid use of cltd in favor of a mov+shift. */
7148 emit_move_insn (operands[1], operands[2]);
7149 operands[4] = operands[1];
7152 [(set_attr "type" "multi")
7153 (set_attr "mode" "<MODE>")])
7155 (define_insn_and_split "*divmod<mode>4"
7156 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7157 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7158 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7159 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7160 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7161 (clobber (reg:CC FLAGS_REG))]
7165 [(parallel [(set (match_dup 1)
7166 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7167 (clobber (reg:CC FLAGS_REG))])
7168 (parallel [(set (match_dup 0)
7169 (div:SWIM248 (match_dup 2) (match_dup 3)))
7171 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7173 (clobber (reg:CC FLAGS_REG))])]
7175 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7177 if (<MODE>mode != HImode
7178 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7179 operands[4] = operands[2];
7182 /* Avoid use of cltd in favor of a mov+shift. */
7183 emit_move_insn (operands[1], operands[2]);
7184 operands[4] = operands[1];
7187 [(set_attr "type" "multi")
7188 (set_attr "mode" "<MODE>")])
7190 (define_insn "*divmod<mode>4_noext"
7191 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7192 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7193 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7194 (set (match_operand:SWIM248 1 "register_operand" "=d")
7195 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7196 (use (match_operand:SWIM248 4 "register_operand" "1"))
7197 (clobber (reg:CC FLAGS_REG))]
7199 "idiv{<imodesuffix>}\t%3"
7200 [(set_attr "type" "idiv")
7201 (set_attr "mode" "<MODE>")])
7203 (define_expand "divmodqi4"
7204 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7206 (match_operand:QI 1 "register_operand" "")
7207 (match_operand:QI 2 "nonimmediate_operand" "")))
7208 (set (match_operand:QI 3 "register_operand" "")
7209 (mod:QI (match_dup 1) (match_dup 2)))
7210 (clobber (reg:CC FLAGS_REG))])]
7211 "TARGET_QIMODE_MATH"
7216 tmp0 = gen_reg_rtx (HImode);
7217 tmp1 = gen_reg_rtx (HImode);
7219 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7221 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7222 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7224 /* Extract remainder from AH. */
7225 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7226 insn = emit_move_insn (operands[3], tmp1);
7228 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7229 set_unique_reg_note (insn, REG_EQUAL, mod);
7231 /* Extract quotient from AL. */
7232 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7234 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7235 set_unique_reg_note (insn, REG_EQUAL, div);
7240 ;; Divide AX by r/m8, with result stored in
7243 ;; Change div/mod to HImode and extend the second argument to HImode
7244 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7245 ;; combine may fail.
7246 (define_insn "divmodhiqi3"
7247 [(set (match_operand:HI 0 "register_operand" "=a")
7252 (mod:HI (match_operand:HI 1 "register_operand" "0")
7254 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7258 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "TARGET_QIMODE_MATH"
7262 [(set_attr "type" "idiv")
7263 (set_attr "mode" "QI")])
7265 (define_expand "udivmod<mode>4"
7266 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7268 (match_operand:SWIM248 1 "register_operand" "")
7269 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7270 (set (match_operand:SWIM248 3 "register_operand" "")
7271 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7272 (clobber (reg:CC FLAGS_REG))])])
7274 ;; Split with 8bit unsigned divide:
7275 ;; if (dividend an divisor are in [0-255])
7276 ;; use 8bit unsigned integer divide
7278 ;; use original integer divide
7280 [(set (match_operand:SWI48 0 "register_operand" "")
7281 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7282 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7283 (set (match_operand:SWI48 1 "register_operand" "")
7284 (umod:SWI48 (match_dup 2) (match_dup 3)))
7285 (clobber (reg:CC FLAGS_REG))]
7286 "TARGET_USE_8BIT_IDIV
7287 && TARGET_QIMODE_MATH
7288 && can_create_pseudo_p ()
7289 && !optimize_insn_for_size_p ()"
7291 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7293 (define_insn_and_split "udivmod<mode>4_1"
7294 [(set (match_operand:SWI48 0 "register_operand" "=a")
7295 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7296 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7297 (set (match_operand:SWI48 1 "register_operand" "=&d")
7298 (umod:SWI48 (match_dup 2) (match_dup 3)))
7299 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7300 (clobber (reg:CC FLAGS_REG))]
7304 [(set (match_dup 1) (const_int 0))
7305 (parallel [(set (match_dup 0)
7306 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7308 (umod:SWI48 (match_dup 2) (match_dup 3)))
7310 (clobber (reg:CC FLAGS_REG))])]
7312 [(set_attr "type" "multi")
7313 (set_attr "mode" "<MODE>")])
7315 (define_insn_and_split "*udivmod<mode>4"
7316 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7317 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7318 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7319 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7320 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7321 (clobber (reg:CC FLAGS_REG))]
7325 [(set (match_dup 1) (const_int 0))
7326 (parallel [(set (match_dup 0)
7327 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7329 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7331 (clobber (reg:CC FLAGS_REG))])]
7333 [(set_attr "type" "multi")
7334 (set_attr "mode" "<MODE>")])
7336 (define_insn "*udivmod<mode>4_noext"
7337 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7338 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7339 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7340 (set (match_operand:SWIM248 1 "register_operand" "=d")
7341 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7342 (use (match_operand:SWIM248 4 "register_operand" "1"))
7343 (clobber (reg:CC FLAGS_REG))]
7345 "div{<imodesuffix>}\t%3"
7346 [(set_attr "type" "idiv")
7347 (set_attr "mode" "<MODE>")])
7349 (define_expand "udivmodqi4"
7350 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7352 (match_operand:QI 1 "register_operand" "")
7353 (match_operand:QI 2 "nonimmediate_operand" "")))
7354 (set (match_operand:QI 3 "register_operand" "")
7355 (umod:QI (match_dup 1) (match_dup 2)))
7356 (clobber (reg:CC FLAGS_REG))])]
7357 "TARGET_QIMODE_MATH"
7362 tmp0 = gen_reg_rtx (HImode);
7363 tmp1 = gen_reg_rtx (HImode);
7365 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7367 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7368 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7370 /* Extract remainder from AH. */
7371 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7372 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7373 insn = emit_move_insn (operands[3], tmp1);
7375 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7376 set_unique_reg_note (insn, REG_EQUAL, mod);
7378 /* Extract quotient from AL. */
7379 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7381 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7382 set_unique_reg_note (insn, REG_EQUAL, div);
7387 (define_insn "udivmodhiqi3"
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7393 (mod:HI (match_operand:HI 1 "register_operand" "0")
7395 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7399 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7400 (clobber (reg:CC FLAGS_REG))]
7401 "TARGET_QIMODE_MATH"
7403 [(set_attr "type" "idiv")
7404 (set_attr "mode" "QI")])
7406 ;; We cannot use div/idiv for double division, because it causes
7407 ;; "division by zero" on the overflow and that's not what we expect
7408 ;; from truncate. Because true (non truncating) double division is
7409 ;; never generated, we can't create this insn anyway.
7412 ; [(set (match_operand:SI 0 "register_operand" "=a")
7414 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7416 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7417 ; (set (match_operand:SI 3 "register_operand" "=d")
7419 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7420 ; (clobber (reg:CC FLAGS_REG))]
7422 ; "div{l}\t{%2, %0|%0, %2}"
7423 ; [(set_attr "type" "idiv")])
7425 ;;- Logical AND instructions
7427 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7428 ;; Note that this excludes ah.
7430 (define_expand "testsi_ccno_1"
7431 [(set (reg:CCNO FLAGS_REG)
7433 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7434 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7437 (define_expand "testqi_ccz_1"
7438 [(set (reg:CCZ FLAGS_REG)
7439 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7440 (match_operand:QI 1 "nonmemory_operand" ""))
7443 (define_expand "testdi_ccno_1"
7444 [(set (reg:CCNO FLAGS_REG)
7446 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7447 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7449 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7451 (define_insn "*testdi_1"
7452 [(set (reg FLAGS_REG)
7455 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7456 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7461 test{l}\t{%k1, %k0|%k0, %k1}
7462 test{l}\t{%k1, %k0|%k0, %k1}
7463 test{q}\t{%1, %0|%0, %1}
7464 test{q}\t{%1, %0|%0, %1}
7465 test{q}\t{%1, %0|%0, %1}"
7466 [(set_attr "type" "test")
7467 (set_attr "modrm" "0,1,0,1,1")
7468 (set_attr "mode" "SI,SI,DI,DI,DI")])
7470 (define_insn "*testqi_1_maybe_si"
7471 [(set (reg FLAGS_REG)
7474 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7475 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7477 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7478 && ix86_match_ccmode (insn,
7479 CONST_INT_P (operands[1])
7480 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7482 if (which_alternative == 3)
7484 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7485 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7486 return "test{l}\t{%1, %k0|%k0, %1}";
7488 return "test{b}\t{%1, %0|%0, %1}";
7490 [(set_attr "type" "test")
7491 (set_attr "modrm" "0,1,1,1")
7492 (set_attr "mode" "QI,QI,QI,SI")
7493 (set_attr "pent_pair" "uv,np,uv,np")])
7495 (define_insn "*test<mode>_1"
7496 [(set (reg FLAGS_REG)
7499 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7500 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7502 "ix86_match_ccmode (insn, CCNOmode)
7503 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7504 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7505 [(set_attr "type" "test")
7506 (set_attr "modrm" "0,1,1")
7507 (set_attr "mode" "<MODE>")
7508 (set_attr "pent_pair" "uv,np,uv")])
7510 (define_expand "testqi_ext_ccno_0"
7511 [(set (reg:CCNO FLAGS_REG)
7515 (match_operand 0 "ext_register_operand" "")
7518 (match_operand 1 "const_int_operand" ""))
7521 (define_insn "*testqi_ext_0"
7522 [(set (reg FLAGS_REG)
7526 (match_operand 0 "ext_register_operand" "Q")
7529 (match_operand 1 "const_int_operand" "n"))
7531 "ix86_match_ccmode (insn, CCNOmode)"
7532 "test{b}\t{%1, %h0|%h0, %1}"
7533 [(set_attr "type" "test")
7534 (set_attr "mode" "QI")
7535 (set_attr "length_immediate" "1")
7536 (set_attr "modrm" "1")
7537 (set_attr "pent_pair" "np")])
7539 (define_insn "*testqi_ext_1_rex64"
7540 [(set (reg FLAGS_REG)
7544 (match_operand 0 "ext_register_operand" "Q")
7548 (match_operand:QI 1 "register_operand" "Q")))
7550 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7551 "test{b}\t{%1, %h0|%h0, %1}"
7552 [(set_attr "type" "test")
7553 (set_attr "mode" "QI")])
7555 (define_insn "*testqi_ext_1"
7556 [(set (reg FLAGS_REG)
7560 (match_operand 0 "ext_register_operand" "Q")
7564 (match_operand:QI 1 "general_operand" "Qm")))
7566 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7567 "test{b}\t{%1, %h0|%h0, %1}"
7568 [(set_attr "type" "test")
7569 (set_attr "mode" "QI")])
7571 (define_insn "*testqi_ext_2"
7572 [(set (reg FLAGS_REG)
7576 (match_operand 0 "ext_register_operand" "Q")
7580 (match_operand 1 "ext_register_operand" "Q")
7584 "ix86_match_ccmode (insn, CCNOmode)"
7585 "test{b}\t{%h1, %h0|%h0, %h1}"
7586 [(set_attr "type" "test")
7587 (set_attr "mode" "QI")])
7589 (define_insn "*testqi_ext_3_rex64"
7590 [(set (reg FLAGS_REG)
7591 (compare (zero_extract:DI
7592 (match_operand 0 "nonimmediate_operand" "rm")
7593 (match_operand:DI 1 "const_int_operand" "")
7594 (match_operand:DI 2 "const_int_operand" ""))
7597 && ix86_match_ccmode (insn, CCNOmode)
7598 && INTVAL (operands[1]) > 0
7599 && INTVAL (operands[2]) >= 0
7600 /* Ensure that resulting mask is zero or sign extended operand. */
7601 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7602 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7603 && INTVAL (operands[1]) > 32))
7604 && (GET_MODE (operands[0]) == SImode
7605 || GET_MODE (operands[0]) == DImode
7606 || GET_MODE (operands[0]) == HImode
7607 || GET_MODE (operands[0]) == QImode)"
7610 ;; Combine likes to form bit extractions for some tests. Humor it.
7611 (define_insn "*testqi_ext_3"
7612 [(set (reg FLAGS_REG)
7613 (compare (zero_extract:SI
7614 (match_operand 0 "nonimmediate_operand" "rm")
7615 (match_operand:SI 1 "const_int_operand" "")
7616 (match_operand:SI 2 "const_int_operand" ""))
7618 "ix86_match_ccmode (insn, CCNOmode)
7619 && INTVAL (operands[1]) > 0
7620 && INTVAL (operands[2]) >= 0
7621 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7622 && (GET_MODE (operands[0]) == SImode
7623 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7624 || GET_MODE (operands[0]) == HImode
7625 || GET_MODE (operands[0]) == QImode)"
7629 [(set (match_operand 0 "flags_reg_operand" "")
7630 (match_operator 1 "compare_operator"
7632 (match_operand 2 "nonimmediate_operand" "")
7633 (match_operand 3 "const_int_operand" "")
7634 (match_operand 4 "const_int_operand" ""))
7636 "ix86_match_ccmode (insn, CCNOmode)"
7637 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7639 rtx val = operands[2];
7640 HOST_WIDE_INT len = INTVAL (operands[3]);
7641 HOST_WIDE_INT pos = INTVAL (operands[4]);
7643 enum machine_mode mode, submode;
7645 mode = GET_MODE (val);
7648 /* ??? Combine likes to put non-volatile mem extractions in QImode
7649 no matter the size of the test. So find a mode that works. */
7650 if (! MEM_VOLATILE_P (val))
7652 mode = smallest_mode_for_size (pos + len, MODE_INT);
7653 val = adjust_address (val, mode, 0);
7656 else if (GET_CODE (val) == SUBREG
7657 && (submode = GET_MODE (SUBREG_REG (val)),
7658 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7659 && pos + len <= GET_MODE_BITSIZE (submode)
7660 && GET_MODE_CLASS (submode) == MODE_INT)
7662 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7664 val = SUBREG_REG (val);
7666 else if (mode == HImode && pos + len <= 8)
7668 /* Small HImode tests can be converted to QImode. */
7670 val = gen_lowpart (QImode, val);
7673 if (len == HOST_BITS_PER_WIDE_INT)
7676 mask = ((HOST_WIDE_INT)1 << len) - 1;
7679 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7682 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7683 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7684 ;; this is relatively important trick.
7685 ;; Do the conversion only post-reload to avoid limiting of the register class
7688 [(set (match_operand 0 "flags_reg_operand" "")
7689 (match_operator 1 "compare_operator"
7690 [(and (match_operand 2 "register_operand" "")
7691 (match_operand 3 "const_int_operand" ""))
7694 && QI_REG_P (operands[2])
7695 && GET_MODE (operands[2]) != QImode
7696 && ((ix86_match_ccmode (insn, CCZmode)
7697 && !(INTVAL (operands[3]) & ~(255 << 8)))
7698 || (ix86_match_ccmode (insn, CCNOmode)
7699 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7702 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7705 "operands[2] = gen_lowpart (SImode, operands[2]);
7706 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7709 [(set (match_operand 0 "flags_reg_operand" "")
7710 (match_operator 1 "compare_operator"
7711 [(and (match_operand 2 "nonimmediate_operand" "")
7712 (match_operand 3 "const_int_operand" ""))
7715 && GET_MODE (operands[2]) != QImode
7716 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7717 && ((ix86_match_ccmode (insn, CCZmode)
7718 && !(INTVAL (operands[3]) & ~255))
7719 || (ix86_match_ccmode (insn, CCNOmode)
7720 && !(INTVAL (operands[3]) & ~127)))"
7722 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7724 "operands[2] = gen_lowpart (QImode, operands[2]);
7725 operands[3] = gen_lowpart (QImode, operands[3]);")
7727 ;; %%% This used to optimize known byte-wide and operations to memory,
7728 ;; and sometimes to QImode registers. If this is considered useful,
7729 ;; it should be done with splitters.
7731 (define_expand "and<mode>3"
7732 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7733 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7734 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7736 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7738 (define_insn "*anddi_1"
7739 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7741 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7742 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7746 switch (get_attr_type (insn))
7750 enum machine_mode mode;
7752 gcc_assert (CONST_INT_P (operands[2]));
7753 if (INTVAL (operands[2]) == 0xff)
7757 gcc_assert (INTVAL (operands[2]) == 0xffff);
7761 operands[1] = gen_lowpart (mode, operands[1]);
7763 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7765 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7769 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7770 if (get_attr_mode (insn) == MODE_SI)
7771 return "and{l}\t{%k2, %k0|%k0, %k2}";
7773 return "and{q}\t{%2, %0|%0, %2}";
7776 [(set_attr "type" "alu,alu,alu,imovx")
7777 (set_attr "length_immediate" "*,*,*,0")
7778 (set (attr "prefix_rex")
7780 (and (eq_attr "type" "imovx")
7781 (and (match_test "INTVAL (operands[2]) == 0xff")
7782 (match_operand 1 "ext_QIreg_operand" "")))
7784 (const_string "*")))
7785 (set_attr "mode" "SI,DI,DI,SI")])
7787 (define_insn "*andsi_1"
7788 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7789 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7790 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "ix86_binary_operator_ok (AND, SImode, operands)"
7794 switch (get_attr_type (insn))
7798 enum machine_mode mode;
7800 gcc_assert (CONST_INT_P (operands[2]));
7801 if (INTVAL (operands[2]) == 0xff)
7805 gcc_assert (INTVAL (operands[2]) == 0xffff);
7809 operands[1] = gen_lowpart (mode, operands[1]);
7811 return "movz{bl|x}\t{%1, %0|%0, %1}";
7813 return "movz{wl|x}\t{%1, %0|%0, %1}";
7817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7818 return "and{l}\t{%2, %0|%0, %2}";
7821 [(set_attr "type" "alu,alu,imovx")
7822 (set (attr "prefix_rex")
7824 (and (eq_attr "type" "imovx")
7825 (and (match_test "INTVAL (operands[2]) == 0xff")
7826 (match_operand 1 "ext_QIreg_operand" "")))
7828 (const_string "*")))
7829 (set_attr "length_immediate" "*,*,0")
7830 (set_attr "mode" "SI")])
7832 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7833 (define_insn "*andsi_1_zext"
7834 [(set (match_operand:DI 0 "register_operand" "=r")
7836 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7837 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7838 (clobber (reg:CC FLAGS_REG))]
7839 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7840 "and{l}\t{%2, %k0|%k0, %2}"
7841 [(set_attr "type" "alu")
7842 (set_attr "mode" "SI")])
7844 (define_insn "*andhi_1"
7845 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7846 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7847 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, HImode, operands)"
7851 switch (get_attr_type (insn))
7854 gcc_assert (CONST_INT_P (operands[2]));
7855 gcc_assert (INTVAL (operands[2]) == 0xff);
7856 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7861 return "and{w}\t{%2, %0|%0, %2}";
7864 [(set_attr "type" "alu,alu,imovx")
7865 (set_attr "length_immediate" "*,*,0")
7866 (set (attr "prefix_rex")
7868 (and (eq_attr "type" "imovx")
7869 (match_operand 1 "ext_QIreg_operand" ""))
7871 (const_string "*")))
7872 (set_attr "mode" "HI,HI,SI")])
7874 ;; %%% Potential partial reg stall on alternative 2. What to do?
7875 (define_insn "*andqi_1"
7876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7877 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7878 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "ix86_binary_operator_ok (AND, QImode, operands)"
7882 and{b}\t{%2, %0|%0, %2}
7883 and{b}\t{%2, %0|%0, %2}
7884 and{l}\t{%k2, %k0|%k0, %k2}"
7885 [(set_attr "type" "alu")
7886 (set_attr "mode" "QI,QI,SI")])
7888 (define_insn "*andqi_1_slp"
7889 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7890 (and:QI (match_dup 0)
7891 (match_operand:QI 1 "general_operand" "qn,qmn")))
7892 (clobber (reg:CC FLAGS_REG))]
7893 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7894 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7895 "and{b}\t{%1, %0|%0, %1}"
7896 [(set_attr "type" "alu1")
7897 (set_attr "mode" "QI")])
7900 [(set (match_operand 0 "register_operand" "")
7902 (const_int -65536)))
7903 (clobber (reg:CC FLAGS_REG))]
7904 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7905 || optimize_function_for_size_p (cfun)"
7906 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7907 "operands[1] = gen_lowpart (HImode, operands[0]);")
7910 [(set (match_operand 0 "ext_register_operand" "")
7913 (clobber (reg:CC FLAGS_REG))]
7914 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7915 && reload_completed"
7916 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7917 "operands[1] = gen_lowpart (QImode, operands[0]);")
7920 [(set (match_operand 0 "ext_register_operand" "")
7922 (const_int -65281)))
7923 (clobber (reg:CC FLAGS_REG))]
7924 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7925 && reload_completed"
7926 [(parallel [(set (zero_extract:SI (match_dup 0)
7930 (zero_extract:SI (match_dup 0)
7933 (zero_extract:SI (match_dup 0)
7936 (clobber (reg:CC FLAGS_REG))])]
7937 "operands[0] = gen_lowpart (SImode, operands[0]);")
7939 (define_insn "*anddi_2"
7940 [(set (reg FLAGS_REG)
7943 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7944 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7946 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7947 (and:DI (match_dup 1) (match_dup 2)))]
7948 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7949 && ix86_binary_operator_ok (AND, DImode, operands)"
7951 and{l}\t{%k2, %k0|%k0, %k2}
7952 and{q}\t{%2, %0|%0, %2}
7953 and{q}\t{%2, %0|%0, %2}"
7954 [(set_attr "type" "alu")
7955 (set_attr "mode" "SI,DI,DI")])
7957 (define_insn "*andqi_2_maybe_si"
7958 [(set (reg FLAGS_REG)
7960 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7961 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7963 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7964 (and:QI (match_dup 1) (match_dup 2)))]
7965 "ix86_binary_operator_ok (AND, QImode, operands)
7966 && ix86_match_ccmode (insn,
7967 CONST_INT_P (operands[2])
7968 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7970 if (which_alternative == 2)
7972 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7973 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7974 return "and{l}\t{%2, %k0|%k0, %2}";
7976 return "and{b}\t{%2, %0|%0, %2}";
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "QI,QI,SI")])
7981 (define_insn "*and<mode>_2"
7982 [(set (reg FLAGS_REG)
7983 (compare (and:SWI124
7984 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7985 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7987 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7988 (and:SWI124 (match_dup 1) (match_dup 2)))]
7989 "ix86_match_ccmode (insn, CCNOmode)
7990 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7991 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7992 [(set_attr "type" "alu")
7993 (set_attr "mode" "<MODE>")])
7995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7996 (define_insn "*andsi_2_zext"
7997 [(set (reg FLAGS_REG)
7999 (match_operand:SI 1 "nonimmediate_operand" "%0")
8000 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8002 (set (match_operand:DI 0 "register_operand" "=r")
8003 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8004 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8005 && ix86_binary_operator_ok (AND, SImode, operands)"
8006 "and{l}\t{%2, %k0|%k0, %2}"
8007 [(set_attr "type" "alu")
8008 (set_attr "mode" "SI")])
8010 (define_insn "*andqi_2_slp"
8011 [(set (reg FLAGS_REG)
8013 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8014 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8016 (set (strict_low_part (match_dup 0))
8017 (and:QI (match_dup 0) (match_dup 1)))]
8018 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8019 && ix86_match_ccmode (insn, CCNOmode)
8020 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8021 "and{b}\t{%1, %0|%0, %1}"
8022 [(set_attr "type" "alu1")
8023 (set_attr "mode" "QI")])
8025 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8026 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8027 ;; for a QImode operand, which of course failed.
8028 (define_insn "andqi_ext_0"
8029 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8034 (match_operand 1 "ext_register_operand" "0")
8037 (match_operand 2 "const_int_operand" "n")))
8038 (clobber (reg:CC FLAGS_REG))]
8040 "and{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "type" "alu")
8042 (set_attr "length_immediate" "1")
8043 (set_attr "modrm" "1")
8044 (set_attr "mode" "QI")])
8046 ;; Generated by peephole translating test to and. This shows up
8047 ;; often in fp comparisons.
8048 (define_insn "*andqi_ext_0_cc"
8049 [(set (reg FLAGS_REG)
8053 (match_operand 1 "ext_register_operand" "0")
8056 (match_operand 2 "const_int_operand" "n"))
8058 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8067 "ix86_match_ccmode (insn, CCNOmode)"
8068 "and{b}\t{%2, %h0|%h0, %2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "length_immediate" "1")
8071 (set_attr "modrm" "1")
8072 (set_attr "mode" "QI")])
8074 (define_insn "*andqi_ext_1_rex64"
8075 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8080 (match_operand 1 "ext_register_operand" "0")
8084 (match_operand 2 "ext_register_operand" "Q"))))
8085 (clobber (reg:CC FLAGS_REG))]
8087 "and{b}\t{%2, %h0|%h0, %2}"
8088 [(set_attr "type" "alu")
8089 (set_attr "length_immediate" "0")
8090 (set_attr "mode" "QI")])
8092 (define_insn "*andqi_ext_1"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8098 (match_operand 1 "ext_register_operand" "0")
8102 (match_operand:QI 2 "general_operand" "Qm"))))
8103 (clobber (reg:CC FLAGS_REG))]
8105 "and{b}\t{%2, %h0|%h0, %2}"
8106 [(set_attr "type" "alu")
8107 (set_attr "length_immediate" "0")
8108 (set_attr "mode" "QI")])
8110 (define_insn "*andqi_ext_2"
8111 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8116 (match_operand 1 "ext_register_operand" "%0")
8120 (match_operand 2 "ext_register_operand" "Q")
8123 (clobber (reg:CC FLAGS_REG))]
8125 "and{b}\t{%h2, %h0|%h0, %h2}"
8126 [(set_attr "type" "alu")
8127 (set_attr "length_immediate" "0")
8128 (set_attr "mode" "QI")])
8130 ;; Convert wide AND instructions with immediate operand to shorter QImode
8131 ;; equivalents when possible.
8132 ;; Don't do the splitting with memory operands, since it introduces risk
8133 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8134 ;; for size, but that can (should?) be handled by generic code instead.
8136 [(set (match_operand 0 "register_operand" "")
8137 (and (match_operand 1 "register_operand" "")
8138 (match_operand 2 "const_int_operand" "")))
8139 (clobber (reg:CC FLAGS_REG))]
8141 && QI_REG_P (operands[0])
8142 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8143 && !(~INTVAL (operands[2]) & ~(255 << 8))
8144 && GET_MODE (operands[0]) != QImode"
8145 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8146 (and:SI (zero_extract:SI (match_dup 1)
8147 (const_int 8) (const_int 8))
8149 (clobber (reg:CC FLAGS_REG))])]
8150 "operands[0] = gen_lowpart (SImode, operands[0]);
8151 operands[1] = gen_lowpart (SImode, operands[1]);
8152 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8154 ;; Since AND can be encoded with sign extended immediate, this is only
8155 ;; profitable when 7th bit is not set.
8157 [(set (match_operand 0 "register_operand" "")
8158 (and (match_operand 1 "general_operand" "")
8159 (match_operand 2 "const_int_operand" "")))
8160 (clobber (reg:CC FLAGS_REG))]
8162 && ANY_QI_REG_P (operands[0])
8163 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8164 && !(~INTVAL (operands[2]) & ~255)
8165 && !(INTVAL (operands[2]) & 128)
8166 && GET_MODE (operands[0]) != QImode"
8167 [(parallel [(set (strict_low_part (match_dup 0))
8168 (and:QI (match_dup 1)
8170 (clobber (reg:CC FLAGS_REG))])]
8171 "operands[0] = gen_lowpart (QImode, operands[0]);
8172 operands[1] = gen_lowpart (QImode, operands[1]);
8173 operands[2] = gen_lowpart (QImode, operands[2]);")
8175 ;; Logical inclusive and exclusive OR instructions
8177 ;; %%% This used to optimize known byte-wide and operations to memory.
8178 ;; If this is considered useful, it should be done with splitters.
8180 (define_expand "<code><mode>3"
8181 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8182 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8183 (match_operand:SWIM 2 "<general_operand>" "")))]
8185 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8187 (define_insn "*<code><mode>_1"
8188 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8190 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8191 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8192 (clobber (reg:CC FLAGS_REG))]
8193 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8194 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "mode" "<MODE>")])
8198 ;; %%% Potential partial reg stall on alternative 2. What to do?
8199 (define_insn "*<code>qi_1"
8200 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8201 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8202 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8203 (clobber (reg:CC FLAGS_REG))]
8204 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8206 <logic>{b}\t{%2, %0|%0, %2}
8207 <logic>{b}\t{%2, %0|%0, %2}
8208 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "QI,QI,SI")])
8212 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8213 (define_insn "*<code>si_1_zext"
8214 [(set (match_operand:DI 0 "register_operand" "=r")
8216 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8217 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8218 (clobber (reg:CC FLAGS_REG))]
8219 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220 "<logic>{l}\t{%2, %k0|%k0, %2}"
8221 [(set_attr "type" "alu")
8222 (set_attr "mode" "SI")])
8224 (define_insn "*<code>si_1_zext_imm"
8225 [(set (match_operand:DI 0 "register_operand" "=r")
8227 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8228 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8231 "<logic>{l}\t{%2, %k0|%k0, %2}"
8232 [(set_attr "type" "alu")
8233 (set_attr "mode" "SI")])
8235 (define_insn "*<code>qi_1_slp"
8236 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8237 (any_or:QI (match_dup 0)
8238 (match_operand:QI 1 "general_operand" "qmn,qn")))
8239 (clobber (reg:CC FLAGS_REG))]
8240 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8241 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8242 "<logic>{b}\t{%1, %0|%0, %1}"
8243 [(set_attr "type" "alu1")
8244 (set_attr "mode" "QI")])
8246 (define_insn "*<code><mode>_2"
8247 [(set (reg FLAGS_REG)
8248 (compare (any_or:SWI
8249 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8250 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8252 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8253 (any_or:SWI (match_dup 1) (match_dup 2)))]
8254 "ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8256 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "<MODE>")])
8260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8261 ;; ??? Special case for immediate operand is missing - it is tricky.
8262 (define_insn "*<code>si_2_zext"
8263 [(set (reg FLAGS_REG)
8264 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8265 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8267 (set (match_operand:DI 0 "register_operand" "=r")
8268 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8269 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8270 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8271 "<logic>{l}\t{%2, %k0|%k0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "mode" "SI")])
8275 (define_insn "*<code>si_2_zext_imm"
8276 [(set (reg FLAGS_REG)
8278 (match_operand:SI 1 "nonimmediate_operand" "%0")
8279 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8281 (set (match_operand:DI 0 "register_operand" "=r")
8282 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8283 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8284 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8285 "<logic>{l}\t{%2, %k0|%k0, %2}"
8286 [(set_attr "type" "alu")
8287 (set_attr "mode" "SI")])
8289 (define_insn "*<code>qi_2_slp"
8290 [(set (reg FLAGS_REG)
8291 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8292 (match_operand:QI 1 "general_operand" "qmn,qn"))
8294 (set (strict_low_part (match_dup 0))
8295 (any_or:QI (match_dup 0) (match_dup 1)))]
8296 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8297 && ix86_match_ccmode (insn, CCNOmode)
8298 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8299 "<logic>{b}\t{%1, %0|%0, %1}"
8300 [(set_attr "type" "alu1")
8301 (set_attr "mode" "QI")])
8303 (define_insn "*<code><mode>_3"
8304 [(set (reg FLAGS_REG)
8305 (compare (any_or:SWI
8306 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8307 (match_operand:SWI 2 "<general_operand>" "<g>"))
8309 (clobber (match_scratch:SWI 0 "=<r>"))]
8310 "ix86_match_ccmode (insn, CCNOmode)
8311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8312 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8313 [(set_attr "type" "alu")
8314 (set_attr "mode" "<MODE>")])
8316 (define_insn "*<code>qi_ext_0"
8317 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8322 (match_operand 1 "ext_register_operand" "0")
8325 (match_operand 2 "const_int_operand" "n")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8328 "<logic>{b}\t{%2, %h0|%h0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "length_immediate" "1")
8331 (set_attr "modrm" "1")
8332 (set_attr "mode" "QI")])
8334 (define_insn "*<code>qi_ext_1_rex64"
8335 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8340 (match_operand 1 "ext_register_operand" "0")
8344 (match_operand 2 "ext_register_operand" "Q"))))
8345 (clobber (reg:CC FLAGS_REG))]
8347 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8348 "<logic>{b}\t{%2, %h0|%h0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "length_immediate" "0")
8351 (set_attr "mode" "QI")])
8353 (define_insn "*<code>qi_ext_1"
8354 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359 (match_operand 1 "ext_register_operand" "0")
8363 (match_operand:QI 2 "general_operand" "Qm"))))
8364 (clobber (reg:CC FLAGS_REG))]
8366 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8367 "<logic>{b}\t{%2, %h0|%h0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "length_immediate" "0")
8370 (set_attr "mode" "QI")])
8372 (define_insn "*<code>qi_ext_2"
8373 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8377 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8380 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8383 (clobber (reg:CC FLAGS_REG))]
8384 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8385 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "length_immediate" "0")
8388 (set_attr "mode" "QI")])
8391 [(set (match_operand 0 "register_operand" "")
8392 (any_or (match_operand 1 "register_operand" "")
8393 (match_operand 2 "const_int_operand" "")))
8394 (clobber (reg:CC FLAGS_REG))]
8396 && QI_REG_P (operands[0])
8397 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && !(INTVAL (operands[2]) & ~(255 << 8))
8399 && GET_MODE (operands[0]) != QImode"
8400 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8401 (any_or:SI (zero_extract:SI (match_dup 1)
8402 (const_int 8) (const_int 8))
8404 (clobber (reg:CC FLAGS_REG))])]
8405 "operands[0] = gen_lowpart (SImode, operands[0]);
8406 operands[1] = gen_lowpart (SImode, operands[1]);
8407 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8409 ;; Since OR can be encoded with sign extended immediate, this is only
8410 ;; profitable when 7th bit is set.
8412 [(set (match_operand 0 "register_operand" "")
8413 (any_or (match_operand 1 "general_operand" "")
8414 (match_operand 2 "const_int_operand" "")))
8415 (clobber (reg:CC FLAGS_REG))]
8417 && ANY_QI_REG_P (operands[0])
8418 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8419 && !(INTVAL (operands[2]) & ~255)
8420 && (INTVAL (operands[2]) & 128)
8421 && GET_MODE (operands[0]) != QImode"
8422 [(parallel [(set (strict_low_part (match_dup 0))
8423 (any_or:QI (match_dup 1)
8425 (clobber (reg:CC FLAGS_REG))])]
8426 "operands[0] = gen_lowpart (QImode, operands[0]);
8427 operands[1] = gen_lowpart (QImode, operands[1]);
8428 operands[2] = gen_lowpart (QImode, operands[2]);")
8430 (define_expand "xorqi_cc_ext_1"
8432 (set (reg:CCNO FLAGS_REG)
8436 (match_operand 1 "ext_register_operand" "")
8439 (match_operand:QI 2 "general_operand" ""))
8441 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8451 (define_insn "*xorqi_cc_ext_1_rex64"
8452 [(set (reg FLAGS_REG)
8456 (match_operand 1 "ext_register_operand" "0")
8459 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8461 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8471 "xor{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "modrm" "1")
8474 (set_attr "mode" "QI")])
8476 (define_insn "*xorqi_cc_ext_1"
8477 [(set (reg FLAGS_REG)
8481 (match_operand 1 "ext_register_operand" "0")
8484 (match_operand:QI 2 "general_operand" "qmn"))
8486 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8495 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8496 "xor{b}\t{%2, %h0|%h0, %2}"
8497 [(set_attr "type" "alu")
8498 (set_attr "modrm" "1")
8499 (set_attr "mode" "QI")])
8501 ;; Negation instructions
8503 (define_expand "neg<mode>2"
8504 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8505 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8507 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8509 (define_insn_and_split "*neg<dwi>2_doubleword"
8510 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8511 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8512 (clobber (reg:CC FLAGS_REG))]
8513 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8517 [(set (reg:CCZ FLAGS_REG)
8518 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8519 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8522 (plus:DWIH (match_dup 3)
8523 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8525 (clobber (reg:CC FLAGS_REG))])
8528 (neg:DWIH (match_dup 2)))
8529 (clobber (reg:CC FLAGS_REG))])]
8530 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8532 (define_insn "*neg<mode>2_1"
8533 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8534 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8537 "neg{<imodesuffix>}\t%0"
8538 [(set_attr "type" "negnot")
8539 (set_attr "mode" "<MODE>")])
8541 ;; Combine is quite creative about this pattern.
8542 (define_insn "*negsi2_1_zext"
8543 [(set (match_operand:DI 0 "register_operand" "=r")
8545 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8548 (clobber (reg:CC FLAGS_REG))]
8549 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8551 [(set_attr "type" "negnot")
8552 (set_attr "mode" "SI")])
8554 ;; The problem with neg is that it does not perform (compare x 0),
8555 ;; it really performs (compare 0 x), which leaves us with the zero
8556 ;; flag being the only useful item.
8558 (define_insn "*neg<mode>2_cmpz"
8559 [(set (reg:CCZ FLAGS_REG)
8561 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8563 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8564 (neg:SWI (match_dup 1)))]
8565 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8566 "neg{<imodesuffix>}\t%0"
8567 [(set_attr "type" "negnot")
8568 (set_attr "mode" "<MODE>")])
8570 (define_insn "*negsi2_cmpz_zext"
8571 [(set (reg:CCZ FLAGS_REG)
8575 (match_operand:DI 1 "register_operand" "0")
8579 (set (match_operand:DI 0 "register_operand" "=r")
8580 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8583 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8585 [(set_attr "type" "negnot")
8586 (set_attr "mode" "SI")])
8588 ;; Changing of sign for FP values is doable using integer unit too.
8590 (define_expand "<code><mode>2"
8591 [(set (match_operand:X87MODEF 0 "register_operand" "")
8592 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8593 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8594 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8596 (define_insn "*absneg<mode>2_mixed"
8597 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8598 (match_operator:MODEF 3 "absneg_operator"
8599 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8600 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8601 (clobber (reg:CC FLAGS_REG))]
8602 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8605 (define_insn "*absneg<mode>2_sse"
8606 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8607 (match_operator:MODEF 3 "absneg_operator"
8608 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8609 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8614 (define_insn "*absneg<mode>2_i387"
8615 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8616 (match_operator:X87MODEF 3 "absneg_operator"
8617 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8618 (use (match_operand 2 "" ""))
8619 (clobber (reg:CC FLAGS_REG))]
8620 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8623 (define_expand "<code>tf2"
8624 [(set (match_operand:TF 0 "register_operand" "")
8625 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8627 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8629 (define_insn "*absnegtf2_sse"
8630 [(set (match_operand:TF 0 "register_operand" "=x,x")
8631 (match_operator:TF 3 "absneg_operator"
8632 [(match_operand:TF 1 "register_operand" "0,x")]))
8633 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8634 (clobber (reg:CC FLAGS_REG))]
8638 ;; Splitters for fp abs and neg.
8641 [(set (match_operand 0 "fp_register_operand" "")
8642 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8643 (use (match_operand 2 "" ""))
8644 (clobber (reg:CC FLAGS_REG))]
8646 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8649 [(set (match_operand 0 "register_operand" "")
8650 (match_operator 3 "absneg_operator"
8651 [(match_operand 1 "register_operand" "")]))
8652 (use (match_operand 2 "nonimmediate_operand" ""))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "reload_completed && SSE_REG_P (operands[0])"
8655 [(set (match_dup 0) (match_dup 3))]
8657 enum machine_mode mode = GET_MODE (operands[0]);
8658 enum machine_mode vmode = GET_MODE (operands[2]);
8661 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8662 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8663 if (operands_match_p (operands[0], operands[2]))
8666 operands[1] = operands[2];
8669 if (GET_CODE (operands[3]) == ABS)
8670 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8672 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8677 [(set (match_operand:SF 0 "register_operand" "")
8678 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8679 (use (match_operand:V4SF 2 "" ""))
8680 (clobber (reg:CC FLAGS_REG))]
8682 [(parallel [(set (match_dup 0) (match_dup 1))
8683 (clobber (reg:CC FLAGS_REG))])]
8686 operands[0] = gen_lowpart (SImode, operands[0]);
8687 if (GET_CODE (operands[1]) == ABS)
8689 tmp = gen_int_mode (0x7fffffff, SImode);
8690 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8694 tmp = gen_int_mode (0x80000000, SImode);
8695 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8701 [(set (match_operand:DF 0 "register_operand" "")
8702 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8703 (use (match_operand 2 "" ""))
8704 (clobber (reg:CC FLAGS_REG))]
8706 [(parallel [(set (match_dup 0) (match_dup 1))
8707 (clobber (reg:CC FLAGS_REG))])]
8712 tmp = gen_lowpart (DImode, operands[0]);
8713 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8716 if (GET_CODE (operands[1]) == ABS)
8719 tmp = gen_rtx_NOT (DImode, tmp);
8723 operands[0] = gen_highpart (SImode, operands[0]);
8724 if (GET_CODE (operands[1]) == ABS)
8726 tmp = gen_int_mode (0x7fffffff, SImode);
8727 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8731 tmp = gen_int_mode (0x80000000, SImode);
8732 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8739 [(set (match_operand:XF 0 "register_operand" "")
8740 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8741 (use (match_operand 2 "" ""))
8742 (clobber (reg:CC FLAGS_REG))]
8744 [(parallel [(set (match_dup 0) (match_dup 1))
8745 (clobber (reg:CC FLAGS_REG))])]
8748 operands[0] = gen_rtx_REG (SImode,
8749 true_regnum (operands[0])
8750 + (TARGET_64BIT ? 1 : 2));
8751 if (GET_CODE (operands[1]) == ABS)
8753 tmp = GEN_INT (0x7fff);
8754 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8758 tmp = GEN_INT (0x8000);
8759 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8764 ;; Conditionalize these after reload. If they match before reload, we
8765 ;; lose the clobber and ability to use integer instructions.
8767 (define_insn "*<code><mode>2_1"
8768 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8769 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8771 && (reload_completed
8772 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8773 "f<absneg_mnemonic>"
8774 [(set_attr "type" "fsgn")
8775 (set_attr "mode" "<MODE>")])
8777 (define_insn "*<code>extendsfdf2"
8778 [(set (match_operand:DF 0 "register_operand" "=f")
8779 (absneg:DF (float_extend:DF
8780 (match_operand:SF 1 "register_operand" "0"))))]
8781 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8782 "f<absneg_mnemonic>"
8783 [(set_attr "type" "fsgn")
8784 (set_attr "mode" "DF")])
8786 (define_insn "*<code>extendsfxf2"
8787 [(set (match_operand:XF 0 "register_operand" "=f")
8788 (absneg:XF (float_extend:XF
8789 (match_operand:SF 1 "register_operand" "0"))))]
8791 "f<absneg_mnemonic>"
8792 [(set_attr "type" "fsgn")
8793 (set_attr "mode" "XF")])
8795 (define_insn "*<code>extenddfxf2"
8796 [(set (match_operand:XF 0 "register_operand" "=f")
8797 (absneg:XF (float_extend:XF
8798 (match_operand:DF 1 "register_operand" "0"))))]
8800 "f<absneg_mnemonic>"
8801 [(set_attr "type" "fsgn")
8802 (set_attr "mode" "XF")])
8804 ;; Copysign instructions
8806 (define_mode_iterator CSGNMODE [SF DF TF])
8807 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8809 (define_expand "copysign<mode>3"
8810 [(match_operand:CSGNMODE 0 "register_operand" "")
8811 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8812 (match_operand:CSGNMODE 2 "register_operand" "")]
8813 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8814 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8815 "ix86_expand_copysign (operands); DONE;")
8817 (define_insn_and_split "copysign<mode>3_const"
8818 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8820 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8821 (match_operand:CSGNMODE 2 "register_operand" "0")
8822 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8824 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8825 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8827 "&& reload_completed"
8829 "ix86_split_copysign_const (operands); DONE;")
8831 (define_insn "copysign<mode>3_var"
8832 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8834 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8835 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8836 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8837 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8839 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8840 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8841 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8845 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8847 [(match_operand:CSGNMODE 2 "register_operand" "")
8848 (match_operand:CSGNMODE 3 "register_operand" "")
8849 (match_operand:<CSGNVMODE> 4 "" "")
8850 (match_operand:<CSGNVMODE> 5 "" "")]
8852 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8853 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8854 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8855 && reload_completed"
8857 "ix86_split_copysign_var (operands); DONE;")
8859 ;; One complement instructions
8861 (define_expand "one_cmpl<mode>2"
8862 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8863 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8865 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8867 (define_insn "*one_cmpl<mode>2_1"
8868 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8869 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8870 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8871 "not{<imodesuffix>}\t%0"
8872 [(set_attr "type" "negnot")
8873 (set_attr "mode" "<MODE>")])
8875 ;; %%% Potential partial reg stall on alternative 1. What to do?
8876 (define_insn "*one_cmplqi2_1"
8877 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8878 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8879 "ix86_unary_operator_ok (NOT, QImode, operands)"
8883 [(set_attr "type" "negnot")
8884 (set_attr "mode" "QI,SI")])
8886 ;; ??? Currently never generated - xor is used instead.
8887 (define_insn "*one_cmplsi2_1_zext"
8888 [(set (match_operand:DI 0 "register_operand" "=r")
8890 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8891 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8893 [(set_attr "type" "negnot")
8894 (set_attr "mode" "SI")])
8896 (define_insn "*one_cmpl<mode>2_2"
8897 [(set (reg FLAGS_REG)
8898 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8900 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8901 (not:SWI (match_dup 1)))]
8902 "ix86_match_ccmode (insn, CCNOmode)
8903 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8905 [(set_attr "type" "alu1")
8906 (set_attr "mode" "<MODE>")])
8909 [(set (match_operand 0 "flags_reg_operand" "")
8910 (match_operator 2 "compare_operator"
8911 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8913 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8914 (not:SWI (match_dup 3)))]
8915 "ix86_match_ccmode (insn, CCNOmode)"
8916 [(parallel [(set (match_dup 0)
8917 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8920 (xor:SWI (match_dup 3) (const_int -1)))])])
8922 ;; ??? Currently never generated - xor is used instead.
8923 (define_insn "*one_cmplsi2_2_zext"
8924 [(set (reg FLAGS_REG)
8925 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8927 (set (match_operand:DI 0 "register_operand" "=r")
8928 (zero_extend:DI (not:SI (match_dup 1))))]
8929 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8930 && ix86_unary_operator_ok (NOT, SImode, operands)"
8932 [(set_attr "type" "alu1")
8933 (set_attr "mode" "SI")])
8936 [(set (match_operand 0 "flags_reg_operand" "")
8937 (match_operator 2 "compare_operator"
8938 [(not:SI (match_operand:SI 3 "register_operand" ""))
8940 (set (match_operand:DI 1 "register_operand" "")
8941 (zero_extend:DI (not:SI (match_dup 3))))]
8942 "ix86_match_ccmode (insn, CCNOmode)"
8943 [(parallel [(set (match_dup 0)
8944 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8947 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8949 ;; Shift instructions
8951 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8952 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8953 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8954 ;; from the assembler input.
8956 ;; This instruction shifts the target reg/mem as usual, but instead of
8957 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8958 ;; is a left shift double, bits are taken from the high order bits of
8959 ;; reg, else if the insn is a shift right double, bits are taken from the
8960 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8961 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8963 ;; Since sh[lr]d does not change the `reg' operand, that is done
8964 ;; separately, making all shifts emit pairs of shift double and normal
8965 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8966 ;; support a 63 bit shift, each shift where the count is in a reg expands
8967 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8969 ;; If the shift count is a constant, we need never emit more than one
8970 ;; shift pair, instead using moves and sign extension for counts greater
8973 (define_expand "ashl<mode>3"
8974 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8975 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8976 (match_operand:QI 2 "nonmemory_operand" "")))]
8978 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8980 (define_insn "*ashl<mode>3_doubleword"
8981 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8982 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8983 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8984 (clobber (reg:CC FLAGS_REG))]
8987 [(set_attr "type" "multi")])
8990 [(set (match_operand:DWI 0 "register_operand" "")
8991 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8992 (match_operand:QI 2 "nonmemory_operand" "")))
8993 (clobber (reg:CC FLAGS_REG))]
8994 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8996 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8998 ;; By default we don't ask for a scratch register, because when DWImode
8999 ;; values are manipulated, registers are already at a premium. But if
9000 ;; we have one handy, we won't turn it away.
9003 [(match_scratch:DWIH 3 "r")
9004 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9006 (match_operand:<DWI> 1 "nonmemory_operand" "")
9007 (match_operand:QI 2 "nonmemory_operand" "")))
9008 (clobber (reg:CC FLAGS_REG))])
9012 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9014 (define_insn "x86_64_shld"
9015 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9016 (ior:DI (ashift:DI (match_dup 0)
9017 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9018 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9019 (minus:QI (const_int 64) (match_dup 2)))))
9020 (clobber (reg:CC FLAGS_REG))]
9022 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9023 [(set_attr "type" "ishift")
9024 (set_attr "prefix_0f" "1")
9025 (set_attr "mode" "DI")
9026 (set_attr "athlon_decode" "vector")
9027 (set_attr "amdfam10_decode" "vector")
9028 (set_attr "bdver1_decode" "vector")])
9030 (define_insn "x86_shld"
9031 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9032 (ior:SI (ashift:SI (match_dup 0)
9033 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9034 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9035 (minus:QI (const_int 32) (match_dup 2)))))
9036 (clobber (reg:CC FLAGS_REG))]
9038 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9039 [(set_attr "type" "ishift")
9040 (set_attr "prefix_0f" "1")
9041 (set_attr "mode" "SI")
9042 (set_attr "pent_pair" "np")
9043 (set_attr "athlon_decode" "vector")
9044 (set_attr "amdfam10_decode" "vector")
9045 (set_attr "bdver1_decode" "vector")])
9047 (define_expand "x86_shift<mode>_adj_1"
9048 [(set (reg:CCZ FLAGS_REG)
9049 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9052 (set (match_operand:SWI48 0 "register_operand" "")
9053 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054 (match_operand:SWI48 1 "register_operand" "")
9057 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9058 (match_operand:SWI48 3 "register_operand" "r")
9061 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9063 (define_expand "x86_shift<mode>_adj_2"
9064 [(use (match_operand:SWI48 0 "register_operand" ""))
9065 (use (match_operand:SWI48 1 "register_operand" ""))
9066 (use (match_operand:QI 2 "register_operand" ""))]
9069 rtx label = gen_label_rtx ();
9072 emit_insn (gen_testqi_ccz_1 (operands[2],
9073 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9075 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9076 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9077 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9078 gen_rtx_LABEL_REF (VOIDmode, label),
9080 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9081 JUMP_LABEL (tmp) = label;
9083 emit_move_insn (operands[0], operands[1]);
9084 ix86_expand_clear (operands[1]);
9087 LABEL_NUSES (label) = 1;
9092 ;; Avoid useless masking of count operand.
9093 (define_insn_and_split "*ashl<mode>3_mask"
9094 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9096 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9099 (match_operand:SI 2 "nonimmediate_operand" "c")
9100 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9103 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9104 == GET_MODE_BITSIZE (<MODE>mode)-1"
9107 [(parallel [(set (match_dup 0)
9108 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9109 (clobber (reg:CC FLAGS_REG))])]
9111 if (can_create_pseudo_p ())
9112 operands [2] = force_reg (SImode, operands[2]);
9114 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9116 [(set_attr "type" "ishift")
9117 (set_attr "mode" "<MODE>")])
9119 (define_insn "*bmi2_ashl<mode>3_1"
9120 [(set (match_operand:SWI48 0 "register_operand" "=r")
9121 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9122 (match_operand:SWI48 2 "register_operand" "r")))]
9124 "shlx\t{%2, %1, %0|%0, %1, %2}"
9125 [(set_attr "type" "ishiftx")
9126 (set_attr "mode" "<MODE>")])
9128 (define_insn "*ashl<mode>3_1"
9129 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9130 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9131 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9135 switch (get_attr_type (insn))
9142 gcc_assert (operands[2] == const1_rtx);
9143 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9144 return "add{<imodesuffix>}\t%0, %0";
9147 if (operands[2] == const1_rtx
9148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9149 return "sal{<imodesuffix>}\t%0";
9151 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9154 [(set_attr "isa" "*,*,bmi2")
9156 (cond [(eq_attr "alternative" "1")
9157 (const_string "lea")
9158 (eq_attr "alternative" "2")
9159 (const_string "ishiftx")
9160 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9161 (match_operand 0 "register_operand" ""))
9162 (match_operand 2 "const1_operand" ""))
9163 (const_string "alu")
9165 (const_string "ishift")))
9166 (set (attr "length_immediate")
9168 (ior (eq_attr "type" "alu")
9169 (and (eq_attr "type" "ishift")
9170 (and (match_operand 2 "const1_operand" "")
9171 (ior (match_test "TARGET_SHIFT1")
9172 (match_test "optimize_function_for_size_p (cfun)")))))
9174 (const_string "*")))
9175 (set_attr "mode" "<MODE>")])
9177 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9179 [(set (match_operand:SWI48 0 "register_operand" "")
9180 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9181 (match_operand:QI 2 "register_operand" "")))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "TARGET_BMI2 && reload_completed"
9185 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9186 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9188 (define_insn "*bmi2_ashlsi3_1_zext"
9189 [(set (match_operand:DI 0 "register_operand" "=r")
9191 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9192 (match_operand:SI 2 "register_operand" "r"))))]
9193 "TARGET_64BIT && TARGET_BMI2"
9194 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9195 [(set_attr "type" "ishiftx")
9196 (set_attr "mode" "SI")])
9198 (define_insn "*ashlsi3_1_zext"
9199 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9201 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9202 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9206 switch (get_attr_type (insn))
9213 gcc_assert (operands[2] == const1_rtx);
9214 return "add{l}\t%k0, %k0";
9217 if (operands[2] == const1_rtx
9218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9219 return "sal{l}\t%k0";
9221 return "sal{l}\t{%2, %k0|%k0, %2}";
9224 [(set_attr "isa" "*,*,bmi2")
9226 (cond [(eq_attr "alternative" "1")
9227 (const_string "lea")
9228 (eq_attr "alternative" "2")
9229 (const_string "ishiftx")
9230 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9231 (match_operand 2 "const1_operand" ""))
9232 (const_string "alu")
9234 (const_string "ishift")))
9235 (set (attr "length_immediate")
9237 (ior (eq_attr "type" "alu")
9238 (and (eq_attr "type" "ishift")
9239 (and (match_operand 2 "const1_operand" "")
9240 (ior (match_test "TARGET_SHIFT1")
9241 (match_test "optimize_function_for_size_p (cfun)")))))
9243 (const_string "*")))
9244 (set_attr "mode" "SI")])
9246 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9248 [(set (match_operand:DI 0 "register_operand" "")
9250 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9251 (match_operand:QI 2 "register_operand" ""))))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9255 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9256 "operands[2] = gen_lowpart (SImode, operands[2]);")
9258 (define_insn "*ashlhi3_1"
9259 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9260 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9261 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9262 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9265 switch (get_attr_type (insn))
9271 gcc_assert (operands[2] == const1_rtx);
9272 return "add{w}\t%0, %0";
9275 if (operands[2] == const1_rtx
9276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9277 return "sal{w}\t%0";
9279 return "sal{w}\t{%2, %0|%0, %2}";
9283 (cond [(eq_attr "alternative" "1")
9284 (const_string "lea")
9285 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9286 (match_operand 0 "register_operand" ""))
9287 (match_operand 2 "const1_operand" ""))
9288 (const_string "alu")
9290 (const_string "ishift")))
9291 (set (attr "length_immediate")
9293 (ior (eq_attr "type" "alu")
9294 (and (eq_attr "type" "ishift")
9295 (and (match_operand 2 "const1_operand" "")
9296 (ior (match_test "TARGET_SHIFT1")
9297 (match_test "optimize_function_for_size_p (cfun)")))))
9299 (const_string "*")))
9300 (set_attr "mode" "HI,SI")])
9302 ;; %%% Potential partial reg stall on alternative 1. What to do?
9303 (define_insn "*ashlqi3_1"
9304 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9305 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9306 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9310 switch (get_attr_type (insn))
9316 gcc_assert (operands[2] == const1_rtx);
9317 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9318 return "add{l}\t%k0, %k0";
9320 return "add{b}\t%0, %0";
9323 if (operands[2] == const1_rtx
9324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9326 if (get_attr_mode (insn) == MODE_SI)
9327 return "sal{l}\t%k0";
9329 return "sal{b}\t%0";
9333 if (get_attr_mode (insn) == MODE_SI)
9334 return "sal{l}\t{%2, %k0|%k0, %2}";
9336 return "sal{b}\t{%2, %0|%0, %2}";
9341 (cond [(eq_attr "alternative" "2")
9342 (const_string "lea")
9343 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9344 (match_operand 0 "register_operand" ""))
9345 (match_operand 2 "const1_operand" ""))
9346 (const_string "alu")
9348 (const_string "ishift")))
9349 (set (attr "length_immediate")
9351 (ior (eq_attr "type" "alu")
9352 (and (eq_attr "type" "ishift")
9353 (and (match_operand 2 "const1_operand" "")
9354 (ior (match_test "TARGET_SHIFT1")
9355 (match_test "optimize_function_for_size_p (cfun)")))))
9357 (const_string "*")))
9358 (set_attr "mode" "QI,SI,SI")])
9360 (define_insn "*ashlqi3_1_slp"
9361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9362 (ashift:QI (match_dup 0)
9363 (match_operand:QI 1 "nonmemory_operand" "cI")))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "(optimize_function_for_size_p (cfun)
9366 || !TARGET_PARTIAL_FLAG_REG_STALL
9367 || (operands[1] == const1_rtx
9369 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9371 switch (get_attr_type (insn))
9374 gcc_assert (operands[1] == const1_rtx);
9375 return "add{b}\t%0, %0";
9378 if (operands[1] == const1_rtx
9379 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380 return "sal{b}\t%0";
9382 return "sal{b}\t{%1, %0|%0, %1}";
9386 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9387 (match_operand 0 "register_operand" ""))
9388 (match_operand 1 "const1_operand" ""))
9389 (const_string "alu")
9391 (const_string "ishift1")))
9392 (set (attr "length_immediate")
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift1")
9396 (and (match_operand 1 "const1_operand" "")
9397 (ior (match_test "TARGET_SHIFT1")
9398 (match_test "optimize_function_for_size_p (cfun)")))))
9400 (const_string "*")))
9401 (set_attr "mode" "QI")])
9403 ;; Convert ashift to the lea pattern to avoid flags dependency.
9405 [(set (match_operand 0 "register_operand" "")
9406 (ashift (match_operand 1 "index_register_operand" "")
9407 (match_operand:QI 2 "const_int_operand" "")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9411 && true_regnum (operands[0]) != true_regnum (operands[1])"
9414 enum machine_mode mode = GET_MODE (operands[0]);
9417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9420 operands[0] = gen_lowpart (mode, operands[0]);
9421 operands[1] = gen_lowpart (mode, operands[1]);
9424 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9426 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9432 ;; Convert ashift to the lea pattern to avoid flags dependency.
9434 [(set (match_operand:DI 0 "register_operand" "")
9436 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9437 (match_operand:QI 2 "const_int_operand" ""))))
9438 (clobber (reg:CC FLAGS_REG))]
9439 "TARGET_64BIT && reload_completed
9440 && true_regnum (operands[0]) != true_regnum (operands[1])"
9442 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9444 operands[1] = gen_lowpart (DImode, operands[1]);
9445 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9448 ;; This pattern can't accept a variable shift count, since shifts by
9449 ;; zero don't affect the flags. We assume that shifts by constant
9450 ;; zero are optimized away.
9451 (define_insn "*ashl<mode>3_cmp"
9452 [(set (reg FLAGS_REG)
9454 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9455 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9457 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9458 (ashift:SWI (match_dup 1) (match_dup 2)))]
9459 "(optimize_function_for_size_p (cfun)
9460 || !TARGET_PARTIAL_FLAG_REG_STALL
9461 || (operands[2] == const1_rtx
9463 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9464 && ix86_match_ccmode (insn, CCGOCmode)
9465 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9467 switch (get_attr_type (insn))
9470 gcc_assert (operands[2] == const1_rtx);
9471 return "add{<imodesuffix>}\t%0, %0";
9474 if (operands[2] == const1_rtx
9475 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9476 return "sal{<imodesuffix>}\t%0";
9478 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9482 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9483 (match_operand 0 "register_operand" ""))
9484 (match_operand 2 "const1_operand" ""))
9485 (const_string "alu")
9487 (const_string "ishift")))
9488 (set (attr "length_immediate")
9490 (ior (eq_attr "type" "alu")
9491 (and (eq_attr "type" "ishift")
9492 (and (match_operand 2 "const1_operand" "")
9493 (ior (match_test "TARGET_SHIFT1")
9494 (match_test "optimize_function_for_size_p (cfun)")))))
9496 (const_string "*")))
9497 (set_attr "mode" "<MODE>")])
9499 (define_insn "*ashlsi3_cmp_zext"
9500 [(set (reg FLAGS_REG)
9502 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9503 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9505 (set (match_operand:DI 0 "register_operand" "=r")
9506 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9508 && (optimize_function_for_size_p (cfun)
9509 || !TARGET_PARTIAL_FLAG_REG_STALL
9510 || (operands[2] == const1_rtx
9512 || TARGET_DOUBLE_WITH_ADD)))
9513 && ix86_match_ccmode (insn, CCGOCmode)
9514 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9516 switch (get_attr_type (insn))
9519 gcc_assert (operands[2] == const1_rtx);
9520 return "add{l}\t%k0, %k0";
9523 if (operands[2] == const1_rtx
9524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9525 return "sal{l}\t%k0";
9527 return "sal{l}\t{%2, %k0|%k0, %2}";
9531 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9532 (match_operand 2 "const1_operand" ""))
9533 (const_string "alu")
9535 (const_string "ishift")))
9536 (set (attr "length_immediate")
9538 (ior (eq_attr "type" "alu")
9539 (and (eq_attr "type" "ishift")
9540 (and (match_operand 2 "const1_operand" "")
9541 (ior (match_test "TARGET_SHIFT1")
9542 (match_test "optimize_function_for_size_p (cfun)")))))
9544 (const_string "*")))
9545 (set_attr "mode" "SI")])
9547 (define_insn "*ashl<mode>3_cconly"
9548 [(set (reg FLAGS_REG)
9550 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9551 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9553 (clobber (match_scratch:SWI 0 "=<r>"))]
9554 "(optimize_function_for_size_p (cfun)
9555 || !TARGET_PARTIAL_FLAG_REG_STALL
9556 || (operands[2] == const1_rtx
9558 || TARGET_DOUBLE_WITH_ADD)))
9559 && ix86_match_ccmode (insn, CCGOCmode)"
9561 switch (get_attr_type (insn))
9564 gcc_assert (operands[2] == const1_rtx);
9565 return "add{<imodesuffix>}\t%0, %0";
9568 if (operands[2] == const1_rtx
9569 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9570 return "sal{<imodesuffix>}\t%0";
9572 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9576 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9577 (match_operand 0 "register_operand" ""))
9578 (match_operand 2 "const1_operand" ""))
9579 (const_string "alu")
9581 (const_string "ishift")))
9582 (set (attr "length_immediate")
9584 (ior (eq_attr "type" "alu")
9585 (and (eq_attr "type" "ishift")
9586 (and (match_operand 2 "const1_operand" "")
9587 (ior (match_test "TARGET_SHIFT1")
9588 (match_test "optimize_function_for_size_p (cfun)")))))
9590 (const_string "*")))
9591 (set_attr "mode" "<MODE>")])
9593 ;; See comment above `ashl<mode>3' about how this works.
9595 (define_expand "<shift_insn><mode>3"
9596 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9597 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9598 (match_operand:QI 2 "nonmemory_operand" "")))]
9600 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9602 ;; Avoid useless masking of count operand.
9603 (define_insn_and_split "*<shift_insn><mode>3_mask"
9604 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9606 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9609 (match_operand:SI 2 "nonimmediate_operand" "c")
9610 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9611 (clobber (reg:CC FLAGS_REG))]
9612 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9613 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9614 == GET_MODE_BITSIZE (<MODE>mode)-1"
9617 [(parallel [(set (match_dup 0)
9618 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9619 (clobber (reg:CC FLAGS_REG))])]
9621 if (can_create_pseudo_p ())
9622 operands [2] = force_reg (SImode, operands[2]);
9624 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9626 [(set_attr "type" "ishift")
9627 (set_attr "mode" "<MODE>")])
9629 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9630 [(set (match_operand:DWI 0 "register_operand" "=r")
9631 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9632 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9633 (clobber (reg:CC FLAGS_REG))]
9636 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9638 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9639 [(set_attr "type" "multi")])
9641 ;; By default we don't ask for a scratch register, because when DWImode
9642 ;; values are manipulated, registers are already at a premium. But if
9643 ;; we have one handy, we won't turn it away.
9646 [(match_scratch:DWIH 3 "r")
9647 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9649 (match_operand:<DWI> 1 "register_operand" "")
9650 (match_operand:QI 2 "nonmemory_operand" "")))
9651 (clobber (reg:CC FLAGS_REG))])
9655 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9657 (define_insn "x86_64_shrd"
9658 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9659 (ior:DI (ashiftrt:DI (match_dup 0)
9660 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9661 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9662 (minus:QI (const_int 64) (match_dup 2)))))
9663 (clobber (reg:CC FLAGS_REG))]
9665 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9666 [(set_attr "type" "ishift")
9667 (set_attr "prefix_0f" "1")
9668 (set_attr "mode" "DI")
9669 (set_attr "athlon_decode" "vector")
9670 (set_attr "amdfam10_decode" "vector")
9671 (set_attr "bdver1_decode" "vector")])
9673 (define_insn "x86_shrd"
9674 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9675 (ior:SI (ashiftrt:SI (match_dup 0)
9676 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9677 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9678 (minus:QI (const_int 32) (match_dup 2)))))
9679 (clobber (reg:CC FLAGS_REG))]
9681 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9682 [(set_attr "type" "ishift")
9683 (set_attr "prefix_0f" "1")
9684 (set_attr "mode" "SI")
9685 (set_attr "pent_pair" "np")
9686 (set_attr "athlon_decode" "vector")
9687 (set_attr "amdfam10_decode" "vector")
9688 (set_attr "bdver1_decode" "vector")])
9690 (define_insn "ashrdi3_cvt"
9691 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9692 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9693 (match_operand:QI 2 "const_int_operand" "")))
9694 (clobber (reg:CC FLAGS_REG))]
9695 "TARGET_64BIT && INTVAL (operands[2]) == 63
9696 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9697 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9700 sar{q}\t{%2, %0|%0, %2}"
9701 [(set_attr "type" "imovx,ishift")
9702 (set_attr "prefix_0f" "0,*")
9703 (set_attr "length_immediate" "0,*")
9704 (set_attr "modrm" "0,1")
9705 (set_attr "mode" "DI")])
9707 (define_insn "ashrsi3_cvt"
9708 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9709 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9710 (match_operand:QI 2 "const_int_operand" "")))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "INTVAL (operands[2]) == 31
9713 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9714 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9717 sar{l}\t{%2, %0|%0, %2}"
9718 [(set_attr "type" "imovx,ishift")
9719 (set_attr "prefix_0f" "0,*")
9720 (set_attr "length_immediate" "0,*")
9721 (set_attr "modrm" "0,1")
9722 (set_attr "mode" "SI")])
9724 (define_insn "*ashrsi3_cvt_zext"
9725 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9727 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9728 (match_operand:QI 2 "const_int_operand" ""))))
9729 (clobber (reg:CC FLAGS_REG))]
9730 "TARGET_64BIT && INTVAL (operands[2]) == 31
9731 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9732 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9735 sar{l}\t{%2, %k0|%k0, %2}"
9736 [(set_attr "type" "imovx,ishift")
9737 (set_attr "prefix_0f" "0,*")
9738 (set_attr "length_immediate" "0,*")
9739 (set_attr "modrm" "0,1")
9740 (set_attr "mode" "SI")])
9742 (define_expand "x86_shift<mode>_adj_3"
9743 [(use (match_operand:SWI48 0 "register_operand" ""))
9744 (use (match_operand:SWI48 1 "register_operand" ""))
9745 (use (match_operand:QI 2 "register_operand" ""))]
9748 rtx label = gen_label_rtx ();
9751 emit_insn (gen_testqi_ccz_1 (operands[2],
9752 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9754 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9755 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9756 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9757 gen_rtx_LABEL_REF (VOIDmode, label),
9759 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9760 JUMP_LABEL (tmp) = label;
9762 emit_move_insn (operands[0], operands[1]);
9763 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9764 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9766 LABEL_NUSES (label) = 1;
9771 (define_insn "*bmi2_<shift_insn><mode>3_1"
9772 [(set (match_operand:SWI48 0 "register_operand" "=r")
9773 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9774 (match_operand:SWI48 2 "register_operand" "r")))]
9776 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9777 [(set_attr "type" "ishiftx")
9778 (set_attr "mode" "<MODE>")])
9780 (define_insn "*<shift_insn><mode>3_1"
9781 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9783 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9784 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9785 (clobber (reg:CC FLAGS_REG))]
9786 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9788 switch (get_attr_type (insn))
9794 if (operands[2] == const1_rtx
9795 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9796 return "<shift>{<imodesuffix>}\t%0";
9798 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9801 [(set_attr "isa" "*,bmi2")
9802 (set_attr "type" "ishift,ishiftx")
9803 (set (attr "length_immediate")
9805 (and (match_operand 2 "const1_operand" "")
9806 (ior (match_test "TARGET_SHIFT1")
9807 (match_test "optimize_function_for_size_p (cfun)")))
9809 (const_string "*")))
9810 (set_attr "mode" "<MODE>")])
9812 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9814 [(set (match_operand:SWI48 0 "register_operand" "")
9815 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9816 (match_operand:QI 2 "register_operand" "")))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "TARGET_BMI2 && reload_completed"
9820 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9821 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9823 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9824 [(set (match_operand:DI 0 "register_operand" "=r")
9826 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9827 (match_operand:SI 2 "register_operand" "r"))))]
9828 "TARGET_64BIT && TARGET_BMI2"
9829 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9830 [(set_attr "type" "ishiftx")
9831 (set_attr "mode" "SI")])
9833 (define_insn "*<shift_insn>si3_1_zext"
9834 [(set (match_operand:DI 0 "register_operand" "=r,r")
9836 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9837 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9838 (clobber (reg:CC FLAGS_REG))]
9839 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9841 switch (get_attr_type (insn))
9847 if (operands[2] == const1_rtx
9848 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849 return "<shift>{l}\t%k0";
9851 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9854 [(set_attr "isa" "*,bmi2")
9855 (set_attr "type" "ishift,ishiftx")
9856 (set (attr "length_immediate")
9858 (and (match_operand 2 "const1_operand" "")
9859 (ior (match_test "TARGET_SHIFT1")
9860 (match_test "optimize_function_for_size_p (cfun)")))
9862 (const_string "*")))
9863 (set_attr "mode" "SI")])
9865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9867 [(set (match_operand:DI 0 "register_operand" "")
9869 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9870 (match_operand:QI 2 "register_operand" ""))))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9874 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9875 "operands[2] = gen_lowpart (SImode, operands[2]);")
9877 (define_insn "*<shift_insn><mode>3_1"
9878 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9880 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9881 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9885 if (operands[2] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shift>{<imodesuffix>}\t%0";
9889 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9891 [(set_attr "type" "ishift")
9892 (set (attr "length_immediate")
9894 (and (match_operand 2 "const1_operand" "")
9895 (ior (match_test "TARGET_SHIFT1")
9896 (match_test "optimize_function_for_size_p (cfun)")))
9898 (const_string "*")))
9899 (set_attr "mode" "<MODE>")])
9901 (define_insn "*<shift_insn>qi3_1_slp"
9902 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9903 (any_shiftrt:QI (match_dup 0)
9904 (match_operand:QI 1 "nonmemory_operand" "cI")))
9905 (clobber (reg:CC FLAGS_REG))]
9906 "(optimize_function_for_size_p (cfun)
9907 || !TARGET_PARTIAL_REG_STALL
9908 || (operands[1] == const1_rtx
9911 if (operands[1] == const1_rtx
9912 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9913 return "<shift>{b}\t%0";
9915 return "<shift>{b}\t{%1, %0|%0, %1}";
9917 [(set_attr "type" "ishift1")
9918 (set (attr "length_immediate")
9920 (and (match_operand 1 "const1_operand" "")
9921 (ior (match_test "TARGET_SHIFT1")
9922 (match_test "optimize_function_for_size_p (cfun)")))
9924 (const_string "*")))
9925 (set_attr "mode" "QI")])
9927 ;; This pattern can't accept a variable shift count, since shifts by
9928 ;; zero don't affect the flags. We assume that shifts by constant
9929 ;; zero are optimized away.
9930 (define_insn "*<shift_insn><mode>3_cmp"
9931 [(set (reg FLAGS_REG)
9934 (match_operand:SWI 1 "nonimmediate_operand" "0")
9935 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9937 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9938 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9939 "(optimize_function_for_size_p (cfun)
9940 || !TARGET_PARTIAL_FLAG_REG_STALL
9941 || (operands[2] == const1_rtx
9943 && ix86_match_ccmode (insn, CCGOCmode)
9944 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9946 if (operands[2] == const1_rtx
9947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9948 return "<shift>{<imodesuffix>}\t%0";
9950 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9952 [(set_attr "type" "ishift")
9953 (set (attr "length_immediate")
9955 (and (match_operand 2 "const1_operand" "")
9956 (ior (match_test "TARGET_SHIFT1")
9957 (match_test "optimize_function_for_size_p (cfun)")))
9959 (const_string "*")))
9960 (set_attr "mode" "<MODE>")])
9962 (define_insn "*<shift_insn>si3_cmp_zext"
9963 [(set (reg FLAGS_REG)
9965 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9966 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9968 (set (match_operand:DI 0 "register_operand" "=r")
9969 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9971 && (optimize_function_for_size_p (cfun)
9972 || !TARGET_PARTIAL_FLAG_REG_STALL
9973 || (operands[2] == const1_rtx
9975 && ix86_match_ccmode (insn, CCGOCmode)
9976 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9978 if (operands[2] == const1_rtx
9979 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9980 return "<shift>{l}\t%k0";
9982 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9984 [(set_attr "type" "ishift")
9985 (set (attr "length_immediate")
9987 (and (match_operand 2 "const1_operand" "")
9988 (ior (match_test "TARGET_SHIFT1")
9989 (match_test "optimize_function_for_size_p (cfun)")))
9991 (const_string "*")))
9992 (set_attr "mode" "SI")])
9994 (define_insn "*<shift_insn><mode>3_cconly"
9995 [(set (reg FLAGS_REG)
9998 (match_operand:SWI 1 "register_operand" "0")
9999 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10001 (clobber (match_scratch:SWI 0 "=<r>"))]
10002 "(optimize_function_for_size_p (cfun)
10003 || !TARGET_PARTIAL_FLAG_REG_STALL
10004 || (operands[2] == const1_rtx
10006 && ix86_match_ccmode (insn, CCGOCmode)"
10008 if (operands[2] == const1_rtx
10009 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10010 return "<shift>{<imodesuffix>}\t%0";
10012 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10014 [(set_attr "type" "ishift")
10015 (set (attr "length_immediate")
10017 (and (match_operand 2 "const1_operand" "")
10018 (ior (match_test "TARGET_SHIFT1")
10019 (match_test "optimize_function_for_size_p (cfun)")))
10021 (const_string "*")))
10022 (set_attr "mode" "<MODE>")])
10024 ;; Rotate instructions
10026 (define_expand "<rotate_insn>ti3"
10027 [(set (match_operand:TI 0 "register_operand" "")
10028 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10029 (match_operand:QI 2 "nonmemory_operand" "")))]
10032 if (const_1_to_63_operand (operands[2], VOIDmode))
10033 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10034 (operands[0], operands[1], operands[2]));
10041 (define_expand "<rotate_insn>di3"
10042 [(set (match_operand:DI 0 "shiftdi_operand" "")
10043 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10048 ix86_expand_binary_operator (<CODE>, DImode, operands);
10049 else if (const_1_to_31_operand (operands[2], VOIDmode))
10050 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10051 (operands[0], operands[1], operands[2]));
10058 (define_expand "<rotate_insn><mode>3"
10059 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10060 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10061 (match_operand:QI 2 "nonmemory_operand" "")))]
10063 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10065 ;; Avoid useless masking of count operand.
10066 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10067 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10069 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10072 (match_operand:SI 2 "nonimmediate_operand" "c")
10073 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10074 (clobber (reg:CC FLAGS_REG))]
10075 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10076 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10077 == GET_MODE_BITSIZE (<MODE>mode)-1"
10080 [(parallel [(set (match_dup 0)
10081 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10082 (clobber (reg:CC FLAGS_REG))])]
10084 if (can_create_pseudo_p ())
10085 operands [2] = force_reg (SImode, operands[2]);
10087 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10089 [(set_attr "type" "rotate")
10090 (set_attr "mode" "<MODE>")])
10092 ;; Implement rotation using two double-precision
10093 ;; shift instructions and a scratch register.
10095 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10096 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10097 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10098 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10099 (clobber (reg:CC FLAGS_REG))
10100 (clobber (match_scratch:DWIH 3 "=&r"))]
10104 [(set (match_dup 3) (match_dup 4))
10106 [(set (match_dup 4)
10107 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10108 (lshiftrt:DWIH (match_dup 5)
10109 (minus:QI (match_dup 6) (match_dup 2)))))
10110 (clobber (reg:CC FLAGS_REG))])
10112 [(set (match_dup 5)
10113 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10114 (lshiftrt:DWIH (match_dup 3)
10115 (minus:QI (match_dup 6) (match_dup 2)))))
10116 (clobber (reg:CC FLAGS_REG))])]
10118 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10120 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10123 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10124 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10125 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10126 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10127 (clobber (reg:CC FLAGS_REG))
10128 (clobber (match_scratch:DWIH 3 "=&r"))]
10132 [(set (match_dup 3) (match_dup 4))
10134 [(set (match_dup 4)
10135 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10136 (ashift:DWIH (match_dup 5)
10137 (minus:QI (match_dup 6) (match_dup 2)))))
10138 (clobber (reg:CC FLAGS_REG))])
10140 [(set (match_dup 5)
10141 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10142 (ashift:DWIH (match_dup 3)
10143 (minus:QI (match_dup 6) (match_dup 2)))))
10144 (clobber (reg:CC FLAGS_REG))])]
10146 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10148 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10151 (define_insn "*bmi2_rorx<mode>3_1"
10152 [(set (match_operand:SWI48 0 "register_operand" "=r")
10153 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10154 (match_operand:QI 2 "immediate_operand" "<S>")))]
10156 "rorx\t{%2, %1, %0|%0, %1, %2}"
10157 [(set_attr "type" "rotatex")
10158 (set_attr "mode" "<MODE>")])
10160 (define_insn "*<rotate_insn><mode>3_1"
10161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10163 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10164 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10165 (clobber (reg:CC FLAGS_REG))]
10166 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10168 switch (get_attr_type (insn))
10174 if (operands[2] == const1_rtx
10175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10176 return "<rotate>{<imodesuffix>}\t%0";
10178 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10181 [(set_attr "isa" "*,bmi2")
10182 (set_attr "type" "rotate,rotatex")
10183 (set (attr "length_immediate")
10185 (and (eq_attr "type" "rotate")
10186 (and (match_operand 2 "const1_operand" "")
10187 (ior (match_test "TARGET_SHIFT1")
10188 (match_test "optimize_function_for_size_p (cfun)"))))
10190 (const_string "*")))
10191 (set_attr "mode" "<MODE>")])
10193 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10195 [(set (match_operand:SWI48 0 "register_operand" "")
10196 (rotate: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)))]
10204 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10208 [(set (match_operand:SWI48 0 "register_operand" "")
10209 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10210 (match_operand:QI 2 "immediate_operand" "")))
10211 (clobber (reg:CC FLAGS_REG))]
10212 "TARGET_BMI2 && reload_completed"
10213 [(set (match_dup 0)
10214 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10216 (define_insn "*bmi2_rorxsi3_1_zext"
10217 [(set (match_operand:DI 0 "register_operand" "=r")
10219 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10220 (match_operand:QI 2 "immediate_operand" "I"))))]
10221 "TARGET_64BIT && TARGET_BMI2"
10222 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10223 [(set_attr "type" "rotatex")
10224 (set_attr "mode" "SI")])
10226 (define_insn "*<rotate_insn>si3_1_zext"
10227 [(set (match_operand:DI 0 "register_operand" "=r,r")
10229 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10230 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10234 switch (get_attr_type (insn))
10240 if (operands[2] == const1_rtx
10241 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10242 return "<rotate>{l}\t%k0";
10244 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10247 [(set_attr "isa" "*,bmi2")
10248 (set_attr "type" "rotate,rotatex")
10249 (set (attr "length_immediate")
10251 (and (eq_attr "type" "rotate")
10252 (and (match_operand 2 "const1_operand" "")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)"))))
10256 (const_string "*")))
10257 (set_attr "mode" "SI")])
10259 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10261 [(set (match_operand:DI 0 "register_operand" "")
10263 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10264 (match_operand:QI 2 "immediate_operand" ""))))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10267 [(set (match_dup 0)
10268 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10271 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10275 [(set (match_operand:DI 0 "register_operand" "")
10277 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10278 (match_operand:QI 2 "immediate_operand" ""))))
10279 (clobber (reg:CC FLAGS_REG))]
10280 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10281 [(set (match_dup 0)
10282 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10284 (define_insn "*<rotate_insn><mode>3_1"
10285 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10286 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10287 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10288 (clobber (reg:CC FLAGS_REG))]
10289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10291 if (operands[2] == const1_rtx
10292 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10293 return "<rotate>{<imodesuffix>}\t%0";
10295 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10297 [(set_attr "type" "rotate")
10298 (set (attr "length_immediate")
10300 (and (match_operand 2 "const1_operand" "")
10301 (ior (match_test "TARGET_SHIFT1")
10302 (match_test "optimize_function_for_size_p (cfun)")))
10304 (const_string "*")))
10305 (set_attr "mode" "<MODE>")])
10307 (define_insn "*<rotate_insn>qi3_1_slp"
10308 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10309 (any_rotate:QI (match_dup 0)
10310 (match_operand:QI 1 "nonmemory_operand" "cI")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "(optimize_function_for_size_p (cfun)
10313 || !TARGET_PARTIAL_REG_STALL
10314 || (operands[1] == const1_rtx
10315 && TARGET_SHIFT1))"
10317 if (operands[1] == const1_rtx
10318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10319 return "<rotate>{b}\t%0";
10321 return "<rotate>{b}\t{%1, %0|%0, %1}";
10323 [(set_attr "type" "rotate1")
10324 (set (attr "length_immediate")
10326 (and (match_operand 1 "const1_operand" "")
10327 (ior (match_test "TARGET_SHIFT1")
10328 (match_test "optimize_function_for_size_p (cfun)")))
10330 (const_string "*")))
10331 (set_attr "mode" "QI")])
10334 [(set (match_operand:HI 0 "register_operand" "")
10335 (any_rotate:HI (match_dup 0) (const_int 8)))
10336 (clobber (reg:CC FLAGS_REG))]
10338 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10339 [(parallel [(set (strict_low_part (match_dup 0))
10340 (bswap:HI (match_dup 0)))
10341 (clobber (reg:CC FLAGS_REG))])])
10343 ;; Bit set / bit test instructions
10345 (define_expand "extv"
10346 [(set (match_operand:SI 0 "register_operand" "")
10347 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10348 (match_operand:SI 2 "const8_operand" "")
10349 (match_operand:SI 3 "const8_operand" "")))]
10352 /* Handle extractions from %ah et al. */
10353 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10356 /* From mips.md: extract_bit_field doesn't verify that our source
10357 matches the predicate, so check it again here. */
10358 if (! ext_register_operand (operands[1], VOIDmode))
10362 (define_expand "extzv"
10363 [(set (match_operand:SI 0 "register_operand" "")
10364 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10365 (match_operand:SI 2 "const8_operand" "")
10366 (match_operand:SI 3 "const8_operand" "")))]
10369 /* Handle extractions from %ah et al. */
10370 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10373 /* From mips.md: extract_bit_field doesn't verify that our source
10374 matches the predicate, so check it again here. */
10375 if (! ext_register_operand (operands[1], VOIDmode))
10379 (define_expand "insv"
10380 [(set (zero_extract (match_operand 0 "register_operand" "")
10381 (match_operand 1 "const_int_operand" "")
10382 (match_operand 2 "const_int_operand" ""))
10383 (match_operand 3 "register_operand" ""))]
10386 rtx (*gen_mov_insv_1) (rtx, rtx);
10388 if (ix86_expand_pinsr (operands))
10391 /* Handle insertions to %ah et al. */
10392 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10395 /* From mips.md: insert_bit_field doesn't verify that our source
10396 matches the predicate, so check it again here. */
10397 if (! ext_register_operand (operands[0], VOIDmode))
10400 gen_mov_insv_1 = (TARGET_64BIT
10401 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10403 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10407 ;; %%% bts, btr, btc, bt.
10408 ;; In general these instructions are *slow* when applied to memory,
10409 ;; since they enforce atomic operation. When applied to registers,
10410 ;; it depends on the cpu implementation. They're never faster than
10411 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10412 ;; no point. But in 64-bit, we can't hold the relevant immediates
10413 ;; within the instruction itself, so operating on bits in the high
10414 ;; 32-bits of a register becomes easier.
10416 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10417 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10418 ;; negdf respectively, so they can never be disabled entirely.
10420 (define_insn "*btsq"
10421 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10423 (match_operand:DI 1 "const_0_to_63_operand" ""))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427 "bts{q}\t{%1, %0|%0, %1}"
10428 [(set_attr "type" "alu1")
10429 (set_attr "prefix_0f" "1")
10430 (set_attr "mode" "DI")])
10432 (define_insn "*btrq"
10433 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10439 "btr{q}\t{%1, %0|%0, %1}"
10440 [(set_attr "type" "alu1")
10441 (set_attr "prefix_0f" "1")
10442 (set_attr "mode" "DI")])
10444 (define_insn "*btcq"
10445 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10447 (match_operand:DI 1 "const_0_to_63_operand" ""))
10448 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10449 (clobber (reg:CC FLAGS_REG))]
10450 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10451 "btc{q}\t{%1, %0|%0, %1}"
10452 [(set_attr "type" "alu1")
10453 (set_attr "prefix_0f" "1")
10454 (set_attr "mode" "DI")])
10456 ;; Allow Nocona to avoid these instructions if a register is available.
10459 [(match_scratch:DI 2 "r")
10460 (parallel [(set (zero_extract:DI
10461 (match_operand:DI 0 "register_operand" "")
10463 (match_operand:DI 1 "const_0_to_63_operand" ""))
10465 (clobber (reg:CC FLAGS_REG))])]
10466 "TARGET_64BIT && !TARGET_USE_BT"
10469 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10472 if (HOST_BITS_PER_WIDE_INT >= 64)
10473 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10474 else if (i < HOST_BITS_PER_WIDE_INT)
10475 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479 op1 = immed_double_const (lo, hi, DImode);
10482 emit_move_insn (operands[2], op1);
10486 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10491 [(match_scratch:DI 2 "r")
10492 (parallel [(set (zero_extract:DI
10493 (match_operand:DI 0 "register_operand" "")
10495 (match_operand:DI 1 "const_0_to_63_operand" ""))
10497 (clobber (reg:CC FLAGS_REG))])]
10498 "TARGET_64BIT && !TARGET_USE_BT"
10501 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10504 if (HOST_BITS_PER_WIDE_INT >= 64)
10505 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10506 else if (i < HOST_BITS_PER_WIDE_INT)
10507 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10509 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10511 op1 = immed_double_const (~lo, ~hi, DImode);
10514 emit_move_insn (operands[2], op1);
10518 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10523 [(match_scratch:DI 2 "r")
10524 (parallel [(set (zero_extract:DI
10525 (match_operand:DI 0 "register_operand" "")
10527 (match_operand:DI 1 "const_0_to_63_operand" ""))
10528 (not:DI (zero_extract:DI
10529 (match_dup 0) (const_int 1) (match_dup 1))))
10530 (clobber (reg:CC FLAGS_REG))])]
10531 "TARGET_64BIT && !TARGET_USE_BT"
10534 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10537 if (HOST_BITS_PER_WIDE_INT >= 64)
10538 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10539 else if (i < HOST_BITS_PER_WIDE_INT)
10540 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10542 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10544 op1 = immed_double_const (lo, hi, DImode);
10547 emit_move_insn (operands[2], op1);
10551 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10555 (define_insn "*bt<mode>"
10556 [(set (reg:CCC FLAGS_REG)
10558 (zero_extract:SWI48
10559 (match_operand:SWI48 0 "register_operand" "r")
10561 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10563 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10564 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10565 [(set_attr "type" "alu1")
10566 (set_attr "prefix_0f" "1")
10567 (set_attr "mode" "<MODE>")])
10569 ;; Store-flag instructions.
10571 ;; For all sCOND expanders, also expand the compare or test insn that
10572 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10574 (define_insn_and_split "*setcc_di_1"
10575 [(set (match_operand:DI 0 "register_operand" "=q")
10576 (match_operator:DI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))]
10578 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10580 "&& reload_completed"
10581 [(set (match_dup 2) (match_dup 1))
10582 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10584 PUT_MODE (operands[1], QImode);
10585 operands[2] = gen_lowpart (QImode, operands[0]);
10588 (define_insn_and_split "*setcc_si_1_and"
10589 [(set (match_operand:SI 0 "register_operand" "=q")
10590 (match_operator:SI 1 "ix86_comparison_operator"
10591 [(reg FLAGS_REG) (const_int 0)]))
10592 (clobber (reg:CC FLAGS_REG))]
10593 "!TARGET_PARTIAL_REG_STALL
10594 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10596 "&& reload_completed"
10597 [(set (match_dup 2) (match_dup 1))
10598 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10599 (clobber (reg:CC FLAGS_REG))])]
10601 PUT_MODE (operands[1], QImode);
10602 operands[2] = gen_lowpart (QImode, operands[0]);
10605 (define_insn_and_split "*setcc_si_1_movzbl"
10606 [(set (match_operand:SI 0 "register_operand" "=q")
10607 (match_operator:SI 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)]))]
10609 "!TARGET_PARTIAL_REG_STALL
10610 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10612 "&& reload_completed"
10613 [(set (match_dup 2) (match_dup 1))
10614 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10616 PUT_MODE (operands[1], QImode);
10617 operands[2] = gen_lowpart (QImode, operands[0]);
10620 (define_insn "*setcc_qi"
10621 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10622 (match_operator:QI 1 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)]))]
10626 [(set_attr "type" "setcc")
10627 (set_attr "mode" "QI")])
10629 (define_insn "*setcc_qi_slp"
10630 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10631 (match_operator:QI 1 "ix86_comparison_operator"
10632 [(reg FLAGS_REG) (const_int 0)]))]
10635 [(set_attr "type" "setcc")
10636 (set_attr "mode" "QI")])
10638 ;; In general it is not safe to assume too much about CCmode registers,
10639 ;; so simplify-rtx stops when it sees a second one. Under certain
10640 ;; conditions this is safe on x86, so help combine not create
10647 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10648 (ne:QI (match_operator 1 "ix86_comparison_operator"
10649 [(reg FLAGS_REG) (const_int 0)])
10652 [(set (match_dup 0) (match_dup 1))]
10653 "PUT_MODE (operands[1], QImode);")
10656 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657 (ne:QI (match_operator 1 "ix86_comparison_operator"
10658 [(reg FLAGS_REG) (const_int 0)])
10661 [(set (match_dup 0) (match_dup 1))]
10662 "PUT_MODE (operands[1], QImode);")
10665 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10666 (eq:QI (match_operator 1 "ix86_comparison_operator"
10667 [(reg FLAGS_REG) (const_int 0)])
10670 [(set (match_dup 0) (match_dup 1))]
10672 rtx new_op1 = copy_rtx (operands[1]);
10673 operands[1] = new_op1;
10674 PUT_MODE (new_op1, QImode);
10675 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10676 GET_MODE (XEXP (new_op1, 0))));
10678 /* Make sure that (a) the CCmode we have for the flags is strong
10679 enough for the reversed compare or (b) we have a valid FP compare. */
10680 if (! ix86_comparison_operator (new_op1, VOIDmode))
10685 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10686 (eq:QI (match_operator 1 "ix86_comparison_operator"
10687 [(reg FLAGS_REG) (const_int 0)])
10690 [(set (match_dup 0) (match_dup 1))]
10692 rtx new_op1 = copy_rtx (operands[1]);
10693 operands[1] = new_op1;
10694 PUT_MODE (new_op1, QImode);
10695 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10696 GET_MODE (XEXP (new_op1, 0))));
10698 /* Make sure that (a) the CCmode we have for the flags is strong
10699 enough for the reversed compare or (b) we have a valid FP compare. */
10700 if (! ix86_comparison_operator (new_op1, VOIDmode))
10704 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10705 ;; subsequent logical operations are used to imitate conditional moves.
10706 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10709 (define_insn "setcc_<mode>_sse"
10710 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10711 (match_operator:MODEF 3 "sse_comparison_operator"
10712 [(match_operand:MODEF 1 "register_operand" "0,x")
10713 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10714 "SSE_FLOAT_MODE_P (<MODE>mode)"
10716 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10717 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10718 [(set_attr "isa" "noavx,avx")
10719 (set_attr "type" "ssecmp")
10720 (set_attr "length_immediate" "1")
10721 (set_attr "prefix" "orig,vex")
10722 (set_attr "mode" "<MODE>")])
10724 ;; Basic conditional jump instructions.
10725 ;; We ignore the overflow flag for signed branch instructions.
10727 (define_insn "*jcc_1"
10729 (if_then_else (match_operator 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)])
10731 (label_ref (match_operand 0 "" ""))
10735 [(set_attr "type" "ibr")
10736 (set_attr "modrm" "0")
10737 (set (attr "length")
10738 (if_then_else (and (ge (minus (match_dup 0) (pc))
10740 (lt (minus (match_dup 0) (pc))
10745 (define_insn "*jcc_2"
10747 (if_then_else (match_operator 1 "ix86_comparison_operator"
10748 [(reg FLAGS_REG) (const_int 0)])
10750 (label_ref (match_operand 0 "" ""))))]
10753 [(set_attr "type" "ibr")
10754 (set_attr "modrm" "0")
10755 (set (attr "length")
10756 (if_then_else (and (ge (minus (match_dup 0) (pc))
10758 (lt (minus (match_dup 0) (pc))
10763 ;; In general it is not safe to assume too much about CCmode registers,
10764 ;; so simplify-rtx stops when it sees a second one. Under certain
10765 ;; conditions this is safe on x86, so help combine not create
10773 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10774 [(reg FLAGS_REG) (const_int 0)])
10776 (label_ref (match_operand 1 "" ""))
10780 (if_then_else (match_dup 0)
10781 (label_ref (match_dup 1))
10783 "PUT_MODE (operands[0], VOIDmode);")
10787 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10788 [(reg FLAGS_REG) (const_int 0)])
10790 (label_ref (match_operand 1 "" ""))
10794 (if_then_else (match_dup 0)
10795 (label_ref (match_dup 1))
10798 rtx new_op0 = copy_rtx (operands[0]);
10799 operands[0] = new_op0;
10800 PUT_MODE (new_op0, VOIDmode);
10801 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10802 GET_MODE (XEXP (new_op0, 0))));
10804 /* Make sure that (a) the CCmode we have for the flags is strong
10805 enough for the reversed compare or (b) we have a valid FP compare. */
10806 if (! ix86_comparison_operator (new_op0, VOIDmode))
10810 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10811 ;; pass generates from shift insn with QImode operand. Actually, the mode
10812 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10813 ;; appropriate modulo of the bit offset value.
10815 (define_insn_and_split "*jcc_bt<mode>"
10817 (if_then_else (match_operator 0 "bt_comparison_operator"
10818 [(zero_extract:SWI48
10819 (match_operand:SWI48 1 "register_operand" "r")
10822 (match_operand:QI 2 "register_operand" "r")))
10824 (label_ref (match_operand 3 "" ""))
10826 (clobber (reg:CC FLAGS_REG))]
10827 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10830 [(set (reg:CCC FLAGS_REG)
10832 (zero_extract:SWI48
10838 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10839 (label_ref (match_dup 3))
10842 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10844 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10847 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10848 ;; also for DImode, this is what combine produces.
10849 (define_insn_and_split "*jcc_bt<mode>_mask"
10851 (if_then_else (match_operator 0 "bt_comparison_operator"
10852 [(zero_extract:SWI48
10853 (match_operand:SWI48 1 "register_operand" "r")
10856 (match_operand:SI 2 "register_operand" "r")
10857 (match_operand:SI 3 "const_int_operand" "n")))])
10858 (label_ref (match_operand 4 "" ""))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10862 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10863 == GET_MODE_BITSIZE (<MODE>mode)-1"
10866 [(set (reg:CCC FLAGS_REG)
10868 (zero_extract:SWI48
10874 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10875 (label_ref (match_dup 4))
10878 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10880 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10883 (define_insn_and_split "*jcc_btsi_1"
10885 (if_then_else (match_operator 0 "bt_comparison_operator"
10888 (match_operand:SI 1 "register_operand" "r")
10889 (match_operand:QI 2 "register_operand" "r"))
10892 (label_ref (match_operand 3 "" ""))
10894 (clobber (reg:CC FLAGS_REG))]
10895 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10898 [(set (reg:CCC FLAGS_REG)
10906 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10907 (label_ref (match_dup 3))
10910 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10912 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10915 ;; avoid useless masking of bit offset operand
10916 (define_insn_and_split "*jcc_btsi_mask_1"
10919 (match_operator 0 "bt_comparison_operator"
10922 (match_operand:SI 1 "register_operand" "r")
10925 (match_operand:SI 2 "register_operand" "r")
10926 (match_operand:SI 3 "const_int_operand" "n")) 0))
10929 (label_ref (match_operand 4 "" ""))
10931 (clobber (reg:CC FLAGS_REG))]
10932 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10933 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10936 [(set (reg:CCC FLAGS_REG)
10944 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10945 (label_ref (match_dup 4))
10947 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10949 ;; Define combination compare-and-branch fp compare instructions to help
10952 (define_insn "*fp_jcc_1_387"
10954 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10955 [(match_operand 1 "register_operand" "f")
10956 (match_operand 2 "nonimmediate_operand" "fm")])
10957 (label_ref (match_operand 3 "" ""))
10959 (clobber (reg:CCFP FPSR_REG))
10960 (clobber (reg:CCFP FLAGS_REG))
10961 (clobber (match_scratch:HI 4 "=a"))]
10963 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10964 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10965 && SELECT_CC_MODE (GET_CODE (operands[0]),
10966 operands[1], operands[2]) == CCFPmode
10970 (define_insn "*fp_jcc_1r_387"
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand" "f")
10974 (match_operand 2 "nonimmediate_operand" "fm")])
10976 (label_ref (match_operand 3 "" ""))))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 4 "=a"))]
10981 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10982 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10983 && SELECT_CC_MODE (GET_CODE (operands[0]),
10984 operands[1], operands[2]) == CCFPmode
10988 (define_insn "*fp_jcc_2_387"
10990 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991 [(match_operand 1 "register_operand" "f")
10992 (match_operand 2 "register_operand" "f")])
10993 (label_ref (match_operand 3 "" ""))
10995 (clobber (reg:CCFP FPSR_REG))
10996 (clobber (reg:CCFP FLAGS_REG))
10997 (clobber (match_scratch:HI 4 "=a"))]
10998 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10999 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 (define_insn "*fp_jcc_2r_387"
11005 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11006 [(match_operand 1 "register_operand" "f")
11007 (match_operand 2 "register_operand" "f")])
11009 (label_ref (match_operand 3 "" ""))))
11010 (clobber (reg:CCFP FPSR_REG))
11011 (clobber (reg:CCFP FLAGS_REG))
11012 (clobber (match_scratch:HI 4 "=a"))]
11013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11014 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11018 (define_insn "*fp_jcc_3_387"
11020 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11021 [(match_operand 1 "register_operand" "f")
11022 (match_operand 2 "const0_operand" "")])
11023 (label_ref (match_operand 3 "" ""))
11025 (clobber (reg:CCFP FPSR_REG))
11026 (clobber (reg:CCFP FLAGS_REG))
11027 (clobber (match_scratch:HI 4 "=a"))]
11028 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11029 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11030 && SELECT_CC_MODE (GET_CODE (operands[0]),
11031 operands[1], operands[2]) == CCFPmode
11037 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11038 [(match_operand 1 "register_operand" "")
11039 (match_operand 2 "nonimmediate_operand" "")])
11040 (match_operand 3 "" "")
11041 (match_operand 4 "" "")))
11042 (clobber (reg:CCFP FPSR_REG))
11043 (clobber (reg:CCFP FLAGS_REG))]
11047 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11048 operands[3], operands[4], NULL_RTX, NULL_RTX);
11054 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055 [(match_operand 1 "register_operand" "")
11056 (match_operand 2 "general_operand" "")])
11057 (match_operand 3 "" "")
11058 (match_operand 4 "" "")))
11059 (clobber (reg:CCFP FPSR_REG))
11060 (clobber (reg:CCFP FLAGS_REG))
11061 (clobber (match_scratch:HI 5 "=a"))]
11065 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11066 operands[3], operands[4], operands[5], NULL_RTX);
11070 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11071 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11072 ;; with a precedence over other operators and is always put in the first
11073 ;; place. Swap condition and operands to match ficom instruction.
11075 (define_insn "*fp_jcc_4_<mode>_387"
11078 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11079 [(match_operator 1 "float_operator"
11080 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11081 (match_operand 3 "register_operand" "f,f")])
11082 (label_ref (match_operand 4 "" ""))
11084 (clobber (reg:CCFP FPSR_REG))
11085 (clobber (reg:CCFP FLAGS_REG))
11086 (clobber (match_scratch:HI 5 "=a,a"))]
11087 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11088 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11089 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11090 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11097 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11098 [(match_operator 1 "float_operator"
11099 [(match_operand:SWI24 2 "memory_operand" "")])
11100 (match_operand 3 "register_operand" "")])
11101 (match_operand 4 "" "")
11102 (match_operand 5 "" "")))
11103 (clobber (reg:CCFP FPSR_REG))
11104 (clobber (reg:CCFP FLAGS_REG))
11105 (clobber (match_scratch:HI 6 "=a"))]
11109 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11111 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11112 operands[3], operands[7],
11113 operands[4], operands[5], operands[6], NULL_RTX);
11117 ;; %%% Kill this when reload knows how to do it.
11121 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11122 [(match_operator 1 "float_operator"
11123 [(match_operand:SWI24 2 "register_operand" "")])
11124 (match_operand 3 "register_operand" "")])
11125 (match_operand 4 "" "")
11126 (match_operand 5 "" "")))
11127 (clobber (reg:CCFP FPSR_REG))
11128 (clobber (reg:CCFP FLAGS_REG))
11129 (clobber (match_scratch:HI 6 "=a"))]
11133 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11134 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11136 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11137 operands[3], operands[7],
11138 operands[4], operands[5], operands[6], operands[2]);
11142 ;; Unconditional and other jump instructions
11144 (define_insn "jump"
11146 (label_ref (match_operand 0 "" "")))]
11149 [(set_attr "type" "ibr")
11150 (set (attr "length")
11151 (if_then_else (and (ge (minus (match_dup 0) (pc))
11153 (lt (minus (match_dup 0) (pc))
11157 (set_attr "modrm" "0")])
11159 (define_expand "indirect_jump"
11160 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11162 (define_insn "*indirect_jump"
11163 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11166 [(set_attr "type" "ibr")
11167 (set_attr "length_immediate" "0")])
11169 (define_expand "tablejump"
11170 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11171 (use (label_ref (match_operand 1 "" "")))])]
11174 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11175 relative. Convert the relative address to an absolute address. */
11179 enum rtx_code code;
11181 /* We can't use @GOTOFF for text labels on VxWorks;
11182 see gotoff_operand. */
11183 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11187 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11189 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11193 op1 = pic_offset_table_rtx;
11198 op0 = pic_offset_table_rtx;
11202 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11205 else if (TARGET_X32)
11206 operands[0] = convert_memory_address (Pmode, operands[0]);
11209 (define_insn "*tablejump_1"
11210 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11211 (use (label_ref (match_operand 1 "" "")))]
11214 [(set_attr "type" "ibr")
11215 (set_attr "length_immediate" "0")])
11217 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11220 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11221 (set (match_operand:QI 1 "register_operand" "")
11222 (match_operator:QI 2 "ix86_comparison_operator"
11223 [(reg FLAGS_REG) (const_int 0)]))
11224 (set (match_operand 3 "q_regs_operand" "")
11225 (zero_extend (match_dup 1)))]
11226 "(peep2_reg_dead_p (3, operands[1])
11227 || operands_match_p (operands[1], operands[3]))
11228 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11229 [(set (match_dup 4) (match_dup 0))
11230 (set (strict_low_part (match_dup 5))
11233 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11234 operands[5] = gen_lowpart (QImode, operands[3]);
11235 ix86_expand_clear (operands[3]);
11238 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11241 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11242 (set (match_operand:QI 1 "register_operand" "")
11243 (match_operator:QI 2 "ix86_comparison_operator"
11244 [(reg FLAGS_REG) (const_int 0)]))
11245 (parallel [(set (match_operand 3 "q_regs_operand" "")
11246 (zero_extend (match_dup 1)))
11247 (clobber (reg:CC FLAGS_REG))])]
11248 "(peep2_reg_dead_p (3, operands[1])
11249 || operands_match_p (operands[1], operands[3]))
11250 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11251 [(set (match_dup 4) (match_dup 0))
11252 (set (strict_low_part (match_dup 5))
11255 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11256 operands[5] = gen_lowpart (QImode, operands[3]);
11257 ix86_expand_clear (operands[3]);
11260 ;; Call instructions.
11262 ;; The predicates normally associated with named expanders are not properly
11263 ;; checked for calls. This is a bug in the generic code, but it isn't that
11264 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11266 ;; P6 processors will jump to the address after the decrement when %esp
11267 ;; is used as a call operand, so they will execute return address as a code.
11268 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11270 ;; Register constraint for call instruction.
11271 (define_mode_attr c [(SI "l") (DI "r")])
11273 ;; Call subroutine returning no value.
11275 (define_expand "call"
11276 [(call (match_operand:QI 0 "" "")
11277 (match_operand 1 "" ""))
11278 (use (match_operand 2 "" ""))]
11281 ix86_expand_call (NULL, operands[0], operands[1],
11282 operands[2], NULL, false);
11286 (define_expand "sibcall"
11287 [(call (match_operand:QI 0 "" "")
11288 (match_operand 1 "" ""))
11289 (use (match_operand 2 "" ""))]
11292 ix86_expand_call (NULL, operands[0], operands[1],
11293 operands[2], NULL, true);
11297 (define_insn_and_split "*call_vzeroupper"
11298 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11299 (match_operand 1 "" ""))
11300 (unspec [(match_operand 2 "const_int_operand" "")]
11301 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11302 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11304 "&& reload_completed"
11306 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11307 [(set_attr "type" "call")])
11309 (define_insn "*call"
11310 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11311 (match_operand 1 "" ""))]
11312 "!SIBLING_CALL_P (insn)"
11313 "* return ix86_output_call_insn (insn, operands[0]);"
11314 [(set_attr "type" "call")])
11316 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11317 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11318 (match_operand 1 "" ""))
11319 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11320 (clobber (reg:TI XMM6_REG))
11321 (clobber (reg:TI XMM7_REG))
11322 (clobber (reg:TI XMM8_REG))
11323 (clobber (reg:TI XMM9_REG))
11324 (clobber (reg:TI XMM10_REG))
11325 (clobber (reg:TI XMM11_REG))
11326 (clobber (reg:TI XMM12_REG))
11327 (clobber (reg:TI XMM13_REG))
11328 (clobber (reg:TI XMM14_REG))
11329 (clobber (reg:TI XMM15_REG))
11330 (clobber (reg:DI SI_REG))
11331 (clobber (reg:DI DI_REG))
11332 (unspec [(match_operand 2 "const_int_operand" "")]
11333 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11334 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11336 "&& reload_completed"
11338 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11339 [(set_attr "type" "call")])
11341 (define_insn "*call_rex64_ms_sysv"
11342 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11343 (match_operand 1 "" ""))
11344 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11345 (clobber (reg:TI XMM6_REG))
11346 (clobber (reg:TI XMM7_REG))
11347 (clobber (reg:TI XMM8_REG))
11348 (clobber (reg:TI XMM9_REG))
11349 (clobber (reg:TI XMM10_REG))
11350 (clobber (reg:TI XMM11_REG))
11351 (clobber (reg:TI XMM12_REG))
11352 (clobber (reg:TI XMM13_REG))
11353 (clobber (reg:TI XMM14_REG))
11354 (clobber (reg:TI XMM15_REG))
11355 (clobber (reg:DI SI_REG))
11356 (clobber (reg:DI DI_REG))]
11357 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11358 "* return ix86_output_call_insn (insn, operands[0]);"
11359 [(set_attr "type" "call")])
11361 (define_insn_and_split "*sibcall_vzeroupper"
11362 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11363 (match_operand 1 "" ""))
11364 (unspec [(match_operand 2 "const_int_operand" "")]
11365 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11366 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11368 "&& reload_completed"
11370 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11371 [(set_attr "type" "call")])
11373 (define_insn "*sibcall"
11374 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11375 (match_operand 1 "" ""))]
11376 "SIBLING_CALL_P (insn)"
11377 "* return ix86_output_call_insn (insn, operands[0]);"
11378 [(set_attr "type" "call")])
11380 (define_expand "call_pop"
11381 [(parallel [(call (match_operand:QI 0 "" "")
11382 (match_operand:SI 1 "" ""))
11383 (set (reg:SI SP_REG)
11384 (plus:SI (reg:SI SP_REG)
11385 (match_operand:SI 3 "" "")))])]
11388 ix86_expand_call (NULL, operands[0], operands[1],
11389 operands[2], operands[3], false);
11393 (define_insn_and_split "*call_pop_vzeroupper"
11394 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11395 (match_operand:SI 1 "" ""))
11396 (set (reg:SI SP_REG)
11397 (plus:SI (reg:SI SP_REG)
11398 (match_operand:SI 2 "immediate_operand" "i")))
11399 (unspec [(match_operand 3 "const_int_operand" "")]
11400 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11401 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11403 "&& reload_completed"
11405 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11406 [(set_attr "type" "call")])
11408 (define_insn "*call_pop"
11409 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11410 (match_operand 1 "" ""))
11411 (set (reg:SI SP_REG)
11412 (plus:SI (reg:SI SP_REG)
11413 (match_operand:SI 2 "immediate_operand" "i")))]
11414 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11415 "* return ix86_output_call_insn (insn, operands[0]);"
11416 [(set_attr "type" "call")])
11418 (define_insn_and_split "*sibcall_pop_vzeroupper"
11419 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11420 (match_operand 1 "" ""))
11421 (set (reg:SI SP_REG)
11422 (plus:SI (reg:SI SP_REG)
11423 (match_operand:SI 2 "immediate_operand" "i")))
11424 (unspec [(match_operand 3 "const_int_operand" "")]
11425 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11426 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11428 "&& reload_completed"
11430 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11431 [(set_attr "type" "call")])
11433 (define_insn "*sibcall_pop"
11434 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11435 (match_operand 1 "" ""))
11436 (set (reg:SI SP_REG)
11437 (plus:SI (reg:SI SP_REG)
11438 (match_operand:SI 2 "immediate_operand" "i")))]
11439 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11440 "* return ix86_output_call_insn (insn, operands[0]);"
11441 [(set_attr "type" "call")])
11443 ;; Call subroutine, returning value in operand 0
11445 (define_expand "call_value"
11446 [(set (match_operand 0 "" "")
11447 (call (match_operand:QI 1 "" "")
11448 (match_operand 2 "" "")))
11449 (use (match_operand 3 "" ""))]
11452 ix86_expand_call (operands[0], operands[1], operands[2],
11453 operands[3], NULL, false);
11457 (define_expand "sibcall_value"
11458 [(set (match_operand 0 "" "")
11459 (call (match_operand:QI 1 "" "")
11460 (match_operand 2 "" "")))
11461 (use (match_operand 3 "" ""))]
11464 ix86_expand_call (operands[0], operands[1], operands[2],
11465 operands[3], NULL, true);
11469 (define_insn_and_split "*call_value_vzeroupper"
11470 [(set (match_operand 0 "" "")
11471 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11472 (match_operand 2 "" "")))
11473 (unspec [(match_operand 3 "const_int_operand" "")]
11474 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11475 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11477 "&& reload_completed"
11479 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11480 [(set_attr "type" "callv")])
11482 (define_insn "*call_value"
11483 [(set (match_operand 0 "" "")
11484 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11485 (match_operand 2 "" "")))]
11486 "!SIBLING_CALL_P (insn)"
11487 "* return ix86_output_call_insn (insn, operands[1]);"
11488 [(set_attr "type" "callv")])
11490 (define_insn_and_split "*sibcall_value_vzeroupper"
11491 [(set (match_operand 0 "" "")
11492 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11493 (match_operand 2 "" "")))
11494 (unspec [(match_operand 3 "const_int_operand" "")]
11495 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11496 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11498 "&& reload_completed"
11500 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11501 [(set_attr "type" "callv")])
11503 (define_insn "*sibcall_value"
11504 [(set (match_operand 0 "" "")
11505 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11506 (match_operand 2 "" "")))]
11507 "SIBLING_CALL_P (insn)"
11508 "* return ix86_output_call_insn (insn, operands[1]);"
11509 [(set_attr "type" "callv")])
11511 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11512 [(set (match_operand 0 "" "")
11513 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11514 (match_operand 2 "" "")))
11515 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11516 (clobber (reg:TI XMM6_REG))
11517 (clobber (reg:TI XMM7_REG))
11518 (clobber (reg:TI XMM8_REG))
11519 (clobber (reg:TI XMM9_REG))
11520 (clobber (reg:TI XMM10_REG))
11521 (clobber (reg:TI XMM11_REG))
11522 (clobber (reg:TI XMM12_REG))
11523 (clobber (reg:TI XMM13_REG))
11524 (clobber (reg:TI XMM14_REG))
11525 (clobber (reg:TI XMM15_REG))
11526 (clobber (reg:DI SI_REG))
11527 (clobber (reg:DI DI_REG))
11528 (unspec [(match_operand 3 "const_int_operand" "")]
11529 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11530 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11532 "&& reload_completed"
11534 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11535 [(set_attr "type" "callv")])
11537 (define_insn "*call_value_rex64_ms_sysv"
11538 [(set (match_operand 0 "" "")
11539 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11540 (match_operand 2 "" "")))
11541 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11542 (clobber (reg:TI XMM6_REG))
11543 (clobber (reg:TI XMM7_REG))
11544 (clobber (reg:TI XMM8_REG))
11545 (clobber (reg:TI XMM9_REG))
11546 (clobber (reg:TI XMM10_REG))
11547 (clobber (reg:TI XMM11_REG))
11548 (clobber (reg:TI XMM12_REG))
11549 (clobber (reg:TI XMM13_REG))
11550 (clobber (reg:TI XMM14_REG))
11551 (clobber (reg:TI XMM15_REG))
11552 (clobber (reg:DI SI_REG))
11553 (clobber (reg:DI DI_REG))]
11554 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555 "* return ix86_output_call_insn (insn, operands[1]);"
11556 [(set_attr "type" "callv")])
11558 (define_expand "call_value_pop"
11559 [(parallel [(set (match_operand 0 "" "")
11560 (call (match_operand:QI 1 "" "")
11561 (match_operand:SI 2 "" "")))
11562 (set (reg:SI SP_REG)
11563 (plus:SI (reg:SI SP_REG)
11564 (match_operand:SI 4 "" "")))])]
11567 ix86_expand_call (operands[0], operands[1], operands[2],
11568 operands[3], operands[4], false);
11572 (define_insn_and_split "*call_value_pop_vzeroupper"
11573 [(set (match_operand 0 "" "")
11574 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11575 (match_operand 2 "" "")))
11576 (set (reg:SI SP_REG)
11577 (plus:SI (reg:SI SP_REG)
11578 (match_operand:SI 3 "immediate_operand" "i")))
11579 (unspec [(match_operand 4 "const_int_operand" "")]
11580 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11583 "&& reload_completed"
11585 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586 [(set_attr "type" "callv")])
11588 (define_insn "*call_value_pop"
11589 [(set (match_operand 0 "" "")
11590 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11591 (match_operand 2 "" "")))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 3 "immediate_operand" "i")))]
11595 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11596 "* return ix86_output_call_insn (insn, operands[1]);"
11597 [(set_attr "type" "callv")])
11599 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11600 [(set (match_operand 0 "" "")
11601 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11602 (match_operand 2 "" "")))
11603 (set (reg:SI SP_REG)
11604 (plus:SI (reg:SI SP_REG)
11605 (match_operand:SI 3 "immediate_operand" "i")))
11606 (unspec [(match_operand 4 "const_int_operand" "")]
11607 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11608 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11610 "&& reload_completed"
11612 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11613 [(set_attr "type" "callv")])
11615 (define_insn "*sibcall_value_pop"
11616 [(set (match_operand 0 "" "")
11617 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11618 (match_operand 2 "" "")))
11619 (set (reg:SI SP_REG)
11620 (plus:SI (reg:SI SP_REG)
11621 (match_operand:SI 3 "immediate_operand" "i")))]
11622 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11623 "* return ix86_output_call_insn (insn, operands[1]);"
11624 [(set_attr "type" "callv")])
11626 ;; Call subroutine returning any type.
11628 (define_expand "untyped_call"
11629 [(parallel [(call (match_operand 0 "" "")
11631 (match_operand 1 "" "")
11632 (match_operand 2 "" "")])]
11637 /* In order to give reg-stack an easier job in validating two
11638 coprocessor registers as containing a possible return value,
11639 simply pretend the untyped call returns a complex long double
11642 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11643 and should have the default ABI. */
11645 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11646 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11647 operands[0], const0_rtx,
11648 GEN_INT ((TARGET_64BIT
11649 ? (ix86_abi == SYSV_ABI
11650 ? X86_64_SSE_REGPARM_MAX
11651 : X86_64_MS_SSE_REGPARM_MAX)
11652 : X86_32_SSE_REGPARM_MAX)
11656 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11658 rtx set = XVECEXP (operands[2], 0, i);
11659 emit_move_insn (SET_DEST (set), SET_SRC (set));
11662 /* The optimizer does not know that the call sets the function value
11663 registers we stored in the result block. We avoid problems by
11664 claiming that all hard registers are used and clobbered at this
11666 emit_insn (gen_blockage ());
11671 ;; Prologue and epilogue instructions
11673 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11674 ;; all of memory. This blocks insns from being moved across this point.
11676 (define_insn "blockage"
11677 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11680 [(set_attr "length" "0")])
11682 ;; Do not schedule instructions accessing memory across this point.
11684 (define_expand "memory_blockage"
11685 [(set (match_dup 0)
11686 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11689 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11690 MEM_VOLATILE_P (operands[0]) = 1;
11693 (define_insn "*memory_blockage"
11694 [(set (match_operand:BLK 0 "" "")
11695 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11698 [(set_attr "length" "0")])
11700 ;; As USE insns aren't meaningful after reload, this is used instead
11701 ;; to prevent deleting instructions setting registers for PIC code
11702 (define_insn "prologue_use"
11703 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11706 [(set_attr "length" "0")])
11708 ;; Insn emitted into the body of a function to return from a function.
11709 ;; This is only done if the function's epilogue is known to be simple.
11710 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11712 (define_expand "return"
11714 "ix86_can_use_return_insn_p ()"
11716 if (crtl->args.pops_args)
11718 rtx popc = GEN_INT (crtl->args.pops_args);
11719 emit_jump_insn (gen_simple_return_pop_internal (popc));
11724 ;; We need to disable this for TARGET_SEH, as otherwise
11725 ;; shrink-wrapped prologue gets enabled too. This might exceed
11726 ;; the maximum size of prologue in unwind information.
11728 (define_expand "simple_return"
11732 if (crtl->args.pops_args)
11734 rtx popc = GEN_INT (crtl->args.pops_args);
11735 emit_jump_insn (gen_simple_return_pop_internal (popc));
11740 (define_insn "simple_return_internal"
11744 [(set_attr "length" "1")
11745 (set_attr "atom_unit" "jeu")
11746 (set_attr "length_immediate" "0")
11747 (set_attr "modrm" "0")])
11749 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11750 ;; instruction Athlon and K8 have.
11752 (define_insn "simple_return_internal_long"
11754 (unspec [(const_int 0)] UNSPEC_REP)]
11757 [(set_attr "length" "2")
11758 (set_attr "atom_unit" "jeu")
11759 (set_attr "length_immediate" "0")
11760 (set_attr "prefix_rep" "1")
11761 (set_attr "modrm" "0")])
11763 (define_insn "simple_return_pop_internal"
11765 (use (match_operand:SI 0 "const_int_operand" ""))]
11768 [(set_attr "length" "3")
11769 (set_attr "atom_unit" "jeu")
11770 (set_attr "length_immediate" "2")
11771 (set_attr "modrm" "0")])
11773 (define_insn "simple_return_indirect_internal"
11775 (use (match_operand:SI 0 "register_operand" "r"))]
11778 [(set_attr "type" "ibr")
11779 (set_attr "length_immediate" "0")])
11785 [(set_attr "length" "1")
11786 (set_attr "length_immediate" "0")
11787 (set_attr "modrm" "0")])
11789 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11790 (define_insn "nops"
11791 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11795 int num = INTVAL (operands[0]);
11797 gcc_assert (num >= 1 && num <= 8);
11800 fputs ("\tnop\n", asm_out_file);
11804 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11805 (set_attr "length_immediate" "0")
11806 (set_attr "modrm" "0")])
11808 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11809 ;; branch prediction penalty for the third jump in a 16-byte
11813 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11816 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11817 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11819 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11820 The align insn is used to avoid 3 jump instructions in the row to improve
11821 branch prediction and the benefits hardly outweigh the cost of extra 8
11822 nops on the average inserted by full alignment pseudo operation. */
11826 [(set_attr "length" "16")])
11828 (define_expand "prologue"
11831 "ix86_expand_prologue (); DONE;")
11833 (define_insn "set_got"
11834 [(set (match_operand:SI 0 "register_operand" "=r")
11835 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11836 (clobber (reg:CC FLAGS_REG))]
11838 "* return output_set_got (operands[0], NULL_RTX);"
11839 [(set_attr "type" "multi")
11840 (set_attr "length" "12")])
11842 (define_insn "set_got_labelled"
11843 [(set (match_operand:SI 0 "register_operand" "=r")
11844 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11846 (clobber (reg:CC FLAGS_REG))]
11848 "* return output_set_got (operands[0], operands[1]);"
11849 [(set_attr "type" "multi")
11850 (set_attr "length" "12")])
11852 (define_insn "set_got_rex64"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11854 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11856 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11857 [(set_attr "type" "lea")
11858 (set_attr "length_address" "4")
11859 (set_attr "mode" "DI")])
11861 (define_insn "set_rip_rex64"
11862 [(set (match_operand:DI 0 "register_operand" "=r")
11863 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11865 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11866 [(set_attr "type" "lea")
11867 (set_attr "length_address" "4")
11868 (set_attr "mode" "DI")])
11870 (define_insn "set_got_offset_rex64"
11871 [(set (match_operand:DI 0 "register_operand" "=r")
11873 [(label_ref (match_operand 1 "" ""))]
11874 UNSPEC_SET_GOT_OFFSET))]
11876 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11877 [(set_attr "type" "imov")
11878 (set_attr "length_immediate" "0")
11879 (set_attr "length_address" "8")
11880 (set_attr "mode" "DI")])
11882 (define_expand "epilogue"
11885 "ix86_expand_epilogue (1); DONE;")
11887 (define_expand "sibcall_epilogue"
11890 "ix86_expand_epilogue (0); DONE;")
11892 (define_expand "eh_return"
11893 [(use (match_operand 0 "register_operand" ""))]
11896 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11898 /* Tricky bit: we write the address of the handler to which we will
11899 be returning into someone else's stack frame, one word below the
11900 stack address we wish to restore. */
11901 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11902 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11903 tmp = gen_rtx_MEM (Pmode, tmp);
11904 emit_move_insn (tmp, ra);
11906 emit_jump_insn (gen_eh_return_internal ());
11911 (define_insn_and_split "eh_return_internal"
11915 "epilogue_completed"
11917 "ix86_expand_epilogue (2); DONE;")
11919 (define_insn "leave"
11920 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11921 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11922 (clobber (mem:BLK (scratch)))]
11925 [(set_attr "type" "leave")])
11927 (define_insn "leave_rex64"
11928 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11929 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11930 (clobber (mem:BLK (scratch)))]
11933 [(set_attr "type" "leave")])
11935 ;; Handle -fsplit-stack.
11937 (define_expand "split_stack_prologue"
11941 ix86_expand_split_stack_prologue ();
11945 ;; In order to support the call/return predictor, we use a return
11946 ;; instruction which the middle-end doesn't see.
11947 (define_insn "split_stack_return"
11948 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11949 UNSPECV_SPLIT_STACK_RETURN)]
11952 if (operands[0] == const0_rtx)
11957 [(set_attr "atom_unit" "jeu")
11958 (set_attr "modrm" "0")
11959 (set (attr "length")
11960 (if_then_else (match_operand:SI 0 "const0_operand" "")
11963 (set (attr "length_immediate")
11964 (if_then_else (match_operand:SI 0 "const0_operand" "")
11968 ;; If there are operand 0 bytes available on the stack, jump to
11971 (define_expand "split_stack_space_check"
11972 [(set (pc) (if_then_else
11973 (ltu (minus (reg SP_REG)
11974 (match_operand 0 "register_operand" ""))
11975 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11976 (label_ref (match_operand 1 "" ""))
11980 rtx reg, size, limit;
11982 reg = gen_reg_rtx (Pmode);
11983 size = force_reg (Pmode, operands[0]);
11984 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11985 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11986 UNSPEC_STACK_CHECK);
11987 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11988 ix86_expand_branch (GEU, reg, limit, operands[1]);
11993 ;; Bit manipulation instructions.
11995 (define_expand "ffs<mode>2"
11996 [(set (match_dup 2) (const_int -1))
11997 (parallel [(set (reg:CCZ FLAGS_REG)
11999 (match_operand:SWI48 1 "nonimmediate_operand" "")
12001 (set (match_operand:SWI48 0 "register_operand" "")
12002 (ctz:SWI48 (match_dup 1)))])
12003 (set (match_dup 0) (if_then_else:SWI48
12004 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12007 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12008 (clobber (reg:CC FLAGS_REG))])]
12011 if (<MODE>mode == SImode && !TARGET_CMOVE)
12013 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12016 operands[2] = gen_reg_rtx (<MODE>mode);
12019 (define_insn_and_split "ffssi2_no_cmove"
12020 [(set (match_operand:SI 0 "register_operand" "=r")
12021 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12022 (clobber (match_scratch:SI 2 "=&q"))
12023 (clobber (reg:CC FLAGS_REG))]
12026 "&& reload_completed"
12027 [(parallel [(set (reg:CCZ FLAGS_REG)
12028 (compare:CCZ (match_dup 1) (const_int 0)))
12029 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12030 (set (strict_low_part (match_dup 3))
12031 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12032 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12033 (clobber (reg:CC FLAGS_REG))])
12034 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12035 (clobber (reg:CC FLAGS_REG))])
12036 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12037 (clobber (reg:CC FLAGS_REG))])]
12039 operands[3] = gen_lowpart (QImode, operands[2]);
12040 ix86_expand_clear (operands[2]);
12043 (define_insn "*ffs<mode>_1"
12044 [(set (reg:CCZ FLAGS_REG)
12045 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12047 (set (match_operand:SWI48 0 "register_operand" "=r")
12048 (ctz:SWI48 (match_dup 1)))]
12050 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set_attr "mode" "<MODE>")])
12055 (define_insn "ctz<mode>2"
12056 [(set (match_operand:SWI248 0 "register_operand" "=r")
12057 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12058 (clobber (reg:CC FLAGS_REG))]
12062 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12064 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12066 [(set_attr "type" "alu1")
12067 (set_attr "prefix_0f" "1")
12068 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12069 (set_attr "mode" "<MODE>")])
12071 (define_expand "clz<mode>2"
12073 [(set (match_operand:SWI248 0 "register_operand" "")
12076 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12077 (clobber (reg:CC FLAGS_REG))])
12079 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12080 (clobber (reg:CC FLAGS_REG))])]
12085 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12088 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12091 (define_insn "clz<mode>2_lzcnt"
12092 [(set (match_operand:SWI248 0 "register_operand" "=r")
12093 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12094 (clobber (reg:CC FLAGS_REG))]
12096 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12097 [(set_attr "prefix_rep" "1")
12098 (set_attr "type" "bitmanip")
12099 (set_attr "mode" "<MODE>")])
12101 ;; BMI instructions.
12102 (define_insn "*bmi_andn_<mode>"
12103 [(set (match_operand:SWI48 0 "register_operand" "=r")
12106 (match_operand:SWI48 1 "register_operand" "r"))
12107 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12108 (clobber (reg:CC FLAGS_REG))]
12110 "andn\t{%2, %1, %0|%0, %1, %2}"
12111 [(set_attr "type" "bitmanip")
12112 (set_attr "mode" "<MODE>")])
12114 (define_insn "bmi_bextr_<mode>"
12115 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12117 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12119 (clobber (reg:CC FLAGS_REG))]
12121 "bextr\t{%2, %1, %0|%0, %1, %2}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "*bmi_blsi_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12131 (clobber (reg:CC FLAGS_REG))]
12133 "blsi\t{%1, %0|%0, %1}"
12134 [(set_attr "type" "bitmanip")
12135 (set_attr "mode" "<MODE>")])
12137 (define_insn "*bmi_blsmsk_<mode>"
12138 [(set (match_operand:SWI48 0 "register_operand" "=r")
12141 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12144 (clobber (reg:CC FLAGS_REG))]
12146 "blsmsk\t{%1, %0|%0, %1}"
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "mode" "<MODE>")])
12150 (define_insn "*bmi_blsr_<mode>"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12157 (clobber (reg:CC FLAGS_REG))]
12159 "blsr\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12163 ;; BMI2 instructions.
12164 (define_insn "bmi2_bzhi_<mode>3"
12165 [(set (match_operand:SWI48 0 "register_operand" "=r")
12166 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12167 (lshiftrt:SWI48 (const_int -1)
12168 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12169 (clobber (reg:CC FLAGS_REG))]
12171 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12172 [(set_attr "type" "bitmanip")
12173 (set_attr "prefix" "vex")
12174 (set_attr "mode" "<MODE>")])
12176 (define_insn "bmi2_pdep_<mode>3"
12177 [(set (match_operand:SWI48 0 "register_operand" "=r")
12178 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12179 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12182 "pdep\t{%2, %1, %0|%0, %1, %2}"
12183 [(set_attr "type" "bitmanip")
12184 (set_attr "prefix" "vex")
12185 (set_attr "mode" "<MODE>")])
12187 (define_insn "bmi2_pext_<mode>3"
12188 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12190 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12193 "pext\t{%2, %1, %0|%0, %1, %2}"
12194 [(set_attr "type" "bitmanip")
12195 (set_attr "prefix" "vex")
12196 (set_attr "mode" "<MODE>")])
12198 ;; TBM instructions.
12199 (define_insn "tbm_bextri_<mode>"
12200 [(set (match_operand:SWI48 0 "register_operand" "=r")
12201 (zero_extract:SWI48
12202 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12204 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12205 (clobber (reg:CC FLAGS_REG))]
12208 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12209 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12211 [(set_attr "type" "bitmanip")
12212 (set_attr "mode" "<MODE>")])
12214 (define_insn "*tbm_blcfill_<mode>"
12215 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (clobber (reg:CC FLAGS_REG))]
12223 "blcfill\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "bitmanip")
12225 (set_attr "mode" "<MODE>")])
12227 (define_insn "*tbm_blci_<mode>"
12228 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (clobber (reg:CC FLAGS_REG))]
12237 "blci\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12241 (define_insn "*tbm_blcic_<mode>"
12242 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12249 (clobber (reg:CC FLAGS_REG))]
12251 "blcic\t{%1, %0|%0, %1}"
12252 [(set_attr "type" "bitmanip")
12253 (set_attr "mode" "<MODE>")])
12255 (define_insn "*tbm_blcmsk_<mode>"
12256 [(set (match_operand:SWI48 0 "register_operand" "=r")
12259 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12262 (clobber (reg:CC FLAGS_REG))]
12264 "blcmsk\t{%1, %0|%0, %1}"
12265 [(set_attr "type" "bitmanip")
12266 (set_attr "mode" "<MODE>")])
12268 (define_insn "*tbm_blcs_<mode>"
12269 [(set (match_operand:SWI48 0 "register_operand" "=r")
12272 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12275 (clobber (reg:CC FLAGS_REG))]
12277 "blcs\t{%1, %0|%0, %1}"
12278 [(set_attr "type" "bitmanip")
12279 (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_blsfill_<mode>"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288 (clobber (reg:CC FLAGS_REG))]
12290 "blsfill\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "bitmanip")
12292 (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_blsic_<mode>"
12295 [(set (match_operand:SWI48 0 "register_operand" "=r")
12298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12302 (clobber (reg:CC FLAGS_REG))]
12304 "blsic\t{%1, %0|%0, %1}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12308 (define_insn "*tbm_t1mskc_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12316 (clobber (reg:CC FLAGS_REG))]
12318 "t1mskc\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "*tbm_tzmsk_<mode>"
12323 [(set (match_operand:SWI48 0 "register_operand" "=r")
12326 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12330 (clobber (reg:CC FLAGS_REG))]
12332 "tzmsk\t{%1, %0|%0, %1}"
12333 [(set_attr "type" "bitmanip")
12334 (set_attr "mode" "<MODE>")])
12336 (define_insn "bsr_rex64"
12337 [(set (match_operand:DI 0 "register_operand" "=r")
12338 (minus:DI (const_int 63)
12339 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12340 (clobber (reg:CC FLAGS_REG))]
12342 "bsr{q}\t{%1, %0|%0, %1}"
12343 [(set_attr "type" "alu1")
12344 (set_attr "prefix_0f" "1")
12345 (set_attr "mode" "DI")])
12348 [(set (match_operand:SI 0 "register_operand" "=r")
12349 (minus:SI (const_int 31)
12350 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12351 (clobber (reg:CC FLAGS_REG))]
12353 "bsr{l}\t{%1, %0|%0, %1}"
12354 [(set_attr "type" "alu1")
12355 (set_attr "prefix_0f" "1")
12356 (set_attr "mode" "SI")])
12358 (define_insn "*bsrhi"
12359 [(set (match_operand:HI 0 "register_operand" "=r")
12360 (minus:HI (const_int 15)
12361 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12362 (clobber (reg:CC FLAGS_REG))]
12364 "bsr{w}\t{%1, %0|%0, %1}"
12365 [(set_attr "type" "alu1")
12366 (set_attr "prefix_0f" "1")
12367 (set_attr "mode" "HI")])
12369 (define_insn "popcount<mode>2"
12370 [(set (match_operand:SWI248 0 "register_operand" "=r")
12372 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12373 (clobber (reg:CC FLAGS_REG))]
12377 return "popcnt\t{%1, %0|%0, %1}";
12379 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12382 [(set_attr "prefix_rep" "1")
12383 (set_attr "type" "bitmanip")
12384 (set_attr "mode" "<MODE>")])
12386 (define_insn "*popcount<mode>2_cmp"
12387 [(set (reg FLAGS_REG)
12390 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12392 (set (match_operand:SWI248 0 "register_operand" "=r")
12393 (popcount:SWI248 (match_dup 1)))]
12394 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12397 return "popcnt\t{%1, %0|%0, %1}";
12399 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12402 [(set_attr "prefix_rep" "1")
12403 (set_attr "type" "bitmanip")
12404 (set_attr "mode" "<MODE>")])
12406 (define_insn "*popcountsi2_cmp_zext"
12407 [(set (reg FLAGS_REG)
12409 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12411 (set (match_operand:DI 0 "register_operand" "=r")
12412 (zero_extend:DI(popcount:SI (match_dup 1))))]
12413 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12416 return "popcnt\t{%1, %0|%0, %1}";
12418 return "popcnt{l}\t{%1, %0|%0, %1}";
12421 [(set_attr "prefix_rep" "1")
12422 (set_attr "type" "bitmanip")
12423 (set_attr "mode" "SI")])
12425 (define_expand "bswap<mode>2"
12426 [(set (match_operand:SWI48 0 "register_operand" "")
12427 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12430 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12432 rtx x = operands[0];
12434 emit_move_insn (x, operands[1]);
12435 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12436 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12437 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12442 (define_insn "*bswap<mode>2_movbe"
12443 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12444 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12449 movbe\t{%1, %0|%0, %1}
12450 movbe\t{%1, %0|%0, %1}"
12451 [(set_attr "type" "bitmanip,imov,imov")
12452 (set_attr "modrm" "0,1,1")
12453 (set_attr "prefix_0f" "*,1,1")
12454 (set_attr "prefix_extra" "*,1,1")
12455 (set_attr "mode" "<MODE>")])
12457 (define_insn "*bswap<mode>2_1"
12458 [(set (match_operand:SWI48 0 "register_operand" "=r")
12459 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12462 [(set_attr "type" "bitmanip")
12463 (set_attr "modrm" "0")
12464 (set_attr "mode" "<MODE>")])
12466 (define_insn "*bswaphi_lowpart_1"
12467 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12468 (bswap:HI (match_dup 0)))
12469 (clobber (reg:CC FLAGS_REG))]
12470 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12472 xchg{b}\t{%h0, %b0|%b0, %h0}
12473 rol{w}\t{$8, %0|%0, 8}"
12474 [(set_attr "length" "2,4")
12475 (set_attr "mode" "QI,HI")])
12477 (define_insn "bswaphi_lowpart"
12478 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12479 (bswap:HI (match_dup 0)))
12480 (clobber (reg:CC FLAGS_REG))]
12482 "rol{w}\t{$8, %0|%0, 8}"
12483 [(set_attr "length" "4")
12484 (set_attr "mode" "HI")])
12486 (define_expand "paritydi2"
12487 [(set (match_operand:DI 0 "register_operand" "")
12488 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12491 rtx scratch = gen_reg_rtx (QImode);
12494 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12495 NULL_RTX, operands[1]));
12497 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12498 gen_rtx_REG (CCmode, FLAGS_REG),
12500 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12503 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12506 rtx tmp = gen_reg_rtx (SImode);
12508 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12509 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12514 (define_expand "paritysi2"
12515 [(set (match_operand:SI 0 "register_operand" "")
12516 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12519 rtx scratch = gen_reg_rtx (QImode);
12522 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12524 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12525 gen_rtx_REG (CCmode, FLAGS_REG),
12527 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12529 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12533 (define_insn_and_split "paritydi2_cmp"
12534 [(set (reg:CC FLAGS_REG)
12535 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12537 (clobber (match_scratch:DI 0 "=r"))
12538 (clobber (match_scratch:SI 1 "=&r"))
12539 (clobber (match_scratch:HI 2 "=Q"))]
12542 "&& reload_completed"
12544 [(set (match_dup 1)
12545 (xor:SI (match_dup 1) (match_dup 4)))
12546 (clobber (reg:CC FLAGS_REG))])
12548 [(set (reg:CC FLAGS_REG)
12549 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12550 (clobber (match_dup 1))
12551 (clobber (match_dup 2))])]
12553 operands[4] = gen_lowpart (SImode, operands[3]);
12557 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12558 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12561 operands[1] = gen_highpart (SImode, operands[3]);
12564 (define_insn_and_split "paritysi2_cmp"
12565 [(set (reg:CC FLAGS_REG)
12566 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12568 (clobber (match_scratch:SI 0 "=r"))
12569 (clobber (match_scratch:HI 1 "=&Q"))]
12572 "&& reload_completed"
12574 [(set (match_dup 1)
12575 (xor:HI (match_dup 1) (match_dup 3)))
12576 (clobber (reg:CC FLAGS_REG))])
12578 [(set (reg:CC FLAGS_REG)
12579 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12580 (clobber (match_dup 1))])]
12582 operands[3] = gen_lowpart (HImode, operands[2]);
12584 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12585 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12588 (define_insn "*parityhi2_cmp"
12589 [(set (reg:CC FLAGS_REG)
12590 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12592 (clobber (match_scratch:HI 0 "=Q"))]
12594 "xor{b}\t{%h0, %b0|%b0, %h0}"
12595 [(set_attr "length" "2")
12596 (set_attr "mode" "HI")])
12599 ;; Thread-local storage patterns for ELF.
12601 ;; Note that these code sequences must appear exactly as shown
12602 ;; in order to allow linker relaxation.
12604 (define_insn "*tls_global_dynamic_32_gnu"
12605 [(set (match_operand:SI 0 "register_operand" "=a")
12607 [(match_operand:SI 1 "register_operand" "b")
12608 (match_operand:SI 2 "tls_symbolic_operand" "")
12609 (match_operand:SI 3 "constant_call_address_operand" "z")]
12611 (clobber (match_scratch:SI 4 "=d"))
12612 (clobber (match_scratch:SI 5 "=c"))
12613 (clobber (reg:CC FLAGS_REG))]
12614 "!TARGET_64BIT && TARGET_GNU_TLS"
12617 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12618 if (TARGET_SUN_TLS)
12619 #ifdef HAVE_AS_IX86_TLSGDPLT
12620 return "call\t%a2@tlsgdplt";
12622 return "call\t%p3@plt";
12624 return "call\t%P3";
12626 [(set_attr "type" "multi")
12627 (set_attr "length" "12")])
12629 (define_expand "tls_global_dynamic_32"
12631 [(set (match_operand:SI 0 "register_operand" "")
12632 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12633 (match_operand:SI 1 "tls_symbolic_operand" "")
12634 (match_operand:SI 3 "constant_call_address_operand" "")]
12636 (clobber (match_scratch:SI 4 ""))
12637 (clobber (match_scratch:SI 5 ""))
12638 (clobber (reg:CC FLAGS_REG))])])
12640 (define_insn "*tls_global_dynamic_64"
12641 [(set (match_operand:DI 0 "register_operand" "=a")
12643 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12644 (match_operand:DI 3 "" "")))
12645 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12650 fputs (ASM_BYTE "0x66\n", asm_out_file);
12652 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12653 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12654 fputs ("\trex64\n", asm_out_file);
12655 if (TARGET_SUN_TLS)
12656 return "call\t%p2@plt";
12657 return "call\t%P2";
12659 [(set_attr "type" "multi")
12660 (set (attr "length")
12661 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12663 (define_expand "tls_global_dynamic_64"
12665 [(set (match_operand:DI 0 "register_operand" "")
12667 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12669 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12672 (define_insn "*tls_local_dynamic_base_32_gnu"
12673 [(set (match_operand:SI 0 "register_operand" "=a")
12675 [(match_operand:SI 1 "register_operand" "b")
12676 (match_operand:SI 2 "constant_call_address_operand" "z")]
12677 UNSPEC_TLS_LD_BASE))
12678 (clobber (match_scratch:SI 3 "=d"))
12679 (clobber (match_scratch:SI 4 "=c"))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "!TARGET_64BIT && TARGET_GNU_TLS"
12684 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12685 if (TARGET_SUN_TLS)
12686 #ifdef HAVE_AS_IX86_TLSLDMPLT
12687 return "call\t%&@tlsldmplt";
12689 return "call\t%p2@plt";
12691 return "call\t%P2";
12693 [(set_attr "type" "multi")
12694 (set_attr "length" "11")])
12696 (define_expand "tls_local_dynamic_base_32"
12698 [(set (match_operand:SI 0 "register_operand" "")
12700 [(match_operand:SI 1 "register_operand" "")
12701 (match_operand:SI 2 "constant_call_address_operand" "")]
12702 UNSPEC_TLS_LD_BASE))
12703 (clobber (match_scratch:SI 3 ""))
12704 (clobber (match_scratch:SI 4 ""))
12705 (clobber (reg:CC FLAGS_REG))])])
12707 (define_insn "*tls_local_dynamic_base_64"
12708 [(set (match_operand:DI 0 "register_operand" "=a")
12710 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12711 (match_operand:DI 2 "" "")))
12712 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12716 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12717 if (TARGET_SUN_TLS)
12718 return "call\t%p1@plt";
12719 return "call\t%P1";
12721 [(set_attr "type" "multi")
12722 (set_attr "length" "12")])
12724 (define_expand "tls_local_dynamic_base_64"
12726 [(set (match_operand:DI 0 "register_operand" "")
12728 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12730 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12732 ;; Local dynamic of a single variable is a lose. Show combine how
12733 ;; to convert that back to global dynamic.
12735 (define_insn_and_split "*tls_local_dynamic_32_once"
12736 [(set (match_operand:SI 0 "register_operand" "=a")
12738 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12739 (match_operand:SI 2 "constant_call_address_operand" "z")]
12740 UNSPEC_TLS_LD_BASE)
12741 (const:SI (unspec:SI
12742 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12744 (clobber (match_scratch:SI 4 "=d"))
12745 (clobber (match_scratch:SI 5 "=c"))
12746 (clobber (reg:CC FLAGS_REG))]
12751 [(set (match_dup 0)
12752 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12754 (clobber (match_dup 4))
12755 (clobber (match_dup 5))
12756 (clobber (reg:CC FLAGS_REG))])])
12758 ;; Segment register for the thread base ptr load
12759 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12761 ;; Load and add the thread base pointer from %<tp_seg>:0.
12762 (define_insn "*load_tp_x32"
12763 [(set (match_operand:SI 0 "register_operand" "=r")
12764 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12766 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12767 [(set_attr "type" "imov")
12768 (set_attr "modrm" "0")
12769 (set_attr "length" "7")
12770 (set_attr "memory" "load")
12771 (set_attr "imm_disp" "false")])
12773 (define_insn "*load_tp_x32_zext"
12774 [(set (match_operand:DI 0 "register_operand" "=r")
12775 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12777 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12778 [(set_attr "type" "imov")
12779 (set_attr "modrm" "0")
12780 (set_attr "length" "7")
12781 (set_attr "memory" "load")
12782 (set_attr "imm_disp" "false")])
12784 (define_insn "*load_tp_<mode>"
12785 [(set (match_operand:P 0 "register_operand" "=r")
12786 (unspec:P [(const_int 0)] UNSPEC_TP))]
12788 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12789 [(set_attr "type" "imov")
12790 (set_attr "modrm" "0")
12791 (set_attr "length" "7")
12792 (set_attr "memory" "load")
12793 (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_x32"
12796 [(set (match_operand:SI 0 "register_operand" "=r")
12797 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12798 (match_operand:SI 1 "register_operand" "0")))
12799 (clobber (reg:CC FLAGS_REG))]
12801 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12802 [(set_attr "type" "alu")
12803 (set_attr "modrm" "0")
12804 (set_attr "length" "7")
12805 (set_attr "memory" "load")
12806 (set_attr "imm_disp" "false")])
12808 (define_insn "*add_tp_x32_zext"
12809 [(set (match_operand:DI 0 "register_operand" "=r")
12811 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12812 (match_operand:SI 1 "register_operand" "0"))))
12813 (clobber (reg:CC FLAGS_REG))]
12815 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12816 [(set_attr "type" "alu")
12817 (set_attr "modrm" "0")
12818 (set_attr "length" "7")
12819 (set_attr "memory" "load")
12820 (set_attr "imm_disp" "false")])
12822 (define_insn "*add_tp_<mode>"
12823 [(set (match_operand:P 0 "register_operand" "=r")
12824 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12825 (match_operand:P 1 "register_operand" "0")))
12826 (clobber (reg:CC FLAGS_REG))]
12828 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12829 [(set_attr "type" "alu")
12830 (set_attr "modrm" "0")
12831 (set_attr "length" "7")
12832 (set_attr "memory" "load")
12833 (set_attr "imm_disp" "false")])
12835 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12836 ;; %rax as destination of the initial executable code sequence.
12837 (define_insn "tls_initial_exec_64_sun"
12838 [(set (match_operand:DI 0 "register_operand" "=a")
12840 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12841 UNSPEC_TLS_IE_SUN))
12842 (clobber (reg:CC FLAGS_REG))]
12843 "TARGET_64BIT && TARGET_SUN_TLS"
12846 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12847 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12849 [(set_attr "type" "multi")])
12851 ;; GNU2 TLS patterns can be split.
12853 (define_expand "tls_dynamic_gnu2_32"
12854 [(set (match_dup 3)
12855 (plus:SI (match_operand:SI 2 "register_operand" "")
12857 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12860 [(set (match_operand:SI 0 "register_operand" "")
12861 (unspec:SI [(match_dup 1) (match_dup 3)
12862 (match_dup 2) (reg:SI SP_REG)]
12864 (clobber (reg:CC FLAGS_REG))])]
12865 "!TARGET_64BIT && TARGET_GNU2_TLS"
12867 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12868 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12871 (define_insn "*tls_dynamic_gnu2_lea_32"
12872 [(set (match_operand:SI 0 "register_operand" "=r")
12873 (plus:SI (match_operand:SI 1 "register_operand" "b")
12875 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12876 UNSPEC_TLSDESC))))]
12877 "!TARGET_64BIT && TARGET_GNU2_TLS"
12878 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12879 [(set_attr "type" "lea")
12880 (set_attr "mode" "SI")
12881 (set_attr "length" "6")
12882 (set_attr "length_address" "4")])
12884 (define_insn "*tls_dynamic_gnu2_call_32"
12885 [(set (match_operand:SI 0 "register_operand" "=a")
12886 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12887 (match_operand:SI 2 "register_operand" "0")
12888 ;; we have to make sure %ebx still points to the GOT
12889 (match_operand:SI 3 "register_operand" "b")
12892 (clobber (reg:CC FLAGS_REG))]
12893 "!TARGET_64BIT && TARGET_GNU2_TLS"
12894 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12895 [(set_attr "type" "call")
12896 (set_attr "length" "2")
12897 (set_attr "length_address" "0")])
12899 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12900 [(set (match_operand:SI 0 "register_operand" "=&a")
12902 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12903 (match_operand:SI 4 "" "")
12904 (match_operand:SI 2 "register_operand" "b")
12907 (const:SI (unspec:SI
12908 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12910 (clobber (reg:CC FLAGS_REG))]
12911 "!TARGET_64BIT && TARGET_GNU2_TLS"
12914 [(set (match_dup 0) (match_dup 5))]
12916 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12917 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12920 (define_expand "tls_dynamic_gnu2_64"
12921 [(set (match_dup 2)
12922 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12925 [(set (match_operand:DI 0 "register_operand" "")
12926 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12928 (clobber (reg:CC FLAGS_REG))])]
12929 "TARGET_64BIT && TARGET_GNU2_TLS"
12931 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12932 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12935 (define_insn "*tls_dynamic_gnu2_lea_64"
12936 [(set (match_operand:DI 0 "register_operand" "=r")
12937 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12939 "TARGET_64BIT && TARGET_GNU2_TLS"
12940 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12941 [(set_attr "type" "lea")
12942 (set_attr "mode" "DI")
12943 (set_attr "length" "7")
12944 (set_attr "length_address" "4")])
12946 (define_insn "*tls_dynamic_gnu2_call_64"
12947 [(set (match_operand:DI 0 "register_operand" "=a")
12948 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12949 (match_operand:DI 2 "register_operand" "0")
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_64BIT && TARGET_GNU2_TLS"
12954 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12955 [(set_attr "type" "call")
12956 (set_attr "length" "2")
12957 (set_attr "length_address" "0")])
12959 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12960 [(set (match_operand:DI 0 "register_operand" "=&a")
12962 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12963 (match_operand:DI 3 "" "")
12966 (const:DI (unspec:DI
12967 [(match_operand 1 "tls_symbolic_operand" "")]
12969 (clobber (reg:CC FLAGS_REG))]
12970 "TARGET_64BIT && TARGET_GNU2_TLS"
12973 [(set (match_dup 0) (match_dup 4))]
12975 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12976 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12979 ;; These patterns match the binary 387 instructions for addM3, subM3,
12980 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12981 ;; SFmode. The first is the normal insn, the second the same insn but
12982 ;; with one operand a conversion, and the third the same insn but with
12983 ;; the other operand a conversion. The conversion may be SFmode or
12984 ;; SImode if the target mode DFmode, but only SImode if the target mode
12987 ;; Gcc is slightly more smart about handling normal two address instructions
12988 ;; so use special patterns for add and mull.
12990 (define_insn "*fop_<mode>_comm_mixed"
12991 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12992 (match_operator:MODEF 3 "binary_fp_operator"
12993 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12994 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12995 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12996 && COMMUTATIVE_ARITH_P (operands[3])
12997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12998 "* return output_387_binary_op (insn, operands);"
12999 [(set (attr "type")
13000 (if_then_else (eq_attr "alternative" "1,2")
13001 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13002 (const_string "ssemul")
13003 (const_string "sseadd"))
13004 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13005 (const_string "fmul")
13006 (const_string "fop"))))
13007 (set_attr "isa" "*,noavx,avx")
13008 (set_attr "prefix" "orig,orig,vex")
13009 (set_attr "mode" "<MODE>")])
13011 (define_insn "*fop_<mode>_comm_sse"
13012 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13013 (match_operator:MODEF 3 "binary_fp_operator"
13014 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13015 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13016 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
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 "ssemul")
13023 (const_string "sseadd")))
13024 (set_attr "isa" "noavx,avx")
13025 (set_attr "prefix" "orig,vex")
13026 (set_attr "mode" "<MODE>")])
13028 (define_insn "*fop_<mode>_comm_i387"
13029 [(set (match_operand:MODEF 0 "register_operand" "=f")
13030 (match_operator:MODEF 3 "binary_fp_operator"
13031 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13032 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13033 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13034 && COMMUTATIVE_ARITH_P (operands[3])
13035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13036 "* return output_387_binary_op (insn, operands);"
13037 [(set (attr "type")
13038 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13039 (const_string "fmul")
13040 (const_string "fop")))
13041 (set_attr "mode" "<MODE>")])
13043 (define_insn "*fop_<mode>_1_mixed"
13044 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13045 (match_operator:MODEF 3 "binary_fp_operator"
13046 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13047 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13048 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13049 && !COMMUTATIVE_ARITH_P (operands[3])
13050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13051 "* return output_387_binary_op (insn, operands);"
13052 [(set (attr "type")
13053 (cond [(and (eq_attr "alternative" "2,3")
13054 (match_operand:MODEF 3 "mult_operator" ""))
13055 (const_string "ssemul")
13056 (and (eq_attr "alternative" "2,3")
13057 (match_operand:MODEF 3 "div_operator" ""))
13058 (const_string "ssediv")
13059 (eq_attr "alternative" "2,3")
13060 (const_string "sseadd")
13061 (match_operand:MODEF 3 "mult_operator" "")
13062 (const_string "fmul")
13063 (match_operand:MODEF 3 "div_operator" "")
13064 (const_string "fdiv")
13066 (const_string "fop")))
13067 (set_attr "isa" "*,*,noavx,avx")
13068 (set_attr "prefix" "orig,orig,orig,vex")
13069 (set_attr "mode" "<MODE>")])
13071 (define_insn "*rcpsf2_sse"
13072 [(set (match_operand:SF 0 "register_operand" "=x")
13073 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13076 "%vrcpss\t{%1, %d0|%d0, %1}"
13077 [(set_attr "type" "sse")
13078 (set_attr "atom_sse_attr" "rcp")
13079 (set_attr "prefix" "maybe_vex")
13080 (set_attr "mode" "SF")])
13082 (define_insn "*fop_<mode>_1_sse"
13083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13084 (match_operator:MODEF 3 "binary_fp_operator"
13085 [(match_operand:MODEF 1 "register_operand" "0,x")
13086 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13087 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13088 && !COMMUTATIVE_ARITH_P (operands[3])"
13089 "* return output_387_binary_op (insn, operands);"
13090 [(set (attr "type")
13091 (cond [(match_operand:MODEF 3 "mult_operator" "")
13092 (const_string "ssemul")
13093 (match_operand:MODEF 3 "div_operator" "")
13094 (const_string "ssediv")
13096 (const_string "sseadd")))
13097 (set_attr "isa" "noavx,avx")
13098 (set_attr "prefix" "orig,vex")
13099 (set_attr "mode" "<MODE>")])
13101 ;; This pattern is not fully shadowed by the pattern above.
13102 (define_insn "*fop_<mode>_1_i387"
13103 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13104 (match_operator:MODEF 3 "binary_fp_operator"
13105 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13106 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13107 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13108 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13109 && !COMMUTATIVE_ARITH_P (operands[3])
13110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13111 "* return output_387_binary_op (insn, operands);"
13112 [(set (attr "type")
13113 (cond [(match_operand:MODEF 3 "mult_operator" "")
13114 (const_string "fmul")
13115 (match_operand:MODEF 3 "div_operator" "")
13116 (const_string "fdiv")
13118 (const_string "fop")))
13119 (set_attr "mode" "<MODE>")])
13121 ;; ??? Add SSE splitters for these!
13122 (define_insn "*fop_<MODEF:mode>_2_i387"
13123 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13124 (match_operator:MODEF 3 "binary_fp_operator"
13126 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13127 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13128 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13129 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13130 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13131 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13132 [(set (attr "type")
13133 (cond [(match_operand:MODEF 3 "mult_operator" "")
13134 (const_string "fmul")
13135 (match_operand:MODEF 3 "div_operator" "")
13136 (const_string "fdiv")
13138 (const_string "fop")))
13139 (set_attr "fp_int_src" "true")
13140 (set_attr "mode" "<SWI24:MODE>")])
13142 (define_insn "*fop_<MODEF:mode>_3_i387"
13143 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13144 (match_operator:MODEF 3 "binary_fp_operator"
13145 [(match_operand:MODEF 1 "register_operand" "0,0")
13147 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13148 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13149 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13150 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13151 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13152 [(set (attr "type")
13153 (cond [(match_operand:MODEF 3 "mult_operator" "")
13154 (const_string "fmul")
13155 (match_operand:MODEF 3 "div_operator" "")
13156 (const_string "fdiv")
13158 (const_string "fop")))
13159 (set_attr "fp_int_src" "true")
13160 (set_attr "mode" "<MODE>")])
13162 (define_insn "*fop_df_4_i387"
13163 [(set (match_operand:DF 0 "register_operand" "=f,f")
13164 (match_operator:DF 3 "binary_fp_operator"
13166 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13167 (match_operand:DF 2 "register_operand" "0,f")]))]
13168 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13169 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13171 "* return output_387_binary_op (insn, operands);"
13172 [(set (attr "type")
13173 (cond [(match_operand:DF 3 "mult_operator" "")
13174 (const_string "fmul")
13175 (match_operand:DF 3 "div_operator" "")
13176 (const_string "fdiv")
13178 (const_string "fop")))
13179 (set_attr "mode" "SF")])
13181 (define_insn "*fop_df_5_i387"
13182 [(set (match_operand:DF 0 "register_operand" "=f,f")
13183 (match_operator:DF 3 "binary_fp_operator"
13184 [(match_operand:DF 1 "register_operand" "0,f")
13186 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13187 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13188 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13189 "* return output_387_binary_op (insn, operands);"
13190 [(set (attr "type")
13191 (cond [(match_operand:DF 3 "mult_operator" "")
13192 (const_string "fmul")
13193 (match_operand:DF 3 "div_operator" "")
13194 (const_string "fdiv")
13196 (const_string "fop")))
13197 (set_attr "mode" "SF")])
13199 (define_insn "*fop_df_6_i387"
13200 [(set (match_operand:DF 0 "register_operand" "=f,f")
13201 (match_operator:DF 3 "binary_fp_operator"
13203 (match_operand:SF 1 "register_operand" "0,f"))
13205 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13206 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13207 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13208 "* return output_387_binary_op (insn, operands);"
13209 [(set (attr "type")
13210 (cond [(match_operand:DF 3 "mult_operator" "")
13211 (const_string "fmul")
13212 (match_operand:DF 3 "div_operator" "")
13213 (const_string "fdiv")
13215 (const_string "fop")))
13216 (set_attr "mode" "SF")])
13218 (define_insn "*fop_xf_comm_i387"
13219 [(set (match_operand:XF 0 "register_operand" "=f")
13220 (match_operator:XF 3 "binary_fp_operator"
13221 [(match_operand:XF 1 "register_operand" "%0")
13222 (match_operand:XF 2 "register_operand" "f")]))]
13224 && COMMUTATIVE_ARITH_P (operands[3])"
13225 "* return output_387_binary_op (insn, operands);"
13226 [(set (attr "type")
13227 (if_then_else (match_operand:XF 3 "mult_operator" "")
13228 (const_string "fmul")
13229 (const_string "fop")))
13230 (set_attr "mode" "XF")])
13232 (define_insn "*fop_xf_1_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f,f")
13234 (match_operator:XF 3 "binary_fp_operator"
13235 [(match_operand:XF 1 "register_operand" "0,f")
13236 (match_operand:XF 2 "register_operand" "f,0")]))]
13238 && !COMMUTATIVE_ARITH_P (operands[3])"
13239 "* return 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 "mode" "XF")])
13249 (define_insn "*fop_xf_2_i387"
13250 [(set (match_operand:XF 0 "register_operand" "=f,f")
13251 (match_operator:XF 3 "binary_fp_operator"
13253 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13254 (match_operand:XF 2 "register_operand" "0,0")]))]
13255 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13256 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13257 [(set (attr "type")
13258 (cond [(match_operand:XF 3 "mult_operator" "")
13259 (const_string "fmul")
13260 (match_operand:XF 3 "div_operator" "")
13261 (const_string "fdiv")
13263 (const_string "fop")))
13264 (set_attr "fp_int_src" "true")
13265 (set_attr "mode" "<MODE>")])
13267 (define_insn "*fop_xf_3_i387"
13268 [(set (match_operand:XF 0 "register_operand" "=f,f")
13269 (match_operator:XF 3 "binary_fp_operator"
13270 [(match_operand:XF 1 "register_operand" "0,0")
13272 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13273 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13274 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13275 [(set (attr "type")
13276 (cond [(match_operand:XF 3 "mult_operator" "")
13277 (const_string "fmul")
13278 (match_operand:XF 3 "div_operator" "")
13279 (const_string "fdiv")
13281 (const_string "fop")))
13282 (set_attr "fp_int_src" "true")
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "*fop_xf_4_i387"
13286 [(set (match_operand:XF 0 "register_operand" "=f,f")
13287 (match_operator:XF 3 "binary_fp_operator"
13289 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13290 (match_operand:XF 2 "register_operand" "0,f")]))]
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_5_i387"
13303 [(set (match_operand:XF 0 "register_operand" "=f,f")
13304 (match_operator:XF 3 "binary_fp_operator"
13305 [(match_operand:XF 1 "register_operand" "0,f")
13307 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13309 "* return output_387_binary_op (insn, operands);"
13310 [(set (attr "type")
13311 (cond [(match_operand:XF 3 "mult_operator" "")
13312 (const_string "fmul")
13313 (match_operand:XF 3 "div_operator" "")
13314 (const_string "fdiv")
13316 (const_string "fop")))
13317 (set_attr "mode" "<MODE>")])
13319 (define_insn "*fop_xf_6_i387"
13320 [(set (match_operand:XF 0 "register_operand" "=f,f")
13321 (match_operator:XF 3 "binary_fp_operator"
13323 (match_operand:MODEF 1 "register_operand" "0,f"))
13325 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13327 "* return output_387_binary_op (insn, operands);"
13328 [(set (attr "type")
13329 (cond [(match_operand:XF 3 "mult_operator" "")
13330 (const_string "fmul")
13331 (match_operand:XF 3 "div_operator" "")
13332 (const_string "fdiv")
13334 (const_string "fop")))
13335 (set_attr "mode" "<MODE>")])
13338 [(set (match_operand 0 "register_operand" "")
13339 (match_operator 3 "binary_fp_operator"
13340 [(float (match_operand:SWI24 1 "register_operand" ""))
13341 (match_operand 2 "register_operand" "")]))]
13343 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13344 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13347 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13348 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13349 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13350 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13351 GET_MODE (operands[3]),
13354 ix86_free_from_memory (GET_MODE (operands[1]));
13359 [(set (match_operand 0 "register_operand" "")
13360 (match_operator 3 "binary_fp_operator"
13361 [(match_operand 1 "register_operand" "")
13362 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13364 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13365 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13368 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13369 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13370 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13371 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13372 GET_MODE (operands[3]),
13375 ix86_free_from_memory (GET_MODE (operands[2]));
13379 ;; FPU special functions.
13381 ;; This pattern implements a no-op XFmode truncation for
13382 ;; all fancy i386 XFmode math functions.
13384 (define_insn "truncxf<mode>2_i387_noop_unspec"
13385 [(set (match_operand:MODEF 0 "register_operand" "=f")
13386 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13387 UNSPEC_TRUNC_NOOP))]
13388 "TARGET_USE_FANCY_MATH_387"
13389 "* return output_387_reg_move (insn, operands);"
13390 [(set_attr "type" "fmov")
13391 (set_attr "mode" "<MODE>")])
13393 (define_insn "sqrtxf2"
13394 [(set (match_operand:XF 0 "register_operand" "=f")
13395 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13396 "TARGET_USE_FANCY_MATH_387"
13398 [(set_attr "type" "fpspc")
13399 (set_attr "mode" "XF")
13400 (set_attr "athlon_decode" "direct")
13401 (set_attr "amdfam10_decode" "direct")
13402 (set_attr "bdver1_decode" "direct")])
13404 (define_insn "sqrt_extend<mode>xf2_i387"
13405 [(set (match_operand:XF 0 "register_operand" "=f")
13408 (match_operand:MODEF 1 "register_operand" "0"))))]
13409 "TARGET_USE_FANCY_MATH_387"
13411 [(set_attr "type" "fpspc")
13412 (set_attr "mode" "XF")
13413 (set_attr "athlon_decode" "direct")
13414 (set_attr "amdfam10_decode" "direct")
13415 (set_attr "bdver1_decode" "direct")])
13417 (define_insn "*rsqrtsf2_sse"
13418 [(set (match_operand:SF 0 "register_operand" "=x")
13419 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13422 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13423 [(set_attr "type" "sse")
13424 (set_attr "atom_sse_attr" "rcp")
13425 (set_attr "prefix" "maybe_vex")
13426 (set_attr "mode" "SF")])
13428 (define_expand "rsqrtsf2"
13429 [(set (match_operand:SF 0 "register_operand" "")
13430 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13434 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13438 (define_insn "*sqrt<mode>2_sse"
13439 [(set (match_operand:MODEF 0 "register_operand" "=x")
13441 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13442 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13443 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13444 [(set_attr "type" "sse")
13445 (set_attr "atom_sse_attr" "sqrt")
13446 (set_attr "prefix" "maybe_vex")
13447 (set_attr "mode" "<MODE>")
13448 (set_attr "athlon_decode" "*")
13449 (set_attr "amdfam10_decode" "*")
13450 (set_attr "bdver1_decode" "*")])
13452 (define_expand "sqrt<mode>2"
13453 [(set (match_operand:MODEF 0 "register_operand" "")
13455 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13456 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13459 if (<MODE>mode == SFmode
13461 && TARGET_RECIP_SQRT
13462 && !optimize_function_for_size_p (cfun)
13463 && flag_finite_math_only && !flag_trapping_math
13464 && flag_unsafe_math_optimizations)
13466 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13470 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13472 rtx op0 = gen_reg_rtx (XFmode);
13473 rtx op1 = force_reg (<MODE>mode, operands[1]);
13475 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13476 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13481 (define_insn "fpremxf4_i387"
13482 [(set (match_operand:XF 0 "register_operand" "=f")
13483 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13484 (match_operand:XF 3 "register_operand" "1")]
13486 (set (match_operand:XF 1 "register_operand" "=u")
13487 (unspec:XF [(match_dup 2) (match_dup 3)]
13489 (set (reg:CCFP FPSR_REG)
13490 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13492 "TARGET_USE_FANCY_MATH_387"
13494 [(set_attr "type" "fpspc")
13495 (set_attr "mode" "XF")])
13497 (define_expand "fmodxf3"
13498 [(use (match_operand:XF 0 "register_operand" ""))
13499 (use (match_operand:XF 1 "general_operand" ""))
13500 (use (match_operand:XF 2 "general_operand" ""))]
13501 "TARGET_USE_FANCY_MATH_387"
13503 rtx label = gen_label_rtx ();
13505 rtx op1 = gen_reg_rtx (XFmode);
13506 rtx op2 = gen_reg_rtx (XFmode);
13508 emit_move_insn (op2, operands[2]);
13509 emit_move_insn (op1, operands[1]);
13511 emit_label (label);
13512 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513 ix86_emit_fp_unordered_jump (label);
13514 LABEL_NUSES (label) = 1;
13516 emit_move_insn (operands[0], op1);
13520 (define_expand "fmod<mode>3"
13521 [(use (match_operand:MODEF 0 "register_operand" ""))
13522 (use (match_operand:MODEF 1 "general_operand" ""))
13523 (use (match_operand:MODEF 2 "general_operand" ""))]
13524 "TARGET_USE_FANCY_MATH_387"
13526 rtx (*gen_truncxf) (rtx, rtx);
13528 rtx label = gen_label_rtx ();
13530 rtx op1 = gen_reg_rtx (XFmode);
13531 rtx op2 = gen_reg_rtx (XFmode);
13533 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13534 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13536 emit_label (label);
13537 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13538 ix86_emit_fp_unordered_jump (label);
13539 LABEL_NUSES (label) = 1;
13541 /* Truncate the result properly for strict SSE math. */
13542 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13543 && !TARGET_MIX_SSE_I387)
13544 gen_truncxf = gen_truncxf<mode>2;
13546 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13548 emit_insn (gen_truncxf (operands[0], op1));
13552 (define_insn "fprem1xf4_i387"
13553 [(set (match_operand:XF 0 "register_operand" "=f")
13554 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13555 (match_operand:XF 3 "register_operand" "1")]
13557 (set (match_operand:XF 1 "register_operand" "=u")
13558 (unspec:XF [(match_dup 2) (match_dup 3)]
13560 (set (reg:CCFP FPSR_REG)
13561 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13563 "TARGET_USE_FANCY_MATH_387"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13568 (define_expand "remainderxf3"
13569 [(use (match_operand:XF 0 "register_operand" ""))
13570 (use (match_operand:XF 1 "general_operand" ""))
13571 (use (match_operand:XF 2 "general_operand" ""))]
13572 "TARGET_USE_FANCY_MATH_387"
13574 rtx label = gen_label_rtx ();
13576 rtx op1 = gen_reg_rtx (XFmode);
13577 rtx op2 = gen_reg_rtx (XFmode);
13579 emit_move_insn (op2, operands[2]);
13580 emit_move_insn (op1, operands[1]);
13582 emit_label (label);
13583 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13584 ix86_emit_fp_unordered_jump (label);
13585 LABEL_NUSES (label) = 1;
13587 emit_move_insn (operands[0], op1);
13591 (define_expand "remainder<mode>3"
13592 [(use (match_operand:MODEF 0 "register_operand" ""))
13593 (use (match_operand:MODEF 1 "general_operand" ""))
13594 (use (match_operand:MODEF 2 "general_operand" ""))]
13595 "TARGET_USE_FANCY_MATH_387"
13597 rtx (*gen_truncxf) (rtx, rtx);
13599 rtx label = gen_label_rtx ();
13601 rtx op1 = gen_reg_rtx (XFmode);
13602 rtx op2 = gen_reg_rtx (XFmode);
13604 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13605 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13607 emit_label (label);
13609 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13610 ix86_emit_fp_unordered_jump (label);
13611 LABEL_NUSES (label) = 1;
13613 /* Truncate the result properly for strict SSE math. */
13614 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13615 && !TARGET_MIX_SSE_I387)
13616 gen_truncxf = gen_truncxf<mode>2;
13618 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13620 emit_insn (gen_truncxf (operands[0], op1));
13624 (define_insn "*sinxf2_i387"
13625 [(set (match_operand:XF 0 "register_operand" "=f")
13626 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13627 "TARGET_USE_FANCY_MATH_387
13628 && flag_unsafe_math_optimizations"
13630 [(set_attr "type" "fpspc")
13631 (set_attr "mode" "XF")])
13633 (define_insn "*sin_extend<mode>xf2_i387"
13634 [(set (match_operand:XF 0 "register_operand" "=f")
13635 (unspec:XF [(float_extend:XF
13636 (match_operand:MODEF 1 "register_operand" "0"))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640 || TARGET_MIX_SSE_I387)
13641 && flag_unsafe_math_optimizations"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")])
13646 (define_insn "*cosxf2_i387"
13647 [(set (match_operand:XF 0 "register_operand" "=f")
13648 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13649 "TARGET_USE_FANCY_MATH_387
13650 && flag_unsafe_math_optimizations"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")])
13655 (define_insn "*cos_extend<mode>xf2_i387"
13656 [(set (match_operand:XF 0 "register_operand" "=f")
13657 (unspec:XF [(float_extend:XF
13658 (match_operand:MODEF 1 "register_operand" "0"))]
13660 "TARGET_USE_FANCY_MATH_387
13661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662 || TARGET_MIX_SSE_I387)
13663 && flag_unsafe_math_optimizations"
13665 [(set_attr "type" "fpspc")
13666 (set_attr "mode" "XF")])
13668 ;; When sincos pattern is defined, sin and cos builtin functions will be
13669 ;; expanded to sincos pattern with one of its outputs left unused.
13670 ;; CSE pass will figure out if two sincos patterns can be combined,
13671 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13672 ;; depending on the unused output.
13674 (define_insn "sincosxf3"
13675 [(set (match_operand:XF 0 "register_operand" "=f")
13676 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13677 UNSPEC_SINCOS_COS))
13678 (set (match_operand:XF 1 "register_operand" "=u")
13679 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13680 "TARGET_USE_FANCY_MATH_387
13681 && flag_unsafe_math_optimizations"
13683 [(set_attr "type" "fpspc")
13684 (set_attr "mode" "XF")])
13687 [(set (match_operand:XF 0 "register_operand" "")
13688 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13689 UNSPEC_SINCOS_COS))
13690 (set (match_operand:XF 1 "register_operand" "")
13691 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13692 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13693 && can_create_pseudo_p ()"
13694 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13697 [(set (match_operand:XF 0 "register_operand" "")
13698 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13699 UNSPEC_SINCOS_COS))
13700 (set (match_operand:XF 1 "register_operand" "")
13701 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13702 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13703 && can_create_pseudo_p ()"
13704 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13706 (define_insn "sincos_extend<mode>xf3_i387"
13707 [(set (match_operand:XF 0 "register_operand" "=f")
13708 (unspec:XF [(float_extend:XF
13709 (match_operand:MODEF 2 "register_operand" "0"))]
13710 UNSPEC_SINCOS_COS))
13711 (set (match_operand:XF 1 "register_operand" "=u")
13712 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13713 "TARGET_USE_FANCY_MATH_387
13714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13715 || TARGET_MIX_SSE_I387)
13716 && flag_unsafe_math_optimizations"
13718 [(set_attr "type" "fpspc")
13719 (set_attr "mode" "XF")])
13722 [(set (match_operand:XF 0 "register_operand" "")
13723 (unspec:XF [(float_extend:XF
13724 (match_operand:MODEF 2 "register_operand" ""))]
13725 UNSPEC_SINCOS_COS))
13726 (set (match_operand:XF 1 "register_operand" "")
13727 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13728 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13729 && can_create_pseudo_p ()"
13730 [(set (match_dup 1)
13731 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13734 [(set (match_operand:XF 0 "register_operand" "")
13735 (unspec:XF [(float_extend:XF
13736 (match_operand:MODEF 2 "register_operand" ""))]
13737 UNSPEC_SINCOS_COS))
13738 (set (match_operand:XF 1 "register_operand" "")
13739 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13740 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13741 && can_create_pseudo_p ()"
13742 [(set (match_dup 0)
13743 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13745 (define_expand "sincos<mode>3"
13746 [(use (match_operand:MODEF 0 "register_operand" ""))
13747 (use (match_operand:MODEF 1 "register_operand" ""))
13748 (use (match_operand:MODEF 2 "register_operand" ""))]
13749 "TARGET_USE_FANCY_MATH_387
13750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751 || TARGET_MIX_SSE_I387)
13752 && flag_unsafe_math_optimizations"
13754 rtx op0 = gen_reg_rtx (XFmode);
13755 rtx op1 = gen_reg_rtx (XFmode);
13757 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13758 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13759 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13763 (define_insn "fptanxf4_i387"
13764 [(set (match_operand:XF 0 "register_operand" "=f")
13765 (match_operand:XF 3 "const_double_operand" "F"))
13766 (set (match_operand:XF 1 "register_operand" "=u")
13767 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13769 "TARGET_USE_FANCY_MATH_387
13770 && flag_unsafe_math_optimizations
13771 && standard_80387_constant_p (operands[3]) == 2"
13773 [(set_attr "type" "fpspc")
13774 (set_attr "mode" "XF")])
13776 (define_insn "fptan_extend<mode>xf4_i387"
13777 [(set (match_operand:MODEF 0 "register_operand" "=f")
13778 (match_operand:MODEF 3 "const_double_operand" "F"))
13779 (set (match_operand:XF 1 "register_operand" "=u")
13780 (unspec:XF [(float_extend:XF
13781 (match_operand:MODEF 2 "register_operand" "0"))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations
13787 && standard_80387_constant_p (operands[3]) == 2"
13789 [(set_attr "type" "fpspc")
13790 (set_attr "mode" "XF")])
13792 (define_expand "tanxf2"
13793 [(use (match_operand:XF 0 "register_operand" ""))
13794 (use (match_operand:XF 1 "register_operand" ""))]
13795 "TARGET_USE_FANCY_MATH_387
13796 && flag_unsafe_math_optimizations"
13798 rtx one = gen_reg_rtx (XFmode);
13799 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13801 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13805 (define_expand "tan<mode>2"
13806 [(use (match_operand:MODEF 0 "register_operand" ""))
13807 (use (match_operand:MODEF 1 "register_operand" ""))]
13808 "TARGET_USE_FANCY_MATH_387
13809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810 || TARGET_MIX_SSE_I387)
13811 && flag_unsafe_math_optimizations"
13813 rtx op0 = gen_reg_rtx (XFmode);
13815 rtx one = gen_reg_rtx (<MODE>mode);
13816 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13818 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13819 operands[1], op2));
13820 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13824 (define_insn "*fpatanxf3_i387"
13825 [(set (match_operand:XF 0 "register_operand" "=f")
13826 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13827 (match_operand:XF 2 "register_operand" "u")]
13829 (clobber (match_scratch:XF 3 "=2"))]
13830 "TARGET_USE_FANCY_MATH_387
13831 && flag_unsafe_math_optimizations"
13833 [(set_attr "type" "fpspc")
13834 (set_attr "mode" "XF")])
13836 (define_insn "fpatan_extend<mode>xf3_i387"
13837 [(set (match_operand:XF 0 "register_operand" "=f")
13838 (unspec:XF [(float_extend:XF
13839 (match_operand:MODEF 1 "register_operand" "0"))
13841 (match_operand:MODEF 2 "register_operand" "u"))]
13843 (clobber (match_scratch:XF 3 "=2"))]
13844 "TARGET_USE_FANCY_MATH_387
13845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13846 || TARGET_MIX_SSE_I387)
13847 && flag_unsafe_math_optimizations"
13849 [(set_attr "type" "fpspc")
13850 (set_attr "mode" "XF")])
13852 (define_expand "atan2xf3"
13853 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13855 (match_operand:XF 1 "register_operand" "")]
13857 (clobber (match_scratch:XF 3 ""))])]
13858 "TARGET_USE_FANCY_MATH_387
13859 && flag_unsafe_math_optimizations")
13861 (define_expand "atan2<mode>3"
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "register_operand" ""))
13864 (use (match_operand:MODEF 2 "register_operand" ""))]
13865 "TARGET_USE_FANCY_MATH_387
13866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13867 || TARGET_MIX_SSE_I387)
13868 && flag_unsafe_math_optimizations"
13870 rtx op0 = gen_reg_rtx (XFmode);
13872 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13877 (define_expand "atanxf2"
13878 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13879 (unspec:XF [(match_dup 2)
13880 (match_operand:XF 1 "register_operand" "")]
13882 (clobber (match_scratch:XF 3 ""))])]
13883 "TARGET_USE_FANCY_MATH_387
13884 && flag_unsafe_math_optimizations"
13886 operands[2] = gen_reg_rtx (XFmode);
13887 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13890 (define_expand "atan<mode>2"
13891 [(use (match_operand:MODEF 0 "register_operand" ""))
13892 (use (match_operand:MODEF 1 "register_operand" ""))]
13893 "TARGET_USE_FANCY_MATH_387
13894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13895 || TARGET_MIX_SSE_I387)
13896 && flag_unsafe_math_optimizations"
13898 rtx op0 = gen_reg_rtx (XFmode);
13900 rtx op2 = gen_reg_rtx (<MODE>mode);
13901 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13903 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13908 (define_expand "asinxf2"
13909 [(set (match_dup 2)
13910 (mult:XF (match_operand:XF 1 "register_operand" "")
13912 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13913 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13914 (parallel [(set (match_operand:XF 0 "register_operand" "")
13915 (unspec:XF [(match_dup 5) (match_dup 1)]
13917 (clobber (match_scratch:XF 6 ""))])]
13918 "TARGET_USE_FANCY_MATH_387
13919 && flag_unsafe_math_optimizations"
13923 if (optimize_insn_for_size_p ())
13926 for (i = 2; i < 6; i++)
13927 operands[i] = gen_reg_rtx (XFmode);
13929 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13932 (define_expand "asin<mode>2"
13933 [(use (match_operand:MODEF 0 "register_operand" ""))
13934 (use (match_operand:MODEF 1 "general_operand" ""))]
13935 "TARGET_USE_FANCY_MATH_387
13936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13937 || TARGET_MIX_SSE_I387)
13938 && flag_unsafe_math_optimizations"
13940 rtx op0 = gen_reg_rtx (XFmode);
13941 rtx op1 = gen_reg_rtx (XFmode);
13943 if (optimize_insn_for_size_p ())
13946 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13947 emit_insn (gen_asinxf2 (op0, op1));
13948 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13952 (define_expand "acosxf2"
13953 [(set (match_dup 2)
13954 (mult:XF (match_operand:XF 1 "register_operand" "")
13956 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13957 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13958 (parallel [(set (match_operand:XF 0 "register_operand" "")
13959 (unspec:XF [(match_dup 1) (match_dup 5)]
13961 (clobber (match_scratch:XF 6 ""))])]
13962 "TARGET_USE_FANCY_MATH_387
13963 && flag_unsafe_math_optimizations"
13967 if (optimize_insn_for_size_p ())
13970 for (i = 2; i < 6; i++)
13971 operands[i] = gen_reg_rtx (XFmode);
13973 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13976 (define_expand "acos<mode>2"
13977 [(use (match_operand:MODEF 0 "register_operand" ""))
13978 (use (match_operand:MODEF 1 "general_operand" ""))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13984 rtx op0 = gen_reg_rtx (XFmode);
13985 rtx op1 = gen_reg_rtx (XFmode);
13987 if (optimize_insn_for_size_p ())
13990 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13991 emit_insn (gen_acosxf2 (op0, op1));
13992 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13996 (define_insn "fyl2xxf3_i387"
13997 [(set (match_operand:XF 0 "register_operand" "=f")
13998 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13999 (match_operand:XF 2 "register_operand" "u")]
14001 (clobber (match_scratch:XF 3 "=2"))]
14002 "TARGET_USE_FANCY_MATH_387
14003 && flag_unsafe_math_optimizations"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14008 (define_insn "fyl2x_extend<mode>xf3_i387"
14009 [(set (match_operand:XF 0 "register_operand" "=f")
14010 (unspec:XF [(float_extend:XF
14011 (match_operand:MODEF 1 "register_operand" "0"))
14012 (match_operand:XF 2 "register_operand" "u")]
14014 (clobber (match_scratch:XF 3 "=2"))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14017 || TARGET_MIX_SSE_I387)
14018 && flag_unsafe_math_optimizations"
14020 [(set_attr "type" "fpspc")
14021 (set_attr "mode" "XF")])
14023 (define_expand "logxf2"
14024 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14025 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14026 (match_dup 2)] UNSPEC_FYL2X))
14027 (clobber (match_scratch:XF 3 ""))])]
14028 "TARGET_USE_FANCY_MATH_387
14029 && flag_unsafe_math_optimizations"
14031 operands[2] = gen_reg_rtx (XFmode);
14032 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14035 (define_expand "log<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand" ""))
14037 (use (match_operand:MODEF 1 "register_operand" ""))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14043 rtx op0 = gen_reg_rtx (XFmode);
14045 rtx op2 = gen_reg_rtx (XFmode);
14046 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14048 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 (define_expand "log10xf2"
14054 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14055 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14056 (match_dup 2)] UNSPEC_FYL2X))
14057 (clobber (match_scratch:XF 3 ""))])]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations"
14061 operands[2] = gen_reg_rtx (XFmode);
14062 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14065 (define_expand "log10<mode>2"
14066 [(use (match_operand:MODEF 0 "register_operand" ""))
14067 (use (match_operand:MODEF 1 "register_operand" ""))]
14068 "TARGET_USE_FANCY_MATH_387
14069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070 || TARGET_MIX_SSE_I387)
14071 && flag_unsafe_math_optimizations"
14073 rtx op0 = gen_reg_rtx (XFmode);
14075 rtx op2 = gen_reg_rtx (XFmode);
14076 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14078 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14083 (define_expand "log2xf2"
14084 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14085 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14086 (match_dup 2)] UNSPEC_FYL2X))
14087 (clobber (match_scratch:XF 3 ""))])]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations"
14091 operands[2] = gen_reg_rtx (XFmode);
14092 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14095 (define_expand "log2<mode>2"
14096 [(use (match_operand:MODEF 0 "register_operand" ""))
14097 (use (match_operand:MODEF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14100 || TARGET_MIX_SSE_I387)
14101 && flag_unsafe_math_optimizations"
14103 rtx op0 = gen_reg_rtx (XFmode);
14105 rtx op2 = gen_reg_rtx (XFmode);
14106 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14108 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113 (define_insn "fyl2xp1xf3_i387"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14116 (match_operand:XF 2 "register_operand" "u")]
14118 (clobber (match_scratch:XF 3 "=2"))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && flag_unsafe_math_optimizations"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14125 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14126 [(set (match_operand:XF 0 "register_operand" "=f")
14127 (unspec:XF [(float_extend:XF
14128 (match_operand:MODEF 1 "register_operand" "0"))
14129 (match_operand:XF 2 "register_operand" "u")]
14131 (clobber (match_scratch:XF 3 "=2"))]
14132 "TARGET_USE_FANCY_MATH_387
14133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14134 || TARGET_MIX_SSE_I387)
14135 && flag_unsafe_math_optimizations"
14137 [(set_attr "type" "fpspc")
14138 (set_attr "mode" "XF")])
14140 (define_expand "log1pxf2"
14141 [(use (match_operand:XF 0 "register_operand" ""))
14142 (use (match_operand:XF 1 "register_operand" ""))]
14143 "TARGET_USE_FANCY_MATH_387
14144 && flag_unsafe_math_optimizations"
14146 if (optimize_insn_for_size_p ())
14149 ix86_emit_i387_log1p (operands[0], operands[1]);
14153 (define_expand "log1p<mode>2"
14154 [(use (match_operand:MODEF 0 "register_operand" ""))
14155 (use (match_operand:MODEF 1 "register_operand" ""))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14163 if (optimize_insn_for_size_p ())
14166 op0 = gen_reg_rtx (XFmode);
14168 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14170 ix86_emit_i387_log1p (op0, operands[1]);
14171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14175 (define_insn "fxtractxf3_i387"
14176 [(set (match_operand:XF 0 "register_operand" "=f")
14177 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14178 UNSPEC_XTRACT_FRACT))
14179 (set (match_operand:XF 1 "register_operand" "=u")
14180 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14181 "TARGET_USE_FANCY_MATH_387
14182 && flag_unsafe_math_optimizations"
14184 [(set_attr "type" "fpspc")
14185 (set_attr "mode" "XF")])
14187 (define_insn "fxtract_extend<mode>xf3_i387"
14188 [(set (match_operand:XF 0 "register_operand" "=f")
14189 (unspec:XF [(float_extend:XF
14190 (match_operand:MODEF 2 "register_operand" "0"))]
14191 UNSPEC_XTRACT_FRACT))
14192 (set (match_operand:XF 1 "register_operand" "=u")
14193 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14194 "TARGET_USE_FANCY_MATH_387
14195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14196 || TARGET_MIX_SSE_I387)
14197 && flag_unsafe_math_optimizations"
14199 [(set_attr "type" "fpspc")
14200 (set_attr "mode" "XF")])
14202 (define_expand "logbxf2"
14203 [(parallel [(set (match_dup 2)
14204 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14205 UNSPEC_XTRACT_FRACT))
14206 (set (match_operand:XF 0 "register_operand" "")
14207 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14210 "operands[2] = gen_reg_rtx (XFmode);")
14212 (define_expand "logb<mode>2"
14213 [(use (match_operand:MODEF 0 "register_operand" ""))
14214 (use (match_operand:MODEF 1 "register_operand" ""))]
14215 "TARGET_USE_FANCY_MATH_387
14216 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14217 || TARGET_MIX_SSE_I387)
14218 && flag_unsafe_math_optimizations"
14220 rtx op0 = gen_reg_rtx (XFmode);
14221 rtx op1 = gen_reg_rtx (XFmode);
14223 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14228 (define_expand "ilogbxf2"
14229 [(use (match_operand:SI 0 "register_operand" ""))
14230 (use (match_operand:XF 1 "register_operand" ""))]
14231 "TARGET_USE_FANCY_MATH_387
14232 && flag_unsafe_math_optimizations"
14236 if (optimize_insn_for_size_p ())
14239 op0 = gen_reg_rtx (XFmode);
14240 op1 = gen_reg_rtx (XFmode);
14242 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14243 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14247 (define_expand "ilogb<mode>2"
14248 [(use (match_operand:SI 0 "register_operand" ""))
14249 (use (match_operand:MODEF 1 "register_operand" ""))]
14250 "TARGET_USE_FANCY_MATH_387
14251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14252 || TARGET_MIX_SSE_I387)
14253 && flag_unsafe_math_optimizations"
14257 if (optimize_insn_for_size_p ())
14260 op0 = gen_reg_rtx (XFmode);
14261 op1 = gen_reg_rtx (XFmode);
14263 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14264 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14268 (define_insn "*f2xm1xf2_i387"
14269 [(set (match_operand:XF 0 "register_operand" "=f")
14270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14272 "TARGET_USE_FANCY_MATH_387
14273 && flag_unsafe_math_optimizations"
14275 [(set_attr "type" "fpspc")
14276 (set_attr "mode" "XF")])
14278 (define_insn "*fscalexf4_i387"
14279 [(set (match_operand:XF 0 "register_operand" "=f")
14280 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14281 (match_operand:XF 3 "register_operand" "1")]
14282 UNSPEC_FSCALE_FRACT))
14283 (set (match_operand:XF 1 "register_operand" "=u")
14284 (unspec:XF [(match_dup 2) (match_dup 3)]
14285 UNSPEC_FSCALE_EXP))]
14286 "TARGET_USE_FANCY_MATH_387
14287 && flag_unsafe_math_optimizations"
14289 [(set_attr "type" "fpspc")
14290 (set_attr "mode" "XF")])
14292 (define_expand "expNcorexf3"
14293 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14294 (match_operand:XF 2 "register_operand" "")))
14295 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14296 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14297 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14298 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14299 (parallel [(set (match_operand:XF 0 "register_operand" "")
14300 (unspec:XF [(match_dup 8) (match_dup 4)]
14301 UNSPEC_FSCALE_FRACT))
14303 (unspec:XF [(match_dup 8) (match_dup 4)]
14304 UNSPEC_FSCALE_EXP))])]
14305 "TARGET_USE_FANCY_MATH_387
14306 && flag_unsafe_math_optimizations"
14310 if (optimize_insn_for_size_p ())
14313 for (i = 3; i < 10; i++)
14314 operands[i] = gen_reg_rtx (XFmode);
14316 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14319 (define_expand "expxf2"
14320 [(use (match_operand:XF 0 "register_operand" ""))
14321 (use (match_operand:XF 1 "register_operand" ""))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14327 if (optimize_insn_for_size_p ())
14330 op2 = gen_reg_rtx (XFmode);
14331 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14333 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14337 (define_expand "exp<mode>2"
14338 [(use (match_operand:MODEF 0 "register_operand" ""))
14339 (use (match_operand:MODEF 1 "general_operand" ""))]
14340 "TARGET_USE_FANCY_MATH_387
14341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14342 || TARGET_MIX_SSE_I387)
14343 && flag_unsafe_math_optimizations"
14347 if (optimize_insn_for_size_p ())
14350 op0 = gen_reg_rtx (XFmode);
14351 op1 = gen_reg_rtx (XFmode);
14353 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14354 emit_insn (gen_expxf2 (op0, op1));
14355 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14359 (define_expand "exp10xf2"
14360 [(use (match_operand:XF 0 "register_operand" ""))
14361 (use (match_operand:XF 1 "register_operand" ""))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && flag_unsafe_math_optimizations"
14367 if (optimize_insn_for_size_p ())
14370 op2 = gen_reg_rtx (XFmode);
14371 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14373 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14377 (define_expand "exp10<mode>2"
14378 [(use (match_operand:MODEF 0 "register_operand" ""))
14379 (use (match_operand:MODEF 1 "general_operand" ""))]
14380 "TARGET_USE_FANCY_MATH_387
14381 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14382 || TARGET_MIX_SSE_I387)
14383 && flag_unsafe_math_optimizations"
14387 if (optimize_insn_for_size_p ())
14390 op0 = gen_reg_rtx (XFmode);
14391 op1 = gen_reg_rtx (XFmode);
14393 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14394 emit_insn (gen_exp10xf2 (op0, op1));
14395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14399 (define_expand "exp2xf2"
14400 [(use (match_operand:XF 0 "register_operand" ""))
14401 (use (match_operand:XF 1 "register_operand" ""))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && flag_unsafe_math_optimizations"
14407 if (optimize_insn_for_size_p ())
14410 op2 = gen_reg_rtx (XFmode);
14411 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14413 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14417 (define_expand "exp2<mode>2"
14418 [(use (match_operand:MODEF 0 "register_operand" ""))
14419 (use (match_operand:MODEF 1 "general_operand" ""))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations"
14427 if (optimize_insn_for_size_p ())
14430 op0 = gen_reg_rtx (XFmode);
14431 op1 = gen_reg_rtx (XFmode);
14433 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14434 emit_insn (gen_exp2xf2 (op0, op1));
14435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14439 (define_expand "expm1xf2"
14440 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14442 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14443 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14444 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14445 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14446 (parallel [(set (match_dup 7)
14447 (unspec:XF [(match_dup 6) (match_dup 4)]
14448 UNSPEC_FSCALE_FRACT))
14450 (unspec:XF [(match_dup 6) (match_dup 4)]
14451 UNSPEC_FSCALE_EXP))])
14452 (parallel [(set (match_dup 10)
14453 (unspec:XF [(match_dup 9) (match_dup 8)]
14454 UNSPEC_FSCALE_FRACT))
14455 (set (match_dup 11)
14456 (unspec:XF [(match_dup 9) (match_dup 8)]
14457 UNSPEC_FSCALE_EXP))])
14458 (set (match_dup 12) (minus:XF (match_dup 10)
14459 (float_extend:XF (match_dup 13))))
14460 (set (match_operand:XF 0 "register_operand" "")
14461 (plus:XF (match_dup 12) (match_dup 7)))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations"
14467 if (optimize_insn_for_size_p ())
14470 for (i = 2; i < 13; i++)
14471 operands[i] = gen_reg_rtx (XFmode);
14474 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14476 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14479 (define_expand "expm1<mode>2"
14480 [(use (match_operand:MODEF 0 "register_operand" ""))
14481 (use (match_operand:MODEF 1 "general_operand" ""))]
14482 "TARGET_USE_FANCY_MATH_387
14483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484 || TARGET_MIX_SSE_I387)
14485 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14492 op0 = gen_reg_rtx (XFmode);
14493 op1 = gen_reg_rtx (XFmode);
14495 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496 emit_insn (gen_expm1xf2 (op0, op1));
14497 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14501 (define_expand "ldexpxf3"
14502 [(set (match_dup 3)
14503 (float:XF (match_operand:SI 2 "register_operand" "")))
14504 (parallel [(set (match_operand:XF 0 " register_operand" "")
14505 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14507 UNSPEC_FSCALE_FRACT))
14509 (unspec:XF [(match_dup 1) (match_dup 3)]
14510 UNSPEC_FSCALE_EXP))])]
14511 "TARGET_USE_FANCY_MATH_387
14512 && flag_unsafe_math_optimizations"
14514 if (optimize_insn_for_size_p ())
14517 operands[3] = gen_reg_rtx (XFmode);
14518 operands[4] = gen_reg_rtx (XFmode);
14521 (define_expand "ldexp<mode>3"
14522 [(use (match_operand:MODEF 0 "register_operand" ""))
14523 (use (match_operand:MODEF 1 "general_operand" ""))
14524 (use (match_operand:SI 2 "register_operand" ""))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527 || TARGET_MIX_SSE_I387)
14528 && flag_unsafe_math_optimizations"
14532 if (optimize_insn_for_size_p ())
14535 op0 = gen_reg_rtx (XFmode);
14536 op1 = gen_reg_rtx (XFmode);
14538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14539 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14544 (define_expand "scalbxf3"
14545 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14546 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14547 (match_operand:XF 2 "register_operand" "")]
14548 UNSPEC_FSCALE_FRACT))
14550 (unspec:XF [(match_dup 1) (match_dup 2)]
14551 UNSPEC_FSCALE_EXP))])]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14555 if (optimize_insn_for_size_p ())
14558 operands[3] = gen_reg_rtx (XFmode);
14561 (define_expand "scalb<mode>3"
14562 [(use (match_operand:MODEF 0 "register_operand" ""))
14563 (use (match_operand:MODEF 1 "general_operand" ""))
14564 (use (match_operand:MODEF 2 "general_operand" ""))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14567 || TARGET_MIX_SSE_I387)
14568 && flag_unsafe_math_optimizations"
14572 if (optimize_insn_for_size_p ())
14575 op0 = gen_reg_rtx (XFmode);
14576 op1 = gen_reg_rtx (XFmode);
14577 op2 = gen_reg_rtx (XFmode);
14579 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14580 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14581 emit_insn (gen_scalbxf3 (op0, op1, op2));
14582 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586 (define_expand "significandxf2"
14587 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14588 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14589 UNSPEC_XTRACT_FRACT))
14591 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14594 "operands[2] = gen_reg_rtx (XFmode);")
14596 (define_expand "significand<mode>2"
14597 [(use (match_operand:MODEF 0 "register_operand" ""))
14598 (use (match_operand:MODEF 1 "register_operand" ""))]
14599 "TARGET_USE_FANCY_MATH_387
14600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601 || TARGET_MIX_SSE_I387)
14602 && flag_unsafe_math_optimizations"
14604 rtx op0 = gen_reg_rtx (XFmode);
14605 rtx op1 = gen_reg_rtx (XFmode);
14607 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14608 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14613 (define_insn "sse4_1_round<mode>2"
14614 [(set (match_operand:MODEF 0 "register_operand" "=x")
14615 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14616 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14619 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14620 [(set_attr "type" "ssecvt")
14621 (set_attr "prefix_extra" "1")
14622 (set_attr "prefix" "maybe_vex")
14623 (set_attr "mode" "<MODE>")])
14625 (define_insn "rintxf2"
14626 [(set (match_operand:XF 0 "register_operand" "=f")
14627 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14629 "TARGET_USE_FANCY_MATH_387
14630 && flag_unsafe_math_optimizations"
14632 [(set_attr "type" "fpspc")
14633 (set_attr "mode" "XF")])
14635 (define_expand "rint<mode>2"
14636 [(use (match_operand:MODEF 0 "register_operand" ""))
14637 (use (match_operand:MODEF 1 "register_operand" ""))]
14638 "(TARGET_USE_FANCY_MATH_387
14639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14640 || TARGET_MIX_SSE_I387)
14641 && flag_unsafe_math_optimizations)
14642 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14643 && !flag_trapping_math)"
14645 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14646 && !flag_trapping_math)
14649 emit_insn (gen_sse4_1_round<mode>2
14650 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14651 else if (optimize_insn_for_size_p ())
14654 ix86_expand_rint (operand0, operand1);
14658 rtx op0 = gen_reg_rtx (XFmode);
14659 rtx op1 = gen_reg_rtx (XFmode);
14661 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14662 emit_insn (gen_rintxf2 (op0, op1));
14664 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14669 (define_expand "round<mode>2"
14670 [(match_operand:X87MODEF 0 "register_operand" "")
14671 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14672 "(TARGET_USE_FANCY_MATH_387
14673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14674 || TARGET_MIX_SSE_I387)
14675 && flag_unsafe_math_optimizations)
14676 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14677 && !flag_trapping_math && !flag_rounding_math)"
14679 if (optimize_insn_for_size_p ())
14682 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14683 && !flag_trapping_math && !flag_rounding_math)
14687 operands[1] = force_reg (<MODE>mode, operands[1]);
14688 ix86_expand_round_sse4 (operands[0], operands[1]);
14690 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14691 ix86_expand_round (operands[0], operands[1]);
14693 ix86_expand_rounddf_32 (operands[0], operands[1]);
14697 operands[1] = force_reg (<MODE>mode, operands[1]);
14698 ix86_emit_i387_round (operands[0], operands[1]);
14703 (define_insn_and_split "*fistdi2_1"
14704 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14705 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14707 "TARGET_USE_FANCY_MATH_387
14708 && can_create_pseudo_p ()"
14713 if (memory_operand (operands[0], VOIDmode))
14714 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14717 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14718 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14723 [(set_attr "type" "fpspc")
14724 (set_attr "mode" "DI")])
14726 (define_insn "fistdi2"
14727 [(set (match_operand:DI 0 "memory_operand" "=m")
14728 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14730 (clobber (match_scratch:XF 2 "=&1f"))]
14731 "TARGET_USE_FANCY_MATH_387"
14732 "* return output_fix_trunc (insn, operands, false);"
14733 [(set_attr "type" "fpspc")
14734 (set_attr "mode" "DI")])
14736 (define_insn "fistdi2_with_temp"
14737 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14738 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14740 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14741 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14742 "TARGET_USE_FANCY_MATH_387"
14744 [(set_attr "type" "fpspc")
14745 (set_attr "mode" "DI")])
14748 [(set (match_operand:DI 0 "register_operand" "")
14749 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14751 (clobber (match_operand:DI 2 "memory_operand" ""))
14752 (clobber (match_scratch 3 ""))]
14754 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14755 (clobber (match_dup 3))])
14756 (set (match_dup 0) (match_dup 2))])
14759 [(set (match_operand:DI 0 "memory_operand" "")
14760 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14762 (clobber (match_operand:DI 2 "memory_operand" ""))
14763 (clobber (match_scratch 3 ""))]
14765 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14766 (clobber (match_dup 3))])])
14768 (define_insn_and_split "*fist<mode>2_1"
14769 [(set (match_operand:SWI24 0 "register_operand" "")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14772 "TARGET_USE_FANCY_MATH_387
14773 && can_create_pseudo_p ()"
14778 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14779 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14783 [(set_attr "type" "fpspc")
14784 (set_attr "mode" "<MODE>")])
14786 (define_insn "fist<mode>2"
14787 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14788 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14790 "TARGET_USE_FANCY_MATH_387"
14791 "* return output_fix_trunc (insn, operands, false);"
14792 [(set_attr "type" "fpspc")
14793 (set_attr "mode" "<MODE>")])
14795 (define_insn "fist<mode>2_with_temp"
14796 [(set (match_operand:SWI24 0 "register_operand" "=r")
14797 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14799 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14800 "TARGET_USE_FANCY_MATH_387"
14802 [(set_attr "type" "fpspc")
14803 (set_attr "mode" "<MODE>")])
14806 [(set (match_operand:SWI24 0 "register_operand" "")
14807 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14809 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14811 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14812 (set (match_dup 0) (match_dup 2))])
14815 [(set (match_operand:SWI24 0 "memory_operand" "")
14816 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14818 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14820 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14822 (define_expand "lrintxf<mode>2"
14823 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14824 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14826 "TARGET_USE_FANCY_MATH_387")
14828 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14829 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14830 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14831 UNSPEC_FIX_NOTRUNC))]
14832 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14833 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14835 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14836 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14837 (match_operand:X87MODEF 1 "register_operand" "")]
14838 "(TARGET_USE_FANCY_MATH_387
14839 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14840 || TARGET_MIX_SSE_I387)
14841 && flag_unsafe_math_optimizations)
14842 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14843 && <SWI248x:MODE>mode != HImode
14844 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14845 && !flag_trapping_math && !flag_rounding_math)"
14847 if (optimize_insn_for_size_p ())
14850 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14851 && <SWI248x:MODE>mode != HImode
14852 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14853 && !flag_trapping_math && !flag_rounding_math)
14854 ix86_expand_lround (operand0, operand1);
14856 ix86_emit_i387_round (operands[0], operands[1]);
14860 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14861 (define_insn_and_split "frndintxf2_floor"
14862 [(set (match_operand:XF 0 "register_operand" "")
14863 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14864 UNSPEC_FRNDINT_FLOOR))
14865 (clobber (reg:CC FLAGS_REG))]
14866 "TARGET_USE_FANCY_MATH_387
14867 && flag_unsafe_math_optimizations
14868 && can_create_pseudo_p ()"
14873 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14875 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14876 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14878 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14879 operands[2], operands[3]));
14882 [(set_attr "type" "frndint")
14883 (set_attr "i387_cw" "floor")
14884 (set_attr "mode" "XF")])
14886 (define_insn "frndintxf2_floor_i387"
14887 [(set (match_operand:XF 0 "register_operand" "=f")
14888 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14889 UNSPEC_FRNDINT_FLOOR))
14890 (use (match_operand:HI 2 "memory_operand" "m"))
14891 (use (match_operand:HI 3 "memory_operand" "m"))]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14894 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14895 [(set_attr "type" "frndint")
14896 (set_attr "i387_cw" "floor")
14897 (set_attr "mode" "XF")])
14899 (define_expand "floorxf2"
14900 [(use (match_operand:XF 0 "register_operand" ""))
14901 (use (match_operand:XF 1 "register_operand" ""))]
14902 "TARGET_USE_FANCY_MATH_387
14903 && flag_unsafe_math_optimizations"
14905 if (optimize_insn_for_size_p ())
14907 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14911 (define_expand "floor<mode>2"
14912 [(use (match_operand:MODEF 0 "register_operand" ""))
14913 (use (match_operand:MODEF 1 "register_operand" ""))]
14914 "(TARGET_USE_FANCY_MATH_387
14915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916 || TARGET_MIX_SSE_I387)
14917 && flag_unsafe_math_optimizations)
14918 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14919 && !flag_trapping_math)"
14921 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922 && !flag_trapping_math)
14925 emit_insn (gen_sse4_1_round<mode>2
14926 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14927 else if (optimize_insn_for_size_p ())
14929 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14930 ix86_expand_floorceil (operand0, operand1, true);
14932 ix86_expand_floorceildf_32 (operand0, operand1, true);
14938 if (optimize_insn_for_size_p ())
14941 op0 = gen_reg_rtx (XFmode);
14942 op1 = gen_reg_rtx (XFmode);
14943 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944 emit_insn (gen_frndintxf2_floor (op0, op1));
14946 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14951 (define_insn_and_split "*fist<mode>2_floor_1"
14952 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14953 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14954 UNSPEC_FIST_FLOOR))
14955 (clobber (reg:CC FLAGS_REG))]
14956 "TARGET_USE_FANCY_MATH_387
14957 && flag_unsafe_math_optimizations
14958 && can_create_pseudo_p ()"
14963 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14965 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14966 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14967 if (memory_operand (operands[0], VOIDmode))
14968 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14969 operands[2], operands[3]));
14972 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14973 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14974 operands[2], operands[3],
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "<MODE>")])
14983 (define_insn "fistdi2_floor"
14984 [(set (match_operand:DI 0 "memory_operand" "=m")
14985 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" "m"))
14988 (use (match_operand:HI 3 "memory_operand" "m"))
14989 (clobber (match_scratch:XF 4 "=&1f"))]
14990 "TARGET_USE_FANCY_MATH_387
14991 && flag_unsafe_math_optimizations"
14992 "* return output_fix_trunc (insn, operands, false);"
14993 [(set_attr "type" "fistp")
14994 (set_attr "i387_cw" "floor")
14995 (set_attr "mode" "DI")])
14997 (define_insn "fistdi2_floor_with_temp"
14998 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14999 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15000 UNSPEC_FIST_FLOOR))
15001 (use (match_operand:HI 2 "memory_operand" "m,m"))
15002 (use (match_operand:HI 3 "memory_operand" "m,m"))
15003 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15004 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15005 "TARGET_USE_FANCY_MATH_387
15006 && flag_unsafe_math_optimizations"
15008 [(set_attr "type" "fistp")
15009 (set_attr "i387_cw" "floor")
15010 (set_attr "mode" "DI")])
15013 [(set (match_operand:DI 0 "register_operand" "")
15014 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15015 UNSPEC_FIST_FLOOR))
15016 (use (match_operand:HI 2 "memory_operand" ""))
15017 (use (match_operand:HI 3 "memory_operand" ""))
15018 (clobber (match_operand:DI 4 "memory_operand" ""))
15019 (clobber (match_scratch 5 ""))]
15021 [(parallel [(set (match_dup 4)
15022 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15023 (use (match_dup 2))
15024 (use (match_dup 3))
15025 (clobber (match_dup 5))])
15026 (set (match_dup 0) (match_dup 4))])
15029 [(set (match_operand:DI 0 "memory_operand" "")
15030 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15031 UNSPEC_FIST_FLOOR))
15032 (use (match_operand:HI 2 "memory_operand" ""))
15033 (use (match_operand:HI 3 "memory_operand" ""))
15034 (clobber (match_operand:DI 4 "memory_operand" ""))
15035 (clobber (match_scratch 5 ""))]
15037 [(parallel [(set (match_dup 0)
15038 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15039 (use (match_dup 2))
15040 (use (match_dup 3))
15041 (clobber (match_dup 5))])])
15043 (define_insn "fist<mode>2_floor"
15044 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15045 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15046 UNSPEC_FIST_FLOOR))
15047 (use (match_operand:HI 2 "memory_operand" "m"))
15048 (use (match_operand:HI 3 "memory_operand" "m"))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && flag_unsafe_math_optimizations"
15051 "* return output_fix_trunc (insn, operands, false);"
15052 [(set_attr "type" "fistp")
15053 (set_attr "i387_cw" "floor")
15054 (set_attr "mode" "<MODE>")])
15056 (define_insn "fist<mode>2_floor_with_temp"
15057 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15058 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15059 UNSPEC_FIST_FLOOR))
15060 (use (match_operand:HI 2 "memory_operand" "m,m"))
15061 (use (match_operand:HI 3 "memory_operand" "m,m"))
15062 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15063 "TARGET_USE_FANCY_MATH_387
15064 && flag_unsafe_math_optimizations"
15066 [(set_attr "type" "fistp")
15067 (set_attr "i387_cw" "floor")
15068 (set_attr "mode" "<MODE>")])
15071 [(set (match_operand:SWI24 0 "register_operand" "")
15072 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15073 UNSPEC_FIST_FLOOR))
15074 (use (match_operand:HI 2 "memory_operand" ""))
15075 (use (match_operand:HI 3 "memory_operand" ""))
15076 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15078 [(parallel [(set (match_dup 4)
15079 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15080 (use (match_dup 2))
15081 (use (match_dup 3))])
15082 (set (match_dup 0) (match_dup 4))])
15085 [(set (match_operand:SWI24 0 "memory_operand" "")
15086 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15087 UNSPEC_FIST_FLOOR))
15088 (use (match_operand:HI 2 "memory_operand" ""))
15089 (use (match_operand:HI 3 "memory_operand" ""))
15090 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15092 [(parallel [(set (match_dup 0)
15093 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15094 (use (match_dup 2))
15095 (use (match_dup 3))])])
15097 (define_expand "lfloorxf<mode>2"
15098 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15099 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15100 UNSPEC_FIST_FLOOR))
15101 (clobber (reg:CC FLAGS_REG))])]
15102 "TARGET_USE_FANCY_MATH_387
15103 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15104 && flag_unsafe_math_optimizations")
15106 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15107 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15108 (match_operand:MODEF 1 "register_operand" "")]
15109 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15110 && !flag_trapping_math"
15112 if (TARGET_64BIT && optimize_insn_for_size_p ())
15114 ix86_expand_lfloorceil (operand0, operand1, true);
15118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15119 (define_insn_and_split "frndintxf2_ceil"
15120 [(set (match_operand:XF 0 "register_operand" "")
15121 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15122 UNSPEC_FRNDINT_CEIL))
15123 (clobber (reg:CC FLAGS_REG))]
15124 "TARGET_USE_FANCY_MATH_387
15125 && flag_unsafe_math_optimizations
15126 && can_create_pseudo_p ()"
15131 ix86_optimize_mode_switching[I387_CEIL] = 1;
15133 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15134 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15136 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15137 operands[2], operands[3]));
15140 [(set_attr "type" "frndint")
15141 (set_attr "i387_cw" "ceil")
15142 (set_attr "mode" "XF")])
15144 (define_insn "frndintxf2_ceil_i387"
15145 [(set (match_operand:XF 0 "register_operand" "=f")
15146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15147 UNSPEC_FRNDINT_CEIL))
15148 (use (match_operand:HI 2 "memory_operand" "m"))
15149 (use (match_operand:HI 3 "memory_operand" "m"))]
15150 "TARGET_USE_FANCY_MATH_387
15151 && flag_unsafe_math_optimizations"
15152 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15153 [(set_attr "type" "frndint")
15154 (set_attr "i387_cw" "ceil")
15155 (set_attr "mode" "XF")])
15157 (define_expand "ceilxf2"
15158 [(use (match_operand:XF 0 "register_operand" ""))
15159 (use (match_operand:XF 1 "register_operand" ""))]
15160 "TARGET_USE_FANCY_MATH_387
15161 && flag_unsafe_math_optimizations"
15163 if (optimize_insn_for_size_p ())
15165 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15169 (define_expand "ceil<mode>2"
15170 [(use (match_operand:MODEF 0 "register_operand" ""))
15171 (use (match_operand:MODEF 1 "register_operand" ""))]
15172 "(TARGET_USE_FANCY_MATH_387
15173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15174 || TARGET_MIX_SSE_I387)
15175 && flag_unsafe_math_optimizations)
15176 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15177 && !flag_trapping_math)"
15179 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15180 && !flag_trapping_math)
15183 emit_insn (gen_sse4_1_round<mode>2
15184 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15185 else if (optimize_insn_for_size_p ())
15187 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15188 ix86_expand_floorceil (operand0, operand1, false);
15190 ix86_expand_floorceildf_32 (operand0, operand1, false);
15196 if (optimize_insn_for_size_p ())
15199 op0 = gen_reg_rtx (XFmode);
15200 op1 = gen_reg_rtx (XFmode);
15201 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15202 emit_insn (gen_frndintxf2_ceil (op0, op1));
15204 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15209 (define_insn_and_split "*fist<mode>2_ceil_1"
15210 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15211 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15213 (clobber (reg:CC FLAGS_REG))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations
15216 && can_create_pseudo_p ()"
15221 ix86_optimize_mode_switching[I387_CEIL] = 1;
15223 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15224 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15225 if (memory_operand (operands[0], VOIDmode))
15226 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15227 operands[2], operands[3]));
15230 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15231 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15232 operands[2], operands[3],
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "<MODE>")])
15241 (define_insn "fistdi2_ceil"
15242 [(set (match_operand:DI 0 "memory_operand" "=m")
15243 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15245 (use (match_operand:HI 2 "memory_operand" "m"))
15246 (use (match_operand:HI 3 "memory_operand" "m"))
15247 (clobber (match_scratch:XF 4 "=&1f"))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_unsafe_math_optimizations"
15250 "* return output_fix_trunc (insn, operands, false);"
15251 [(set_attr "type" "fistp")
15252 (set_attr "i387_cw" "ceil")
15253 (set_attr "mode" "DI")])
15255 (define_insn "fistdi2_ceil_with_temp"
15256 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15257 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15259 (use (match_operand:HI 2 "memory_operand" "m,m"))
15260 (use (match_operand:HI 3 "memory_operand" "m,m"))
15261 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15262 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15266 [(set_attr "type" "fistp")
15267 (set_attr "i387_cw" "ceil")
15268 (set_attr "mode" "DI")])
15271 [(set (match_operand:DI 0 "register_operand" "")
15272 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15274 (use (match_operand:HI 2 "memory_operand" ""))
15275 (use (match_operand:HI 3 "memory_operand" ""))
15276 (clobber (match_operand:DI 4 "memory_operand" ""))
15277 (clobber (match_scratch 5 ""))]
15279 [(parallel [(set (match_dup 4)
15280 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15281 (use (match_dup 2))
15282 (use (match_dup 3))
15283 (clobber (match_dup 5))])
15284 (set (match_dup 0) (match_dup 4))])
15287 [(set (match_operand:DI 0 "memory_operand" "")
15288 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15290 (use (match_operand:HI 2 "memory_operand" ""))
15291 (use (match_operand:HI 3 "memory_operand" ""))
15292 (clobber (match_operand:DI 4 "memory_operand" ""))
15293 (clobber (match_scratch 5 ""))]
15295 [(parallel [(set (match_dup 0)
15296 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15297 (use (match_dup 2))
15298 (use (match_dup 3))
15299 (clobber (match_dup 5))])])
15301 (define_insn "fist<mode>2_ceil"
15302 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15303 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15305 (use (match_operand:HI 2 "memory_operand" "m"))
15306 (use (match_operand:HI 3 "memory_operand" "m"))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15309 "* return output_fix_trunc (insn, operands, false);"
15310 [(set_attr "type" "fistp")
15311 (set_attr "i387_cw" "ceil")
15312 (set_attr "mode" "<MODE>")])
15314 (define_insn "fist<mode>2_ceil_with_temp"
15315 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15316 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15318 (use (match_operand:HI 2 "memory_operand" "m,m"))
15319 (use (match_operand:HI 3 "memory_operand" "m,m"))
15320 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations"
15324 [(set_attr "type" "fistp")
15325 (set_attr "i387_cw" "ceil")
15326 (set_attr "mode" "<MODE>")])
15329 [(set (match_operand:SWI24 0 "register_operand" "")
15330 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15332 (use (match_operand:HI 2 "memory_operand" ""))
15333 (use (match_operand:HI 3 "memory_operand" ""))
15334 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15336 [(parallel [(set (match_dup 4)
15337 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15338 (use (match_dup 2))
15339 (use (match_dup 3))])
15340 (set (match_dup 0) (match_dup 4))])
15343 [(set (match_operand:SWI24 0 "memory_operand" "")
15344 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15346 (use (match_operand:HI 2 "memory_operand" ""))
15347 (use (match_operand:HI 3 "memory_operand" ""))
15348 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15350 [(parallel [(set (match_dup 0)
15351 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15352 (use (match_dup 2))
15353 (use (match_dup 3))])])
15355 (define_expand "lceilxf<mode>2"
15356 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15357 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15359 (clobber (reg:CC FLAGS_REG))])]
15360 "TARGET_USE_FANCY_MATH_387
15361 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations")
15364 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15365 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15366 (match_operand:MODEF 1 "register_operand" "")]
15367 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15368 && !flag_trapping_math"
15370 ix86_expand_lfloorceil (operand0, operand1, false);
15374 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15375 (define_insn_and_split "frndintxf2_trunc"
15376 [(set (match_operand:XF 0 "register_operand" "")
15377 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15378 UNSPEC_FRNDINT_TRUNC))
15379 (clobber (reg:CC FLAGS_REG))]
15380 "TARGET_USE_FANCY_MATH_387
15381 && flag_unsafe_math_optimizations
15382 && can_create_pseudo_p ()"
15387 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15389 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15390 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15392 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15393 operands[2], operands[3]));
15396 [(set_attr "type" "frndint")
15397 (set_attr "i387_cw" "trunc")
15398 (set_attr "mode" "XF")])
15400 (define_insn "frndintxf2_trunc_i387"
15401 [(set (match_operand:XF 0 "register_operand" "=f")
15402 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15403 UNSPEC_FRNDINT_TRUNC))
15404 (use (match_operand:HI 2 "memory_operand" "m"))
15405 (use (match_operand:HI 3 "memory_operand" "m"))]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations"
15408 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15409 [(set_attr "type" "frndint")
15410 (set_attr "i387_cw" "trunc")
15411 (set_attr "mode" "XF")])
15413 (define_expand "btruncxf2"
15414 [(use (match_operand:XF 0 "register_operand" ""))
15415 (use (match_operand:XF 1 "register_operand" ""))]
15416 "TARGET_USE_FANCY_MATH_387
15417 && flag_unsafe_math_optimizations"
15419 if (optimize_insn_for_size_p ())
15421 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15425 (define_expand "btrunc<mode>2"
15426 [(use (match_operand:MODEF 0 "register_operand" ""))
15427 (use (match_operand:MODEF 1 "register_operand" ""))]
15428 "(TARGET_USE_FANCY_MATH_387
15429 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15430 || TARGET_MIX_SSE_I387)
15431 && flag_unsafe_math_optimizations)
15432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15433 && !flag_trapping_math)"
15435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15436 && !flag_trapping_math)
15439 emit_insn (gen_sse4_1_round<mode>2
15440 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15441 else if (optimize_insn_for_size_p ())
15443 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15444 ix86_expand_trunc (operand0, operand1);
15446 ix86_expand_truncdf_32 (operand0, operand1);
15452 if (optimize_insn_for_size_p ())
15455 op0 = gen_reg_rtx (XFmode);
15456 op1 = gen_reg_rtx (XFmode);
15457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15458 emit_insn (gen_frndintxf2_trunc (op0, op1));
15460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15466 (define_insn_and_split "frndintxf2_mask_pm"
15467 [(set (match_operand:XF 0 "register_operand" "")
15468 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15469 UNSPEC_FRNDINT_MASK_PM))
15470 (clobber (reg:CC FLAGS_REG))]
15471 "TARGET_USE_FANCY_MATH_387
15472 && flag_unsafe_math_optimizations
15473 && can_create_pseudo_p ()"
15478 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15480 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15481 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15483 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15484 operands[2], operands[3]));
15487 [(set_attr "type" "frndint")
15488 (set_attr "i387_cw" "mask_pm")
15489 (set_attr "mode" "XF")])
15491 (define_insn "frndintxf2_mask_pm_i387"
15492 [(set (match_operand:XF 0 "register_operand" "=f")
15493 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15494 UNSPEC_FRNDINT_MASK_PM))
15495 (use (match_operand:HI 2 "memory_operand" "m"))
15496 (use (match_operand:HI 3 "memory_operand" "m"))]
15497 "TARGET_USE_FANCY_MATH_387
15498 && flag_unsafe_math_optimizations"
15499 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15500 [(set_attr "type" "frndint")
15501 (set_attr "i387_cw" "mask_pm")
15502 (set_attr "mode" "XF")])
15504 (define_expand "nearbyintxf2"
15505 [(use (match_operand:XF 0 "register_operand" ""))
15506 (use (match_operand:XF 1 "register_operand" ""))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && flag_unsafe_math_optimizations"
15510 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15514 (define_expand "nearbyint<mode>2"
15515 [(use (match_operand:MODEF 0 "register_operand" ""))
15516 (use (match_operand:MODEF 1 "register_operand" ""))]
15517 "TARGET_USE_FANCY_MATH_387
15518 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15519 || TARGET_MIX_SSE_I387)
15520 && flag_unsafe_math_optimizations"
15522 rtx op0 = gen_reg_rtx (XFmode);
15523 rtx op1 = gen_reg_rtx (XFmode);
15525 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15526 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15528 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15532 (define_insn "fxam<mode>2_i387"
15533 [(set (match_operand:HI 0 "register_operand" "=a")
15535 [(match_operand:X87MODEF 1 "register_operand" "f")]
15537 "TARGET_USE_FANCY_MATH_387"
15538 "fxam\n\tfnstsw\t%0"
15539 [(set_attr "type" "multi")
15540 (set_attr "length" "4")
15541 (set_attr "unit" "i387")
15542 (set_attr "mode" "<MODE>")])
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545 [(set (match_operand:HI 0 "register_operand" "")
15547 [(match_operand:MODEF 1 "memory_operand" "")]
15549 "TARGET_USE_FANCY_MATH_387
15550 && can_create_pseudo_p ()"
15553 [(set (match_dup 2)(match_dup 1))
15555 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15557 operands[2] = gen_reg_rtx (<MODE>mode);
15559 MEM_VOLATILE_P (operands[1]) = 1;
15561 [(set_attr "type" "multi")
15562 (set_attr "unit" "i387")
15563 (set_attr "mode" "<MODE>")])
15565 (define_expand "isinfxf2"
15566 [(use (match_operand:SI 0 "register_operand" ""))
15567 (use (match_operand:XF 1 "register_operand" ""))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && TARGET_C99_FUNCTIONS"
15571 rtx mask = GEN_INT (0x45);
15572 rtx val = GEN_INT (0x05);
15576 rtx scratch = gen_reg_rtx (HImode);
15577 rtx res = gen_reg_rtx (QImode);
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15581 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583 cond = gen_rtx_fmt_ee (EQ, QImode,
15584 gen_rtx_REG (CCmode, FLAGS_REG),
15586 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15591 (define_expand "isinf<mode>2"
15592 [(use (match_operand:SI 0 "register_operand" ""))
15593 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && TARGET_C99_FUNCTIONS
15596 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15598 rtx mask = GEN_INT (0x45);
15599 rtx val = GEN_INT (0x05);
15603 rtx scratch = gen_reg_rtx (HImode);
15604 rtx res = gen_reg_rtx (QImode);
15606 /* Remove excess precision by forcing value through memory. */
15607 if (memory_operand (operands[1], VOIDmode))
15608 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15611 enum ix86_stack_slot slot = (virtuals_instantiated
15614 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15616 emit_move_insn (temp, operands[1]);
15617 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15620 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15621 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15622 cond = gen_rtx_fmt_ee (EQ, QImode,
15623 gen_rtx_REG (CCmode, FLAGS_REG),
15625 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15626 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15630 (define_expand "signbitxf2"
15631 [(use (match_operand:SI 0 "register_operand" ""))
15632 (use (match_operand:XF 1 "register_operand" ""))]
15633 "TARGET_USE_FANCY_MATH_387"
15635 rtx scratch = gen_reg_rtx (HImode);
15637 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15638 emit_insn (gen_andsi3 (operands[0],
15639 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15643 (define_insn "movmsk_df"
15644 [(set (match_operand:SI 0 "register_operand" "=r")
15646 [(match_operand:DF 1 "register_operand" "x")]
15648 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15649 "%vmovmskpd\t{%1, %0|%0, %1}"
15650 [(set_attr "type" "ssemov")
15651 (set_attr "prefix" "maybe_vex")
15652 (set_attr "mode" "DF")])
15654 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15655 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15656 (define_expand "signbitdf2"
15657 [(use (match_operand:SI 0 "register_operand" ""))
15658 (use (match_operand:DF 1 "register_operand" ""))]
15659 "TARGET_USE_FANCY_MATH_387
15660 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15662 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15664 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15665 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15669 rtx scratch = gen_reg_rtx (HImode);
15671 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15672 emit_insn (gen_andsi3 (operands[0],
15673 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15678 (define_expand "signbitsf2"
15679 [(use (match_operand:SI 0 "register_operand" ""))
15680 (use (match_operand:SF 1 "register_operand" ""))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15684 rtx scratch = gen_reg_rtx (HImode);
15686 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15687 emit_insn (gen_andsi3 (operands[0],
15688 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15692 ;; Block operation instructions
15695 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15698 [(set_attr "length" "1")
15699 (set_attr "length_immediate" "0")
15700 (set_attr "modrm" "0")])
15702 (define_expand "movmem<mode>"
15703 [(use (match_operand:BLK 0 "memory_operand" ""))
15704 (use (match_operand:BLK 1 "memory_operand" ""))
15705 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15706 (use (match_operand:SWI48 3 "const_int_operand" ""))
15707 (use (match_operand:SI 4 "const_int_operand" ""))
15708 (use (match_operand:SI 5 "const_int_operand" ""))]
15711 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15712 operands[4], operands[5]))
15718 ;; Most CPUs don't like single string operations
15719 ;; Handle this case here to simplify previous expander.
15721 (define_expand "strmov"
15722 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15723 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15724 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15725 (clobber (reg:CC FLAGS_REG))])
15726 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15727 (clobber (reg:CC FLAGS_REG))])]
15730 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15732 /* If .md ever supports :P for Pmode, these can be directly
15733 in the pattern above. */
15734 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15735 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15737 /* Can't use this if the user has appropriated esi or edi. */
15738 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15739 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15741 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15742 operands[2], operands[3],
15743 operands[5], operands[6]));
15747 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15750 (define_expand "strmov_singleop"
15751 [(parallel [(set (match_operand 1 "memory_operand" "")
15752 (match_operand 3 "memory_operand" ""))
15753 (set (match_operand 0 "register_operand" "")
15754 (match_operand 4 "" ""))
15755 (set (match_operand 2 "register_operand" "")
15756 (match_operand 5 "" ""))])]
15758 "ix86_current_function_needs_cld = 1;")
15760 (define_insn "*strmovdi_rex_1"
15761 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15762 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15763 (set (match_operand:DI 0 "register_operand" "=D")
15764 (plus:DI (match_dup 2)
15766 (set (match_operand:DI 1 "register_operand" "=S")
15767 (plus:DI (match_dup 3)
15770 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "DI")])
15776 (define_insn "*strmovsi_1"
15777 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15778 (mem:SI (match_operand:P 3 "register_operand" "1")))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (match_dup 2)
15782 (set (match_operand:P 1 "register_operand" "=S")
15783 (plus:P (match_dup 3)
15785 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "SI")])
15791 (define_insn "*strmovhi_1"
15792 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15793 (mem:HI (match_operand:P 3 "register_operand" "1")))
15794 (set (match_operand:P 0 "register_operand" "=D")
15795 (plus:P (match_dup 2)
15797 (set (match_operand:P 1 "register_operand" "=S")
15798 (plus:P (match_dup 3)
15800 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set_attr "mode" "HI")])
15806 (define_insn "*strmovqi_1"
15807 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15808 (mem:QI (match_operand:P 3 "register_operand" "1")))
15809 (set (match_operand:P 0 "register_operand" "=D")
15810 (plus:P (match_dup 2)
15812 (set (match_operand:P 1 "register_operand" "=S")
15813 (plus:P (match_dup 3)
15815 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15817 [(set_attr "type" "str")
15818 (set_attr "memory" "both")
15819 (set (attr "prefix_rex")
15821 (match_test "<P:MODE>mode == DImode")
15823 (const_string "*")))
15824 (set_attr "mode" "QI")])
15826 (define_expand "rep_mov"
15827 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15828 (set (match_operand 0 "register_operand" "")
15829 (match_operand 5 "" ""))
15830 (set (match_operand 2 "register_operand" "")
15831 (match_operand 6 "" ""))
15832 (set (match_operand 1 "memory_operand" "")
15833 (match_operand 3 "memory_operand" ""))
15834 (use (match_dup 4))])]
15836 "ix86_current_function_needs_cld = 1;")
15838 (define_insn "*rep_movdi_rex64"
15839 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15840 (set (match_operand:DI 0 "register_operand" "=D")
15841 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15843 (match_operand:DI 3 "register_operand" "0")))
15844 (set (match_operand:DI 1 "register_operand" "=S")
15845 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15846 (match_operand:DI 4 "register_operand" "1")))
15847 (set (mem:BLK (match_dup 3))
15848 (mem:BLK (match_dup 4)))
15849 (use (match_dup 5))]
15851 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15853 [(set_attr "type" "str")
15854 (set_attr "prefix_rep" "1")
15855 (set_attr "memory" "both")
15856 (set_attr "mode" "DI")])
15858 (define_insn "*rep_movsi"
15859 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15863 (match_operand:P 3 "register_operand" "0")))
15864 (set (match_operand:P 1 "register_operand" "=S")
15865 (plus:P (ashift:P (match_dup 5) (const_int 2))
15866 (match_operand:P 4 "register_operand" "1")))
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])"
15871 "rep{%;} movs{l|d}"
15872 [(set_attr "type" "str")
15873 (set_attr "prefix_rep" "1")
15874 (set_attr "memory" "both")
15875 (set_attr "mode" "SI")])
15877 (define_insn "*rep_movqi"
15878 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15879 (set (match_operand:P 0 "register_operand" "=D")
15880 (plus:P (match_operand:P 3 "register_operand" "0")
15881 (match_operand:P 5 "register_operand" "2")))
15882 (set (match_operand:P 1 "register_operand" "=S")
15883 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15884 (set (mem:BLK (match_dup 3))
15885 (mem:BLK (match_dup 4)))
15886 (use (match_dup 5))]
15887 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15889 [(set_attr "type" "str")
15890 (set_attr "prefix_rep" "1")
15891 (set_attr "memory" "both")
15892 (set_attr "mode" "QI")])
15894 (define_expand "setmem<mode>"
15895 [(use (match_operand:BLK 0 "memory_operand" ""))
15896 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15897 (use (match_operand:QI 2 "nonmemory_operand" ""))
15898 (use (match_operand 3 "const_int_operand" ""))
15899 (use (match_operand:SI 4 "const_int_operand" ""))
15900 (use (match_operand:SI 5 "const_int_operand" ""))]
15903 if (ix86_expand_setmem (operands[0], operands[1],
15904 operands[2], operands[3],
15905 operands[4], operands[5]))
15911 ;; Most CPUs don't like single string operations
15912 ;; Handle this case here to simplify previous expander.
15914 (define_expand "strset"
15915 [(set (match_operand 1 "memory_operand" "")
15916 (match_operand 2 "register_operand" ""))
15917 (parallel [(set (match_operand 0 "register_operand" "")
15919 (clobber (reg:CC FLAGS_REG))])]
15922 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15923 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15925 /* If .md ever supports :P for Pmode, this can be directly
15926 in the pattern above. */
15927 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15928 GEN_INT (GET_MODE_SIZE (GET_MODE
15930 /* Can't use this if the user has appropriated eax or edi. */
15931 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15932 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15934 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15940 (define_expand "strset_singleop"
15941 [(parallel [(set (match_operand 1 "memory_operand" "")
15942 (match_operand 2 "register_operand" ""))
15943 (set (match_operand 0 "register_operand" "")
15944 (match_operand 3 "" ""))])]
15946 "ix86_current_function_needs_cld = 1;")
15948 (define_insn "*strsetdi_rex_1"
15949 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15950 (match_operand:DI 2 "register_operand" "a"))
15951 (set (match_operand:DI 0 "register_operand" "=D")
15952 (plus:DI (match_dup 1)
15955 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "DI")])
15961 (define_insn "*strsetsi_1"
15962 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:SI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "SI")])
15973 (define_insn "*strsethi_1"
15974 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:HI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "HI")])
15985 (define_insn "*strsetqi_1"
15986 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15987 (match_operand:QI 2 "register_operand" "a"))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_dup 1)
15991 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "store")
15995 (set (attr "prefix_rex")
15997 (match_test "<P:MODE>mode == DImode")
15999 (const_string "*")))
16000 (set_attr "mode" "QI")])
16002 (define_expand "rep_stos"
16003 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16004 (set (match_operand 0 "register_operand" "")
16005 (match_operand 4 "" ""))
16006 (set (match_operand 2 "memory_operand" "") (const_int 0))
16007 (use (match_operand 3 "register_operand" ""))
16008 (use (match_dup 1))])]
16010 "ix86_current_function_needs_cld = 1;")
16012 (define_insn "*rep_stosdi_rex64"
16013 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:DI 0 "register_operand" "=D")
16015 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16017 (match_operand:DI 3 "register_operand" "0")))
16018 (set (mem:BLK (match_dup 3))
16020 (use (match_operand:DI 2 "register_operand" "a"))
16021 (use (match_dup 4))]
16023 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "DI")])
16030 (define_insn "*rep_stossi"
16031 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032 (set (match_operand:P 0 "register_operand" "=D")
16033 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16035 (match_operand:P 3 "register_operand" "0")))
16036 (set (mem:BLK (match_dup 3))
16038 (use (match_operand:SI 2 "register_operand" "a"))
16039 (use (match_dup 4))]
16040 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041 "rep{%;} stos{l|d}"
16042 [(set_attr "type" "str")
16043 (set_attr "prefix_rep" "1")
16044 (set_attr "memory" "store")
16045 (set_attr "mode" "SI")])
16047 (define_insn "*rep_stosqi"
16048 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16049 (set (match_operand:P 0 "register_operand" "=D")
16050 (plus:P (match_operand:P 3 "register_operand" "0")
16051 (match_operand:P 4 "register_operand" "1")))
16052 (set (mem:BLK (match_dup 3))
16054 (use (match_operand:QI 2 "register_operand" "a"))
16055 (use (match_dup 4))]
16056 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16058 [(set_attr "type" "str")
16059 (set_attr "prefix_rep" "1")
16060 (set_attr "memory" "store")
16061 (set (attr "prefix_rex")
16063 (match_test "<P:MODE>mode == DImode")
16065 (const_string "*")))
16066 (set_attr "mode" "QI")])
16068 (define_expand "cmpstrnsi"
16069 [(set (match_operand:SI 0 "register_operand" "")
16070 (compare:SI (match_operand:BLK 1 "general_operand" "")
16071 (match_operand:BLK 2 "general_operand" "")))
16072 (use (match_operand 3 "general_operand" ""))
16073 (use (match_operand 4 "immediate_operand" ""))]
16076 rtx addr1, addr2, out, outlow, count, countreg, align;
16078 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16081 /* Can't use this if the user has appropriated ecx, esi or edi. */
16082 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16087 out = gen_reg_rtx (SImode);
16089 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16090 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16091 if (addr1 != XEXP (operands[1], 0))
16092 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16093 if (addr2 != XEXP (operands[2], 0))
16094 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16096 count = operands[3];
16097 countreg = ix86_zero_extend_to_Pmode (count);
16099 /* %%% Iff we are testing strict equality, we can use known alignment
16100 to good advantage. This may be possible with combine, particularly
16101 once cc0 is dead. */
16102 align = operands[4];
16104 if (CONST_INT_P (count))
16106 if (INTVAL (count) == 0)
16108 emit_move_insn (operands[0], const0_rtx);
16111 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16112 operands[1], operands[2]));
16116 rtx (*gen_cmp) (rtx, rtx);
16118 gen_cmp = (TARGET_64BIT
16119 ? gen_cmpdi_1 : gen_cmpsi_1);
16121 emit_insn (gen_cmp (countreg, countreg));
16122 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16123 operands[1], operands[2]));
16126 outlow = gen_lowpart (QImode, out);
16127 emit_insn (gen_cmpintqi (outlow));
16128 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16130 if (operands[0] != out)
16131 emit_move_insn (operands[0], out);
16136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16138 (define_expand "cmpintqi"
16139 [(set (match_dup 1)
16140 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16142 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16143 (parallel [(set (match_operand:QI 0 "register_operand" "")
16144 (minus:QI (match_dup 1)
16146 (clobber (reg:CC FLAGS_REG))])]
16149 operands[1] = gen_reg_rtx (QImode);
16150 operands[2] = gen_reg_rtx (QImode);
16153 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16154 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16156 (define_expand "cmpstrnqi_nz_1"
16157 [(parallel [(set (reg:CC FLAGS_REG)
16158 (compare:CC (match_operand 4 "memory_operand" "")
16159 (match_operand 5 "memory_operand" "")))
16160 (use (match_operand 2 "register_operand" ""))
16161 (use (match_operand:SI 3 "immediate_operand" ""))
16162 (clobber (match_operand 0 "register_operand" ""))
16163 (clobber (match_operand 1 "register_operand" ""))
16164 (clobber (match_dup 2))])]
16166 "ix86_current_function_needs_cld = 1;")
16168 (define_insn "*cmpstrnqi_nz_1"
16169 [(set (reg:CC FLAGS_REG)
16170 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16171 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16172 (use (match_operand:P 6 "register_operand" "2"))
16173 (use (match_operand:SI 3 "immediate_operand" "i"))
16174 (clobber (match_operand:P 0 "register_operand" "=S"))
16175 (clobber (match_operand:P 1 "register_operand" "=D"))
16176 (clobber (match_operand:P 2 "register_operand" "=c"))]
16177 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16179 [(set_attr "type" "str")
16180 (set_attr "mode" "QI")
16181 (set (attr "prefix_rex")
16183 (match_test "<P:MODE>mode == DImode")
16185 (const_string "*")))
16186 (set_attr "prefix_rep" "1")])
16188 ;; The same, but the count is not known to not be zero.
16190 (define_expand "cmpstrnqi_1"
16191 [(parallel [(set (reg:CC FLAGS_REG)
16192 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16194 (compare:CC (match_operand 4 "memory_operand" "")
16195 (match_operand 5 "memory_operand" ""))
16197 (use (match_operand:SI 3 "immediate_operand" ""))
16198 (use (reg:CC FLAGS_REG))
16199 (clobber (match_operand 0 "register_operand" ""))
16200 (clobber (match_operand 1 "register_operand" ""))
16201 (clobber (match_dup 2))])]
16203 "ix86_current_function_needs_cld = 1;")
16205 (define_insn "*cmpstrnqi_1"
16206 [(set (reg:CC FLAGS_REG)
16207 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16209 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16210 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16212 (use (match_operand:SI 3 "immediate_operand" "i"))
16213 (use (reg:CC FLAGS_REG))
16214 (clobber (match_operand:P 0 "register_operand" "=S"))
16215 (clobber (match_operand:P 1 "register_operand" "=D"))
16216 (clobber (match_operand:P 2 "register_operand" "=c"))]
16217 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16219 [(set_attr "type" "str")
16220 (set_attr "mode" "QI")
16221 (set (attr "prefix_rex")
16223 (match_test "<P:MODE>mode == DImode")
16225 (const_string "*")))
16226 (set_attr "prefix_rep" "1")])
16228 (define_expand "strlen<mode>"
16229 [(set (match_operand:P 0 "register_operand" "")
16230 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16231 (match_operand:QI 2 "immediate_operand" "")
16232 (match_operand 3 "immediate_operand" "")]
16236 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16242 (define_expand "strlenqi_1"
16243 [(parallel [(set (match_operand 0 "register_operand" "")
16244 (match_operand 2 "" ""))
16245 (clobber (match_operand 1 "register_operand" ""))
16246 (clobber (reg:CC FLAGS_REG))])]
16248 "ix86_current_function_needs_cld = 1;")
16250 (define_insn "*strlenqi_1"
16251 [(set (match_operand:P 0 "register_operand" "=&c")
16252 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16253 (match_operand:QI 2 "register_operand" "a")
16254 (match_operand:P 3 "immediate_operand" "i")
16255 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16256 (clobber (match_operand:P 1 "register_operand" "=D"))
16257 (clobber (reg:CC FLAGS_REG))]
16258 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16260 [(set_attr "type" "str")
16261 (set_attr "mode" "QI")
16262 (set (attr "prefix_rex")
16264 (match_test "<P:MODE>mode == DImode")
16266 (const_string "*")))
16267 (set_attr "prefix_rep" "1")])
16269 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16270 ;; handled in combine, but it is not currently up to the task.
16271 ;; When used for their truth value, the cmpstrn* expanders generate
16280 ;; The intermediate three instructions are unnecessary.
16282 ;; This one handles cmpstrn*_nz_1...
16285 (set (reg:CC FLAGS_REG)
16286 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16287 (mem:BLK (match_operand 5 "register_operand" ""))))
16288 (use (match_operand 6 "register_operand" ""))
16289 (use (match_operand:SI 3 "immediate_operand" ""))
16290 (clobber (match_operand 0 "register_operand" ""))
16291 (clobber (match_operand 1 "register_operand" ""))
16292 (clobber (match_operand 2 "register_operand" ""))])
16293 (set (match_operand:QI 7 "register_operand" "")
16294 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16295 (set (match_operand:QI 8 "register_operand" "")
16296 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16297 (set (reg FLAGS_REG)
16298 (compare (match_dup 7) (match_dup 8)))
16300 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16302 (set (reg:CC FLAGS_REG)
16303 (compare:CC (mem:BLK (match_dup 4))
16304 (mem:BLK (match_dup 5))))
16305 (use (match_dup 6))
16306 (use (match_dup 3))
16307 (clobber (match_dup 0))
16308 (clobber (match_dup 1))
16309 (clobber (match_dup 2))])])
16311 ;; ...and this one handles cmpstrn*_1.
16314 (set (reg:CC FLAGS_REG)
16315 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16317 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16318 (mem:BLK (match_operand 5 "register_operand" "")))
16320 (use (match_operand:SI 3 "immediate_operand" ""))
16321 (use (reg:CC FLAGS_REG))
16322 (clobber (match_operand 0 "register_operand" ""))
16323 (clobber (match_operand 1 "register_operand" ""))
16324 (clobber (match_operand 2 "register_operand" ""))])
16325 (set (match_operand:QI 7 "register_operand" "")
16326 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16327 (set (match_operand:QI 8 "register_operand" "")
16328 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16329 (set (reg FLAGS_REG)
16330 (compare (match_dup 7) (match_dup 8)))
16332 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16334 (set (reg:CC FLAGS_REG)
16335 (if_then_else:CC (ne (match_dup 6)
16337 (compare:CC (mem:BLK (match_dup 4))
16338 (mem:BLK (match_dup 5)))
16340 (use (match_dup 3))
16341 (use (reg:CC FLAGS_REG))
16342 (clobber (match_dup 0))
16343 (clobber (match_dup 1))
16344 (clobber (match_dup 2))])])
16346 ;; Conditional move instructions.
16348 (define_expand "mov<mode>cc"
16349 [(set (match_operand:SWIM 0 "register_operand" "")
16350 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16351 (match_operand:SWIM 2 "<general_operand>" "")
16352 (match_operand:SWIM 3 "<general_operand>" "")))]
16354 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16356 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16357 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16358 ;; So just document what we're doing explicitly.
16360 (define_expand "x86_mov<mode>cc_0_m1"
16362 [(set (match_operand:SWI48 0 "register_operand" "")
16363 (if_then_else:SWI48
16364 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16365 [(match_operand 1 "flags_reg_operand" "")
16369 (clobber (reg:CC FLAGS_REG))])])
16371 (define_insn "*x86_mov<mode>cc_0_m1"
16372 [(set (match_operand:SWI48 0 "register_operand" "=r")
16373 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16374 [(reg FLAGS_REG) (const_int 0)])
16377 (clobber (reg:CC FLAGS_REG))]
16379 "sbb{<imodesuffix>}\t%0, %0"
16380 ; Since we don't have the proper number of operands for an alu insn,
16381 ; fill in all the blanks.
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_se"
16391 [(set (match_operand:SWI48 0 "register_operand" "=r")
16392 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16396 (clobber (reg:CC FLAGS_REG))]
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16407 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16408 [(set (match_operand:SWI48 0 "register_operand" "=r")
16409 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16410 [(reg FLAGS_REG) (const_int 0)])))]
16412 "sbb{<imodesuffix>}\t%0, %0"
16413 [(set_attr "type" "alu")
16414 (set_attr "use_carry" "1")
16415 (set_attr "pent_pair" "pu")
16416 (set_attr "memory" "none")
16417 (set_attr "imm_disp" "false")
16418 (set_attr "mode" "<MODE>")
16419 (set_attr "length_immediate" "0")])
16421 (define_insn "*mov<mode>cc_noc"
16422 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16423 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16424 [(reg FLAGS_REG) (const_int 0)])
16425 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16426 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16427 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16429 cmov%O2%C1\t{%2, %0|%0, %2}
16430 cmov%O2%c1\t{%3, %0|%0, %3}"
16431 [(set_attr "type" "icmov")
16432 (set_attr "mode" "<MODE>")])
16434 (define_insn_and_split "*movqicc_noc"
16435 [(set (match_operand:QI 0 "register_operand" "=r,r")
16436 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16437 [(match_operand 4 "flags_reg_operand" "")
16439 (match_operand:QI 2 "register_operand" "r,0")
16440 (match_operand:QI 3 "register_operand" "0,r")))]
16441 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16443 "&& reload_completed"
16444 [(set (match_dup 0)
16445 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16448 "operands[0] = gen_lowpart (SImode, operands[0]);
16449 operands[2] = gen_lowpart (SImode, operands[2]);
16450 operands[3] = gen_lowpart (SImode, operands[3]);"
16451 [(set_attr "type" "icmov")
16452 (set_attr "mode" "SI")])
16454 (define_expand "mov<mode>cc"
16455 [(set (match_operand:X87MODEF 0 "register_operand" "")
16456 (if_then_else:X87MODEF
16457 (match_operand 1 "ix86_fp_comparison_operator" "")
16458 (match_operand:X87MODEF 2 "register_operand" "")
16459 (match_operand:X87MODEF 3 "register_operand" "")))]
16460 "(TARGET_80387 && TARGET_CMOVE)
16461 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16462 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16464 (define_insn "*movxfcc_1"
16465 [(set (match_operand:XF 0 "register_operand" "=f,f")
16466 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)])
16468 (match_operand:XF 2 "register_operand" "f,0")
16469 (match_operand:XF 3 "register_operand" "0,f")))]
16470 "TARGET_80387 && TARGET_CMOVE"
16472 fcmov%F1\t{%2, %0|%0, %2}
16473 fcmov%f1\t{%3, %0|%0, %3}"
16474 [(set_attr "type" "fcmov")
16475 (set_attr "mode" "XF")])
16477 (define_insn "*movdfcc_1_rex64"
16478 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16479 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16480 [(reg FLAGS_REG) (const_int 0)])
16481 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16482 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16483 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16484 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16486 fcmov%F1\t{%2, %0|%0, %2}
16487 fcmov%f1\t{%3, %0|%0, %3}
16488 cmov%O2%C1\t{%2, %0|%0, %2}
16489 cmov%O2%c1\t{%3, %0|%0, %3}"
16490 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16491 (set_attr "mode" "DF,DF,DI,DI")])
16493 (define_insn "*movdfcc_1"
16494 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16495 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16496 [(reg FLAGS_REG) (const_int 0)])
16497 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16498 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16499 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16500 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16502 fcmov%F1\t{%2, %0|%0, %2}
16503 fcmov%f1\t{%3, %0|%0, %3}
16506 [(set_attr "type" "fcmov,fcmov,multi,multi")
16507 (set_attr "mode" "DF,DF,DI,DI")])
16510 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16511 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16512 [(match_operand 4 "flags_reg_operand" "")
16514 (match_operand:DF 2 "nonimmediate_operand" "")
16515 (match_operand:DF 3 "nonimmediate_operand" "")))]
16516 "!TARGET_64BIT && reload_completed"
16517 [(set (match_dup 2)
16518 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16522 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16526 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16527 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16530 (define_insn "*movsfcc_1_387"
16531 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16532 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16533 [(reg FLAGS_REG) (const_int 0)])
16534 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16535 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16536 "TARGET_80387 && TARGET_CMOVE
16537 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16539 fcmov%F1\t{%2, %0|%0, %2}
16540 fcmov%f1\t{%3, %0|%0, %3}
16541 cmov%O2%C1\t{%2, %0|%0, %2}
16542 cmov%O2%c1\t{%3, %0|%0, %3}"
16543 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16544 (set_attr "mode" "SF,SF,SI,SI")])
16546 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16547 ;; the scalar versions to have only XMM registers as operands.
16549 ;; XOP conditional move
16550 (define_insn "*xop_pcmov_<mode>"
16551 [(set (match_operand:MODEF 0 "register_operand" "=x")
16552 (if_then_else:MODEF
16553 (match_operand:MODEF 1 "register_operand" "x")
16554 (match_operand:MODEF 2 "register_operand" "x")
16555 (match_operand:MODEF 3 "register_operand" "x")))]
16557 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16558 [(set_attr "type" "sse4arg")])
16560 ;; These versions of the min/max patterns are intentionally ignorant of
16561 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16562 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16563 ;; are undefined in this condition, we're certain this is correct.
16565 (define_insn "<code><mode>3"
16566 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16568 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16569 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16570 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16572 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16573 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16574 [(set_attr "isa" "noavx,avx")
16575 (set_attr "prefix" "orig,vex")
16576 (set_attr "type" "sseadd")
16577 (set_attr "mode" "<MODE>")])
16579 ;; These versions of the min/max patterns implement exactly the operations
16580 ;; min = (op1 < op2 ? op1 : op2)
16581 ;; max = (!(op1 < op2) ? op1 : op2)
16582 ;; Their operands are not commutative, and thus they may be used in the
16583 ;; presence of -0.0 and NaN.
16585 (define_insn "*ieee_smin<mode>3"
16586 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16588 [(match_operand:MODEF 1 "register_operand" "0,x")
16589 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16591 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16593 min<ssemodesuffix>\t{%2, %0|%0, %2}
16594 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16595 [(set_attr "isa" "noavx,avx")
16596 (set_attr "prefix" "orig,vex")
16597 (set_attr "type" "sseadd")
16598 (set_attr "mode" "<MODE>")])
16600 (define_insn "*ieee_smax<mode>3"
16601 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16603 [(match_operand:MODEF 1 "register_operand" "0,x")
16604 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16606 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16608 max<ssemodesuffix>\t{%2, %0|%0, %2}
16609 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16610 [(set_attr "isa" "noavx,avx")
16611 (set_attr "prefix" "orig,vex")
16612 (set_attr "type" "sseadd")
16613 (set_attr "mode" "<MODE>")])
16615 ;; Make two stack loads independent:
16617 ;; fld %st(0) -> fld bb
16618 ;; fmul bb fmul %st(1), %st
16620 ;; Actually we only match the last two instructions for simplicity.
16622 [(set (match_operand 0 "fp_register_operand" "")
16623 (match_operand 1 "fp_register_operand" ""))
16625 (match_operator 2 "binary_fp_operator"
16627 (match_operand 3 "memory_operand" "")]))]
16628 "REGNO (operands[0]) != REGNO (operands[1])"
16629 [(set (match_dup 0) (match_dup 3))
16630 (set (match_dup 0) (match_dup 4))]
16632 ;; The % modifier is not operational anymore in peephole2's, so we have to
16633 ;; swap the operands manually in the case of addition and multiplication.
16634 "if (COMMUTATIVE_ARITH_P (operands[2]))
16635 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16636 GET_MODE (operands[2]),
16637 operands[0], operands[1]);
16639 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16640 GET_MODE (operands[2]),
16641 operands[1], operands[0]);")
16643 ;; Conditional addition patterns
16644 (define_expand "add<mode>cc"
16645 [(match_operand:SWI 0 "register_operand" "")
16646 (match_operand 1 "ordered_comparison_operator" "")
16647 (match_operand:SWI 2 "register_operand" "")
16648 (match_operand:SWI 3 "const_int_operand" "")]
16650 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16652 ;; Misc patterns (?)
16654 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16655 ;; Otherwise there will be nothing to keep
16657 ;; [(set (reg ebp) (reg esp))]
16658 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16659 ;; (clobber (eflags)]
16660 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16662 ;; in proper program order.
16664 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16665 [(set (match_operand:P 0 "register_operand" "=r,r")
16666 (plus:P (match_operand:P 1 "register_operand" "0,r")
16667 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16668 (clobber (reg:CC FLAGS_REG))
16669 (clobber (mem:BLK (scratch)))]
16672 switch (get_attr_type (insn))
16675 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16679 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16680 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16682 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16685 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16686 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16689 [(set (attr "type")
16690 (cond [(and (eq_attr "alternative" "0")
16691 (not (match_test "TARGET_OPT_AGU")))
16692 (const_string "alu")
16693 (match_operand:<MODE> 2 "const0_operand" "")
16694 (const_string "imov")
16696 (const_string "lea")))
16697 (set (attr "length_immediate")
16698 (cond [(eq_attr "type" "imov")
16700 (and (eq_attr "type" "alu")
16701 (match_operand 2 "const128_operand" ""))
16704 (const_string "*")))
16705 (set_attr "mode" "<MODE>")])
16707 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16708 [(set (match_operand:P 0 "register_operand" "=r")
16709 (minus:P (match_operand:P 1 "register_operand" "0")
16710 (match_operand:P 2 "register_operand" "r")))
16711 (clobber (reg:CC FLAGS_REG))
16712 (clobber (mem:BLK (scratch)))]
16714 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16715 [(set_attr "type" "alu")
16716 (set_attr "mode" "<MODE>")])
16718 (define_insn "allocate_stack_worker_probe_<mode>"
16719 [(set (match_operand:P 0 "register_operand" "=a")
16720 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16721 UNSPECV_STACK_PROBE))
16722 (clobber (reg:CC FLAGS_REG))]
16723 "ix86_target_stack_probe ()"
16724 "call\t___chkstk_ms"
16725 [(set_attr "type" "multi")
16726 (set_attr "length" "5")])
16728 (define_expand "allocate_stack"
16729 [(match_operand 0 "register_operand" "")
16730 (match_operand 1 "general_operand" "")]
16731 "ix86_target_stack_probe ()"
16735 #ifndef CHECK_STACK_LIMIT
16736 #define CHECK_STACK_LIMIT 0
16739 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16740 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16742 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16743 stack_pointer_rtx, 0, OPTAB_DIRECT);
16744 if (x != stack_pointer_rtx)
16745 emit_move_insn (stack_pointer_rtx, x);
16749 x = copy_to_mode_reg (Pmode, operands[1]);
16751 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16753 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16754 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16755 stack_pointer_rtx, 0, OPTAB_DIRECT);
16756 if (x != stack_pointer_rtx)
16757 emit_move_insn (stack_pointer_rtx, x);
16760 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16764 ;; Use IOR for stack probes, this is shorter.
16765 (define_expand "probe_stack"
16766 [(match_operand 0 "memory_operand" "")]
16769 rtx (*gen_ior3) (rtx, rtx, rtx);
16771 gen_ior3 = (GET_MODE (operands[0]) == DImode
16772 ? gen_iordi3 : gen_iorsi3);
16774 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16778 (define_insn "adjust_stack_and_probe<mode>"
16779 [(set (match_operand:P 0 "register_operand" "=r")
16780 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16781 UNSPECV_PROBE_STACK_RANGE))
16782 (set (reg:P SP_REG)
16783 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16784 (clobber (reg:CC FLAGS_REG))
16785 (clobber (mem:BLK (scratch)))]
16787 "* return output_adjust_stack_and_probe (operands[0]);"
16788 [(set_attr "type" "multi")])
16790 (define_insn "probe_stack_range<mode>"
16791 [(set (match_operand:P 0 "register_operand" "=r")
16792 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16793 (match_operand:P 2 "const_int_operand" "n")]
16794 UNSPECV_PROBE_STACK_RANGE))
16795 (clobber (reg:CC FLAGS_REG))]
16797 "* return output_probe_stack_range (operands[0], operands[2]);"
16798 [(set_attr "type" "multi")])
16800 (define_expand "builtin_setjmp_receiver"
16801 [(label_ref (match_operand 0 "" ""))]
16802 "!TARGET_64BIT && flag_pic"
16808 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16809 rtx label_rtx = gen_label_rtx ();
16810 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16811 xops[0] = xops[1] = picreg;
16812 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16813 ix86_expand_binary_operator (MINUS, SImode, xops);
16817 emit_insn (gen_set_got (pic_offset_table_rtx));
16821 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16824 [(set (match_operand 0 "register_operand" "")
16825 (match_operator 3 "promotable_binary_operator"
16826 [(match_operand 1 "register_operand" "")
16827 (match_operand 2 "aligned_operand" "")]))
16828 (clobber (reg:CC FLAGS_REG))]
16829 "! TARGET_PARTIAL_REG_STALL && reload_completed
16830 && ((GET_MODE (operands[0]) == HImode
16831 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16832 /* ??? next two lines just !satisfies_constraint_K (...) */
16833 || !CONST_INT_P (operands[2])
16834 || satisfies_constraint_K (operands[2])))
16835 || (GET_MODE (operands[0]) == QImode
16836 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16837 [(parallel [(set (match_dup 0)
16838 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16839 (clobber (reg:CC FLAGS_REG))])]
16840 "operands[0] = gen_lowpart (SImode, operands[0]);
16841 operands[1] = gen_lowpart (SImode, operands[1]);
16842 if (GET_CODE (operands[3]) != ASHIFT)
16843 operands[2] = gen_lowpart (SImode, operands[2]);
16844 PUT_MODE (operands[3], SImode);")
16846 ; Promote the QImode tests, as i386 has encoding of the AND
16847 ; instruction with 32-bit sign-extended immediate and thus the
16848 ; instruction size is unchanged, except in the %eax case for
16849 ; which it is increased by one byte, hence the ! optimize_size.
16851 [(set (match_operand 0 "flags_reg_operand" "")
16852 (match_operator 2 "compare_operator"
16853 [(and (match_operand 3 "aligned_operand" "")
16854 (match_operand 4 "const_int_operand" ""))
16856 (set (match_operand 1 "register_operand" "")
16857 (and (match_dup 3) (match_dup 4)))]
16858 "! TARGET_PARTIAL_REG_STALL && reload_completed
16859 && optimize_insn_for_speed_p ()
16860 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16861 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16862 /* Ensure that the operand will remain sign-extended immediate. */
16863 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16864 [(parallel [(set (match_dup 0)
16865 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16868 (and:SI (match_dup 3) (match_dup 4)))])]
16871 = gen_int_mode (INTVAL (operands[4])
16872 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16873 operands[1] = gen_lowpart (SImode, operands[1]);
16874 operands[3] = gen_lowpart (SImode, operands[3]);
16877 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16878 ; the TEST instruction with 32-bit sign-extended immediate and thus
16879 ; the instruction size would at least double, which is not what we
16880 ; want even with ! optimize_size.
16882 [(set (match_operand 0 "flags_reg_operand" "")
16883 (match_operator 1 "compare_operator"
16884 [(and (match_operand:HI 2 "aligned_operand" "")
16885 (match_operand:HI 3 "const_int_operand" ""))
16887 "! TARGET_PARTIAL_REG_STALL && reload_completed
16888 && ! TARGET_FAST_PREFIX
16889 && optimize_insn_for_speed_p ()
16890 /* Ensure that the operand will remain sign-extended immediate. */
16891 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16892 [(set (match_dup 0)
16893 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16897 = gen_int_mode (INTVAL (operands[3])
16898 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16899 operands[2] = gen_lowpart (SImode, operands[2]);
16903 [(set (match_operand 0 "register_operand" "")
16904 (neg (match_operand 1 "register_operand" "")))
16905 (clobber (reg:CC FLAGS_REG))]
16906 "! TARGET_PARTIAL_REG_STALL && reload_completed
16907 && (GET_MODE (operands[0]) == HImode
16908 || (GET_MODE (operands[0]) == QImode
16909 && (TARGET_PROMOTE_QImode
16910 || optimize_insn_for_size_p ())))"
16911 [(parallel [(set (match_dup 0)
16912 (neg:SI (match_dup 1)))
16913 (clobber (reg:CC FLAGS_REG))])]
16914 "operands[0] = gen_lowpart (SImode, operands[0]);
16915 operands[1] = gen_lowpart (SImode, operands[1]);")
16918 [(set (match_operand 0 "register_operand" "")
16919 (not (match_operand 1 "register_operand" "")))]
16920 "! TARGET_PARTIAL_REG_STALL && reload_completed
16921 && (GET_MODE (operands[0]) == HImode
16922 || (GET_MODE (operands[0]) == QImode
16923 && (TARGET_PROMOTE_QImode
16924 || optimize_insn_for_size_p ())))"
16925 [(set (match_dup 0)
16926 (not:SI (match_dup 1)))]
16927 "operands[0] = gen_lowpart (SImode, operands[0]);
16928 operands[1] = gen_lowpart (SImode, operands[1]);")
16931 [(set (match_operand 0 "register_operand" "")
16932 (if_then_else (match_operator 1 "ordered_comparison_operator"
16933 [(reg FLAGS_REG) (const_int 0)])
16934 (match_operand 2 "register_operand" "")
16935 (match_operand 3 "register_operand" "")))]
16936 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16937 && (GET_MODE (operands[0]) == HImode
16938 || (GET_MODE (operands[0]) == QImode
16939 && (TARGET_PROMOTE_QImode
16940 || optimize_insn_for_size_p ())))"
16941 [(set (match_dup 0)
16942 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16943 "operands[0] = gen_lowpart (SImode, operands[0]);
16944 operands[2] = gen_lowpart (SImode, operands[2]);
16945 operands[3] = gen_lowpart (SImode, operands[3]);")
16947 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16948 ;; transform a complex memory operation into two memory to register operations.
16950 ;; Don't push memory operands
16952 [(set (match_operand:SWI 0 "push_operand" "")
16953 (match_operand:SWI 1 "memory_operand" ""))
16954 (match_scratch:SWI 2 "<r>")]
16955 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16956 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16957 [(set (match_dup 2) (match_dup 1))
16958 (set (match_dup 0) (match_dup 2))])
16960 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16963 [(set (match_operand:SF 0 "push_operand" "")
16964 (match_operand:SF 1 "memory_operand" ""))
16965 (match_scratch:SF 2 "r")]
16966 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16967 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16968 [(set (match_dup 2) (match_dup 1))
16969 (set (match_dup 0) (match_dup 2))])
16971 ;; Don't move an immediate directly to memory when the instruction
16974 [(match_scratch:SWI124 1 "<r>")
16975 (set (match_operand:SWI124 0 "memory_operand" "")
16977 "optimize_insn_for_speed_p ()
16978 && !TARGET_USE_MOV0
16979 && TARGET_SPLIT_LONG_MOVES
16980 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16981 && peep2_regno_dead_p (0, FLAGS_REG)"
16982 [(parallel [(set (match_dup 2) (const_int 0))
16983 (clobber (reg:CC FLAGS_REG))])
16984 (set (match_dup 0) (match_dup 1))]
16985 "operands[2] = gen_lowpart (SImode, operands[1]);")
16988 [(match_scratch:SWI124 2 "<r>")
16989 (set (match_operand:SWI124 0 "memory_operand" "")
16990 (match_operand:SWI124 1 "immediate_operand" ""))]
16991 "optimize_insn_for_speed_p ()
16992 && TARGET_SPLIT_LONG_MOVES
16993 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16994 [(set (match_dup 2) (match_dup 1))
16995 (set (match_dup 0) (match_dup 2))])
16997 ;; Don't compare memory with zero, load and use a test instead.
16999 [(set (match_operand 0 "flags_reg_operand" "")
17000 (match_operator 1 "compare_operator"
17001 [(match_operand:SI 2 "memory_operand" "")
17003 (match_scratch:SI 3 "r")]
17004 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17005 [(set (match_dup 3) (match_dup 2))
17006 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17008 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17009 ;; Don't split NOTs with a displacement operand, because resulting XOR
17010 ;; will not be pairable anyway.
17012 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17013 ;; represented using a modRM byte. The XOR replacement is long decoded,
17014 ;; so this split helps here as well.
17016 ;; Note: Can't do this as a regular split because we can't get proper
17017 ;; lifetime information then.
17020 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17021 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17022 "optimize_insn_for_speed_p ()
17023 && ((TARGET_NOT_UNPAIRABLE
17024 && (!MEM_P (operands[0])
17025 || !memory_displacement_operand (operands[0], <MODE>mode)))
17026 || (TARGET_NOT_VECTORMODE
17027 && long_memory_operand (operands[0], <MODE>mode)))
17028 && peep2_regno_dead_p (0, FLAGS_REG)"
17029 [(parallel [(set (match_dup 0)
17030 (xor:SWI124 (match_dup 1) (const_int -1)))
17031 (clobber (reg:CC FLAGS_REG))])])
17033 ;; Non pairable "test imm, reg" instructions can be translated to
17034 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17035 ;; byte opcode instead of two, have a short form for byte operands),
17036 ;; so do it for other CPUs as well. Given that the value was dead,
17037 ;; this should not create any new dependencies. Pass on the sub-word
17038 ;; versions if we're concerned about partial register stalls.
17041 [(set (match_operand 0 "flags_reg_operand" "")
17042 (match_operator 1 "compare_operator"
17043 [(and:SI (match_operand:SI 2 "register_operand" "")
17044 (match_operand:SI 3 "immediate_operand" ""))
17046 "ix86_match_ccmode (insn, CCNOmode)
17047 && (true_regnum (operands[2]) != AX_REG
17048 || satisfies_constraint_K (operands[3]))
17049 && peep2_reg_dead_p (1, operands[2])"
17051 [(set (match_dup 0)
17052 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17055 (and:SI (match_dup 2) (match_dup 3)))])])
17057 ;; We don't need to handle HImode case, because it will be promoted to SImode
17058 ;; on ! TARGET_PARTIAL_REG_STALL
17061 [(set (match_operand 0 "flags_reg_operand" "")
17062 (match_operator 1 "compare_operator"
17063 [(and:QI (match_operand:QI 2 "register_operand" "")
17064 (match_operand:QI 3 "immediate_operand" ""))
17066 "! TARGET_PARTIAL_REG_STALL
17067 && ix86_match_ccmode (insn, CCNOmode)
17068 && true_regnum (operands[2]) != AX_REG
17069 && peep2_reg_dead_p (1, operands[2])"
17071 [(set (match_dup 0)
17072 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17075 (and:QI (match_dup 2) (match_dup 3)))])])
17078 [(set (match_operand 0 "flags_reg_operand" "")
17079 (match_operator 1 "compare_operator"
17082 (match_operand 2 "ext_register_operand" "")
17085 (match_operand 3 "const_int_operand" ""))
17087 "! TARGET_PARTIAL_REG_STALL
17088 && ix86_match_ccmode (insn, CCNOmode)
17089 && true_regnum (operands[2]) != AX_REG
17090 && peep2_reg_dead_p (1, operands[2])"
17091 [(parallel [(set (match_dup 0)
17100 (set (zero_extract:SI (match_dup 2)
17108 (match_dup 3)))])])
17110 ;; Don't do logical operations with memory inputs.
17112 [(match_scratch:SI 2 "r")
17113 (parallel [(set (match_operand:SI 0 "register_operand" "")
17114 (match_operator:SI 3 "arith_or_logical_operator"
17116 (match_operand:SI 1 "memory_operand" "")]))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17119 [(set (match_dup 2) (match_dup 1))
17120 (parallel [(set (match_dup 0)
17121 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17122 (clobber (reg:CC FLAGS_REG))])])
17125 [(match_scratch:SI 2 "r")
17126 (parallel [(set (match_operand:SI 0 "register_operand" "")
17127 (match_operator:SI 3 "arith_or_logical_operator"
17128 [(match_operand:SI 1 "memory_operand" "")
17130 (clobber (reg:CC FLAGS_REG))])]
17131 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17132 [(set (match_dup 2) (match_dup 1))
17133 (parallel [(set (match_dup 0)
17134 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17135 (clobber (reg:CC FLAGS_REG))])])
17137 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17138 ;; refers to the destination of the load!
17141 [(set (match_operand:SI 0 "register_operand" "")
17142 (match_operand:SI 1 "register_operand" ""))
17143 (parallel [(set (match_dup 0)
17144 (match_operator:SI 3 "commutative_operator"
17146 (match_operand:SI 2 "memory_operand" "")]))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "REGNO (operands[0]) != REGNO (operands[1])
17149 && GENERAL_REGNO_P (REGNO (operands[0]))
17150 && GENERAL_REGNO_P (REGNO (operands[1]))"
17151 [(set (match_dup 0) (match_dup 4))
17152 (parallel [(set (match_dup 0)
17153 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17154 (clobber (reg:CC FLAGS_REG))])]
17155 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17158 [(set (match_operand 0 "register_operand" "")
17159 (match_operand 1 "register_operand" ""))
17161 (match_operator 3 "commutative_operator"
17163 (match_operand 2 "memory_operand" "")]))]
17164 "REGNO (operands[0]) != REGNO (operands[1])
17165 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17166 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17167 [(set (match_dup 0) (match_dup 2))
17169 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17171 ; Don't do logical operations with memory outputs
17173 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17174 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17175 ; the same decoder scheduling characteristics as the original.
17178 [(match_scratch:SI 2 "r")
17179 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17180 (match_operator:SI 3 "arith_or_logical_operator"
17182 (match_operand:SI 1 "nonmemory_operand" "")]))
17183 (clobber (reg:CC FLAGS_REG))])]
17184 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17185 /* Do not split stack checking probes. */
17186 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17187 [(set (match_dup 2) (match_dup 0))
17188 (parallel [(set (match_dup 2)
17189 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17190 (clobber (reg:CC FLAGS_REG))])
17191 (set (match_dup 0) (match_dup 2))])
17194 [(match_scratch:SI 2 "r")
17195 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17196 (match_operator:SI 3 "arith_or_logical_operator"
17197 [(match_operand:SI 1 "nonmemory_operand" "")
17199 (clobber (reg:CC FLAGS_REG))])]
17200 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17201 /* Do not split stack checking probes. */
17202 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17203 [(set (match_dup 2) (match_dup 0))
17204 (parallel [(set (match_dup 2)
17205 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17206 (clobber (reg:CC FLAGS_REG))])
17207 (set (match_dup 0) (match_dup 2))])
17209 ;; Attempt to use arith or logical operations with memory outputs with
17210 ;; setting of flags.
17212 [(set (match_operand:SWI 0 "register_operand" "")
17213 (match_operand:SWI 1 "memory_operand" ""))
17214 (parallel [(set (match_dup 0)
17215 (match_operator:SWI 3 "plusminuslogic_operator"
17217 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17218 (clobber (reg:CC FLAGS_REG))])
17219 (set (match_dup 1) (match_dup 0))
17220 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17221 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17222 && peep2_reg_dead_p (4, operands[0])
17223 && !reg_overlap_mentioned_p (operands[0], operands[1])
17224 && ix86_match_ccmode (peep2_next_insn (3),
17225 (GET_CODE (operands[3]) == PLUS
17226 || GET_CODE (operands[3]) == MINUS)
17227 ? CCGOCmode : CCNOmode)"
17228 [(parallel [(set (match_dup 4) (match_dup 5))
17229 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17230 (match_dup 2)]))])]
17231 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);")
17239 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17240 (match_operator:SWI 2 "plusminuslogic_operator"
17242 (match_operand:SWI 1 "memory_operand" "")]))
17243 (clobber (reg:CC FLAGS_REG))])
17244 (set (match_dup 1) (match_dup 0))
17245 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17246 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17247 && GET_CODE (operands[2]) != MINUS
17248 && peep2_reg_dead_p (3, operands[0])
17249 && !reg_overlap_mentioned_p (operands[0], operands[1])
17250 && ix86_match_ccmode (peep2_next_insn (2),
17251 GET_CODE (operands[2]) == PLUS
17252 ? CCGOCmode : CCNOmode)"
17253 [(parallel [(set (match_dup 3) (match_dup 4))
17254 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17255 (match_dup 0)]))])]
17256 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17257 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17258 copy_rtx (operands[1]),
17259 copy_rtx (operands[0]));
17260 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17261 operands[4], const0_rtx);")
17264 [(set (match_operand:SWI12 0 "register_operand" "")
17265 (match_operand:SWI12 1 "memory_operand" ""))
17266 (parallel [(set (match_operand:SI 4 "register_operand" "")
17267 (match_operator:SI 3 "plusminuslogic_operator"
17269 (match_operand:SI 2 "nonmemory_operand" "")]))
17270 (clobber (reg:CC FLAGS_REG))])
17271 (set (match_dup 1) (match_dup 0))
17272 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17273 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17274 && REG_P (operands[0]) && REG_P (operands[4])
17275 && REGNO (operands[0]) == REGNO (operands[4])
17276 && peep2_reg_dead_p (4, operands[0])
17277 && !reg_overlap_mentioned_p (operands[0], operands[1])
17278 && ix86_match_ccmode (peep2_next_insn (3),
17279 (GET_CODE (operands[3]) == PLUS
17280 || GET_CODE (operands[3]) == MINUS)
17281 ? CCGOCmode : CCNOmode)"
17282 [(parallel [(set (match_dup 4) (match_dup 5))
17283 (set (match_dup 1) (match_dup 6))])]
17284 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17285 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17286 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17287 copy_rtx (operands[1]), operands[2]);
17288 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17289 operands[5], const0_rtx);
17290 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17291 copy_rtx (operands[1]),
17292 copy_rtx (operands[2]));")
17294 ;; Attempt to always use XOR for zeroing registers.
17296 [(set (match_operand 0 "register_operand" "")
17297 (match_operand 1 "const0_operand" ""))]
17298 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17299 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17300 && GENERAL_REG_P (operands[0])
17301 && peep2_regno_dead_p (0, FLAGS_REG)"
17302 [(parallel [(set (match_dup 0) (const_int 0))
17303 (clobber (reg:CC FLAGS_REG))])]
17304 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17307 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17309 "(GET_MODE (operands[0]) == QImode
17310 || GET_MODE (operands[0]) == HImode)
17311 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17312 && peep2_regno_dead_p (0, FLAGS_REG)"
17313 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17314 (clobber (reg:CC FLAGS_REG))])])
17316 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17318 [(set (match_operand:SWI248 0 "register_operand" "")
17320 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17321 && peep2_regno_dead_p (0, FLAGS_REG)"
17322 [(parallel [(set (match_dup 0) (const_int -1))
17323 (clobber (reg:CC FLAGS_REG))])]
17325 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17326 operands[0] = gen_lowpart (SImode, operands[0]);
17329 ;; Attempt to convert simple lea to add/shift.
17330 ;; These can be created by move expanders.
17333 [(set (match_operand:SWI48 0 "register_operand" "")
17334 (plus:SWI48 (match_dup 0)
17335 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17336 "peep2_regno_dead_p (0, FLAGS_REG)"
17337 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17338 (clobber (reg:CC FLAGS_REG))])])
17341 [(set (match_operand:SI 0 "register_operand" "")
17342 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17343 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17345 && peep2_regno_dead_p (0, FLAGS_REG)
17346 && REGNO (operands[0]) == REGNO (operands[1])"
17347 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17348 (clobber (reg:CC FLAGS_REG))])]
17349 "operands[2] = gen_lowpart (SImode, operands[2]);")
17352 [(set (match_operand:SWI48 0 "register_operand" "")
17353 (mult:SWI48 (match_dup 0)
17354 (match_operand:SWI48 1 "const_int_operand" "")))]
17355 "exact_log2 (INTVAL (operands[1])) >= 0
17356 && peep2_regno_dead_p (0, FLAGS_REG)"
17357 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17358 (clobber (reg:CC FLAGS_REG))])]
17359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17362 [(set (match_operand:SI 0 "register_operand" "")
17363 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17364 (match_operand:DI 2 "const_int_operand" "")) 0))]
17366 && exact_log2 (INTVAL (operands[2])) >= 0
17367 && REGNO (operands[0]) == REGNO (operands[1])
17368 && peep2_regno_dead_p (0, FLAGS_REG)"
17369 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17370 (clobber (reg:CC FLAGS_REG))])]
17371 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17373 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17374 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17375 ;; On many CPUs it is also faster, since special hardware to avoid esp
17376 ;; dependencies is present.
17378 ;; While some of these conversions may be done using splitters, we use
17379 ;; peepholes in order to allow combine_stack_adjustments pass to see
17380 ;; nonobfuscated RTL.
17382 ;; Convert prologue esp subtractions to push.
17383 ;; We need register to push. In order to keep verify_flow_info happy we have
17385 ;; - use scratch and clobber it in order to avoid dependencies
17386 ;; - use already live register
17387 ;; We can't use the second way right now, since there is no reliable way how to
17388 ;; verify that given register is live. First choice will also most likely in
17389 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17390 ;; call clobbered registers are dead. We may want to use base pointer as an
17391 ;; alternative when no register is available later.
17394 [(match_scratch:P 1 "r")
17395 (parallel [(set (reg:P SP_REG)
17396 (plus:P (reg:P SP_REG)
17397 (match_operand:P 0 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))])]
17400 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17402 [(clobber (match_dup 1))
17403 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (clobber (mem:BLK (scratch)))])])
17407 [(match_scratch:P 1 "r")
17408 (parallel [(set (reg:P SP_REG)
17409 (plus:P (reg:P SP_REG)
17410 (match_operand:P 0 "const_int_operand" "")))
17411 (clobber (reg:CC FLAGS_REG))
17412 (clobber (mem:BLK (scratch)))])]
17413 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17414 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17415 [(clobber (match_dup 1))
17416 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17417 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17418 (clobber (mem:BLK (scratch)))])])
17420 ;; Convert esp subtractions to push.
17422 [(match_scratch:P 1 "r")
17423 (parallel [(set (reg:P SP_REG)
17424 (plus:P (reg:P SP_REG)
17425 (match_operand:P 0 "const_int_operand" "")))
17426 (clobber (reg:CC FLAGS_REG))])]
17427 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17428 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17429 [(clobber (match_dup 1))
17430 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17433 [(match_scratch:P 1 "r")
17434 (parallel [(set (reg:P SP_REG)
17435 (plus:P (reg:P SP_REG)
17436 (match_operand:P 0 "const_int_operand" "")))
17437 (clobber (reg:CC FLAGS_REG))])]
17438 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17439 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17440 [(clobber (match_dup 1))
17441 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17442 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17444 ;; Convert epilogue deallocator to pop.
17446 [(match_scratch:P 1 "r")
17447 (parallel [(set (reg:P SP_REG)
17448 (plus:P (reg:P SP_REG)
17449 (match_operand:P 0 "const_int_operand" "")))
17450 (clobber (reg:CC FLAGS_REG))
17451 (clobber (mem:BLK (scratch)))])]
17452 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17453 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17454 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17455 (clobber (mem:BLK (scratch)))])])
17457 ;; Two pops case is tricky, since pop causes dependency
17458 ;; on destination register. We use two registers if available.
17460 [(match_scratch:P 1 "r")
17461 (match_scratch:P 2 "r")
17462 (parallel [(set (reg:P SP_REG)
17463 (plus:P (reg:P SP_REG)
17464 (match_operand:P 0 "const_int_operand" "")))
17465 (clobber (reg:CC FLAGS_REG))
17466 (clobber (mem:BLK (scratch)))])]
17467 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17468 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470 (clobber (mem:BLK (scratch)))])
17471 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17474 [(match_scratch:P 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand" "")))
17478 (clobber (reg:CC FLAGS_REG))
17479 (clobber (mem:BLK (scratch)))])]
17480 "optimize_insn_for_size_p ()
17481 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17482 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17483 (clobber (mem:BLK (scratch)))])
17484 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17486 ;; Convert esp additions to pop.
17488 [(match_scratch:P 1 "r")
17489 (parallel [(set (reg:P SP_REG)
17490 (plus:P (reg:P SP_REG)
17491 (match_operand:P 0 "const_int_operand" "")))
17492 (clobber (reg:CC FLAGS_REG))])]
17493 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17494 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17496 ;; Two pops case is tricky, since pop causes dependency
17497 ;; on destination register. We use two registers if available.
17499 [(match_scratch:P 1 "r")
17500 (match_scratch:P 2 "r")
17501 (parallel [(set (reg:P SP_REG)
17502 (plus:P (reg:P SP_REG)
17503 (match_operand:P 0 "const_int_operand" "")))
17504 (clobber (reg:CC FLAGS_REG))])]
17505 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17506 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17507 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17510 [(match_scratch:P 1 "r")
17511 (parallel [(set (reg:P SP_REG)
17512 (plus:P (reg:P SP_REG)
17513 (match_operand:P 0 "const_int_operand" "")))
17514 (clobber (reg:CC FLAGS_REG))])]
17515 "optimize_insn_for_size_p ()
17516 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17517 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17518 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17520 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17521 ;; required and register dies. Similarly for 128 to -128.
17523 [(set (match_operand 0 "flags_reg_operand" "")
17524 (match_operator 1 "compare_operator"
17525 [(match_operand 2 "register_operand" "")
17526 (match_operand 3 "const_int_operand" "")]))]
17527 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17528 && incdec_operand (operands[3], GET_MODE (operands[3])))
17529 || (!TARGET_FUSE_CMP_AND_BRANCH
17530 && INTVAL (operands[3]) == 128))
17531 && ix86_match_ccmode (insn, CCGCmode)
17532 && peep2_reg_dead_p (1, operands[2])"
17533 [(parallel [(set (match_dup 0)
17534 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17535 (clobber (match_dup 2))])])
17537 ;; Convert imul by three, five and nine into lea
17540 [(set (match_operand:SWI48 0 "register_operand" "")
17541 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17542 (match_operand:SWI48 2 "const359_operand" "")))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "!TARGET_PARTIAL_REG_STALL
17545 || <MODE>mode == SImode
17546 || optimize_function_for_size_p (cfun)"
17547 [(set (match_dup 0)
17548 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17550 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17554 [(set (match_operand:SWI48 0 "register_operand" "")
17555 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17556 (match_operand:SWI48 2 "const359_operand" "")))
17557 (clobber (reg:CC FLAGS_REG))])]
17558 "optimize_insn_for_speed_p ()
17559 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17560 [(set (match_dup 0) (match_dup 1))
17562 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17564 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17566 ;; imul $32bit_imm, mem, reg is vector decoded, while
17567 ;; imul $32bit_imm, reg, reg is direct decoded.
17569 [(match_scratch:SWI48 3 "r")
17570 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17571 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17572 (match_operand:SWI48 2 "immediate_operand" "")))
17573 (clobber (reg:CC FLAGS_REG))])]
17574 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17575 && !satisfies_constraint_K (operands[2])"
17576 [(set (match_dup 3) (match_dup 1))
17577 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17578 (clobber (reg:CC FLAGS_REG))])])
17581 [(match_scratch:SI 3 "r")
17582 (parallel [(set (match_operand:DI 0 "register_operand" "")
17584 (mult:SI (match_operand:SI 1 "memory_operand" "")
17585 (match_operand:SI 2 "immediate_operand" ""))))
17586 (clobber (reg:CC FLAGS_REG))])]
17588 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17589 && !satisfies_constraint_K (operands[2])"
17590 [(set (match_dup 3) (match_dup 1))
17591 (parallel [(set (match_dup 0)
17592 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17593 (clobber (reg:CC FLAGS_REG))])])
17595 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17596 ;; Convert it into imul reg, reg
17597 ;; It would be better to force assembler to encode instruction using long
17598 ;; immediate, but there is apparently no way to do so.
17600 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17602 (match_operand:SWI248 1 "nonimmediate_operand" "")
17603 (match_operand:SWI248 2 "const_int_operand" "")))
17604 (clobber (reg:CC FLAGS_REG))])
17605 (match_scratch:SWI248 3 "r")]
17606 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17607 && satisfies_constraint_K (operands[2])"
17608 [(set (match_dup 3) (match_dup 2))
17609 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17610 (clobber (reg:CC FLAGS_REG))])]
17612 if (!rtx_equal_p (operands[0], operands[1]))
17613 emit_move_insn (operands[0], operands[1]);
17616 ;; After splitting up read-modify operations, array accesses with memory
17617 ;; operands might end up in form:
17619 ;; movl 4(%esp), %edx
17621 ;; instead of pre-splitting:
17623 ;; addl 4(%esp), %eax
17625 ;; movl 4(%esp), %edx
17626 ;; leal (%edx,%eax,4), %eax
17629 [(match_scratch:P 5 "r")
17630 (parallel [(set (match_operand 0 "register_operand" "")
17631 (ashift (match_operand 1 "register_operand" "")
17632 (match_operand 2 "const_int_operand" "")))
17633 (clobber (reg:CC FLAGS_REG))])
17634 (parallel [(set (match_operand 3 "register_operand" "")
17635 (plus (match_dup 0)
17636 (match_operand 4 "x86_64_general_operand" "")))
17637 (clobber (reg:CC FLAGS_REG))])]
17638 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17639 /* Validate MODE for lea. */
17640 && ((!TARGET_PARTIAL_REG_STALL
17641 && (GET_MODE (operands[0]) == QImode
17642 || GET_MODE (operands[0]) == HImode))
17643 || GET_MODE (operands[0]) == SImode
17644 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17645 && (rtx_equal_p (operands[0], operands[3])
17646 || peep2_reg_dead_p (2, operands[0]))
17647 /* We reorder load and the shift. */
17648 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17649 [(set (match_dup 5) (match_dup 4))
17650 (set (match_dup 0) (match_dup 1))]
17652 enum machine_mode op1mode = GET_MODE (operands[1]);
17653 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17654 int scale = 1 << INTVAL (operands[2]);
17655 rtx index = gen_lowpart (Pmode, operands[1]);
17656 rtx base = gen_lowpart (Pmode, operands[5]);
17657 rtx dest = gen_lowpart (mode, operands[3]);
17659 operands[1] = gen_rtx_PLUS (Pmode, base,
17660 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17661 operands[5] = base;
17663 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17664 if (op1mode != Pmode)
17665 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17666 operands[0] = dest;
17669 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17670 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17671 ;; caught for use by garbage collectors and the like. Using an insn that
17672 ;; maps to SIGILL makes it more likely the program will rightfully die.
17673 ;; Keeping with tradition, "6" is in honor of #UD.
17674 (define_insn "trap"
17675 [(trap_if (const_int 1) (const_int 6))]
17677 { return ASM_SHORT "0x0b0f"; }
17678 [(set_attr "length" "2")])
17680 (define_expand "prefetch"
17681 [(prefetch (match_operand 0 "address_operand" "")
17682 (match_operand:SI 1 "const_int_operand" "")
17683 (match_operand:SI 2 "const_int_operand" ""))]
17684 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17686 int rw = INTVAL (operands[1]);
17687 int locality = INTVAL (operands[2]);
17689 gcc_assert (rw == 0 || rw == 1);
17690 gcc_assert (locality >= 0 && locality <= 3);
17691 gcc_assert (GET_MODE (operands[0]) == Pmode
17692 || GET_MODE (operands[0]) == VOIDmode);
17694 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17695 supported by SSE counterpart or the SSE prefetch is not available
17696 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17698 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17699 operands[2] = GEN_INT (3);
17701 operands[1] = const0_rtx;
17704 (define_insn "*prefetch_sse_<mode>"
17705 [(prefetch (match_operand:P 0 "address_operand" "p")
17707 (match_operand:SI 1 "const_int_operand" ""))]
17708 "TARGET_PREFETCH_SSE"
17710 static const char * const patterns[4] = {
17711 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17714 int locality = INTVAL (operands[1]);
17715 gcc_assert (locality >= 0 && locality <= 3);
17717 return patterns[locality];
17719 [(set_attr "type" "sse")
17720 (set_attr "atom_sse_attr" "prefetch")
17721 (set (attr "length_address")
17722 (symbol_ref "memory_address_length (operands[0])"))
17723 (set_attr "memory" "none")])
17725 (define_insn "*prefetch_3dnow_<mode>"
17726 [(prefetch (match_operand:P 0 "address_operand" "p")
17727 (match_operand:SI 1 "const_int_operand" "n")
17731 if (INTVAL (operands[1]) == 0)
17732 return "prefetch\t%a0";
17734 return "prefetchw\t%a0";
17736 [(set_attr "type" "mmx")
17737 (set (attr "length_address")
17738 (symbol_ref "memory_address_length (operands[0])"))
17739 (set_attr "memory" "none")])
17741 (define_expand "stack_protect_set"
17742 [(match_operand 0 "memory_operand" "")
17743 (match_operand 1 "memory_operand" "")]
17746 rtx (*insn)(rtx, rtx);
17748 #ifdef TARGET_THREAD_SSP_OFFSET
17749 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17750 insn = (TARGET_LP64
17751 ? gen_stack_tls_protect_set_di
17752 : gen_stack_tls_protect_set_si);
17754 insn = (TARGET_LP64
17755 ? gen_stack_protect_set_di
17756 : gen_stack_protect_set_si);
17759 emit_insn (insn (operands[0], operands[1]));
17763 (define_insn "stack_protect_set_<mode>"
17764 [(set (match_operand:PTR 0 "memory_operand" "=m")
17765 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17767 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17768 (clobber (reg:CC FLAGS_REG))]
17770 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17771 [(set_attr "type" "multi")])
17773 (define_insn "stack_tls_protect_set_<mode>"
17774 [(set (match_operand:PTR 0 "memory_operand" "=m")
17775 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17776 UNSPEC_SP_TLS_SET))
17777 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17778 (clobber (reg:CC FLAGS_REG))]
17780 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17781 [(set_attr "type" "multi")])
17783 (define_expand "stack_protect_test"
17784 [(match_operand 0 "memory_operand" "")
17785 (match_operand 1 "memory_operand" "")
17786 (match_operand 2 "" "")]
17789 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17791 rtx (*insn)(rtx, rtx, rtx);
17793 #ifdef TARGET_THREAD_SSP_OFFSET
17794 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17795 insn = (TARGET_LP64
17796 ? gen_stack_tls_protect_test_di
17797 : gen_stack_tls_protect_test_si);
17799 insn = (TARGET_LP64
17800 ? gen_stack_protect_test_di
17801 : gen_stack_protect_test_si);
17804 emit_insn (insn (flags, operands[0], operands[1]));
17806 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17807 flags, const0_rtx, operands[2]));
17811 (define_insn "stack_protect_test_<mode>"
17812 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17813 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17814 (match_operand:PTR 2 "memory_operand" "m")]
17816 (clobber (match_scratch:PTR 3 "=&r"))]
17818 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17819 [(set_attr "type" "multi")])
17821 (define_insn "stack_tls_protect_test_<mode>"
17822 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17823 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17824 (match_operand:PTR 2 "const_int_operand" "i")]
17825 UNSPEC_SP_TLS_TEST))
17826 (clobber (match_scratch:PTR 3 "=r"))]
17828 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17829 [(set_attr "type" "multi")])
17831 (define_insn "sse4_2_crc32<mode>"
17832 [(set (match_operand:SI 0 "register_operand" "=r")
17834 [(match_operand:SI 1 "register_operand" "0")
17835 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17837 "TARGET_SSE4_2 || TARGET_CRC32"
17838 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17839 [(set_attr "type" "sselog1")
17840 (set_attr "prefix_rep" "1")
17841 (set_attr "prefix_extra" "1")
17842 (set (attr "prefix_data16")
17843 (if_then_else (match_operand:HI 2 "" "")
17845 (const_string "*")))
17846 (set (attr "prefix_rex")
17847 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17849 (const_string "*")))
17850 (set_attr "mode" "SI")])
17852 (define_insn "sse4_2_crc32di"
17853 [(set (match_operand:DI 0 "register_operand" "=r")
17855 [(match_operand:DI 1 "register_operand" "0")
17856 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17858 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17859 "crc32{q}\t{%2, %0|%0, %2}"
17860 [(set_attr "type" "sselog1")
17861 (set_attr "prefix_rep" "1")
17862 (set_attr "prefix_extra" "1")
17863 (set_attr "mode" "DI")])
17865 (define_expand "rdpmc"
17866 [(match_operand:DI 0 "register_operand" "")
17867 (match_operand:SI 1 "register_operand" "")]
17870 rtx reg = gen_reg_rtx (DImode);
17873 /* Force operand 1 into ECX. */
17874 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17875 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17876 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17881 rtvec vec = rtvec_alloc (2);
17882 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17883 rtx upper = gen_reg_rtx (DImode);
17884 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17885 gen_rtvec (1, const0_rtx),
17887 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17888 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17890 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17891 NULL, 1, OPTAB_DIRECT);
17892 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17896 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17897 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17901 (define_insn "*rdpmc"
17902 [(set (match_operand:DI 0 "register_operand" "=A")
17903 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17907 [(set_attr "type" "other")
17908 (set_attr "length" "2")])
17910 (define_insn "*rdpmc_rex64"
17911 [(set (match_operand:DI 0 "register_operand" "=a")
17912 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17914 (set (match_operand:DI 1 "register_operand" "=d")
17915 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17918 [(set_attr "type" "other")
17919 (set_attr "length" "2")])
17921 (define_expand "rdtsc"
17922 [(set (match_operand:DI 0 "register_operand" "")
17923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17928 rtvec vec = rtvec_alloc (2);
17929 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17930 rtx upper = gen_reg_rtx (DImode);
17931 rtx lower = gen_reg_rtx (DImode);
17932 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17933 gen_rtvec (1, const0_rtx),
17935 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17936 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17938 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17939 NULL, 1, OPTAB_DIRECT);
17940 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17942 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17947 (define_insn "*rdtsc"
17948 [(set (match_operand:DI 0 "register_operand" "=A")
17949 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17952 [(set_attr "type" "other")
17953 (set_attr "length" "2")])
17955 (define_insn "*rdtsc_rex64"
17956 [(set (match_operand:DI 0 "register_operand" "=a")
17957 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17958 (set (match_operand:DI 1 "register_operand" "=d")
17959 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17962 [(set_attr "type" "other")
17963 (set_attr "length" "2")])
17965 (define_expand "rdtscp"
17966 [(match_operand:DI 0 "register_operand" "")
17967 (match_operand:SI 1 "memory_operand" "")]
17970 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17971 gen_rtvec (1, const0_rtx),
17973 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17974 gen_rtvec (1, const0_rtx),
17976 rtx reg = gen_reg_rtx (DImode);
17977 rtx tmp = gen_reg_rtx (SImode);
17981 rtvec vec = rtvec_alloc (3);
17982 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17983 rtx upper = gen_reg_rtx (DImode);
17984 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17985 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17986 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17988 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17989 NULL, 1, OPTAB_DIRECT);
17990 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17995 rtvec vec = rtvec_alloc (2);
17996 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17997 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17998 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18002 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18006 (define_insn "*rdtscp"
18007 [(set (match_operand:DI 0 "register_operand" "=A")
18008 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18009 (set (match_operand:SI 1 "register_operand" "=c")
18010 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18013 [(set_attr "type" "other")
18014 (set_attr "length" "3")])
18016 (define_insn "*rdtscp_rex64"
18017 [(set (match_operand:DI 0 "register_operand" "=a")
18018 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18019 (set (match_operand:DI 1 "register_operand" "=d")
18020 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18021 (set (match_operand:SI 2 "register_operand" "=c")
18022 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18025 [(set_attr "type" "other")
18026 (set_attr "length" "3")])
18028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18030 ;; LWP instructions
18032 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18034 (define_expand "lwp_llwpcb"
18035 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18036 UNSPECV_LLWP_INTRINSIC)]
18039 (define_insn "*lwp_llwpcb<mode>1"
18040 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18041 UNSPECV_LLWP_INTRINSIC)]
18044 [(set_attr "type" "lwp")
18045 (set_attr "mode" "<MODE>")
18046 (set_attr "length" "5")])
18048 (define_expand "lwp_slwpcb"
18049 [(set (match_operand 0 "register_operand" "=r")
18050 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18055 insn = (TARGET_64BIT
18057 : gen_lwp_slwpcbsi);
18059 emit_insn (insn (operands[0]));
18063 (define_insn "lwp_slwpcb<mode>"
18064 [(set (match_operand:P 0 "register_operand" "=r")
18065 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18068 [(set_attr "type" "lwp")
18069 (set_attr "mode" "<MODE>")
18070 (set_attr "length" "5")])
18072 (define_expand "lwp_lwpval<mode>3"
18073 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18074 (match_operand:SI 2 "nonimmediate_operand" "rm")
18075 (match_operand:SI 3 "const_int_operand" "i")]
18076 UNSPECV_LWPVAL_INTRINSIC)]
18078 "/* Avoid unused variable warning. */
18081 (define_insn "*lwp_lwpval<mode>3_1"
18082 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18083 (match_operand:SI 1 "nonimmediate_operand" "rm")
18084 (match_operand:SI 2 "const_int_operand" "i")]
18085 UNSPECV_LWPVAL_INTRINSIC)]
18087 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18088 [(set_attr "type" "lwp")
18089 (set_attr "mode" "<MODE>")
18090 (set (attr "length")
18091 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18093 (define_expand "lwp_lwpins<mode>3"
18094 [(set (reg:CCC FLAGS_REG)
18095 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18096 (match_operand:SI 2 "nonimmediate_operand" "rm")
18097 (match_operand:SI 3 "const_int_operand" "i")]
18098 UNSPECV_LWPINS_INTRINSIC))
18099 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18100 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18103 (define_insn "*lwp_lwpins<mode>3_1"
18104 [(set (reg:CCC FLAGS_REG)
18105 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18106 (match_operand:SI 1 "nonimmediate_operand" "rm")
18107 (match_operand:SI 2 "const_int_operand" "i")]
18108 UNSPECV_LWPINS_INTRINSIC))]
18110 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18111 [(set_attr "type" "lwp")
18112 (set_attr "mode" "<MODE>")
18113 (set (attr "length")
18114 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18116 (define_insn "rdfsbase<mode>"
18117 [(set (match_operand:SWI48 0 "register_operand" "=r")
18118 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18119 "TARGET_64BIT && TARGET_FSGSBASE"
18121 [(set_attr "type" "other")
18122 (set_attr "prefix_extra" "2")])
18124 (define_insn "rdgsbase<mode>"
18125 [(set (match_operand:SWI48 0 "register_operand" "=r")
18126 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18127 "TARGET_64BIT && TARGET_FSGSBASE"
18129 [(set_attr "type" "other")
18130 (set_attr "prefix_extra" "2")])
18132 (define_insn "wrfsbase<mode>"
18133 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18135 "TARGET_64BIT && TARGET_FSGSBASE"
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "2")])
18140 (define_insn "wrgsbase<mode>"
18141 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18143 "TARGET_64BIT && TARGET_FSGSBASE"
18145 [(set_attr "type" "other")
18146 (set_attr "prefix_extra" "2")])
18148 (define_insn "rdrand<mode>_1"
18149 [(set (match_operand:SWI248 0 "register_operand" "=r")
18150 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18151 (set (reg:CCC FLAGS_REG)
18152 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18155 [(set_attr "type" "other")
18156 (set_attr "prefix_extra" "1")])
18158 (define_expand "pause"
18159 [(set (match_dup 0)
18160 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18163 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18164 MEM_VOLATILE_P (operands[0]) = 1;
18167 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18168 ;; They have the same encoding.
18169 (define_insn "*pause"
18170 [(set (match_operand:BLK 0 "" "")
18171 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18174 [(set_attr "length" "2")
18175 (set_attr "memory" "unknown")])
18179 (include "sync.md")