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_REGNO_P (reg_or_subregno (operands[0]))"
4924 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4927 [(set (match_operand:MODEF 0 "register_operand" "")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4934 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
4935 [(set (match_dup 2) (match_dup 1))
4936 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4938 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4939 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4941 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4942 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4943 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4944 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4947 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4948 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4949 [(set_attr "type" "fmov,sseicvt,sseicvt")
4950 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4951 (set_attr "mode" "<MODEF:MODE>")
4952 (set (attr "prefix_rex")
4954 (and (eq_attr "prefix" "maybe_vex")
4955 (match_test "<SWI48x:MODE>mode == DImode"))
4957 (const_string "*")))
4958 (set_attr "unit" "i387,*,*")
4959 (set_attr "athlon_decode" "*,double,direct")
4960 (set_attr "amdfam10_decode" "*,vector,double")
4961 (set_attr "bdver1_decode" "*,double,direct")
4962 (set_attr "fp_int_src" "true")])
4964 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4965 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4967 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4968 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4969 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4970 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4973 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4974 [(set_attr "type" "fmov,sseicvt")
4975 (set_attr "prefix" "orig,maybe_vex")
4976 (set_attr "mode" "<MODEF:MODE>")
4977 (set (attr "prefix_rex")
4979 (and (eq_attr "prefix" "maybe_vex")
4980 (match_test "<SWI48x:MODE>mode == DImode"))
4982 (const_string "*")))
4983 (set_attr "athlon_decode" "*,direct")
4984 (set_attr "amdfam10_decode" "*,double")
4985 (set_attr "bdver1_decode" "*,direct")
4986 (set_attr "fp_int_src" "true")])
4988 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4989 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4991 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4992 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4993 "TARGET_SSE2 && TARGET_SSE_MATH
4994 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4996 [(set_attr "type" "sseicvt")
4997 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4998 (set_attr "athlon_decode" "double,direct,double")
4999 (set_attr "amdfam10_decode" "vector,double,double")
5000 (set_attr "bdver1_decode" "double,direct,double")
5001 (set_attr "fp_int_src" "true")])
5003 (define_insn "*floatsi<mode>2_vector_sse"
5004 [(set (match_operand:MODEF 0 "register_operand" "=x")
5005 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5006 "TARGET_SSE2 && TARGET_SSE_MATH
5007 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5009 [(set_attr "type" "sseicvt")
5010 (set_attr "mode" "<MODE>")
5011 (set_attr "athlon_decode" "direct")
5012 (set_attr "amdfam10_decode" "double")
5013 (set_attr "bdver1_decode" "direct")
5014 (set_attr "fp_int_src" "true")])
5017 [(set (match_operand:MODEF 0 "register_operand" "")
5018 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5019 (clobber (match_operand:SI 2 "memory_operand" ""))]
5020 "TARGET_SSE2 && TARGET_SSE_MATH
5021 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5023 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5026 rtx op1 = operands[1];
5028 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5030 if (GET_CODE (op1) == SUBREG)
5031 op1 = SUBREG_REG (op1);
5033 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5036 emit_insn (gen_sse2_loadld (operands[4],
5037 CONST0_RTX (V4SImode), operands[1]));
5039 /* We can ignore possible trapping value in the
5040 high part of SSE register for non-trapping math. */
5041 else if (SSE_REG_P (op1) && !flag_trapping_math)
5042 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5045 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5046 emit_move_insn (operands[2], operands[1]);
5047 emit_insn (gen_sse2_loadld (operands[4],
5048 CONST0_RTX (V4SImode), operands[2]));
5050 if (<ssevecmode>mode == V4SFmode)
5051 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5053 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5058 [(set (match_operand:MODEF 0 "register_operand" "")
5059 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5060 (clobber (match_operand:SI 2 "memory_operand" ""))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5064 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5073 if (<ssevecmode>mode == V4SFmode)
5074 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5076 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5081 [(set (match_operand:MODEF 0 "register_operand" "")
5082 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5083 "TARGET_SSE2 && TARGET_SSE_MATH
5084 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5086 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5089 rtx op1 = operands[1];
5091 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5093 if (GET_CODE (op1) == SUBREG)
5094 op1 = SUBREG_REG (op1);
5096 if (GENERAL_REG_P (op1))
5098 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5099 if (TARGET_INTER_UNIT_MOVES)
5100 emit_insn (gen_sse2_loadld (operands[4],
5101 CONST0_RTX (V4SImode), operands[1]));
5104 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5106 emit_insn (gen_sse2_loadld (operands[4],
5107 CONST0_RTX (V4SImode), operands[5]));
5108 ix86_free_from_memory (GET_MODE (operands[1]));
5111 /* We can ignore possible trapping value in the
5112 high part of SSE register for non-trapping math. */
5113 else if (SSE_REG_P (op1) && !flag_trapping_math)
5114 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5117 if (<ssevecmode>mode == V4SFmode)
5118 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5120 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5125 [(set (match_operand:MODEF 0 "register_operand" "")
5126 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5127 "TARGET_SSE2 && TARGET_SSE_MATH
5128 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5130 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5133 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5135 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5137 emit_insn (gen_sse2_loadld (operands[4],
5138 CONST0_RTX (V4SImode), operands[1]));
5139 if (<ssevecmode>mode == V4SFmode)
5140 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5142 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5146 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5147 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5149 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5150 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5151 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5152 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5154 [(set_attr "type" "sseicvt")
5155 (set_attr "mode" "<MODEF:MODE>")
5156 (set_attr "athlon_decode" "double,direct")
5157 (set_attr "amdfam10_decode" "vector,double")
5158 (set_attr "bdver1_decode" "double,direct")
5159 (set_attr "fp_int_src" "true")])
5161 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5162 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5164 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5165 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5166 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5167 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5168 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5169 [(set_attr "type" "sseicvt")
5170 (set_attr "prefix" "maybe_vex")
5171 (set_attr "mode" "<MODEF:MODE>")
5172 (set (attr "prefix_rex")
5174 (and (eq_attr "prefix" "maybe_vex")
5175 (match_test "<SWI48x:MODE>mode == DImode"))
5177 (const_string "*")))
5178 (set_attr "athlon_decode" "double,direct")
5179 (set_attr "amdfam10_decode" "vector,double")
5180 (set_attr "bdver1_decode" "double,direct")
5181 (set_attr "fp_int_src" "true")])
5184 [(set (match_operand:MODEF 0 "register_operand" "")
5185 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5186 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5187 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5189 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5191 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5194 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5195 [(set (match_operand:MODEF 0 "register_operand" "=x")
5197 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5201 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5202 [(set_attr "type" "sseicvt")
5203 (set_attr "prefix" "maybe_vex")
5204 (set_attr "mode" "<MODEF:MODE>")
5205 (set (attr "prefix_rex")
5207 (and (eq_attr "prefix" "maybe_vex")
5208 (match_test "<SWI48x:MODE>mode == DImode"))
5210 (const_string "*")))
5211 (set_attr "athlon_decode" "direct")
5212 (set_attr "amdfam10_decode" "double")
5213 (set_attr "bdver1_decode" "direct")
5214 (set_attr "fp_int_src" "true")])
5217 [(set (match_operand:MODEF 0 "register_operand" "")
5218 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5220 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5221 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5222 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5224 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5225 [(set (match_dup 2) (match_dup 1))
5226 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5229 [(set (match_operand:MODEF 0 "register_operand" "")
5230 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5231 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5232 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5235 && SSE_REGNO_P (reg_or_subregno (operands[0]))"
5236 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5238 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5239 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5241 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5242 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5244 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5248 [(set_attr "type" "fmov,multi")
5249 (set_attr "mode" "<X87MODEF:MODE>")
5250 (set_attr "unit" "*,i387")
5251 (set_attr "fp_int_src" "true")])
5253 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5254 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5256 (match_operand:SWI48x 1 "memory_operand" "m")))]
5258 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5260 [(set_attr "type" "fmov")
5261 (set_attr "mode" "<X87MODEF:MODE>")
5262 (set_attr "fp_int_src" "true")])
5265 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5266 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5267 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5269 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5270 && reload_completed"
5271 [(set (match_dup 2) (match_dup 1))
5272 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5275 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5276 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5277 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5279 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5280 && reload_completed"
5281 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5283 ;; Avoid store forwarding (partial memory) stall penalty
5284 ;; by passing DImode value through XMM registers. */
5286 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5287 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5290 (clobber (match_scratch:V4SI 3 "=X,x"))
5291 (clobber (match_scratch:V4SI 4 "=X,x"))
5292 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5293 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5294 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5295 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<X87MODEF:MODE>")
5299 (set_attr "unit" "i387")
5300 (set_attr "fp_int_src" "true")])
5303 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5304 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5305 (clobber (match_scratch:V4SI 3 ""))
5306 (clobber (match_scratch:V4SI 4 ""))
5307 (clobber (match_operand:DI 2 "memory_operand" ""))]
5308 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5310 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5311 && reload_completed"
5312 [(set (match_dup 2) (match_dup 3))
5313 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5315 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5316 Assemble the 64-bit DImode value in an xmm register. */
5317 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5318 gen_rtx_SUBREG (SImode, operands[1], 0)));
5319 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5320 gen_rtx_SUBREG (SImode, operands[1], 4)));
5321 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5324 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5328 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5329 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5330 (clobber (match_scratch:V4SI 3 ""))
5331 (clobber (match_scratch:V4SI 4 ""))
5332 (clobber (match_operand:DI 2 "memory_operand" ""))]
5333 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5335 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5336 && reload_completed"
5337 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5339 ;; Avoid store forwarding (partial memory) stall penalty by extending
5340 ;; SImode value to DImode through XMM register instead of pushing two
5341 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5342 ;; targets benefit from this optimization. Also note that fild
5343 ;; loads from memory only.
5345 (define_insn "*floatunssi<mode>2_1"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347 (unsigned_float:X87MODEF
5348 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5349 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5350 (clobber (match_scratch:SI 3 "=X,x"))]
5352 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<MODE>")])
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5360 (unsigned_float:X87MODEF
5361 (match_operand:SI 1 "register_operand" "")))
5362 (clobber (match_operand:DI 2 "memory_operand" ""))
5363 (clobber (match_scratch:SI 3 ""))]
5365 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5367 && reload_completed"
5368 [(set (match_dup 2) (match_dup 1))
5370 (float:X87MODEF (match_dup 2)))]
5371 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5374 [(set (match_operand:X87MODEF 0 "register_operand" "")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "memory_operand" "")))
5377 (clobber (match_operand:DI 2 "memory_operand" ""))
5378 (clobber (match_scratch:SI 3 ""))]
5380 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5382 && reload_completed"
5383 [(set (match_dup 2) (match_dup 3))
5385 (float:X87MODEF (match_dup 2)))]
5387 emit_move_insn (operands[3], operands[1]);
5388 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5391 (define_expand "floatunssi<mode>2"
5393 [(set (match_operand:X87MODEF 0 "register_operand" "")
5394 (unsigned_float:X87MODEF
5395 (match_operand:SI 1 "nonimmediate_operand" "")))
5396 (clobber (match_dup 2))
5397 (clobber (match_scratch:SI 3 ""))])]
5399 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5403 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5405 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5410 enum ix86_stack_slot slot = (virtuals_instantiated
5413 operands[2] = assign_386_stack_local (DImode, slot);
5417 (define_expand "floatunsdisf2"
5418 [(use (match_operand:SF 0 "register_operand" ""))
5419 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5420 "TARGET_64BIT && TARGET_SSE_MATH"
5421 "x86_emit_floatuns (operands); DONE;")
5423 (define_expand "floatunsdidf2"
5424 [(use (match_operand:DF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5427 && TARGET_SSE2 && TARGET_SSE_MATH"
5430 x86_emit_floatuns (operands);
5432 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5438 (define_expand "add<mode>3"
5439 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5440 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5441 (match_operand:SDWIM 2 "<general_operand>" "")))]
5443 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5445 (define_insn_and_split "*add<dwi>3_doubleword"
5446 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5448 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5449 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5450 (clobber (reg:CC FLAGS_REG))]
5451 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5454 [(parallel [(set (reg:CC FLAGS_REG)
5455 (unspec:CC [(match_dup 1) (match_dup 2)]
5458 (plus:DWIH (match_dup 1) (match_dup 2)))])
5459 (parallel [(set (match_dup 3)
5463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5465 (clobber (reg:CC FLAGS_REG))])]
5466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5468 (define_insn "*add<mode>3_cc"
5469 [(set (reg:CC FLAGS_REG)
5471 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5474 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5475 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5477 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5478 [(set_attr "type" "alu")
5479 (set_attr "mode" "<MODE>")])
5481 (define_insn "addqi3_cc"
5482 [(set (reg:CC FLAGS_REG)
5484 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5485 (match_operand:QI 2 "general_operand" "qn,qm")]
5487 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5488 (plus:QI (match_dup 1) (match_dup 2)))]
5489 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5490 "add{b}\t{%2, %0|%0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "QI")])
5494 (define_insn_and_split "*lea_1"
5495 [(set (match_operand:SI 0 "register_operand" "=r")
5496 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5498 "lea{l}\t{%a1, %0|%0, %a1}"
5499 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5502 ix86_split_lea_for_addr (operands, SImode);
5505 [(set_attr "type" "lea")
5506 (set_attr "mode" "SI")])
5508 (define_insn_and_split "*lea<mode>_2"
5509 [(set (match_operand:SWI48 0 "register_operand" "=r")
5510 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5512 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5513 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5516 ix86_split_lea_for_addr (operands, <MODE>mode);
5519 [(set_attr "type" "lea")
5520 (set_attr "mode" "<MODE>")])
5522 (define_insn "*lea_3_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5525 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5527 "lea{l}\t{%a1, %k0|%k0, %a1}"
5528 [(set_attr "type" "lea")
5529 (set_attr "mode" "SI")])
5531 (define_insn "*lea_4_zext"
5532 [(set (match_operand:DI 0 "register_operand" "=r")
5534 (match_operand:SI 1 "lea_address_operand" "p")))]
5536 "lea{l}\t{%a1, %k0|%k0, %a1}"
5537 [(set_attr "type" "lea")
5538 (set_attr "mode" "SI")])
5540 (define_insn "*lea_5_zext"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5544 (match_operand:DI 2 "const_32bit_mask" "n")))]
5546 "lea{l}\t{%a1, %k0|%k0, %a1}"
5547 [(set_attr "type" "lea")
5548 (set_attr "mode" "SI")])
5550 (define_insn "*lea_6_zext"
5551 [(set (match_operand:DI 0 "register_operand" "=r")
5553 (match_operand:DI 1 "lea_address_operand" "p")
5554 (match_operand:DI 2 "const_32bit_mask" "n")))]
5556 "lea{l}\t{%a1, %k0|%k0, %a1}"
5557 [(set_attr "type" "lea")
5558 (set_attr "mode" "SI")])
5560 (define_insn "*add<mode>_1"
5561 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5563 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5564 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5565 (clobber (reg:CC FLAGS_REG))]
5566 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5568 switch (get_attr_type (insn))
5574 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5575 if (operands[2] == const1_rtx)
5576 return "inc{<imodesuffix>}\t%0";
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{<imodesuffix>}\t%0";
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 2)
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5594 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5596 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5600 (cond [(eq_attr "alternative" "3")
5601 (const_string "lea")
5602 (match_operand:SWI48 2 "incdec_operand" "")
5603 (const_string "incdec")
5605 (const_string "alu")))
5606 (set (attr "length_immediate")
5608 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5610 (const_string "*")))
5611 (set_attr "mode" "<MODE>")])
5613 ;; It may seem that nonimmediate operand is proper one for operand 1.
5614 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5615 ;; we take care in ix86_binary_operator_ok to not allow two memory
5616 ;; operands so proper swapping will be done in reload. This allow
5617 ;; patterns constructed from addsi_1 to match.
5619 (define_insn "addsi_1_zext"
5620 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5622 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5623 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5624 (clobber (reg:CC FLAGS_REG))]
5625 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627 switch (get_attr_type (insn))
5633 if (operands[2] == const1_rtx)
5634 return "inc{l}\t%k0";
5637 gcc_assert (operands[2] == constm1_rtx);
5638 return "dec{l}\t%k0";
5642 /* For most processors, ADD is faster than LEA. This alternative
5643 was added to use ADD as much as possible. */
5644 if (which_alternative == 1)
5647 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5650 if (x86_maybe_negate_const_int (&operands[2], SImode))
5651 return "sub{l}\t{%2, %k0|%k0, %2}";
5653 return "add{l}\t{%2, %k0|%k0, %2}";
5657 (cond [(eq_attr "alternative" "2")
5658 (const_string "lea")
5659 (match_operand:SI 2 "incdec_operand" "")
5660 (const_string "incdec")
5662 (const_string "alu")))
5663 (set (attr "length_immediate")
5665 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5667 (const_string "*")))
5668 (set_attr "mode" "SI")])
5670 (define_insn "*addhi_1"
5671 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5672 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5673 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5674 (clobber (reg:CC FLAGS_REG))]
5675 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5677 switch (get_attr_type (insn))
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 if (operands[2] == const1_rtx)
5685 return "inc{w}\t%0";
5688 gcc_assert (operands[2] == constm1_rtx);
5689 return "dec{w}\t%0";
5693 /* For most processors, ADD is faster than LEA. This alternative
5694 was added to use ADD as much as possible. */
5695 if (which_alternative == 2)
5698 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 if (x86_maybe_negate_const_int (&operands[2], HImode))
5703 return "sub{w}\t{%2, %0|%0, %2}";
5705 return "add{w}\t{%2, %0|%0, %2}";
5709 (cond [(eq_attr "alternative" "3")
5710 (const_string "lea")
5711 (match_operand:HI 2 "incdec_operand" "")
5712 (const_string "incdec")
5714 (const_string "alu")))
5715 (set (attr "length_immediate")
5717 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5719 (const_string "*")))
5720 (set_attr "mode" "HI,HI,HI,SI")])
5722 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5723 (define_insn "*addqi_1"
5724 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5725 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5726 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5727 (clobber (reg:CC FLAGS_REG))]
5728 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5730 bool widen = (which_alternative == 3 || which_alternative == 4);
5732 switch (get_attr_type (insn))
5738 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5739 if (operands[2] == const1_rtx)
5740 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5743 gcc_assert (operands[2] == constm1_rtx);
5744 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5748 /* For most processors, ADD is faster than LEA. These alternatives
5749 were added to use ADD as much as possible. */
5750 if (which_alternative == 2 || which_alternative == 4)
5753 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (x86_maybe_negate_const_int (&operands[2], QImode))
5760 return "sub{l}\t{%2, %k0|%k0, %2}";
5762 return "sub{b}\t{%2, %0|%0, %2}";
5765 return "add{l}\t{%k2, %k0|%k0, %k2}";
5767 return "add{b}\t{%2, %0|%0, %2}";
5771 (cond [(eq_attr "alternative" "5")
5772 (const_string "lea")
5773 (match_operand:QI 2 "incdec_operand" "")
5774 (const_string "incdec")
5776 (const_string "alu")))
5777 (set (attr "length_immediate")
5779 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5781 (const_string "*")))
5782 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5784 (define_insn "*addqi_1_slp"
5785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5786 (plus:QI (match_dup 0)
5787 (match_operand:QI 1 "general_operand" "qn,qm")))
5788 (clobber (reg:CC FLAGS_REG))]
5789 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5792 switch (get_attr_type (insn))
5795 if (operands[1] == const1_rtx)
5796 return "inc{b}\t%0";
5799 gcc_assert (operands[1] == constm1_rtx);
5800 return "dec{b}\t%0";
5804 if (x86_maybe_negate_const_int (&operands[1], QImode))
5805 return "sub{b}\t{%1, %0|%0, %1}";
5807 return "add{b}\t{%1, %0|%0, %1}";
5811 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5812 (const_string "incdec")
5813 (const_string "alu1")))
5814 (set (attr "memory")
5815 (if_then_else (match_operand 1 "memory_operand" "")
5816 (const_string "load")
5817 (const_string "none")))
5818 (set_attr "mode" "QI")])
5820 ;; Split non destructive adds if we cannot use lea.
5822 [(set (match_operand:SWI48 0 "register_operand" "")
5823 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5824 (match_operand:SWI48 2 "nonmemory_operand" "")))
5825 (clobber (reg:CC FLAGS_REG))]
5826 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5827 [(set (match_dup 0) (match_dup 1))
5828 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5829 (clobber (reg:CC FLAGS_REG))])])
5831 ;; Convert add to the lea pattern to avoid flags dependency.
5833 [(set (match_operand:SWI 0 "register_operand" "")
5834 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5835 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5840 enum machine_mode mode = <MODE>mode;
5843 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5846 operands[0] = gen_lowpart (mode, operands[0]);
5847 operands[1] = gen_lowpart (mode, operands[1]);
5848 operands[2] = gen_lowpart (mode, operands[2]);
5851 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5853 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5857 ;; Convert add to the lea pattern to avoid flags dependency.
5859 [(set (match_operand:DI 0 "register_operand" "")
5861 (plus:SI (match_operand:SI 1 "register_operand" "")
5862 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5866 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5868 (define_insn "*add<mode>_2"
5869 [(set (reg FLAGS_REG)
5872 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5873 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5875 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5876 (plus:SWI (match_dup 1) (match_dup 2)))]
5877 "ix86_match_ccmode (insn, CCGOCmode)
5878 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5880 switch (get_attr_type (insn))
5883 if (operands[2] == const1_rtx)
5884 return "inc{<imodesuffix>}\t%0";
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{<imodesuffix>}\t%0";
5892 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5893 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5895 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5899 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5900 (const_string "incdec")
5901 (const_string "alu")))
5902 (set (attr "length_immediate")
5904 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5906 (const_string "*")))
5907 (set_attr "mode" "<MODE>")])
5909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5910 (define_insn "*addsi_2_zext"
5911 [(set (reg FLAGS_REG)
5913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5914 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5916 (set (match_operand:DI 0 "register_operand" "=r")
5917 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5918 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5919 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5921 switch (get_attr_type (insn))
5924 if (operands[2] == const1_rtx)
5925 return "inc{l}\t%k0";
5928 gcc_assert (operands[2] == constm1_rtx);
5929 return "dec{l}\t%k0";
5933 if (x86_maybe_negate_const_int (&operands[2], SImode))
5934 return "sub{l}\t{%2, %k0|%k0, %2}";
5936 return "add{l}\t{%2, %k0|%k0, %2}";
5940 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set (attr "length_immediate")
5945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5947 (const_string "*")))
5948 (set_attr "mode" "SI")])
5950 (define_insn "*add<mode>_3"
5951 [(set (reg FLAGS_REG)
5953 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5954 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5955 (clobber (match_scratch:SWI 0 "=<r>"))]
5956 "ix86_match_ccmode (insn, CCZmode)
5957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5959 switch (get_attr_type (insn))
5962 if (operands[2] == const1_rtx)
5963 return "inc{<imodesuffix>}\t%0";
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{<imodesuffix>}\t%0";
5971 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5972 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5974 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5978 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set (attr "length_immediate")
5983 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5985 (const_string "*")))
5986 (set_attr "mode" "<MODE>")])
5988 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5989 (define_insn "*addsi_3_zext"
5990 [(set (reg FLAGS_REG)
5992 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5993 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5994 (set (match_operand:DI 0 "register_operand" "=r")
5995 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5996 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5997 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5999 switch (get_attr_type (insn))
6002 if (operands[2] == const1_rtx)
6003 return "inc{l}\t%k0";
6006 gcc_assert (operands[2] == constm1_rtx);
6007 return "dec{l}\t%k0";
6011 if (x86_maybe_negate_const_int (&operands[2], SImode))
6012 return "sub{l}\t{%2, %k0|%k0, %2}";
6014 return "add{l}\t{%2, %k0|%k0, %2}";
6018 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set (attr "length_immediate")
6023 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6025 (const_string "*")))
6026 (set_attr "mode" "SI")])
6028 ; For comparisons against 1, -1 and 128, we may generate better code
6029 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6030 ; is matched then. We can't accept general immediate, because for
6031 ; case of overflows, the result is messed up.
6032 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6033 ; only for comparisons not depending on it.
6035 (define_insn "*adddi_4"
6036 [(set (reg FLAGS_REG)
6038 (match_operand:DI 1 "nonimmediate_operand" "0")
6039 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6040 (clobber (match_scratch:DI 0 "=rm"))]
6042 && ix86_match_ccmode (insn, CCGCmode)"
6044 switch (get_attr_type (insn))
6047 if (operands[2] == constm1_rtx)
6048 return "inc{q}\t%0";
6051 gcc_assert (operands[2] == const1_rtx);
6052 return "dec{q}\t%0";
6056 if (x86_maybe_negate_const_int (&operands[2], DImode))
6057 return "add{q}\t{%2, %0|%0, %2}";
6059 return "sub{q}\t{%2, %0|%0, %2}";
6063 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set (attr "length_immediate")
6068 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6070 (const_string "*")))
6071 (set_attr "mode" "DI")])
6073 ; For comparisons against 1, -1 and 128, we may generate better code
6074 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6075 ; is matched then. We can't accept general immediate, because for
6076 ; case of overflows, the result is messed up.
6077 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6078 ; only for comparisons not depending on it.
6080 (define_insn "*add<mode>_4"
6081 [(set (reg FLAGS_REG)
6083 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6084 (match_operand:SWI124 2 "const_int_operand" "n")))
6085 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6086 "ix86_match_ccmode (insn, CCGCmode)"
6088 switch (get_attr_type (insn))
6091 if (operands[2] == constm1_rtx)
6092 return "inc{<imodesuffix>}\t%0";
6095 gcc_assert (operands[2] == const1_rtx);
6096 return "dec{<imodesuffix>}\t%0";
6100 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6101 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6103 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6107 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu")))
6110 (set (attr "length_immediate")
6112 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6114 (const_string "*")))
6115 (set_attr "mode" "<MODE>")])
6117 (define_insn "*add<mode>_5"
6118 [(set (reg FLAGS_REG)
6121 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6122 (match_operand:SWI 2 "<general_operand>" "<g>"))
6124 (clobber (match_scratch:SWI 0 "=<r>"))]
6125 "ix86_match_ccmode (insn, CCGOCmode)
6126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6128 switch (get_attr_type (insn))
6131 if (operands[2] == const1_rtx)
6132 return "inc{<imodesuffix>}\t%0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{<imodesuffix>}\t%0";
6140 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6141 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6143 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6147 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set (attr "length_immediate")
6152 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6154 (const_string "*")))
6155 (set_attr "mode" "<MODE>")])
6157 (define_insn "*addqi_ext_1_rex64"
6158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6163 (match_operand 1 "ext_register_operand" "0")
6166 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6167 (clobber (reg:CC FLAGS_REG))]
6170 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{b}\t%h0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{b}\t%h0";
6182 return "add{b}\t{%2, %h0|%h0, %2}";
6186 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6187 (const_string "incdec")
6188 (const_string "alu")))
6189 (set_attr "modrm" "1")
6190 (set_attr "mode" "QI")])
6192 (define_insn "addqi_ext_1"
6193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6198 (match_operand 1 "ext_register_operand" "0")
6201 (match_operand:QI 2 "general_operand" "Qmn")))
6202 (clobber (reg:CC FLAGS_REG))]
6205 switch (get_attr_type (insn))
6208 if (operands[2] == const1_rtx)
6209 return "inc{b}\t%h0";
6212 gcc_assert (operands[2] == constm1_rtx);
6213 return "dec{b}\t%h0";
6217 return "add{b}\t{%2, %h0|%h0, %2}";
6221 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6222 (const_string "incdec")
6223 (const_string "alu")))
6224 (set_attr "modrm" "1")
6225 (set_attr "mode" "QI")])
6227 (define_insn "*addqi_ext_2"
6228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6233 (match_operand 1 "ext_register_operand" "%0")
6237 (match_operand 2 "ext_register_operand" "Q")
6240 (clobber (reg:CC FLAGS_REG))]
6242 "add{b}\t{%h2, %h0|%h0, %h2}"
6243 [(set_attr "type" "alu")
6244 (set_attr "mode" "QI")])
6246 ;; The lea patterns for modes less than 32 bits need to be matched by
6247 ;; several insns converted to real lea by splitters.
6249 (define_insn_and_split "*lea_general_1"
6250 [(set (match_operand 0 "register_operand" "=r")
6251 (plus (plus (match_operand 1 "index_register_operand" "l")
6252 (match_operand 2 "register_operand" "r"))
6253 (match_operand 3 "immediate_operand" "i")))]
6254 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6255 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6256 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6257 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6258 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6259 || GET_MODE (operands[3]) == VOIDmode)"
6261 "&& reload_completed"
6264 enum machine_mode mode = SImode;
6267 operands[0] = gen_lowpart (mode, operands[0]);
6268 operands[1] = gen_lowpart (mode, operands[1]);
6269 operands[2] = gen_lowpart (mode, operands[2]);
6270 operands[3] = gen_lowpart (mode, operands[3]);
6272 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6278 [(set_attr "type" "lea")
6279 (set_attr "mode" "SI")])
6281 (define_insn_and_split "*lea_general_2"
6282 [(set (match_operand 0 "register_operand" "=r")
6283 (plus (mult (match_operand 1 "index_register_operand" "l")
6284 (match_operand 2 "const248_operand" "n"))
6285 (match_operand 3 "nonmemory_operand" "ri")))]
6286 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6287 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6288 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6289 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6290 || GET_MODE (operands[3]) == VOIDmode)"
6292 "&& reload_completed"
6295 enum machine_mode mode = SImode;
6298 operands[0] = gen_lowpart (mode, operands[0]);
6299 operands[1] = gen_lowpart (mode, operands[1]);
6300 operands[3] = gen_lowpart (mode, operands[3]);
6302 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6308 [(set_attr "type" "lea")
6309 (set_attr "mode" "SI")])
6311 (define_insn_and_split "*lea_general_3"
6312 [(set (match_operand 0 "register_operand" "=r")
6313 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6314 (match_operand 2 "const248_operand" "n"))
6315 (match_operand 3 "register_operand" "r"))
6316 (match_operand 4 "immediate_operand" "i")))]
6317 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6318 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6319 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6320 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6322 "&& reload_completed"
6325 enum machine_mode mode = SImode;
6328 operands[0] = gen_lowpart (mode, operands[0]);
6329 operands[1] = gen_lowpart (mode, operands[1]);
6330 operands[3] = gen_lowpart (mode, operands[3]);
6331 operands[4] = gen_lowpart (mode, operands[4]);
6333 pat = gen_rtx_PLUS (mode,
6335 gen_rtx_MULT (mode, operands[1],
6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6343 [(set_attr "type" "lea")
6344 (set_attr "mode" "SI")])
6346 (define_insn_and_split "*lea_general_4"
6347 [(set (match_operand 0 "register_operand" "=r")
6349 (match_operand 1 "index_register_operand" "l")
6350 (match_operand 2 "const_int_operand" "n"))
6351 (match_operand 3 "const_int_operand" "n")))]
6352 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6354 || GET_MODE (operands[0]) == SImode
6355 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6356 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6357 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6358 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6359 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6361 "&& reload_completed"
6364 enum machine_mode mode = GET_MODE (operands[0]);
6367 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6370 operands[0] = gen_lowpart (mode, operands[0]);
6371 operands[1] = gen_lowpart (mode, operands[1]);
6374 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6376 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6377 INTVAL (operands[3]));
6379 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6382 [(set_attr "type" "lea")
6384 (if_then_else (match_operand:DI 0 "" "")
6386 (const_string "SI")))])
6388 ;; Subtract instructions
6390 (define_expand "sub<mode>3"
6391 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6392 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6393 (match_operand:SDWIM 2 "<general_operand>" "")))]
6395 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6397 (define_insn_and_split "*sub<dwi>3_doubleword"
6398 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6400 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6401 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6406 [(parallel [(set (reg:CC FLAGS_REG)
6407 (compare:CC (match_dup 1) (match_dup 2)))
6409 (minus:DWIH (match_dup 1) (match_dup 2)))])
6410 (parallel [(set (match_dup 3)
6414 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6416 (clobber (reg:CC FLAGS_REG))])]
6417 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6419 (define_insn "*sub<mode>_1"
6420 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6422 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6423 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6426 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6427 [(set_attr "type" "alu")
6428 (set_attr "mode" "<MODE>")])
6430 (define_insn "*subsi_1_zext"
6431 [(set (match_operand:DI 0 "register_operand" "=r")
6433 (minus:SI (match_operand:SI 1 "register_operand" "0")
6434 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6435 (clobber (reg:CC FLAGS_REG))]
6436 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6437 "sub{l}\t{%2, %k0|%k0, %2}"
6438 [(set_attr "type" "alu")
6439 (set_attr "mode" "SI")])
6441 (define_insn "*subqi_1_slp"
6442 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6443 (minus:QI (match_dup 0)
6444 (match_operand:QI 1 "general_operand" "qn,qm")))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6448 "sub{b}\t{%1, %0|%0, %1}"
6449 [(set_attr "type" "alu1")
6450 (set_attr "mode" "QI")])
6452 (define_insn "*sub<mode>_2"
6453 [(set (reg FLAGS_REG)
6456 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6459 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6460 (minus:SWI (match_dup 1) (match_dup 2)))]
6461 "ix86_match_ccmode (insn, CCGOCmode)
6462 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6463 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6464 [(set_attr "type" "alu")
6465 (set_attr "mode" "<MODE>")])
6467 (define_insn "*subsi_2_zext"
6468 [(set (reg FLAGS_REG)
6470 (minus:SI (match_operand:SI 1 "register_operand" "0")
6471 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6473 (set (match_operand:DI 0 "register_operand" "=r")
6475 (minus:SI (match_dup 1)
6477 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6478 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479 "sub{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "SI")])
6483 (define_insn "*sub<mode>_3"
6484 [(set (reg FLAGS_REG)
6485 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6487 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6488 (minus:SWI (match_dup 1) (match_dup 2)))]
6489 "ix86_match_ccmode (insn, CCmode)
6490 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6495 (define_insn "*subsi_3_zext"
6496 [(set (reg FLAGS_REG)
6497 (compare (match_operand:SI 1 "register_operand" "0")
6498 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6499 (set (match_operand:DI 0 "register_operand" "=r")
6501 (minus:SI (match_dup 1)
6503 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6504 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6505 "sub{l}\t{%2, %1|%1, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "SI")])
6509 ;; Add with carry and subtract with borrow
6511 (define_expand "<plusminus_insn><mode>3_carry"
6513 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6515 (match_operand:SWI 1 "nonimmediate_operand" "")
6516 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6517 [(match_operand 3 "flags_reg_operand" "")
6519 (match_operand:SWI 2 "<general_operand>" ""))))
6520 (clobber (reg:CC FLAGS_REG))])]
6521 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6523 (define_insn "*<plusminus_insn><mode>3_carry"
6524 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6526 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6528 (match_operator 3 "ix86_carry_flag_operator"
6529 [(reg FLAGS_REG) (const_int 0)])
6530 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6531 (clobber (reg:CC FLAGS_REG))]
6532 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6533 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6534 [(set_attr "type" "alu")
6535 (set_attr "use_carry" "1")
6536 (set_attr "pent_pair" "pu")
6537 (set_attr "mode" "<MODE>")])
6539 (define_insn "*addsi3_carry_zext"
6540 [(set (match_operand:DI 0 "register_operand" "=r")
6542 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6543 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6544 [(reg FLAGS_REG) (const_int 0)])
6545 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6546 (clobber (reg:CC FLAGS_REG))]
6547 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6548 "adc{l}\t{%2, %k0|%k0, %2}"
6549 [(set_attr "type" "alu")
6550 (set_attr "use_carry" "1")
6551 (set_attr "pent_pair" "pu")
6552 (set_attr "mode" "SI")])
6554 (define_insn "*subsi3_carry_zext"
6555 [(set (match_operand:DI 0 "register_operand" "=r")
6557 (minus:SI (match_operand:SI 1 "register_operand" "0")
6558 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6559 [(reg FLAGS_REG) (const_int 0)])
6560 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6561 (clobber (reg:CC FLAGS_REG))]
6562 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6563 "sbb{l}\t{%2, %k0|%k0, %2}"
6564 [(set_attr "type" "alu")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "SI")])
6568 ;; Overflow setting add and subtract instructions
6570 (define_insn "*add<mode>3_cconly_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6575 (match_operand:SWI 2 "<general_operand>" "<g>"))
6577 (clobber (match_scratch:SWI 0 "=<r>"))]
6578 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6579 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6580 [(set_attr "type" "alu")
6581 (set_attr "mode" "<MODE>")])
6583 (define_insn "*sub<mode>3_cconly_overflow"
6584 [(set (reg:CCC FLAGS_REG)
6587 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6588 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6591 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6592 [(set_attr "type" "icmp")
6593 (set_attr "mode" "<MODE>")])
6595 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6596 [(set (reg:CCC FLAGS_REG)
6599 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6600 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6602 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6603 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6604 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6605 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "mode" "<MODE>")])
6609 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6610 [(set (reg:CCC FLAGS_REG)
6613 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6614 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6616 (set (match_operand:DI 0 "register_operand" "=r")
6617 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6618 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6619 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6620 [(set_attr "type" "alu")
6621 (set_attr "mode" "SI")])
6623 ;; The patterns that match these are at the end of this file.
6625 (define_expand "<plusminus_insn>xf3"
6626 [(set (match_operand:XF 0 "register_operand" "")
6628 (match_operand:XF 1 "register_operand" "")
6629 (match_operand:XF 2 "register_operand" "")))]
6632 (define_expand "<plusminus_insn><mode>3"
6633 [(set (match_operand:MODEF 0 "register_operand" "")
6635 (match_operand:MODEF 1 "register_operand" "")
6636 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6637 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6638 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6640 ;; Multiply instructions
6642 (define_expand "mul<mode>3"
6643 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6645 (match_operand:SWIM248 1 "register_operand" "")
6646 (match_operand:SWIM248 2 "<general_operand>" "")))
6647 (clobber (reg:CC FLAGS_REG))])])
6649 (define_expand "mulqi3"
6650 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6652 (match_operand:QI 1 "register_operand" "")
6653 (match_operand:QI 2 "nonimmediate_operand" "")))
6654 (clobber (reg:CC FLAGS_REG))])]
6655 "TARGET_QIMODE_MATH")
6658 ;; IMUL reg32/64, reg32/64, imm8 Direct
6659 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6660 ;; IMUL reg32/64, reg32/64, imm32 Direct
6661 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6662 ;; IMUL reg32/64, reg32/64 Direct
6663 ;; IMUL reg32/64, mem32/64 Direct
6665 ;; On BDVER1, all above IMULs use DirectPath
6667 (define_insn "*mul<mode>3_1"
6668 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6670 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6671 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6672 (clobber (reg:CC FLAGS_REG))]
6673 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6675 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6676 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6677 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "imul")
6679 (set_attr "prefix_0f" "0,0,1")
6680 (set (attr "athlon_decode")
6681 (cond [(eq_attr "cpu" "athlon")
6682 (const_string "vector")
6683 (eq_attr "alternative" "1")
6684 (const_string "vector")
6685 (and (eq_attr "alternative" "2")
6686 (match_operand 1 "memory_operand" ""))
6687 (const_string "vector")]
6688 (const_string "direct")))
6689 (set (attr "amdfam10_decode")
6690 (cond [(and (eq_attr "alternative" "0,1")
6691 (match_operand 1 "memory_operand" ""))
6692 (const_string "vector")]
6693 (const_string "direct")))
6694 (set_attr "bdver1_decode" "direct")
6695 (set_attr "mode" "<MODE>")])
6697 (define_insn "*mulsi3_1_zext"
6698 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6700 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6701 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6702 (clobber (reg:CC FLAGS_REG))]
6704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6706 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6707 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6708 imul{l}\t{%2, %k0|%k0, %2}"
6709 [(set_attr "type" "imul")
6710 (set_attr "prefix_0f" "0,0,1")
6711 (set (attr "athlon_decode")
6712 (cond [(eq_attr "cpu" "athlon")
6713 (const_string "vector")
6714 (eq_attr "alternative" "1")
6715 (const_string "vector")
6716 (and (eq_attr "alternative" "2")
6717 (match_operand 1 "memory_operand" ""))
6718 (const_string "vector")]
6719 (const_string "direct")))
6720 (set (attr "amdfam10_decode")
6721 (cond [(and (eq_attr "alternative" "0,1")
6722 (match_operand 1 "memory_operand" ""))
6723 (const_string "vector")]
6724 (const_string "direct")))
6725 (set_attr "bdver1_decode" "direct")
6726 (set_attr "mode" "SI")])
6729 ;; IMUL reg16, reg16, imm8 VectorPath
6730 ;; IMUL reg16, mem16, imm8 VectorPath
6731 ;; IMUL reg16, reg16, imm16 VectorPath
6732 ;; IMUL reg16, mem16, imm16 VectorPath
6733 ;; IMUL reg16, reg16 Direct
6734 ;; IMUL reg16, mem16 Direct
6736 ;; On BDVER1, all HI MULs use DoublePath
6738 (define_insn "*mulhi3_1"
6739 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6740 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6741 (match_operand:HI 2 "general_operand" "K,n,mr")))
6742 (clobber (reg:CC FLAGS_REG))]
6744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6746 imul{w}\t{%2, %1, %0|%0, %1, %2}
6747 imul{w}\t{%2, %1, %0|%0, %1, %2}
6748 imul{w}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "imul")
6750 (set_attr "prefix_0f" "0,0,1")
6751 (set (attr "athlon_decode")
6752 (cond [(eq_attr "cpu" "athlon")
6753 (const_string "vector")
6754 (eq_attr "alternative" "1,2")
6755 (const_string "vector")]
6756 (const_string "direct")))
6757 (set (attr "amdfam10_decode")
6758 (cond [(eq_attr "alternative" "0,1")
6759 (const_string "vector")]
6760 (const_string "direct")))
6761 (set_attr "bdver1_decode" "double")
6762 (set_attr "mode" "HI")])
6764 ;;On AMDFAM10 and BDVER1
6768 (define_insn "*mulqi3_1"
6769 [(set (match_operand:QI 0 "register_operand" "=a")
6770 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6771 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6772 (clobber (reg:CC FLAGS_REG))]
6774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776 [(set_attr "type" "imul")
6777 (set_attr "length_immediate" "0")
6778 (set (attr "athlon_decode")
6779 (if_then_else (eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (const_string "direct")))
6782 (set_attr "amdfam10_decode" "direct")
6783 (set_attr "bdver1_decode" "direct")
6784 (set_attr "mode" "QI")])
6786 (define_expand "<u>mul<mode><dwi>3"
6787 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6790 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6792 (match_operand:DWIH 2 "register_operand" ""))))
6793 (clobber (reg:CC FLAGS_REG))])])
6795 (define_expand "<u>mulqihi3"
6796 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6799 (match_operand:QI 1 "nonimmediate_operand" ""))
6801 (match_operand:QI 2 "register_operand" ""))))
6802 (clobber (reg:CC FLAGS_REG))])]
6803 "TARGET_QIMODE_MATH")
6805 (define_insn "*bmi2_umulditi3_1"
6806 [(set (match_operand:DI 0 "register_operand" "=r")
6808 (match_operand:DI 2 "nonimmediate_operand" "%d")
6809 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6810 (set (match_operand:DI 1 "register_operand" "=r")
6813 (mult:TI (zero_extend:TI (match_dup 2))
6814 (zero_extend:TI (match_dup 3)))
6816 "TARGET_64BIT && TARGET_BMI2
6817 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 "mulx\t{%3, %0, %1|%1, %0, %3}"
6819 [(set_attr "type" "imulx")
6820 (set_attr "prefix" "vex")
6821 (set_attr "mode" "DI")])
6823 (define_insn "*bmi2_umulsidi3_1"
6824 [(set (match_operand:SI 0 "register_operand" "=r")
6826 (match_operand:SI 2 "nonimmediate_operand" "%d")
6827 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6828 (set (match_operand:SI 1 "register_operand" "=r")
6831 (mult:DI (zero_extend:DI (match_dup 2))
6832 (zero_extend:DI (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" "SI")])
6841 (define_insn "*umul<mode><dwi>3_1"
6842 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6845 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6847 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6848 (clobber (reg:CC FLAGS_REG))]
6849 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6851 mul{<imodesuffix>}\t%2
6853 [(set_attr "isa" "*,bmi2")
6854 (set_attr "type" "imul,imulx")
6855 (set_attr "length_immediate" "0,*")
6856 (set (attr "athlon_decode")
6857 (cond [(eq_attr "alternative" "0")
6858 (if_then_else (eq_attr "cpu" "athlon")
6859 (const_string "vector")
6860 (const_string "double"))]
6861 (const_string "*")))
6862 (set_attr "amdfam10_decode" "double,*")
6863 (set_attr "bdver1_decode" "direct,*")
6864 (set_attr "prefix" "orig,vex")
6865 (set_attr "mode" "<MODE>")])
6867 ;; Convert mul to the mulx pattern to avoid flags dependency.
6869 [(set (match_operand:<DWI> 0 "register_operand" "")
6872 (match_operand:DWIH 1 "register_operand" ""))
6874 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6875 (clobber (reg:CC FLAGS_REG))]
6876 "TARGET_BMI2 && reload_completed
6877 && true_regnum (operands[1]) == DX_REG"
6878 [(parallel [(set (match_dup 3)
6879 (mult:DWIH (match_dup 1) (match_dup 2)))
6883 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6884 (zero_extend:<DWI> (match_dup 2)))
6887 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6889 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6892 (define_insn "*mul<mode><dwi>3_1"
6893 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6896 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6898 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "imul{<imodesuffix>}\t%2"
6902 [(set_attr "type" "imul")
6903 (set_attr "length_immediate" "0")
6904 (set (attr "athlon_decode")
6905 (if_then_else (eq_attr "cpu" "athlon")
6906 (const_string "vector")
6907 (const_string "double")))
6908 (set_attr "amdfam10_decode" "double")
6909 (set_attr "bdver1_decode" "direct")
6910 (set_attr "mode" "<MODE>")])
6912 (define_insn "*<u>mulqihi3_1"
6913 [(set (match_operand:HI 0 "register_operand" "=a")
6916 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6918 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6919 (clobber (reg:CC FLAGS_REG))]
6921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6922 "<sgnprefix>mul{b}\t%2"
6923 [(set_attr "type" "imul")
6924 (set_attr "length_immediate" "0")
6925 (set (attr "athlon_decode")
6926 (if_then_else (eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (const_string "direct")))
6929 (set_attr "amdfam10_decode" "direct")
6930 (set_attr "bdver1_decode" "direct")
6931 (set_attr "mode" "QI")])
6933 (define_expand "<s>mul<mode>3_highpart"
6934 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6939 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6941 (match_operand:SWI48 2 "register_operand" "")))
6943 (clobber (match_scratch:SWI48 3 ""))
6944 (clobber (reg:CC FLAGS_REG))])]
6946 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6948 (define_insn "*<s>muldi3_highpart_1"
6949 [(set (match_operand:DI 0 "register_operand" "=d")
6954 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6956 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6958 (clobber (match_scratch:DI 3 "=1"))
6959 (clobber (reg:CC FLAGS_REG))]
6961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 "<sgnprefix>mul{q}\t%2"
6963 [(set_attr "type" "imul")
6964 (set_attr "length_immediate" "0")
6965 (set (attr "athlon_decode")
6966 (if_then_else (eq_attr "cpu" "athlon")
6967 (const_string "vector")
6968 (const_string "double")))
6969 (set_attr "amdfam10_decode" "double")
6970 (set_attr "bdver1_decode" "direct")
6971 (set_attr "mode" "DI")])
6973 (define_insn "*<s>mulsi3_highpart_1"
6974 [(set (match_operand:SI 0 "register_operand" "=d")
6979 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6981 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6983 (clobber (match_scratch:SI 3 "=1"))
6984 (clobber (reg:CC FLAGS_REG))]
6985 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6986 "<sgnprefix>mul{l}\t%2"
6987 [(set_attr "type" "imul")
6988 (set_attr "length_immediate" "0")
6989 (set (attr "athlon_decode")
6990 (if_then_else (eq_attr "cpu" "athlon")
6991 (const_string "vector")
6992 (const_string "double")))
6993 (set_attr "amdfam10_decode" "double")
6994 (set_attr "bdver1_decode" "direct")
6995 (set_attr "mode" "SI")])
6997 (define_insn "*<s>mulsi3_highpart_zext"
6998 [(set (match_operand:DI 0 "register_operand" "=d")
6999 (zero_extend:DI (truncate:SI
7001 (mult:DI (any_extend:DI
7002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7006 (clobber (match_scratch:SI 3 "=1"))
7007 (clobber (reg:CC FLAGS_REG))]
7009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7010 "<sgnprefix>mul{l}\t%2"
7011 [(set_attr "type" "imul")
7012 (set_attr "length_immediate" "0")
7013 (set (attr "athlon_decode")
7014 (if_then_else (eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (const_string "double")))
7017 (set_attr "amdfam10_decode" "double")
7018 (set_attr "bdver1_decode" "direct")
7019 (set_attr "mode" "SI")])
7021 ;; The patterns that match these are at the end of this file.
7023 (define_expand "mulxf3"
7024 [(set (match_operand:XF 0 "register_operand" "")
7025 (mult:XF (match_operand:XF 1 "register_operand" "")
7026 (match_operand:XF 2 "register_operand" "")))]
7029 (define_expand "mul<mode>3"
7030 [(set (match_operand:MODEF 0 "register_operand" "")
7031 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7032 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7033 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7034 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7036 ;; Divide instructions
7038 ;; The patterns that match these are at the end of this file.
7040 (define_expand "divxf3"
7041 [(set (match_operand:XF 0 "register_operand" "")
7042 (div:XF (match_operand:XF 1 "register_operand" "")
7043 (match_operand:XF 2 "register_operand" "")))]
7046 (define_expand "divdf3"
7047 [(set (match_operand:DF 0 "register_operand" "")
7048 (div:DF (match_operand:DF 1 "register_operand" "")
7049 (match_operand:DF 2 "nonimmediate_operand" "")))]
7050 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7051 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7053 (define_expand "divsf3"
7054 [(set (match_operand:SF 0 "register_operand" "")
7055 (div:SF (match_operand:SF 1 "register_operand" "")
7056 (match_operand:SF 2 "nonimmediate_operand" "")))]
7057 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7062 && optimize_insn_for_speed_p ()
7063 && flag_finite_math_only && !flag_trapping_math
7064 && flag_unsafe_math_optimizations)
7066 ix86_emit_swdivsf (operands[0], operands[1],
7067 operands[2], SFmode);
7072 ;; Divmod instructions.
7074 (define_expand "divmod<mode>4"
7075 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7077 (match_operand:SWIM248 1 "register_operand" "")
7078 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7079 (set (match_operand:SWIM248 3 "register_operand" "")
7080 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7081 (clobber (reg:CC FLAGS_REG))])])
7083 ;; Split with 8bit unsigned divide:
7084 ;; if (dividend an divisor are in [0-255])
7085 ;; use 8bit unsigned integer divide
7087 ;; use original integer divide
7089 [(set (match_operand:SWI48 0 "register_operand" "")
7090 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7091 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7092 (set (match_operand:SWI48 1 "register_operand" "")
7093 (mod:SWI48 (match_dup 2) (match_dup 3)))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "TARGET_USE_8BIT_IDIV
7096 && TARGET_QIMODE_MATH
7097 && can_create_pseudo_p ()
7098 && !optimize_insn_for_size_p ()"
7100 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7102 (define_insn_and_split "divmod<mode>4_1"
7103 [(set (match_operand:SWI48 0 "register_operand" "=a")
7104 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7105 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7106 (set (match_operand:SWI48 1 "register_operand" "=&d")
7107 (mod:SWI48 (match_dup 2) (match_dup 3)))
7108 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7109 (clobber (reg:CC FLAGS_REG))]
7113 [(parallel [(set (match_dup 1)
7114 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7115 (clobber (reg:CC FLAGS_REG))])
7116 (parallel [(set (match_dup 0)
7117 (div:SWI48 (match_dup 2) (match_dup 3)))
7119 (mod:SWI48 (match_dup 2) (match_dup 3)))
7121 (clobber (reg:CC FLAGS_REG))])]
7123 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7125 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7126 operands[4] = operands[2];
7129 /* Avoid use of cltd in favor of a mov+shift. */
7130 emit_move_insn (operands[1], operands[2]);
7131 operands[4] = operands[1];
7134 [(set_attr "type" "multi")
7135 (set_attr "mode" "<MODE>")])
7137 (define_insn_and_split "*divmod<mode>4"
7138 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7139 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7140 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7141 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7142 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))]
7147 [(parallel [(set (match_dup 1)
7148 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7149 (clobber (reg:CC FLAGS_REG))])
7150 (parallel [(set (match_dup 0)
7151 (div:SWIM248 (match_dup 2) (match_dup 3)))
7153 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7155 (clobber (reg:CC FLAGS_REG))])]
7157 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7159 if (<MODE>mode != HImode
7160 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7161 operands[4] = operands[2];
7164 /* Avoid use of cltd in favor of a mov+shift. */
7165 emit_move_insn (operands[1], operands[2]);
7166 operands[4] = operands[1];
7169 [(set_attr "type" "multi")
7170 (set_attr "mode" "<MODE>")])
7172 (define_insn "*divmod<mode>4_noext"
7173 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7174 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7175 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7176 (set (match_operand:SWIM248 1 "register_operand" "=d")
7177 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7178 (use (match_operand:SWIM248 4 "register_operand" "1"))
7179 (clobber (reg:CC FLAGS_REG))]
7181 "idiv{<imodesuffix>}\t%3"
7182 [(set_attr "type" "idiv")
7183 (set_attr "mode" "<MODE>")])
7185 (define_expand "divmodqi4"
7186 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7188 (match_operand:QI 1 "register_operand" "")
7189 (match_operand:QI 2 "nonimmediate_operand" "")))
7190 (set (match_operand:QI 3 "register_operand" "")
7191 (mod:QI (match_dup 1) (match_dup 2)))
7192 (clobber (reg:CC FLAGS_REG))])]
7193 "TARGET_QIMODE_MATH"
7198 tmp0 = gen_reg_rtx (HImode);
7199 tmp1 = gen_reg_rtx (HImode);
7201 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7203 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7204 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7206 /* Extract remainder from AH. */
7207 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7208 insn = emit_move_insn (operands[3], tmp1);
7210 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7211 set_unique_reg_note (insn, REG_EQUAL, mod);
7213 /* Extract quotient from AL. */
7214 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7216 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7217 set_unique_reg_note (insn, REG_EQUAL, div);
7222 ;; Divide AX by r/m8, with result stored in
7225 ;; Change div/mod to HImode and extend the second argument to HImode
7226 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7227 ;; combine may fail.
7228 (define_insn "divmodhiqi3"
7229 [(set (match_operand:HI 0 "register_operand" "=a")
7234 (mod:HI (match_operand:HI 1 "register_operand" "0")
7236 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7240 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7241 (clobber (reg:CC FLAGS_REG))]
7242 "TARGET_QIMODE_MATH"
7244 [(set_attr "type" "idiv")
7245 (set_attr "mode" "QI")])
7247 (define_expand "udivmod<mode>4"
7248 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7250 (match_operand:SWIM248 1 "register_operand" "")
7251 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7252 (set (match_operand:SWIM248 3 "register_operand" "")
7253 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7254 (clobber (reg:CC FLAGS_REG))])])
7256 ;; Split with 8bit unsigned divide:
7257 ;; if (dividend an divisor are in [0-255])
7258 ;; use 8bit unsigned integer divide
7260 ;; use original integer divide
7262 [(set (match_operand:SWI48 0 "register_operand" "")
7263 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7264 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7265 (set (match_operand:SWI48 1 "register_operand" "")
7266 (umod:SWI48 (match_dup 2) (match_dup 3)))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "TARGET_USE_8BIT_IDIV
7269 && TARGET_QIMODE_MATH
7270 && can_create_pseudo_p ()
7271 && !optimize_insn_for_size_p ()"
7273 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7275 (define_insn_and_split "udivmod<mode>4_1"
7276 [(set (match_operand:SWI48 0 "register_operand" "=a")
7277 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7278 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWI48 1 "register_operand" "=&d")
7280 (umod:SWI48 (match_dup 2) (match_dup 3)))
7281 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7282 (clobber (reg:CC FLAGS_REG))]
7286 [(set (match_dup 1) (const_int 0))
7287 (parallel [(set (match_dup 0)
7288 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7290 (umod:SWI48 (match_dup 2) (match_dup 3)))
7292 (clobber (reg:CC FLAGS_REG))])]
7294 [(set_attr "type" "multi")
7295 (set_attr "mode" "<MODE>")])
7297 (define_insn_and_split "*udivmod<mode>4"
7298 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7302 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (clobber (reg:CC FLAGS_REG))]
7307 [(set (match_dup 1) (const_int 0))
7308 (parallel [(set (match_dup 0)
7309 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7311 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7313 (clobber (reg:CC FLAGS_REG))])]
7315 [(set_attr "type" "multi")
7316 (set_attr "mode" "<MODE>")])
7318 (define_insn "*udivmod<mode>4_noext"
7319 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7320 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7321 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7322 (set (match_operand:SWIM248 1 "register_operand" "=d")
7323 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7324 (use (match_operand:SWIM248 4 "register_operand" "1"))
7325 (clobber (reg:CC FLAGS_REG))]
7327 "div{<imodesuffix>}\t%3"
7328 [(set_attr "type" "idiv")
7329 (set_attr "mode" "<MODE>")])
7331 (define_expand "udivmodqi4"
7332 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7334 (match_operand:QI 1 "register_operand" "")
7335 (match_operand:QI 2 "nonimmediate_operand" "")))
7336 (set (match_operand:QI 3 "register_operand" "")
7337 (umod:QI (match_dup 1) (match_dup 2)))
7338 (clobber (reg:CC FLAGS_REG))])]
7339 "TARGET_QIMODE_MATH"
7344 tmp0 = gen_reg_rtx (HImode);
7345 tmp1 = gen_reg_rtx (HImode);
7347 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7349 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7350 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7352 /* Extract remainder from AH. */
7353 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7354 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7355 insn = emit_move_insn (operands[3], tmp1);
7357 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7358 set_unique_reg_note (insn, REG_EQUAL, mod);
7360 /* Extract quotient from AL. */
7361 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7363 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7364 set_unique_reg_note (insn, REG_EQUAL, div);
7369 (define_insn "udivmodhiqi3"
7370 [(set (match_operand:HI 0 "register_operand" "=a")
7375 (mod:HI (match_operand:HI 1 "register_operand" "0")
7377 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7381 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7382 (clobber (reg:CC FLAGS_REG))]
7383 "TARGET_QIMODE_MATH"
7385 [(set_attr "type" "idiv")
7386 (set_attr "mode" "QI")])
7388 ;; We cannot use div/idiv for double division, because it causes
7389 ;; "division by zero" on the overflow and that's not what we expect
7390 ;; from truncate. Because true (non truncating) double division is
7391 ;; never generated, we can't create this insn anyway.
7394 ; [(set (match_operand:SI 0 "register_operand" "=a")
7396 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7398 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7399 ; (set (match_operand:SI 3 "register_operand" "=d")
7401 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7402 ; (clobber (reg:CC FLAGS_REG))]
7404 ; "div{l}\t{%2, %0|%0, %2}"
7405 ; [(set_attr "type" "idiv")])
7407 ;;- Logical AND instructions
7409 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7410 ;; Note that this excludes ah.
7412 (define_expand "testsi_ccno_1"
7413 [(set (reg:CCNO FLAGS_REG)
7415 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7416 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7419 (define_expand "testqi_ccz_1"
7420 [(set (reg:CCZ FLAGS_REG)
7421 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7422 (match_operand:QI 1 "nonmemory_operand" ""))
7425 (define_expand "testdi_ccno_1"
7426 [(set (reg:CCNO FLAGS_REG)
7428 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7429 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7431 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7433 (define_insn "*testdi_1"
7434 [(set (reg FLAGS_REG)
7437 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7438 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7440 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443 test{l}\t{%k1, %k0|%k0, %k1}
7444 test{l}\t{%k1, %k0|%k0, %k1}
7445 test{q}\t{%1, %0|%0, %1}
7446 test{q}\t{%1, %0|%0, %1}
7447 test{q}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,0,1,1")
7450 (set_attr "mode" "SI,SI,DI,DI,DI")])
7452 (define_insn "*testqi_1_maybe_si"
7453 [(set (reg FLAGS_REG)
7456 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7457 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7459 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7460 && ix86_match_ccmode (insn,
7461 CONST_INT_P (operands[1])
7462 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7464 if (which_alternative == 3)
7466 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7467 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7468 return "test{l}\t{%1, %k0|%k0, %1}";
7470 return "test{b}\t{%1, %0|%0, %1}";
7472 [(set_attr "type" "test")
7473 (set_attr "modrm" "0,1,1,1")
7474 (set_attr "mode" "QI,QI,QI,SI")
7475 (set_attr "pent_pair" "uv,np,uv,np")])
7477 (define_insn "*test<mode>_1"
7478 [(set (reg FLAGS_REG)
7481 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7482 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7484 "ix86_match_ccmode (insn, CCNOmode)
7485 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7486 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "modrm" "0,1,1")
7489 (set_attr "mode" "<MODE>")
7490 (set_attr "pent_pair" "uv,np,uv")])
7492 (define_expand "testqi_ext_ccno_0"
7493 [(set (reg:CCNO FLAGS_REG)
7497 (match_operand 0 "ext_register_operand" "")
7500 (match_operand 1 "const_int_operand" ""))
7503 (define_insn "*testqi_ext_0"
7504 [(set (reg FLAGS_REG)
7508 (match_operand 0 "ext_register_operand" "Q")
7511 (match_operand 1 "const_int_operand" "n"))
7513 "ix86_match_ccmode (insn, CCNOmode)"
7514 "test{b}\t{%1, %h0|%h0, %1}"
7515 [(set_attr "type" "test")
7516 (set_attr "mode" "QI")
7517 (set_attr "length_immediate" "1")
7518 (set_attr "modrm" "1")
7519 (set_attr "pent_pair" "np")])
7521 (define_insn "*testqi_ext_1_rex64"
7522 [(set (reg FLAGS_REG)
7526 (match_operand 0 "ext_register_operand" "Q")
7530 (match_operand:QI 1 "register_operand" "Q")))
7532 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7533 "test{b}\t{%1, %h0|%h0, %1}"
7534 [(set_attr "type" "test")
7535 (set_attr "mode" "QI")])
7537 (define_insn "*testqi_ext_1"
7538 [(set (reg FLAGS_REG)
7542 (match_operand 0 "ext_register_operand" "Q")
7546 (match_operand:QI 1 "general_operand" "Qm")))
7548 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7549 "test{b}\t{%1, %h0|%h0, %1}"
7550 [(set_attr "type" "test")
7551 (set_attr "mode" "QI")])
7553 (define_insn "*testqi_ext_2"
7554 [(set (reg FLAGS_REG)
7558 (match_operand 0 "ext_register_operand" "Q")
7562 (match_operand 1 "ext_register_operand" "Q")
7566 "ix86_match_ccmode (insn, CCNOmode)"
7567 "test{b}\t{%h1, %h0|%h0, %h1}"
7568 [(set_attr "type" "test")
7569 (set_attr "mode" "QI")])
7571 (define_insn "*testqi_ext_3_rex64"
7572 [(set (reg FLAGS_REG)
7573 (compare (zero_extract:DI
7574 (match_operand 0 "nonimmediate_operand" "rm")
7575 (match_operand:DI 1 "const_int_operand" "")
7576 (match_operand:DI 2 "const_int_operand" ""))
7579 && ix86_match_ccmode (insn, CCNOmode)
7580 && INTVAL (operands[1]) > 0
7581 && INTVAL (operands[2]) >= 0
7582 /* Ensure that resulting mask is zero or sign extended operand. */
7583 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7584 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7585 && INTVAL (operands[1]) > 32))
7586 && (GET_MODE (operands[0]) == SImode
7587 || GET_MODE (operands[0]) == DImode
7588 || GET_MODE (operands[0]) == HImode
7589 || GET_MODE (operands[0]) == QImode)"
7592 ;; Combine likes to form bit extractions for some tests. Humor it.
7593 (define_insn "*testqi_ext_3"
7594 [(set (reg FLAGS_REG)
7595 (compare (zero_extract:SI
7596 (match_operand 0 "nonimmediate_operand" "rm")
7597 (match_operand:SI 1 "const_int_operand" "")
7598 (match_operand:SI 2 "const_int_operand" ""))
7600 "ix86_match_ccmode (insn, CCNOmode)
7601 && INTVAL (operands[1]) > 0
7602 && INTVAL (operands[2]) >= 0
7603 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7604 && (GET_MODE (operands[0]) == SImode
7605 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7606 || GET_MODE (operands[0]) == HImode
7607 || GET_MODE (operands[0]) == QImode)"
7611 [(set (match_operand 0 "flags_reg_operand" "")
7612 (match_operator 1 "compare_operator"
7614 (match_operand 2 "nonimmediate_operand" "")
7615 (match_operand 3 "const_int_operand" "")
7616 (match_operand 4 "const_int_operand" ""))
7618 "ix86_match_ccmode (insn, CCNOmode)"
7619 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7621 rtx val = operands[2];
7622 HOST_WIDE_INT len = INTVAL (operands[3]);
7623 HOST_WIDE_INT pos = INTVAL (operands[4]);
7625 enum machine_mode mode, submode;
7627 mode = GET_MODE (val);
7630 /* ??? Combine likes to put non-volatile mem extractions in QImode
7631 no matter the size of the test. So find a mode that works. */
7632 if (! MEM_VOLATILE_P (val))
7634 mode = smallest_mode_for_size (pos + len, MODE_INT);
7635 val = adjust_address (val, mode, 0);
7638 else if (GET_CODE (val) == SUBREG
7639 && (submode = GET_MODE (SUBREG_REG (val)),
7640 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7641 && pos + len <= GET_MODE_BITSIZE (submode)
7642 && GET_MODE_CLASS (submode) == MODE_INT)
7644 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7646 val = SUBREG_REG (val);
7648 else if (mode == HImode && pos + len <= 8)
7650 /* Small HImode tests can be converted to QImode. */
7652 val = gen_lowpart (QImode, val);
7655 if (len == HOST_BITS_PER_WIDE_INT)
7658 mask = ((HOST_WIDE_INT)1 << len) - 1;
7661 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7664 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7665 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7666 ;; this is relatively important trick.
7667 ;; Do the conversion only post-reload to avoid limiting of the register class
7670 [(set (match_operand 0 "flags_reg_operand" "")
7671 (match_operator 1 "compare_operator"
7672 [(and (match_operand 2 "register_operand" "")
7673 (match_operand 3 "const_int_operand" ""))
7676 && QI_REG_P (operands[2])
7677 && GET_MODE (operands[2]) != QImode
7678 && ((ix86_match_ccmode (insn, CCZmode)
7679 && !(INTVAL (operands[3]) & ~(255 << 8)))
7680 || (ix86_match_ccmode (insn, CCNOmode)
7681 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7684 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7687 "operands[2] = gen_lowpart (SImode, operands[2]);
7688 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7691 [(set (match_operand 0 "flags_reg_operand" "")
7692 (match_operator 1 "compare_operator"
7693 [(and (match_operand 2 "nonimmediate_operand" "")
7694 (match_operand 3 "const_int_operand" ""))
7697 && GET_MODE (operands[2]) != QImode
7698 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7699 && ((ix86_match_ccmode (insn, CCZmode)
7700 && !(INTVAL (operands[3]) & ~255))
7701 || (ix86_match_ccmode (insn, CCNOmode)
7702 && !(INTVAL (operands[3]) & ~127)))"
7704 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7706 "operands[2] = gen_lowpart (QImode, operands[2]);
7707 operands[3] = gen_lowpart (QImode, operands[3]);")
7709 ;; %%% This used to optimize known byte-wide and operations to memory,
7710 ;; and sometimes to QImode registers. If this is considered useful,
7711 ;; it should be done with splitters.
7713 (define_expand "and<mode>3"
7714 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7715 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7716 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7718 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7720 (define_insn "*anddi_1"
7721 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7723 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7724 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7725 (clobber (reg:CC FLAGS_REG))]
7726 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7728 switch (get_attr_type (insn))
7732 enum machine_mode mode;
7734 gcc_assert (CONST_INT_P (operands[2]));
7735 if (INTVAL (operands[2]) == 0xff)
7739 gcc_assert (INTVAL (operands[2]) == 0xffff);
7743 operands[1] = gen_lowpart (mode, operands[1]);
7745 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7747 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7751 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7752 if (get_attr_mode (insn) == MODE_SI)
7753 return "and{l}\t{%k2, %k0|%k0, %k2}";
7755 return "and{q}\t{%2, %0|%0, %2}";
7758 [(set_attr "type" "alu,alu,alu,imovx")
7759 (set_attr "length_immediate" "*,*,*,0")
7760 (set (attr "prefix_rex")
7762 (and (eq_attr "type" "imovx")
7763 (and (match_test "INTVAL (operands[2]) == 0xff")
7764 (match_operand 1 "ext_QIreg_operand" "")))
7766 (const_string "*")))
7767 (set_attr "mode" "SI,DI,DI,SI")])
7769 (define_insn "*andsi_1"
7770 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7771 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7772 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "ix86_binary_operator_ok (AND, SImode, operands)"
7776 switch (get_attr_type (insn))
7780 enum machine_mode mode;
7782 gcc_assert (CONST_INT_P (operands[2]));
7783 if (INTVAL (operands[2]) == 0xff)
7787 gcc_assert (INTVAL (operands[2]) == 0xffff);
7791 operands[1] = gen_lowpart (mode, operands[1]);
7793 return "movz{bl|x}\t{%1, %0|%0, %1}";
7795 return "movz{wl|x}\t{%1, %0|%0, %1}";
7799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7800 return "and{l}\t{%2, %0|%0, %2}";
7803 [(set_attr "type" "alu,alu,imovx")
7804 (set (attr "prefix_rex")
7806 (and (eq_attr "type" "imovx")
7807 (and (match_test "INTVAL (operands[2]) == 0xff")
7808 (match_operand 1 "ext_QIreg_operand" "")))
7810 (const_string "*")))
7811 (set_attr "length_immediate" "*,*,0")
7812 (set_attr "mode" "SI")])
7814 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7815 (define_insn "*andsi_1_zext"
7816 [(set (match_operand:DI 0 "register_operand" "=r")
7818 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7819 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7822 "and{l}\t{%2, %k0|%k0, %2}"
7823 [(set_attr "type" "alu")
7824 (set_attr "mode" "SI")])
7826 (define_insn "*andhi_1"
7827 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7828 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7829 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7830 (clobber (reg:CC FLAGS_REG))]
7831 "ix86_binary_operator_ok (AND, HImode, operands)"
7833 switch (get_attr_type (insn))
7836 gcc_assert (CONST_INT_P (operands[2]));
7837 gcc_assert (INTVAL (operands[2]) == 0xff);
7838 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7841 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7843 return "and{w}\t{%2, %0|%0, %2}";
7846 [(set_attr "type" "alu,alu,imovx")
7847 (set_attr "length_immediate" "*,*,0")
7848 (set (attr "prefix_rex")
7850 (and (eq_attr "type" "imovx")
7851 (match_operand 1 "ext_QIreg_operand" ""))
7853 (const_string "*")))
7854 (set_attr "mode" "HI,HI,SI")])
7856 ;; %%% Potential partial reg stall on alternative 2. What to do?
7857 (define_insn "*andqi_1"
7858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7859 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7860 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7861 (clobber (reg:CC FLAGS_REG))]
7862 "ix86_binary_operator_ok (AND, QImode, operands)"
7864 and{b}\t{%2, %0|%0, %2}
7865 and{b}\t{%2, %0|%0, %2}
7866 and{l}\t{%k2, %k0|%k0, %k2}"
7867 [(set_attr "type" "alu")
7868 (set_attr "mode" "QI,QI,SI")])
7870 (define_insn "*andqi_1_slp"
7871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7872 (and:QI (match_dup 0)
7873 (match_operand:QI 1 "general_operand" "qn,qmn")))
7874 (clobber (reg:CC FLAGS_REG))]
7875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7876 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7877 "and{b}\t{%1, %0|%0, %1}"
7878 [(set_attr "type" "alu1")
7879 (set_attr "mode" "QI")])
7882 [(set (match_operand 0 "register_operand" "")
7884 (const_int -65536)))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7887 || optimize_function_for_size_p (cfun)"
7888 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7889 "operands[1] = gen_lowpart (HImode, operands[0]);")
7892 [(set (match_operand 0 "ext_register_operand" "")
7895 (clobber (reg:CC FLAGS_REG))]
7896 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7897 && reload_completed"
7898 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7899 "operands[1] = gen_lowpart (QImode, operands[0]);")
7902 [(set (match_operand 0 "ext_register_operand" "")
7904 (const_int -65281)))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7907 && reload_completed"
7908 [(parallel [(set (zero_extract:SI (match_dup 0)
7912 (zero_extract:SI (match_dup 0)
7915 (zero_extract:SI (match_dup 0)
7918 (clobber (reg:CC FLAGS_REG))])]
7919 "operands[0] = gen_lowpart (SImode, operands[0]);")
7921 (define_insn "*anddi_2"
7922 [(set (reg FLAGS_REG)
7925 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7926 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7928 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7929 (and:DI (match_dup 1) (match_dup 2)))]
7930 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7931 && ix86_binary_operator_ok (AND, DImode, operands)"
7933 and{l}\t{%k2, %k0|%k0, %k2}
7934 and{q}\t{%2, %0|%0, %2}
7935 and{q}\t{%2, %0|%0, %2}"
7936 [(set_attr "type" "alu")
7937 (set_attr "mode" "SI,DI,DI")])
7939 (define_insn "*andqi_2_maybe_si"
7940 [(set (reg FLAGS_REG)
7942 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7943 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7945 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7946 (and:QI (match_dup 1) (match_dup 2)))]
7947 "ix86_binary_operator_ok (AND, QImode, operands)
7948 && ix86_match_ccmode (insn,
7949 CONST_INT_P (operands[2])
7950 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7952 if (which_alternative == 2)
7954 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7955 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7956 return "and{l}\t{%2, %k0|%k0, %2}";
7958 return "and{b}\t{%2, %0|%0, %2}";
7960 [(set_attr "type" "alu")
7961 (set_attr "mode" "QI,QI,SI")])
7963 (define_insn "*and<mode>_2"
7964 [(set (reg FLAGS_REG)
7965 (compare (and:SWI124
7966 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7967 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7969 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7970 (and:SWI124 (match_dup 1) (match_dup 2)))]
7971 "ix86_match_ccmode (insn, CCNOmode)
7972 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7973 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "mode" "<MODE>")])
7977 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7978 (define_insn "*andsi_2_zext"
7979 [(set (reg FLAGS_REG)
7981 (match_operand:SI 1 "nonimmediate_operand" "%0")
7982 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7984 (set (match_operand:DI 0 "register_operand" "=r")
7985 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7986 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7987 && ix86_binary_operator_ok (AND, SImode, operands)"
7988 "and{l}\t{%2, %k0|%k0, %2}"
7989 [(set_attr "type" "alu")
7990 (set_attr "mode" "SI")])
7992 (define_insn "*andqi_2_slp"
7993 [(set (reg FLAGS_REG)
7995 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7996 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7998 (set (strict_low_part (match_dup 0))
7999 (and:QI (match_dup 0) (match_dup 1)))]
8000 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8001 && ix86_match_ccmode (insn, CCNOmode)
8002 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8003 "and{b}\t{%1, %0|%0, %1}"
8004 [(set_attr "type" "alu1")
8005 (set_attr "mode" "QI")])
8007 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8008 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8009 ;; for a QImode operand, which of course failed.
8010 (define_insn "andqi_ext_0"
8011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8016 (match_operand 1 "ext_register_operand" "0")
8019 (match_operand 2 "const_int_operand" "n")))
8020 (clobber (reg:CC FLAGS_REG))]
8022 "and{b}\t{%2, %h0|%h0, %2}"
8023 [(set_attr "type" "alu")
8024 (set_attr "length_immediate" "1")
8025 (set_attr "modrm" "1")
8026 (set_attr "mode" "QI")])
8028 ;; Generated by peephole translating test to and. This shows up
8029 ;; often in fp comparisons.
8030 (define_insn "*andqi_ext_0_cc"
8031 [(set (reg FLAGS_REG)
8035 (match_operand 1 "ext_register_operand" "0")
8038 (match_operand 2 "const_int_operand" "n"))
8040 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8049 "ix86_match_ccmode (insn, CCNOmode)"
8050 "and{b}\t{%2, %h0|%h0, %2}"
8051 [(set_attr "type" "alu")
8052 (set_attr "length_immediate" "1")
8053 (set_attr "modrm" "1")
8054 (set_attr "mode" "QI")])
8056 (define_insn "*andqi_ext_1_rex64"
8057 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8062 (match_operand 1 "ext_register_operand" "0")
8066 (match_operand 2 "ext_register_operand" "Q"))))
8067 (clobber (reg:CC FLAGS_REG))]
8069 "and{b}\t{%2, %h0|%h0, %2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "length_immediate" "0")
8072 (set_attr "mode" "QI")])
8074 (define_insn "*andqi_ext_1"
8075 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8080 (match_operand 1 "ext_register_operand" "0")
8084 (match_operand:QI 2 "general_operand" "Qm"))))
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_2"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8098 (match_operand 1 "ext_register_operand" "%0")
8102 (match_operand 2 "ext_register_operand" "Q")
8105 (clobber (reg:CC FLAGS_REG))]
8107 "and{b}\t{%h2, %h0|%h0, %h2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "length_immediate" "0")
8110 (set_attr "mode" "QI")])
8112 ;; Convert wide AND instructions with immediate operand to shorter QImode
8113 ;; equivalents when possible.
8114 ;; Don't do the splitting with memory operands, since it introduces risk
8115 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8116 ;; for size, but that can (should?) be handled by generic code instead.
8118 [(set (match_operand 0 "register_operand" "")
8119 (and (match_operand 1 "register_operand" "")
8120 (match_operand 2 "const_int_operand" "")))
8121 (clobber (reg:CC FLAGS_REG))]
8123 && QI_REG_P (operands[0])
8124 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8125 && !(~INTVAL (operands[2]) & ~(255 << 8))
8126 && GET_MODE (operands[0]) != QImode"
8127 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8128 (and:SI (zero_extract:SI (match_dup 1)
8129 (const_int 8) (const_int 8))
8131 (clobber (reg:CC FLAGS_REG))])]
8132 "operands[0] = gen_lowpart (SImode, operands[0]);
8133 operands[1] = gen_lowpart (SImode, operands[1]);
8134 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8136 ;; Since AND can be encoded with sign extended immediate, this is only
8137 ;; profitable when 7th bit is not set.
8139 [(set (match_operand 0 "register_operand" "")
8140 (and (match_operand 1 "general_operand" "")
8141 (match_operand 2 "const_int_operand" "")))
8142 (clobber (reg:CC FLAGS_REG))]
8144 && ANY_QI_REG_P (operands[0])
8145 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8146 && !(~INTVAL (operands[2]) & ~255)
8147 && !(INTVAL (operands[2]) & 128)
8148 && GET_MODE (operands[0]) != QImode"
8149 [(parallel [(set (strict_low_part (match_dup 0))
8150 (and:QI (match_dup 1)
8152 (clobber (reg:CC FLAGS_REG))])]
8153 "operands[0] = gen_lowpart (QImode, operands[0]);
8154 operands[1] = gen_lowpart (QImode, operands[1]);
8155 operands[2] = gen_lowpart (QImode, operands[2]);")
8157 ;; Logical inclusive and exclusive OR instructions
8159 ;; %%% This used to optimize known byte-wide and operations to memory.
8160 ;; If this is considered useful, it should be done with splitters.
8162 (define_expand "<code><mode>3"
8163 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8164 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8165 (match_operand:SWIM 2 "<general_operand>" "")))]
8167 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8169 (define_insn "*<code><mode>_1"
8170 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8172 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8173 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8176 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "<MODE>")])
8180 ;; %%% Potential partial reg stall on alternative 2. What to do?
8181 (define_insn "*<code>qi_1"
8182 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8183 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8184 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8188 <logic>{b}\t{%2, %0|%0, %2}
8189 <logic>{b}\t{%2, %0|%0, %2}
8190 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "QI,QI,SI")])
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*<code>si_1_zext"
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8198 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202 "<logic>{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8206 (define_insn "*<code>si_1_zext_imm"
8207 [(set (match_operand:DI 0 "register_operand" "=r")
8209 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8210 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213 "<logic>{l}\t{%2, %k0|%k0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "mode" "SI")])
8217 (define_insn "*<code>qi_1_slp"
8218 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8219 (any_or:QI (match_dup 0)
8220 (match_operand:QI 1 "general_operand" "qmn,qn")))
8221 (clobber (reg:CC FLAGS_REG))]
8222 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8223 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224 "<logic>{b}\t{%1, %0|%0, %1}"
8225 [(set_attr "type" "alu1")
8226 (set_attr "mode" "QI")])
8228 (define_insn "*<code><mode>_2"
8229 [(set (reg FLAGS_REG)
8230 (compare (any_or:SWI
8231 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8232 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8234 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8235 (any_or:SWI (match_dup 1) (match_dup 2)))]
8236 "ix86_match_ccmode (insn, CCNOmode)
8237 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8238 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8239 [(set_attr "type" "alu")
8240 (set_attr "mode" "<MODE>")])
8242 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8243 ;; ??? Special case for immediate operand is missing - it is tricky.
8244 (define_insn "*<code>si_2_zext"
8245 [(set (reg FLAGS_REG)
8246 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8247 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8249 (set (match_operand:DI 0 "register_operand" "=r")
8250 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8251 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8252 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8253 "<logic>{l}\t{%2, %k0|%k0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "SI")])
8257 (define_insn "*<code>si_2_zext_imm"
8258 [(set (reg FLAGS_REG)
8260 (match_operand:SI 1 "nonimmediate_operand" "%0")
8261 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8263 (set (match_operand:DI 0 "register_operand" "=r")
8264 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8265 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8266 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8267 "<logic>{l}\t{%2, %k0|%k0, %2}"
8268 [(set_attr "type" "alu")
8269 (set_attr "mode" "SI")])
8271 (define_insn "*<code>qi_2_slp"
8272 [(set (reg FLAGS_REG)
8273 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8274 (match_operand:QI 1 "general_operand" "qmn,qn"))
8276 (set (strict_low_part (match_dup 0))
8277 (any_or:QI (match_dup 0) (match_dup 1)))]
8278 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8279 && ix86_match_ccmode (insn, CCNOmode)
8280 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8281 "<logic>{b}\t{%1, %0|%0, %1}"
8282 [(set_attr "type" "alu1")
8283 (set_attr "mode" "QI")])
8285 (define_insn "*<code><mode>_3"
8286 [(set (reg FLAGS_REG)
8287 (compare (any_or:SWI
8288 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8289 (match_operand:SWI 2 "<general_operand>" "<g>"))
8291 (clobber (match_scratch:SWI 0 "=<r>"))]
8292 "ix86_match_ccmode (insn, CCNOmode)
8293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8294 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "<MODE>")])
8298 (define_insn "*<code>qi_ext_0"
8299 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8304 (match_operand 1 "ext_register_operand" "0")
8307 (match_operand 2 "const_int_operand" "n")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8310 "<logic>{b}\t{%2, %h0|%h0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "1")
8313 (set_attr "modrm" "1")
8314 (set_attr "mode" "QI")])
8316 (define_insn "*<code>qi_ext_1_rex64"
8317 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8322 (match_operand 1 "ext_register_operand" "0")
8326 (match_operand 2 "ext_register_operand" "Q"))))
8327 (clobber (reg:CC FLAGS_REG))]
8329 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8330 "<logic>{b}\t{%2, %h0|%h0, %2}"
8331 [(set_attr "type" "alu")
8332 (set_attr "length_immediate" "0")
8333 (set_attr "mode" "QI")])
8335 (define_insn "*<code>qi_ext_1"
8336 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8341 (match_operand 1 "ext_register_operand" "0")
8345 (match_operand:QI 2 "general_operand" "Qm"))))
8346 (clobber (reg:CC FLAGS_REG))]
8348 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8349 "<logic>{b}\t{%2, %h0|%h0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "length_immediate" "0")
8352 (set_attr "mode" "QI")])
8354 (define_insn "*<code>qi_ext_2"
8355 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8362 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8365 (clobber (reg:CC FLAGS_REG))]
8366 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8367 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "length_immediate" "0")
8370 (set_attr "mode" "QI")])
8373 [(set (match_operand 0 "register_operand" "")
8374 (any_or (match_operand 1 "register_operand" "")
8375 (match_operand 2 "const_int_operand" "")))
8376 (clobber (reg:CC FLAGS_REG))]
8378 && QI_REG_P (operands[0])
8379 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8380 && !(INTVAL (operands[2]) & ~(255 << 8))
8381 && GET_MODE (operands[0]) != QImode"
8382 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8383 (any_or:SI (zero_extract:SI (match_dup 1)
8384 (const_int 8) (const_int 8))
8386 (clobber (reg:CC FLAGS_REG))])]
8387 "operands[0] = gen_lowpart (SImode, operands[0]);
8388 operands[1] = gen_lowpart (SImode, operands[1]);
8389 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8391 ;; Since OR can be encoded with sign extended immediate, this is only
8392 ;; profitable when 7th bit is set.
8394 [(set (match_operand 0 "register_operand" "")
8395 (any_or (match_operand 1 "general_operand" "")
8396 (match_operand 2 "const_int_operand" "")))
8397 (clobber (reg:CC FLAGS_REG))]
8399 && ANY_QI_REG_P (operands[0])
8400 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8401 && !(INTVAL (operands[2]) & ~255)
8402 && (INTVAL (operands[2]) & 128)
8403 && GET_MODE (operands[0]) != QImode"
8404 [(parallel [(set (strict_low_part (match_dup 0))
8405 (any_or:QI (match_dup 1)
8407 (clobber (reg:CC FLAGS_REG))])]
8408 "operands[0] = gen_lowpart (QImode, operands[0]);
8409 operands[1] = gen_lowpart (QImode, operands[1]);
8410 operands[2] = gen_lowpart (QImode, operands[2]);")
8412 (define_expand "xorqi_cc_ext_1"
8414 (set (reg:CCNO FLAGS_REG)
8418 (match_operand 1 "ext_register_operand" "")
8421 (match_operand:QI 2 "general_operand" ""))
8423 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8433 (define_insn "*xorqi_cc_ext_1_rex64"
8434 [(set (reg FLAGS_REG)
8438 (match_operand 1 "ext_register_operand" "0")
8441 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8443 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8453 "xor{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "modrm" "1")
8456 (set_attr "mode" "QI")])
8458 (define_insn "*xorqi_cc_ext_1"
8459 [(set (reg FLAGS_REG)
8463 (match_operand 1 "ext_register_operand" "0")
8466 (match_operand:QI 2 "general_operand" "qmn"))
8468 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8477 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8478 "xor{b}\t{%2, %h0|%h0, %2}"
8479 [(set_attr "type" "alu")
8480 (set_attr "modrm" "1")
8481 (set_attr "mode" "QI")])
8483 ;; Negation instructions
8485 (define_expand "neg<mode>2"
8486 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8487 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8489 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8491 (define_insn_and_split "*neg<dwi>2_doubleword"
8492 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8493 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8499 [(set (reg:CCZ FLAGS_REG)
8500 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8501 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8504 (plus:DWIH (match_dup 3)
8505 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8507 (clobber (reg:CC FLAGS_REG))])
8510 (neg:DWIH (match_dup 2)))
8511 (clobber (reg:CC FLAGS_REG))])]
8512 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8514 (define_insn "*neg<mode>2_1"
8515 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8516 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8519 "neg{<imodesuffix>}\t%0"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "<MODE>")])
8523 ;; Combine is quite creative about this pattern.
8524 (define_insn "*negsi2_1_zext"
8525 [(set (match_operand:DI 0 "register_operand" "=r")
8527 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8530 (clobber (reg:CC FLAGS_REG))]
8531 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8533 [(set_attr "type" "negnot")
8534 (set_attr "mode" "SI")])
8536 ;; The problem with neg is that it does not perform (compare x 0),
8537 ;; it really performs (compare 0 x), which leaves us with the zero
8538 ;; flag being the only useful item.
8540 (define_insn "*neg<mode>2_cmpz"
8541 [(set (reg:CCZ FLAGS_REG)
8543 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8545 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8546 (neg:SWI (match_dup 1)))]
8547 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8548 "neg{<imodesuffix>}\t%0"
8549 [(set_attr "type" "negnot")
8550 (set_attr "mode" "<MODE>")])
8552 (define_insn "*negsi2_cmpz_zext"
8553 [(set (reg:CCZ FLAGS_REG)
8557 (match_operand:DI 1 "register_operand" "0")
8561 (set (match_operand:DI 0 "register_operand" "=r")
8562 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8565 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8567 [(set_attr "type" "negnot")
8568 (set_attr "mode" "SI")])
8570 ;; Changing of sign for FP values is doable using integer unit too.
8572 (define_expand "<code><mode>2"
8573 [(set (match_operand:X87MODEF 0 "register_operand" "")
8574 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8575 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8576 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8578 (define_insn "*absneg<mode>2_mixed"
8579 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8580 (match_operator:MODEF 3 "absneg_operator"
8581 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8582 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8587 (define_insn "*absneg<mode>2_sse"
8588 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8589 (match_operator:MODEF 3 "absneg_operator"
8590 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8591 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8592 (clobber (reg:CC FLAGS_REG))]
8593 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8596 (define_insn "*absneg<mode>2_i387"
8597 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8598 (match_operator:X87MODEF 3 "absneg_operator"
8599 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8600 (use (match_operand 2 "" ""))
8601 (clobber (reg:CC FLAGS_REG))]
8602 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8605 (define_expand "<code>tf2"
8606 [(set (match_operand:TF 0 "register_operand" "")
8607 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8609 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8611 (define_insn "*absnegtf2_sse"
8612 [(set (match_operand:TF 0 "register_operand" "=x,x")
8613 (match_operator:TF 3 "absneg_operator"
8614 [(match_operand:TF 1 "register_operand" "0,x")]))
8615 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8616 (clobber (reg:CC FLAGS_REG))]
8620 ;; Splitters for fp abs and neg.
8623 [(set (match_operand 0 "fp_register_operand" "")
8624 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8625 (use (match_operand 2 "" ""))
8626 (clobber (reg:CC FLAGS_REG))]
8628 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8631 [(set (match_operand 0 "register_operand" "")
8632 (match_operator 3 "absneg_operator"
8633 [(match_operand 1 "register_operand" "")]))
8634 (use (match_operand 2 "nonimmediate_operand" ""))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "reload_completed && SSE_REG_P (operands[0])"
8637 [(set (match_dup 0) (match_dup 3))]
8639 enum machine_mode mode = GET_MODE (operands[0]);
8640 enum machine_mode vmode = GET_MODE (operands[2]);
8643 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8644 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8645 if (operands_match_p (operands[0], operands[2]))
8648 operands[1] = operands[2];
8651 if (GET_CODE (operands[3]) == ABS)
8652 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8654 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8659 [(set (match_operand:SF 0 "register_operand" "")
8660 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8661 (use (match_operand:V4SF 2 "" ""))
8662 (clobber (reg:CC FLAGS_REG))]
8664 [(parallel [(set (match_dup 0) (match_dup 1))
8665 (clobber (reg:CC FLAGS_REG))])]
8668 operands[0] = gen_lowpart (SImode, operands[0]);
8669 if (GET_CODE (operands[1]) == ABS)
8671 tmp = gen_int_mode (0x7fffffff, SImode);
8672 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8676 tmp = gen_int_mode (0x80000000, SImode);
8677 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8683 [(set (match_operand:DF 0 "register_operand" "")
8684 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8685 (use (match_operand 2 "" ""))
8686 (clobber (reg:CC FLAGS_REG))]
8688 [(parallel [(set (match_dup 0) (match_dup 1))
8689 (clobber (reg:CC FLAGS_REG))])]
8694 tmp = gen_lowpart (DImode, operands[0]);
8695 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8698 if (GET_CODE (operands[1]) == ABS)
8701 tmp = gen_rtx_NOT (DImode, tmp);
8705 operands[0] = gen_highpart (SImode, operands[0]);
8706 if (GET_CODE (operands[1]) == ABS)
8708 tmp = gen_int_mode (0x7fffffff, SImode);
8709 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8713 tmp = gen_int_mode (0x80000000, SImode);
8714 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8721 [(set (match_operand:XF 0 "register_operand" "")
8722 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8723 (use (match_operand 2 "" ""))
8724 (clobber (reg:CC FLAGS_REG))]
8726 [(parallel [(set (match_dup 0) (match_dup 1))
8727 (clobber (reg:CC FLAGS_REG))])]
8730 operands[0] = gen_rtx_REG (SImode,
8731 true_regnum (operands[0])
8732 + (TARGET_64BIT ? 1 : 2));
8733 if (GET_CODE (operands[1]) == ABS)
8735 tmp = GEN_INT (0x7fff);
8736 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8740 tmp = GEN_INT (0x8000);
8741 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8746 ;; Conditionalize these after reload. If they match before reload, we
8747 ;; lose the clobber and ability to use integer instructions.
8749 (define_insn "*<code><mode>2_1"
8750 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8751 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8753 && (reload_completed
8754 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8755 "f<absneg_mnemonic>"
8756 [(set_attr "type" "fsgn")
8757 (set_attr "mode" "<MODE>")])
8759 (define_insn "*<code>extendsfdf2"
8760 [(set (match_operand:DF 0 "register_operand" "=f")
8761 (absneg:DF (float_extend:DF
8762 (match_operand:SF 1 "register_operand" "0"))))]
8763 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8764 "f<absneg_mnemonic>"
8765 [(set_attr "type" "fsgn")
8766 (set_attr "mode" "DF")])
8768 (define_insn "*<code>extendsfxf2"
8769 [(set (match_operand:XF 0 "register_operand" "=f")
8770 (absneg:XF (float_extend:XF
8771 (match_operand:SF 1 "register_operand" "0"))))]
8773 "f<absneg_mnemonic>"
8774 [(set_attr "type" "fsgn")
8775 (set_attr "mode" "XF")])
8777 (define_insn "*<code>extenddfxf2"
8778 [(set (match_operand:XF 0 "register_operand" "=f")
8779 (absneg:XF (float_extend:XF
8780 (match_operand:DF 1 "register_operand" "0"))))]
8782 "f<absneg_mnemonic>"
8783 [(set_attr "type" "fsgn")
8784 (set_attr "mode" "XF")])
8786 ;; Copysign instructions
8788 (define_mode_iterator CSGNMODE [SF DF TF])
8789 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8791 (define_expand "copysign<mode>3"
8792 [(match_operand:CSGNMODE 0 "register_operand" "")
8793 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8794 (match_operand:CSGNMODE 2 "register_operand" "")]
8795 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8796 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8797 "ix86_expand_copysign (operands); DONE;")
8799 (define_insn_and_split "copysign<mode>3_const"
8800 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8802 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8803 (match_operand:CSGNMODE 2 "register_operand" "0")
8804 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8806 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8807 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8809 "&& reload_completed"
8811 "ix86_split_copysign_const (operands); DONE;")
8813 (define_insn "copysign<mode>3_var"
8814 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8816 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8817 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8818 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8819 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8821 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8822 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8827 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8829 [(match_operand:CSGNMODE 2 "register_operand" "")
8830 (match_operand:CSGNMODE 3 "register_operand" "")
8831 (match_operand:<CSGNVMODE> 4 "" "")
8832 (match_operand:<CSGNVMODE> 5 "" "")]
8834 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8835 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8836 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8837 && reload_completed"
8839 "ix86_split_copysign_var (operands); DONE;")
8841 ;; One complement instructions
8843 (define_expand "one_cmpl<mode>2"
8844 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8845 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8847 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8849 (define_insn "*one_cmpl<mode>2_1"
8850 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8851 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8852 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8853 "not{<imodesuffix>}\t%0"
8854 [(set_attr "type" "negnot")
8855 (set_attr "mode" "<MODE>")])
8857 ;; %%% Potential partial reg stall on alternative 1. What to do?
8858 (define_insn "*one_cmplqi2_1"
8859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8860 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8861 "ix86_unary_operator_ok (NOT, QImode, operands)"
8865 [(set_attr "type" "negnot")
8866 (set_attr "mode" "QI,SI")])
8868 ;; ??? Currently never generated - xor is used instead.
8869 (define_insn "*one_cmplsi2_1_zext"
8870 [(set (match_operand:DI 0 "register_operand" "=r")
8872 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8873 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8875 [(set_attr "type" "negnot")
8876 (set_attr "mode" "SI")])
8878 (define_insn "*one_cmpl<mode>2_2"
8879 [(set (reg FLAGS_REG)
8880 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8883 (not:SWI (match_dup 1)))]
8884 "ix86_match_ccmode (insn, CCNOmode)
8885 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8887 [(set_attr "type" "alu1")
8888 (set_attr "mode" "<MODE>")])
8891 [(set (match_operand 0 "flags_reg_operand" "")
8892 (match_operator 2 "compare_operator"
8893 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8895 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8896 (not:SWI (match_dup 3)))]
8897 "ix86_match_ccmode (insn, CCNOmode)"
8898 [(parallel [(set (match_dup 0)
8899 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8902 (xor:SWI (match_dup 3) (const_int -1)))])])
8904 ;; ??? Currently never generated - xor is used instead.
8905 (define_insn "*one_cmplsi2_2_zext"
8906 [(set (reg FLAGS_REG)
8907 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8909 (set (match_operand:DI 0 "register_operand" "=r")
8910 (zero_extend:DI (not:SI (match_dup 1))))]
8911 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_unary_operator_ok (NOT, SImode, operands)"
8914 [(set_attr "type" "alu1")
8915 (set_attr "mode" "SI")])
8918 [(set (match_operand 0 "flags_reg_operand" "")
8919 (match_operator 2 "compare_operator"
8920 [(not:SI (match_operand:SI 3 "register_operand" ""))
8922 (set (match_operand:DI 1 "register_operand" "")
8923 (zero_extend:DI (not:SI (match_dup 3))))]
8924 "ix86_match_ccmode (insn, CCNOmode)"
8925 [(parallel [(set (match_dup 0)
8926 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8929 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8931 ;; Shift instructions
8933 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8934 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8935 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8936 ;; from the assembler input.
8938 ;; This instruction shifts the target reg/mem as usual, but instead of
8939 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8940 ;; is a left shift double, bits are taken from the high order bits of
8941 ;; reg, else if the insn is a shift right double, bits are taken from the
8942 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8943 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8945 ;; Since sh[lr]d does not change the `reg' operand, that is done
8946 ;; separately, making all shifts emit pairs of shift double and normal
8947 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8948 ;; support a 63 bit shift, each shift where the count is in a reg expands
8949 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8951 ;; If the shift count is a constant, we need never emit more than one
8952 ;; shift pair, instead using moves and sign extension for counts greater
8955 (define_expand "ashl<mode>3"
8956 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8957 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8958 (match_operand:QI 2 "nonmemory_operand" "")))]
8960 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8962 (define_insn "*ashl<mode>3_doubleword"
8963 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8964 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8965 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8966 (clobber (reg:CC FLAGS_REG))]
8969 [(set_attr "type" "multi")])
8972 [(set (match_operand:DWI 0 "register_operand" "")
8973 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8974 (match_operand:QI 2 "nonmemory_operand" "")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8978 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8980 ;; By default we don't ask for a scratch register, because when DWImode
8981 ;; values are manipulated, registers are already at a premium. But if
8982 ;; we have one handy, we won't turn it away.
8985 [(match_scratch:DWIH 3 "r")
8986 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8988 (match_operand:<DWI> 1 "nonmemory_operand" "")
8989 (match_operand:QI 2 "nonmemory_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))])
8994 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8996 (define_insn "x86_64_shld"
8997 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8998 (ior:DI (ashift:DI (match_dup 0)
8999 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9000 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9001 (minus:QI (const_int 64) (match_dup 2)))))
9002 (clobber (reg:CC FLAGS_REG))]
9004 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9005 [(set_attr "type" "ishift")
9006 (set_attr "prefix_0f" "1")
9007 (set_attr "mode" "DI")
9008 (set_attr "athlon_decode" "vector")
9009 (set_attr "amdfam10_decode" "vector")
9010 (set_attr "bdver1_decode" "vector")])
9012 (define_insn "x86_shld"
9013 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9014 (ior:SI (ashift:SI (match_dup 0)
9015 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9016 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9017 (minus:QI (const_int 32) (match_dup 2)))))
9018 (clobber (reg:CC FLAGS_REG))]
9020 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9021 [(set_attr "type" "ishift")
9022 (set_attr "prefix_0f" "1")
9023 (set_attr "mode" "SI")
9024 (set_attr "pent_pair" "np")
9025 (set_attr "athlon_decode" "vector")
9026 (set_attr "amdfam10_decode" "vector")
9027 (set_attr "bdver1_decode" "vector")])
9029 (define_expand "x86_shift<mode>_adj_1"
9030 [(set (reg:CCZ FLAGS_REG)
9031 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9034 (set (match_operand:SWI48 0 "register_operand" "")
9035 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9036 (match_operand:SWI48 1 "register_operand" "")
9039 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9040 (match_operand:SWI48 3 "register_operand" "r")
9043 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9045 (define_expand "x86_shift<mode>_adj_2"
9046 [(use (match_operand:SWI48 0 "register_operand" ""))
9047 (use (match_operand:SWI48 1 "register_operand" ""))
9048 (use (match_operand:QI 2 "register_operand" ""))]
9051 rtx label = gen_label_rtx ();
9054 emit_insn (gen_testqi_ccz_1 (operands[2],
9055 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9057 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9058 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9059 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9060 gen_rtx_LABEL_REF (VOIDmode, label),
9062 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9063 JUMP_LABEL (tmp) = label;
9065 emit_move_insn (operands[0], operands[1]);
9066 ix86_expand_clear (operands[1]);
9069 LABEL_NUSES (label) = 1;
9074 ;; Avoid useless masking of count operand.
9075 (define_insn_and_split "*ashl<mode>3_mask"
9076 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9078 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9081 (match_operand:SI 2 "nonimmediate_operand" "c")
9082 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9085 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9086 == GET_MODE_BITSIZE (<MODE>mode)-1"
9089 [(parallel [(set (match_dup 0)
9090 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9091 (clobber (reg:CC FLAGS_REG))])]
9093 if (can_create_pseudo_p ())
9094 operands [2] = force_reg (SImode, operands[2]);
9096 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9098 [(set_attr "type" "ishift")
9099 (set_attr "mode" "<MODE>")])
9101 (define_insn "*bmi2_ashl<mode>3_1"
9102 [(set (match_operand:SWI48 0 "register_operand" "=r")
9103 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9104 (match_operand:SWI48 2 "register_operand" "r")))]
9106 "shlx\t{%2, %1, %0|%0, %1, %2}"
9107 [(set_attr "type" "ishiftx")
9108 (set_attr "mode" "<MODE>")])
9110 (define_insn "*ashl<mode>3_1"
9111 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9112 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9113 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9114 (clobber (reg:CC FLAGS_REG))]
9115 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9117 switch (get_attr_type (insn))
9124 gcc_assert (operands[2] == const1_rtx);
9125 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9126 return "add{<imodesuffix>}\t%0, %0";
9129 if (operands[2] == const1_rtx
9130 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9131 return "sal{<imodesuffix>}\t%0";
9133 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9136 [(set_attr "isa" "*,*,bmi2")
9138 (cond [(eq_attr "alternative" "1")
9139 (const_string "lea")
9140 (eq_attr "alternative" "2")
9141 (const_string "ishiftx")
9142 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9143 (match_operand 0 "register_operand" ""))
9144 (match_operand 2 "const1_operand" ""))
9145 (const_string "alu")
9147 (const_string "ishift")))
9148 (set (attr "length_immediate")
9150 (ior (eq_attr "type" "alu")
9151 (and (eq_attr "type" "ishift")
9152 (and (match_operand 2 "const1_operand" "")
9153 (ior (match_test "TARGET_SHIFT1")
9154 (match_test "optimize_function_for_size_p (cfun)")))))
9156 (const_string "*")))
9157 (set_attr "mode" "<MODE>")])
9159 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9161 [(set (match_operand:SWI48 0 "register_operand" "")
9162 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9163 (match_operand:QI 2 "register_operand" "")))
9164 (clobber (reg:CC FLAGS_REG))]
9165 "TARGET_BMI2 && reload_completed"
9167 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9168 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9170 (define_insn "*bmi2_ashlsi3_1_zext"
9171 [(set (match_operand:DI 0 "register_operand" "=r")
9173 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9174 (match_operand:SI 2 "register_operand" "r"))))]
9175 "TARGET_64BIT && TARGET_BMI2"
9176 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9177 [(set_attr "type" "ishiftx")
9178 (set_attr "mode" "SI")])
9180 (define_insn "*ashlsi3_1_zext"
9181 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9183 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9184 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9188 switch (get_attr_type (insn))
9195 gcc_assert (operands[2] == const1_rtx);
9196 return "add{l}\t%k0, %k0";
9199 if (operands[2] == const1_rtx
9200 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9201 return "sal{l}\t%k0";
9203 return "sal{l}\t{%2, %k0|%k0, %2}";
9206 [(set_attr "isa" "*,*,bmi2")
9208 (cond [(eq_attr "alternative" "1")
9209 (const_string "lea")
9210 (eq_attr "alternative" "2")
9211 (const_string "ishiftx")
9212 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9213 (match_operand 2 "const1_operand" ""))
9214 (const_string "alu")
9216 (const_string "ishift")))
9217 (set (attr "length_immediate")
9219 (ior (eq_attr "type" "alu")
9220 (and (eq_attr "type" "ishift")
9221 (and (match_operand 2 "const1_operand" "")
9222 (ior (match_test "TARGET_SHIFT1")
9223 (match_test "optimize_function_for_size_p (cfun)")))))
9225 (const_string "*")))
9226 (set_attr "mode" "SI")])
9228 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9230 [(set (match_operand:DI 0 "register_operand" "")
9232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9233 (match_operand:QI 2 "register_operand" ""))))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9237 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9238 "operands[2] = gen_lowpart (SImode, operands[2]);")
9240 (define_insn "*ashlhi3_1"
9241 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9242 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9243 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9247 switch (get_attr_type (insn))
9253 gcc_assert (operands[2] == const1_rtx);
9254 return "add{w}\t%0, %0";
9257 if (operands[2] == const1_rtx
9258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9259 return "sal{w}\t%0";
9261 return "sal{w}\t{%2, %0|%0, %2}";
9265 (cond [(eq_attr "alternative" "1")
9266 (const_string "lea")
9267 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9268 (match_operand 0 "register_operand" ""))
9269 (match_operand 2 "const1_operand" ""))
9270 (const_string "alu")
9272 (const_string "ishift")))
9273 (set (attr "length_immediate")
9275 (ior (eq_attr "type" "alu")
9276 (and (eq_attr "type" "ishift")
9277 (and (match_operand 2 "const1_operand" "")
9278 (ior (match_test "TARGET_SHIFT1")
9279 (match_test "optimize_function_for_size_p (cfun)")))))
9281 (const_string "*")))
9282 (set_attr "mode" "HI,SI")])
9284 ;; %%% Potential partial reg stall on alternative 1. What to do?
9285 (define_insn "*ashlqi3_1"
9286 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9287 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9288 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9292 switch (get_attr_type (insn))
9298 gcc_assert (operands[2] == const1_rtx);
9299 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9300 return "add{l}\t%k0, %k0";
9302 return "add{b}\t%0, %0";
9305 if (operands[2] == const1_rtx
9306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9308 if (get_attr_mode (insn) == MODE_SI)
9309 return "sal{l}\t%k0";
9311 return "sal{b}\t%0";
9315 if (get_attr_mode (insn) == MODE_SI)
9316 return "sal{l}\t{%2, %k0|%k0, %2}";
9318 return "sal{b}\t{%2, %0|%0, %2}";
9323 (cond [(eq_attr "alternative" "2")
9324 (const_string "lea")
9325 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9326 (match_operand 0 "register_operand" ""))
9327 (match_operand 2 "const1_operand" ""))
9328 (const_string "alu")
9330 (const_string "ishift")))
9331 (set (attr "length_immediate")
9333 (ior (eq_attr "type" "alu")
9334 (and (eq_attr "type" "ishift")
9335 (and (match_operand 2 "const1_operand" "")
9336 (ior (match_test "TARGET_SHIFT1")
9337 (match_test "optimize_function_for_size_p (cfun)")))))
9339 (const_string "*")))
9340 (set_attr "mode" "QI,SI,SI")])
9342 (define_insn "*ashlqi3_1_slp"
9343 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9344 (ashift:QI (match_dup 0)
9345 (match_operand:QI 1 "nonmemory_operand" "cI")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "(optimize_function_for_size_p (cfun)
9348 || !TARGET_PARTIAL_FLAG_REG_STALL
9349 || (operands[1] == const1_rtx
9351 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9353 switch (get_attr_type (insn))
9356 gcc_assert (operands[1] == const1_rtx);
9357 return "add{b}\t%0, %0";
9360 if (operands[1] == const1_rtx
9361 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9362 return "sal{b}\t%0";
9364 return "sal{b}\t{%1, %0|%0, %1}";
9368 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9369 (match_operand 0 "register_operand" ""))
9370 (match_operand 1 "const1_operand" ""))
9371 (const_string "alu")
9373 (const_string "ishift1")))
9374 (set (attr "length_immediate")
9376 (ior (eq_attr "type" "alu")
9377 (and (eq_attr "type" "ishift1")
9378 (and (match_operand 1 "const1_operand" "")
9379 (ior (match_test "TARGET_SHIFT1")
9380 (match_test "optimize_function_for_size_p (cfun)")))))
9382 (const_string "*")))
9383 (set_attr "mode" "QI")])
9385 ;; Convert ashift to the lea pattern to avoid flags dependency.
9387 [(set (match_operand 0 "register_operand" "")
9388 (ashift (match_operand 1 "index_register_operand" "")
9389 (match_operand:QI 2 "const_int_operand" "")))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9393 && true_regnum (operands[0]) != true_regnum (operands[1])"
9396 enum machine_mode mode = GET_MODE (operands[0]);
9399 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9402 operands[0] = gen_lowpart (mode, operands[0]);
9403 operands[1] = gen_lowpart (mode, operands[1]);
9406 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9408 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9410 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9414 ;; Convert ashift to the lea pattern to avoid flags dependency.
9416 [(set (match_operand:DI 0 "register_operand" "")
9418 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9419 (match_operand:QI 2 "const_int_operand" ""))))
9420 (clobber (reg:CC FLAGS_REG))]
9421 "TARGET_64BIT && reload_completed
9422 && true_regnum (operands[0]) != true_regnum (operands[1])"
9424 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9426 operands[1] = gen_lowpart (DImode, operands[1]);
9427 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9430 ;; This pattern can't accept a variable shift count, since shifts by
9431 ;; zero don't affect the flags. We assume that shifts by constant
9432 ;; zero are optimized away.
9433 (define_insn "*ashl<mode>3_cmp"
9434 [(set (reg FLAGS_REG)
9436 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9437 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9439 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9440 (ashift:SWI (match_dup 1) (match_dup 2)))]
9441 "(optimize_function_for_size_p (cfun)
9442 || !TARGET_PARTIAL_FLAG_REG_STALL
9443 || (operands[2] == const1_rtx
9445 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9446 && ix86_match_ccmode (insn, CCGOCmode)
9447 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9449 switch (get_attr_type (insn))
9452 gcc_assert (operands[2] == const1_rtx);
9453 return "add{<imodesuffix>}\t%0, %0";
9456 if (operands[2] == const1_rtx
9457 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9458 return "sal{<imodesuffix>}\t%0";
9460 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9464 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9465 (match_operand 0 "register_operand" ""))
9466 (match_operand 2 "const1_operand" ""))
9467 (const_string "alu")
9469 (const_string "ishift")))
9470 (set (attr "length_immediate")
9472 (ior (eq_attr "type" "alu")
9473 (and (eq_attr "type" "ishift")
9474 (and (match_operand 2 "const1_operand" "")
9475 (ior (match_test "TARGET_SHIFT1")
9476 (match_test "optimize_function_for_size_p (cfun)")))))
9478 (const_string "*")))
9479 (set_attr "mode" "<MODE>")])
9481 (define_insn "*ashlsi3_cmp_zext"
9482 [(set (reg FLAGS_REG)
9484 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9485 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9487 (set (match_operand:DI 0 "register_operand" "=r")
9488 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9490 && (optimize_function_for_size_p (cfun)
9491 || !TARGET_PARTIAL_FLAG_REG_STALL
9492 || (operands[2] == const1_rtx
9494 || TARGET_DOUBLE_WITH_ADD)))
9495 && ix86_match_ccmode (insn, CCGOCmode)
9496 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9498 switch (get_attr_type (insn))
9501 gcc_assert (operands[2] == const1_rtx);
9502 return "add{l}\t%k0, %k0";
9505 if (operands[2] == const1_rtx
9506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9507 return "sal{l}\t%k0";
9509 return "sal{l}\t{%2, %k0|%k0, %2}";
9513 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9514 (match_operand 2 "const1_operand" ""))
9515 (const_string "alu")
9517 (const_string "ishift")))
9518 (set (attr "length_immediate")
9520 (ior (eq_attr "type" "alu")
9521 (and (eq_attr "type" "ishift")
9522 (and (match_operand 2 "const1_operand" "")
9523 (ior (match_test "TARGET_SHIFT1")
9524 (match_test "optimize_function_for_size_p (cfun)")))))
9526 (const_string "*")))
9527 (set_attr "mode" "SI")])
9529 (define_insn "*ashl<mode>3_cconly"
9530 [(set (reg FLAGS_REG)
9532 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9533 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9535 (clobber (match_scratch:SWI 0 "=<r>"))]
9536 "(optimize_function_for_size_p (cfun)
9537 || !TARGET_PARTIAL_FLAG_REG_STALL
9538 || (operands[2] == const1_rtx
9540 || TARGET_DOUBLE_WITH_ADD)))
9541 && ix86_match_ccmode (insn, CCGOCmode)"
9543 switch (get_attr_type (insn))
9546 gcc_assert (operands[2] == const1_rtx);
9547 return "add{<imodesuffix>}\t%0, %0";
9550 if (operands[2] == const1_rtx
9551 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9552 return "sal{<imodesuffix>}\t%0";
9554 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9558 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9559 (match_operand 0 "register_operand" ""))
9560 (match_operand 2 "const1_operand" ""))
9561 (const_string "alu")
9563 (const_string "ishift")))
9564 (set (attr "length_immediate")
9566 (ior (eq_attr "type" "alu")
9567 (and (eq_attr "type" "ishift")
9568 (and (match_operand 2 "const1_operand" "")
9569 (ior (match_test "TARGET_SHIFT1")
9570 (match_test "optimize_function_for_size_p (cfun)")))))
9572 (const_string "*")))
9573 (set_attr "mode" "<MODE>")])
9575 ;; See comment above `ashl<mode>3' about how this works.
9577 (define_expand "<shift_insn><mode>3"
9578 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9579 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9580 (match_operand:QI 2 "nonmemory_operand" "")))]
9582 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9584 ;; Avoid useless masking of count operand.
9585 (define_insn_and_split "*<shift_insn><mode>3_mask"
9586 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9588 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9591 (match_operand:SI 2 "nonimmediate_operand" "c")
9592 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9595 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9596 == GET_MODE_BITSIZE (<MODE>mode)-1"
9599 [(parallel [(set (match_dup 0)
9600 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9601 (clobber (reg:CC FLAGS_REG))])]
9603 if (can_create_pseudo_p ())
9604 operands [2] = force_reg (SImode, operands[2]);
9606 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9608 [(set_attr "type" "ishift")
9609 (set_attr "mode" "<MODE>")])
9611 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9612 [(set (match_operand:DWI 0 "register_operand" "=r")
9613 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9614 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9615 (clobber (reg:CC FLAGS_REG))]
9618 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9620 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9621 [(set_attr "type" "multi")])
9623 ;; By default we don't ask for a scratch register, because when DWImode
9624 ;; values are manipulated, registers are already at a premium. But if
9625 ;; we have one handy, we won't turn it away.
9628 [(match_scratch:DWIH 3 "r")
9629 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9631 (match_operand:<DWI> 1 "register_operand" "")
9632 (match_operand:QI 2 "nonmemory_operand" "")))
9633 (clobber (reg:CC FLAGS_REG))])
9637 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9639 (define_insn "x86_64_shrd"
9640 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9641 (ior:DI (ashiftrt:DI (match_dup 0)
9642 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9643 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9644 (minus:QI (const_int 64) (match_dup 2)))))
9645 (clobber (reg:CC FLAGS_REG))]
9647 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9648 [(set_attr "type" "ishift")
9649 (set_attr "prefix_0f" "1")
9650 (set_attr "mode" "DI")
9651 (set_attr "athlon_decode" "vector")
9652 (set_attr "amdfam10_decode" "vector")
9653 (set_attr "bdver1_decode" "vector")])
9655 (define_insn "x86_shrd"
9656 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9657 (ior:SI (ashiftrt:SI (match_dup 0)
9658 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9659 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9660 (minus:QI (const_int 32) (match_dup 2)))))
9661 (clobber (reg:CC FLAGS_REG))]
9663 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9664 [(set_attr "type" "ishift")
9665 (set_attr "prefix_0f" "1")
9666 (set_attr "mode" "SI")
9667 (set_attr "pent_pair" "np")
9668 (set_attr "athlon_decode" "vector")
9669 (set_attr "amdfam10_decode" "vector")
9670 (set_attr "bdver1_decode" "vector")])
9672 (define_insn "ashrdi3_cvt"
9673 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9674 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9675 (match_operand:QI 2 "const_int_operand" "")))
9676 (clobber (reg:CC FLAGS_REG))]
9677 "TARGET_64BIT && INTVAL (operands[2]) == 63
9678 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9679 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9682 sar{q}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "imovx,ishift")
9684 (set_attr "prefix_0f" "0,*")
9685 (set_attr "length_immediate" "0,*")
9686 (set_attr "modrm" "0,1")
9687 (set_attr "mode" "DI")])
9689 (define_insn "ashrsi3_cvt"
9690 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9691 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9692 (match_operand:QI 2 "const_int_operand" "")))
9693 (clobber (reg:CC FLAGS_REG))]
9694 "INTVAL (operands[2]) == 31
9695 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9696 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9699 sar{l}\t{%2, %0|%0, %2}"
9700 [(set_attr "type" "imovx,ishift")
9701 (set_attr "prefix_0f" "0,*")
9702 (set_attr "length_immediate" "0,*")
9703 (set_attr "modrm" "0,1")
9704 (set_attr "mode" "SI")])
9706 (define_insn "*ashrsi3_cvt_zext"
9707 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9710 (match_operand:QI 2 "const_int_operand" ""))))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "TARGET_64BIT && 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, %k0|%k0, %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_expand "x86_shift<mode>_adj_3"
9725 [(use (match_operand:SWI48 0 "register_operand" ""))
9726 (use (match_operand:SWI48 1 "register_operand" ""))
9727 (use (match_operand:QI 2 "register_operand" ""))]
9730 rtx label = gen_label_rtx ();
9733 emit_insn (gen_testqi_ccz_1 (operands[2],
9734 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9736 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9737 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9738 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9739 gen_rtx_LABEL_REF (VOIDmode, label),
9741 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9742 JUMP_LABEL (tmp) = label;
9744 emit_move_insn (operands[0], operands[1]);
9745 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9746 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9748 LABEL_NUSES (label) = 1;
9753 (define_insn "*bmi2_<shift_insn><mode>3_1"
9754 [(set (match_operand:SWI48 0 "register_operand" "=r")
9755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9756 (match_operand:SWI48 2 "register_operand" "r")))]
9758 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9759 [(set_attr "type" "ishiftx")
9760 (set_attr "mode" "<MODE>")])
9762 (define_insn "*<shift_insn><mode>3_1"
9763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9765 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9766 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9770 switch (get_attr_type (insn))
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shift>{<imodesuffix>}\t%0";
9780 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9783 [(set_attr "isa" "*,bmi2")
9784 (set_attr "type" "ishift,ishiftx")
9785 (set (attr "length_immediate")
9787 (and (match_operand 2 "const1_operand" "")
9788 (ior (match_test "TARGET_SHIFT1")
9789 (match_test "optimize_function_for_size_p (cfun)")))
9791 (const_string "*")))
9792 (set_attr "mode" "<MODE>")])
9794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9796 [(set (match_operand:SWI48 0 "register_operand" "")
9797 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9798 (match_operand:QI 2 "register_operand" "")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_BMI2 && reload_completed"
9802 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9803 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9805 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9806 [(set (match_operand:DI 0 "register_operand" "=r")
9808 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9809 (match_operand:SI 2 "register_operand" "r"))))]
9810 "TARGET_64BIT && TARGET_BMI2"
9811 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9812 [(set_attr "type" "ishiftx")
9813 (set_attr "mode" "SI")])
9815 (define_insn "*<shift_insn>si3_1_zext"
9816 [(set (match_operand:DI 0 "register_operand" "=r,r")
9818 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9819 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9823 switch (get_attr_type (insn))
9829 if (operands[2] == const1_rtx
9830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9831 return "<shift>{l}\t%k0";
9833 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9836 [(set_attr "isa" "*,bmi2")
9837 (set_attr "type" "ishift,ishiftx")
9838 (set (attr "length_immediate")
9840 (and (match_operand 2 "const1_operand" "")
9841 (ior (match_test "TARGET_SHIFT1")
9842 (match_test "optimize_function_for_size_p (cfun)")))
9844 (const_string "*")))
9845 (set_attr "mode" "SI")])
9847 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9849 [(set (match_operand:DI 0 "register_operand" "")
9851 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9852 (match_operand:QI 2 "register_operand" ""))))
9853 (clobber (reg:CC FLAGS_REG))]
9854 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9856 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9857 "operands[2] = gen_lowpart (SImode, operands[2]);")
9859 (define_insn "*<shift_insn><mode>3_1"
9860 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9862 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9863 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9864 (clobber (reg:CC FLAGS_REG))]
9865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shift>{<imodesuffix>}\t%0";
9871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9876 (and (match_operand 2 "const1_operand" "")
9877 (ior (match_test "TARGET_SHIFT1")
9878 (match_test "optimize_function_for_size_p (cfun)")))
9880 (const_string "*")))
9881 (set_attr "mode" "<MODE>")])
9883 (define_insn "*<shift_insn>qi3_1_slp"
9884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9885 (any_shiftrt:QI (match_dup 0)
9886 (match_operand:QI 1 "nonmemory_operand" "cI")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "(optimize_function_for_size_p (cfun)
9889 || !TARGET_PARTIAL_REG_STALL
9890 || (operands[1] == const1_rtx
9893 if (operands[1] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shift>{b}\t%0";
9897 return "<shift>{b}\t{%1, %0|%0, %1}";
9899 [(set_attr "type" "ishift1")
9900 (set (attr "length_immediate")
9902 (and (match_operand 1 "const1_operand" "")
9903 (ior (match_test "TARGET_SHIFT1")
9904 (match_test "optimize_function_for_size_p (cfun)")))
9906 (const_string "*")))
9907 (set_attr "mode" "QI")])
9909 ;; This pattern can't accept a variable shift count, since shifts by
9910 ;; zero don't affect the flags. We assume that shifts by constant
9911 ;; zero are optimized away.
9912 (define_insn "*<shift_insn><mode>3_cmp"
9913 [(set (reg FLAGS_REG)
9916 (match_operand:SWI 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9921 "(optimize_function_for_size_p (cfun)
9922 || !TARGET_PARTIAL_FLAG_REG_STALL
9923 || (operands[2] == const1_rtx
9925 && ix86_match_ccmode (insn, CCGOCmode)
9926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9928 if (operands[2] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930 return "<shift>{<imodesuffix>}\t%0";
9932 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9934 [(set_attr "type" "ishift")
9935 (set (attr "length_immediate")
9937 (and (match_operand 2 "const1_operand" "")
9938 (ior (match_test "TARGET_SHIFT1")
9939 (match_test "optimize_function_for_size_p (cfun)")))
9941 (const_string "*")))
9942 (set_attr "mode" "<MODE>")])
9944 (define_insn "*<shift_insn>si3_cmp_zext"
9945 [(set (reg FLAGS_REG)
9947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9950 (set (match_operand:DI 0 "register_operand" "=r")
9951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9953 && (optimize_function_for_size_p (cfun)
9954 || !TARGET_PARTIAL_FLAG_REG_STALL
9955 || (operands[2] == const1_rtx
9957 && ix86_match_ccmode (insn, CCGOCmode)
9958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "<shift>{l}\t%k0";
9964 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9966 [(set_attr "type" "ishift")
9967 (set (attr "length_immediate")
9969 (and (match_operand 2 "const1_operand" "")
9970 (ior (match_test "TARGET_SHIFT1")
9971 (match_test "optimize_function_for_size_p (cfun)")))
9973 (const_string "*")))
9974 (set_attr "mode" "SI")])
9976 (define_insn "*<shift_insn><mode>3_cconly"
9977 [(set (reg FLAGS_REG)
9980 (match_operand:SWI 1 "register_operand" "0")
9981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9983 (clobber (match_scratch:SWI 0 "=<r>"))]
9984 "(optimize_function_for_size_p (cfun)
9985 || !TARGET_PARTIAL_FLAG_REG_STALL
9986 || (operands[2] == const1_rtx
9988 && ix86_match_ccmode (insn, CCGOCmode)"
9990 if (operands[2] == const1_rtx
9991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9992 return "<shift>{<imodesuffix>}\t%0";
9994 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9996 [(set_attr "type" "ishift")
9997 (set (attr "length_immediate")
9999 (and (match_operand 2 "const1_operand" "")
10000 (ior (match_test "TARGET_SHIFT1")
10001 (match_test "optimize_function_for_size_p (cfun)")))
10003 (const_string "*")))
10004 (set_attr "mode" "<MODE>")])
10006 ;; Rotate instructions
10008 (define_expand "<rotate_insn>ti3"
10009 [(set (match_operand:TI 0 "register_operand" "")
10010 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10011 (match_operand:QI 2 "nonmemory_operand" "")))]
10014 if (const_1_to_63_operand (operands[2], VOIDmode))
10015 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10016 (operands[0], operands[1], operands[2]));
10023 (define_expand "<rotate_insn>di3"
10024 [(set (match_operand:DI 0 "shiftdi_operand" "")
10025 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10026 (match_operand:QI 2 "nonmemory_operand" "")))]
10030 ix86_expand_binary_operator (<CODE>, DImode, operands);
10031 else if (const_1_to_31_operand (operands[2], VOIDmode))
10032 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10033 (operands[0], operands[1], operands[2]));
10040 (define_expand "<rotate_insn><mode>3"
10041 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10042 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10043 (match_operand:QI 2 "nonmemory_operand" "")))]
10045 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10047 ;; Avoid useless masking of count operand.
10048 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10049 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10051 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10054 (match_operand:SI 2 "nonimmediate_operand" "c")
10055 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10056 (clobber (reg:CC FLAGS_REG))]
10057 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10058 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10059 == GET_MODE_BITSIZE (<MODE>mode)-1"
10062 [(parallel [(set (match_dup 0)
10063 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10064 (clobber (reg:CC FLAGS_REG))])]
10066 if (can_create_pseudo_p ())
10067 operands [2] = force_reg (SImode, operands[2]);
10069 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10071 [(set_attr "type" "rotate")
10072 (set_attr "mode" "<MODE>")])
10074 ;; Implement rotation using two double-precision
10075 ;; shift instructions and a scratch register.
10077 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10078 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10079 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10080 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10081 (clobber (reg:CC FLAGS_REG))
10082 (clobber (match_scratch:DWIH 3 "=&r"))]
10086 [(set (match_dup 3) (match_dup 4))
10088 [(set (match_dup 4)
10089 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10090 (lshiftrt:DWIH (match_dup 5)
10091 (minus:QI (match_dup 6) (match_dup 2)))))
10092 (clobber (reg:CC FLAGS_REG))])
10094 [(set (match_dup 5)
10095 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10096 (lshiftrt:DWIH (match_dup 3)
10097 (minus:QI (match_dup 6) (match_dup 2)))))
10098 (clobber (reg:CC FLAGS_REG))])]
10100 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10102 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10105 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10106 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10107 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10108 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10109 (clobber (reg:CC FLAGS_REG))
10110 (clobber (match_scratch:DWIH 3 "=&r"))]
10114 [(set (match_dup 3) (match_dup 4))
10116 [(set (match_dup 4)
10117 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10118 (ashift:DWIH (match_dup 5)
10119 (minus:QI (match_dup 6) (match_dup 2)))))
10120 (clobber (reg:CC FLAGS_REG))])
10122 [(set (match_dup 5)
10123 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10124 (ashift:DWIH (match_dup 3)
10125 (minus:QI (match_dup 6) (match_dup 2)))))
10126 (clobber (reg:CC FLAGS_REG))])]
10128 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10130 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10133 (define_insn "*bmi2_rorx<mode>3_1"
10134 [(set (match_operand:SWI48 0 "register_operand" "=r")
10135 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10136 (match_operand:QI 2 "immediate_operand" "<S>")))]
10138 "rorx\t{%2, %1, %0|%0, %1, %2}"
10139 [(set_attr "type" "rotatex")
10140 (set_attr "mode" "<MODE>")])
10142 (define_insn "*<rotate_insn><mode>3_1"
10143 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10145 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10146 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10150 switch (get_attr_type (insn))
10156 if (operands[2] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158 return "<rotate>{<imodesuffix>}\t%0";
10160 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10163 [(set_attr "isa" "*,bmi2")
10164 (set_attr "type" "rotate,rotatex")
10165 (set (attr "length_immediate")
10167 (and (eq_attr "type" "rotate")
10168 (and (match_operand 2 "const1_operand" "")
10169 (ior (match_test "TARGET_SHIFT1")
10170 (match_test "optimize_function_for_size_p (cfun)"))))
10172 (const_string "*")))
10173 (set_attr "mode" "<MODE>")])
10175 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10177 [(set (match_operand:SWI48 0 "register_operand" "")
10178 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10179 (match_operand:QI 2 "immediate_operand" "")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_BMI2 && reload_completed"
10182 [(set (match_dup 0)
10183 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10186 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10190 [(set (match_operand:SWI48 0 "register_operand" "")
10191 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10192 (match_operand:QI 2 "immediate_operand" "")))
10193 (clobber (reg:CC FLAGS_REG))]
10194 "TARGET_BMI2 && reload_completed"
10195 [(set (match_dup 0)
10196 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10198 (define_insn "*bmi2_rorxsi3_1_zext"
10199 [(set (match_operand:DI 0 "register_operand" "=r")
10201 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10202 (match_operand:QI 2 "immediate_operand" "I"))))]
10203 "TARGET_64BIT && TARGET_BMI2"
10204 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10205 [(set_attr "type" "rotatex")
10206 (set_attr "mode" "SI")])
10208 (define_insn "*<rotate_insn>si3_1_zext"
10209 [(set (match_operand:DI 0 "register_operand" "=r,r")
10211 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10212 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10213 (clobber (reg:CC FLAGS_REG))]
10214 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10216 switch (get_attr_type (insn))
10222 if (operands[2] == const1_rtx
10223 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10224 return "<rotate>{l}\t%k0";
10226 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10229 [(set_attr "isa" "*,bmi2")
10230 (set_attr "type" "rotate,rotatex")
10231 (set (attr "length_immediate")
10233 (and (eq_attr "type" "rotate")
10234 (and (match_operand 2 "const1_operand" "")
10235 (ior (match_test "TARGET_SHIFT1")
10236 (match_test "optimize_function_for_size_p (cfun)"))))
10238 (const_string "*")))
10239 (set_attr "mode" "SI")])
10241 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10243 [(set (match_operand:DI 0 "register_operand" "")
10245 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10246 (match_operand:QI 2 "immediate_operand" ""))))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10249 [(set (match_dup 0)
10250 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10253 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10257 [(set (match_operand:DI 0 "register_operand" "")
10259 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10260 (match_operand:QI 2 "immediate_operand" ""))))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10263 [(set (match_dup 0)
10264 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10266 (define_insn "*<rotate_insn><mode>3_1"
10267 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10268 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10269 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10273 if (operands[2] == const1_rtx
10274 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10275 return "<rotate>{<imodesuffix>}\t%0";
10277 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 [(set_attr "type" "rotate")
10280 (set (attr "length_immediate")
10282 (and (match_operand 2 "const1_operand" "")
10283 (ior (match_test "TARGET_SHIFT1")
10284 (match_test "optimize_function_for_size_p (cfun)")))
10286 (const_string "*")))
10287 (set_attr "mode" "<MODE>")])
10289 (define_insn "*<rotate_insn>qi3_1_slp"
10290 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10291 (any_rotate:QI (match_dup 0)
10292 (match_operand:QI 1 "nonmemory_operand" "cI")))
10293 (clobber (reg:CC FLAGS_REG))]
10294 "(optimize_function_for_size_p (cfun)
10295 || !TARGET_PARTIAL_REG_STALL
10296 || (operands[1] == const1_rtx
10297 && TARGET_SHIFT1))"
10299 if (operands[1] == const1_rtx
10300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10301 return "<rotate>{b}\t%0";
10303 return "<rotate>{b}\t{%1, %0|%0, %1}";
10305 [(set_attr "type" "rotate1")
10306 (set (attr "length_immediate")
10308 (and (match_operand 1 "const1_operand" "")
10309 (ior (match_test "TARGET_SHIFT1")
10310 (match_test "optimize_function_for_size_p (cfun)")))
10312 (const_string "*")))
10313 (set_attr "mode" "QI")])
10316 [(set (match_operand:HI 0 "register_operand" "")
10317 (any_rotate:HI (match_dup 0) (const_int 8)))
10318 (clobber (reg:CC FLAGS_REG))]
10320 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10321 [(parallel [(set (strict_low_part (match_dup 0))
10322 (bswap:HI (match_dup 0)))
10323 (clobber (reg:CC FLAGS_REG))])])
10325 ;; Bit set / bit test instructions
10327 (define_expand "extv"
10328 [(set (match_operand:SI 0 "register_operand" "")
10329 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10330 (match_operand:SI 2 "const8_operand" "")
10331 (match_operand:SI 3 "const8_operand" "")))]
10334 /* Handle extractions from %ah et al. */
10335 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10338 /* From mips.md: extract_bit_field doesn't verify that our source
10339 matches the predicate, so check it again here. */
10340 if (! ext_register_operand (operands[1], VOIDmode))
10344 (define_expand "extzv"
10345 [(set (match_operand:SI 0 "register_operand" "")
10346 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10347 (match_operand:SI 2 "const8_operand" "")
10348 (match_operand:SI 3 "const8_operand" "")))]
10351 /* Handle extractions from %ah et al. */
10352 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10355 /* From mips.md: extract_bit_field doesn't verify that our source
10356 matches the predicate, so check it again here. */
10357 if (! ext_register_operand (operands[1], VOIDmode))
10361 (define_expand "insv"
10362 [(set (zero_extract (match_operand 0 "register_operand" "")
10363 (match_operand 1 "const_int_operand" "")
10364 (match_operand 2 "const_int_operand" ""))
10365 (match_operand 3 "register_operand" ""))]
10368 rtx (*gen_mov_insv_1) (rtx, rtx);
10370 if (ix86_expand_pinsr (operands))
10373 /* Handle insertions to %ah et al. */
10374 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10377 /* From mips.md: insert_bit_field doesn't verify that our source
10378 matches the predicate, so check it again here. */
10379 if (! ext_register_operand (operands[0], VOIDmode))
10382 gen_mov_insv_1 = (TARGET_64BIT
10383 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10385 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10389 ;; %%% bts, btr, btc, bt.
10390 ;; In general these instructions are *slow* when applied to memory,
10391 ;; since they enforce atomic operation. When applied to registers,
10392 ;; it depends on the cpu implementation. They're never faster than
10393 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10394 ;; no point. But in 64-bit, we can't hold the relevant immediates
10395 ;; within the instruction itself, so operating on bits in the high
10396 ;; 32-bits of a register becomes easier.
10398 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10399 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10400 ;; negdf respectively, so they can never be disabled entirely.
10402 (define_insn "*btsq"
10403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405 (match_operand:DI 1 "const_0_to_63_operand" ""))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409 "bts{q}\t{%1, %0|%0, %1}"
10410 [(set_attr "type" "alu1")
10411 (set_attr "prefix_0f" "1")
10412 (set_attr "mode" "DI")])
10414 (define_insn "*btrq"
10415 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10417 (match_operand:DI 1 "const_0_to_63_operand" ""))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10421 "btr{q}\t{%1, %0|%0, %1}"
10422 [(set_attr "type" "alu1")
10423 (set_attr "prefix_0f" "1")
10424 (set_attr "mode" "DI")])
10426 (define_insn "*btcq"
10427 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10429 (match_operand:DI 1 "const_0_to_63_operand" ""))
10430 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10431 (clobber (reg:CC FLAGS_REG))]
10432 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10433 "btc{q}\t{%1, %0|%0, %1}"
10434 [(set_attr "type" "alu1")
10435 (set_attr "prefix_0f" "1")
10436 (set_attr "mode" "DI")])
10438 ;; Allow Nocona to avoid these instructions if a register is available.
10441 [(match_scratch:DI 2 "r")
10442 (parallel [(set (zero_extract:DI
10443 (match_operand:DI 0 "register_operand" "")
10445 (match_operand:DI 1 "const_0_to_63_operand" ""))
10447 (clobber (reg:CC FLAGS_REG))])]
10448 "TARGET_64BIT && !TARGET_USE_BT"
10451 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10454 if (HOST_BITS_PER_WIDE_INT >= 64)
10455 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10456 else if (i < HOST_BITS_PER_WIDE_INT)
10457 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10459 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10461 op1 = immed_double_const (lo, hi, DImode);
10464 emit_move_insn (operands[2], op1);
10468 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10473 [(match_scratch:DI 2 "r")
10474 (parallel [(set (zero_extract:DI
10475 (match_operand:DI 0 "register_operand" "")
10477 (match_operand:DI 1 "const_0_to_63_operand" ""))
10479 (clobber (reg:CC FLAGS_REG))])]
10480 "TARGET_64BIT && !TARGET_USE_BT"
10483 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10486 if (HOST_BITS_PER_WIDE_INT >= 64)
10487 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10488 else if (i < HOST_BITS_PER_WIDE_INT)
10489 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10493 op1 = immed_double_const (~lo, ~hi, DImode);
10496 emit_move_insn (operands[2], op1);
10500 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10505 [(match_scratch:DI 2 "r")
10506 (parallel [(set (zero_extract:DI
10507 (match_operand:DI 0 "register_operand" "")
10509 (match_operand:DI 1 "const_0_to_63_operand" ""))
10510 (not:DI (zero_extract:DI
10511 (match_dup 0) (const_int 1) (match_dup 1))))
10512 (clobber (reg:CC FLAGS_REG))])]
10513 "TARGET_64BIT && !TARGET_USE_BT"
10516 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10519 if (HOST_BITS_PER_WIDE_INT >= 64)
10520 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10521 else if (i < HOST_BITS_PER_WIDE_INT)
10522 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10524 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10526 op1 = immed_double_const (lo, hi, DImode);
10529 emit_move_insn (operands[2], op1);
10533 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10537 (define_insn "*bt<mode>"
10538 [(set (reg:CCC FLAGS_REG)
10540 (zero_extract:SWI48
10541 (match_operand:SWI48 0 "register_operand" "r")
10543 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10545 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10546 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10547 [(set_attr "type" "alu1")
10548 (set_attr "prefix_0f" "1")
10549 (set_attr "mode" "<MODE>")])
10551 ;; Store-flag instructions.
10553 ;; For all sCOND expanders, also expand the compare or test insn that
10554 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10556 (define_insn_and_split "*setcc_di_1"
10557 [(set (match_operand:DI 0 "register_operand" "=q")
10558 (match_operator:DI 1 "ix86_comparison_operator"
10559 [(reg FLAGS_REG) (const_int 0)]))]
10560 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10562 "&& reload_completed"
10563 [(set (match_dup 2) (match_dup 1))
10564 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10566 PUT_MODE (operands[1], QImode);
10567 operands[2] = gen_lowpart (QImode, operands[0]);
10570 (define_insn_and_split "*setcc_si_1_and"
10571 [(set (match_operand:SI 0 "register_operand" "=q")
10572 (match_operator:SI 1 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)]))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "!TARGET_PARTIAL_REG_STALL
10576 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10578 "&& reload_completed"
10579 [(set (match_dup 2) (match_dup 1))
10580 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10581 (clobber (reg:CC FLAGS_REG))])]
10583 PUT_MODE (operands[1], QImode);
10584 operands[2] = gen_lowpart (QImode, operands[0]);
10587 (define_insn_and_split "*setcc_si_1_movzbl"
10588 [(set (match_operand:SI 0 "register_operand" "=q")
10589 (match_operator:SI 1 "ix86_comparison_operator"
10590 [(reg FLAGS_REG) (const_int 0)]))]
10591 "!TARGET_PARTIAL_REG_STALL
10592 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10594 "&& reload_completed"
10595 [(set (match_dup 2) (match_dup 1))
10596 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10598 PUT_MODE (operands[1], QImode);
10599 operands[2] = gen_lowpart (QImode, operands[0]);
10602 (define_insn "*setcc_qi"
10603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10604 (match_operator:QI 1 "ix86_comparison_operator"
10605 [(reg FLAGS_REG) (const_int 0)]))]
10608 [(set_attr "type" "setcc")
10609 (set_attr "mode" "QI")])
10611 (define_insn "*setcc_qi_slp"
10612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10613 (match_operator:QI 1 "ix86_comparison_operator"
10614 [(reg FLAGS_REG) (const_int 0)]))]
10617 [(set_attr "type" "setcc")
10618 (set_attr "mode" "QI")])
10620 ;; In general it is not safe to assume too much about CCmode registers,
10621 ;; so simplify-rtx stops when it sees a second one. Under certain
10622 ;; conditions this is safe on x86, so help combine not create
10629 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10630 (ne:QI (match_operator 1 "ix86_comparison_operator"
10631 [(reg FLAGS_REG) (const_int 0)])
10634 [(set (match_dup 0) (match_dup 1))]
10635 "PUT_MODE (operands[1], QImode);")
10638 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10639 (ne:QI (match_operator 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10643 [(set (match_dup 0) (match_dup 1))]
10644 "PUT_MODE (operands[1], QImode);")
10647 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10648 (eq:QI (match_operator 1 "ix86_comparison_operator"
10649 [(reg FLAGS_REG) (const_int 0)])
10652 [(set (match_dup 0) (match_dup 1))]
10654 rtx new_op1 = copy_rtx (operands[1]);
10655 operands[1] = new_op1;
10656 PUT_MODE (new_op1, QImode);
10657 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10658 GET_MODE (XEXP (new_op1, 0))));
10660 /* Make sure that (a) the CCmode we have for the flags is strong
10661 enough for the reversed compare or (b) we have a valid FP compare. */
10662 if (! ix86_comparison_operator (new_op1, VOIDmode))
10667 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10668 (eq:QI (match_operator 1 "ix86_comparison_operator"
10669 [(reg FLAGS_REG) (const_int 0)])
10672 [(set (match_dup 0) (match_dup 1))]
10674 rtx new_op1 = copy_rtx (operands[1]);
10675 operands[1] = new_op1;
10676 PUT_MODE (new_op1, QImode);
10677 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10678 GET_MODE (XEXP (new_op1, 0))));
10680 /* Make sure that (a) the CCmode we have for the flags is strong
10681 enough for the reversed compare or (b) we have a valid FP compare. */
10682 if (! ix86_comparison_operator (new_op1, VOIDmode))
10686 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10687 ;; subsequent logical operations are used to imitate conditional moves.
10688 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10691 (define_insn "setcc_<mode>_sse"
10692 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10693 (match_operator:MODEF 3 "sse_comparison_operator"
10694 [(match_operand:MODEF 1 "register_operand" "0,x")
10695 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10696 "SSE_FLOAT_MODE_P (<MODE>mode)"
10698 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10699 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10700 [(set_attr "isa" "noavx,avx")
10701 (set_attr "type" "ssecmp")
10702 (set_attr "length_immediate" "1")
10703 (set_attr "prefix" "orig,vex")
10704 (set_attr "mode" "<MODE>")])
10706 ;; Basic conditional jump instructions.
10707 ;; We ignore the overflow flag for signed branch instructions.
10709 (define_insn "*jcc_1"
10711 (if_then_else (match_operator 1 "ix86_comparison_operator"
10712 [(reg FLAGS_REG) (const_int 0)])
10713 (label_ref (match_operand 0 "" ""))
10717 [(set_attr "type" "ibr")
10718 (set_attr "modrm" "0")
10719 (set (attr "length")
10720 (if_then_else (and (ge (minus (match_dup 0) (pc))
10722 (lt (minus (match_dup 0) (pc))
10727 (define_insn "*jcc_2"
10729 (if_then_else (match_operator 1 "ix86_comparison_operator"
10730 [(reg FLAGS_REG) (const_int 0)])
10732 (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 ;; In general it is not safe to assume too much about CCmode registers,
10746 ;; so simplify-rtx stops when it sees a second one. Under certain
10747 ;; conditions this is safe on x86, so help combine not create
10755 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10756 [(reg FLAGS_REG) (const_int 0)])
10758 (label_ref (match_operand 1 "" ""))
10762 (if_then_else (match_dup 0)
10763 (label_ref (match_dup 1))
10765 "PUT_MODE (operands[0], VOIDmode);")
10769 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10770 [(reg FLAGS_REG) (const_int 0)])
10772 (label_ref (match_operand 1 "" ""))
10776 (if_then_else (match_dup 0)
10777 (label_ref (match_dup 1))
10780 rtx new_op0 = copy_rtx (operands[0]);
10781 operands[0] = new_op0;
10782 PUT_MODE (new_op0, VOIDmode);
10783 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10784 GET_MODE (XEXP (new_op0, 0))));
10786 /* Make sure that (a) the CCmode we have for the flags is strong
10787 enough for the reversed compare or (b) we have a valid FP compare. */
10788 if (! ix86_comparison_operator (new_op0, VOIDmode))
10792 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10793 ;; pass generates from shift insn with QImode operand. Actually, the mode
10794 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10795 ;; appropriate modulo of the bit offset value.
10797 (define_insn_and_split "*jcc_bt<mode>"
10799 (if_then_else (match_operator 0 "bt_comparison_operator"
10800 [(zero_extract:SWI48
10801 (match_operand:SWI48 1 "register_operand" "r")
10804 (match_operand:QI 2 "register_operand" "r")))
10806 (label_ref (match_operand 3 "" ""))
10808 (clobber (reg:CC FLAGS_REG))]
10809 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10812 [(set (reg:CCC FLAGS_REG)
10814 (zero_extract:SWI48
10820 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10821 (label_ref (match_dup 3))
10824 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10826 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10829 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10830 ;; also for DImode, this is what combine produces.
10831 (define_insn_and_split "*jcc_bt<mode>_mask"
10833 (if_then_else (match_operator 0 "bt_comparison_operator"
10834 [(zero_extract:SWI48
10835 (match_operand:SWI48 1 "register_operand" "r")
10838 (match_operand:SI 2 "register_operand" "r")
10839 (match_operand:SI 3 "const_int_operand" "n")))])
10840 (label_ref (match_operand 4 "" ""))
10842 (clobber (reg:CC FLAGS_REG))]
10843 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10844 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10845 == GET_MODE_BITSIZE (<MODE>mode)-1"
10848 [(set (reg:CCC FLAGS_REG)
10850 (zero_extract:SWI48
10856 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10857 (label_ref (match_dup 4))
10860 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10862 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10865 (define_insn_and_split "*jcc_btsi_1"
10867 (if_then_else (match_operator 0 "bt_comparison_operator"
10870 (match_operand:SI 1 "register_operand" "r")
10871 (match_operand:QI 2 "register_operand" "r"))
10874 (label_ref (match_operand 3 "" ""))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10880 [(set (reg:CCC FLAGS_REG)
10888 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10889 (label_ref (match_dup 3))
10892 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10894 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10897 ;; avoid useless masking of bit offset operand
10898 (define_insn_and_split "*jcc_btsi_mask_1"
10901 (match_operator 0 "bt_comparison_operator"
10904 (match_operand:SI 1 "register_operand" "r")
10907 (match_operand:SI 2 "register_operand" "r")
10908 (match_operand:SI 3 "const_int_operand" "n")) 0))
10911 (label_ref (match_operand 4 "" ""))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10915 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10918 [(set (reg:CCC FLAGS_REG)
10926 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10927 (label_ref (match_dup 4))
10929 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10931 ;; Define combination compare-and-branch fp compare instructions to help
10934 (define_insn "*fp_jcc_1_387"
10936 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10937 [(match_operand 1 "register_operand" "f")
10938 (match_operand 2 "nonimmediate_operand" "fm")])
10939 (label_ref (match_operand 3 "" ""))
10941 (clobber (reg:CCFP FPSR_REG))
10942 (clobber (reg:CCFP FLAGS_REG))
10943 (clobber (match_scratch:HI 4 "=a"))]
10945 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10946 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10947 && SELECT_CC_MODE (GET_CODE (operands[0]),
10948 operands[1], operands[2]) == CCFPmode
10952 (define_insn "*fp_jcc_1r_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")])
10958 (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_2_387"
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand" "f")
10974 (match_operand 2 "register_operand" "f")])
10975 (label_ref (match_operand 3 "" ""))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 4 "=a"))]
10980 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10985 (define_insn "*fp_jcc_2r_387"
10987 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10988 [(match_operand 1 "register_operand" "f")
10989 (match_operand 2 "register_operand" "f")])
10991 (label_ref (match_operand 3 "" ""))))
10992 (clobber (reg:CCFP FPSR_REG))
10993 (clobber (reg:CCFP FLAGS_REG))
10994 (clobber (match_scratch:HI 4 "=a"))]
10995 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10996 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11000 (define_insn "*fp_jcc_3_387"
11002 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11003 [(match_operand 1 "register_operand" "f")
11004 (match_operand 2 "const0_operand" "")])
11005 (label_ref (match_operand 3 "" ""))
11007 (clobber (reg:CCFP FPSR_REG))
11008 (clobber (reg:CCFP FLAGS_REG))
11009 (clobber (match_scratch:HI 4 "=a"))]
11010 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11011 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11012 && SELECT_CC_MODE (GET_CODE (operands[0]),
11013 operands[1], operands[2]) == CCFPmode
11019 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11020 [(match_operand 1 "register_operand" "")
11021 (match_operand 2 "nonimmediate_operand" "")])
11022 (match_operand 3 "" "")
11023 (match_operand 4 "" "")))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))]
11029 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11030 operands[3], operands[4], NULL_RTX, NULL_RTX);
11036 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11037 [(match_operand 1 "register_operand" "")
11038 (match_operand 2 "general_operand" "")])
11039 (match_operand 3 "" "")
11040 (match_operand 4 "" "")))
11041 (clobber (reg:CCFP FPSR_REG))
11042 (clobber (reg:CCFP FLAGS_REG))
11043 (clobber (match_scratch:HI 5 "=a"))]
11047 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11048 operands[3], operands[4], operands[5], NULL_RTX);
11052 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11053 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11054 ;; with a precedence over other operators and is always put in the first
11055 ;; place. Swap condition and operands to match ficom instruction.
11057 (define_insn "*fp_jcc_4_<mode>_387"
11060 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11061 [(match_operator 1 "float_operator"
11062 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11063 (match_operand 3 "register_operand" "f,f")])
11064 (label_ref (match_operand 4 "" ""))
11066 (clobber (reg:CCFP FPSR_REG))
11067 (clobber (reg:CCFP FLAGS_REG))
11068 (clobber (match_scratch:HI 5 "=a,a"))]
11069 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11070 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11071 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11072 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11079 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11080 [(match_operator 1 "float_operator"
11081 [(match_operand:SWI24 2 "memory_operand" "")])
11082 (match_operand 3 "register_operand" "")])
11083 (match_operand 4 "" "")
11084 (match_operand 5 "" "")))
11085 (clobber (reg:CCFP FPSR_REG))
11086 (clobber (reg:CCFP FLAGS_REG))
11087 (clobber (match_scratch:HI 6 "=a"))]
11091 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11093 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11094 operands[3], operands[7],
11095 operands[4], operands[5], operands[6], NULL_RTX);
11099 ;; %%% Kill this when reload knows how to do it.
11103 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11104 [(match_operator 1 "float_operator"
11105 [(match_operand:SWI24 2 "register_operand" "")])
11106 (match_operand 3 "register_operand" "")])
11107 (match_operand 4 "" "")
11108 (match_operand 5 "" "")))
11109 (clobber (reg:CCFP FPSR_REG))
11110 (clobber (reg:CCFP FLAGS_REG))
11111 (clobber (match_scratch:HI 6 "=a"))]
11115 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11116 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11118 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11119 operands[3], operands[7],
11120 operands[4], operands[5], operands[6], operands[2]);
11124 ;; Unconditional and other jump instructions
11126 (define_insn "jump"
11128 (label_ref (match_operand 0 "" "")))]
11131 [(set_attr "type" "ibr")
11132 (set (attr "length")
11133 (if_then_else (and (ge (minus (match_dup 0) (pc))
11135 (lt (minus (match_dup 0) (pc))
11139 (set_attr "modrm" "0")])
11141 (define_expand "indirect_jump"
11142 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11144 (define_insn "*indirect_jump"
11145 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11148 [(set_attr "type" "ibr")
11149 (set_attr "length_immediate" "0")])
11151 (define_expand "tablejump"
11152 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11153 (use (label_ref (match_operand 1 "" "")))])]
11156 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11157 relative. Convert the relative address to an absolute address. */
11161 enum rtx_code code;
11163 /* We can't use @GOTOFF for text labels on VxWorks;
11164 see gotoff_operand. */
11165 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11169 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11171 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11175 op1 = pic_offset_table_rtx;
11180 op0 = pic_offset_table_rtx;
11184 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11187 else if (TARGET_X32)
11188 operands[0] = convert_memory_address (Pmode, operands[0]);
11191 (define_insn "*tablejump_1"
11192 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11193 (use (label_ref (match_operand 1 "" "")))]
11196 [(set_attr "type" "ibr")
11197 (set_attr "length_immediate" "0")])
11199 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11202 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11203 (set (match_operand:QI 1 "register_operand" "")
11204 (match_operator:QI 2 "ix86_comparison_operator"
11205 [(reg FLAGS_REG) (const_int 0)]))
11206 (set (match_operand 3 "q_regs_operand" "")
11207 (zero_extend (match_dup 1)))]
11208 "(peep2_reg_dead_p (3, operands[1])
11209 || operands_match_p (operands[1], operands[3]))
11210 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11211 [(set (match_dup 4) (match_dup 0))
11212 (set (strict_low_part (match_dup 5))
11215 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11216 operands[5] = gen_lowpart (QImode, operands[3]);
11217 ix86_expand_clear (operands[3]);
11220 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11223 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11224 (set (match_operand:QI 1 "register_operand" "")
11225 (match_operator:QI 2 "ix86_comparison_operator"
11226 [(reg FLAGS_REG) (const_int 0)]))
11227 (parallel [(set (match_operand 3 "q_regs_operand" "")
11228 (zero_extend (match_dup 1)))
11229 (clobber (reg:CC FLAGS_REG))])]
11230 "(peep2_reg_dead_p (3, operands[1])
11231 || operands_match_p (operands[1], operands[3]))
11232 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11233 [(set (match_dup 4) (match_dup 0))
11234 (set (strict_low_part (match_dup 5))
11237 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11238 operands[5] = gen_lowpart (QImode, operands[3]);
11239 ix86_expand_clear (operands[3]);
11242 ;; Call instructions.
11244 ;; The predicates normally associated with named expanders are not properly
11245 ;; checked for calls. This is a bug in the generic code, but it isn't that
11246 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11248 ;; P6 processors will jump to the address after the decrement when %esp
11249 ;; is used as a call operand, so they will execute return address as a code.
11250 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11252 ;; Register constraint for call instruction.
11253 (define_mode_attr c [(SI "l") (DI "r")])
11255 ;; Call subroutine returning no value.
11257 (define_expand "call"
11258 [(call (match_operand:QI 0 "" "")
11259 (match_operand 1 "" ""))
11260 (use (match_operand 2 "" ""))]
11263 ix86_expand_call (NULL, operands[0], operands[1],
11264 operands[2], NULL, false);
11268 (define_expand "sibcall"
11269 [(call (match_operand:QI 0 "" "")
11270 (match_operand 1 "" ""))
11271 (use (match_operand 2 "" ""))]
11274 ix86_expand_call (NULL, operands[0], operands[1],
11275 operands[2], NULL, true);
11279 (define_insn_and_split "*call_vzeroupper"
11280 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11281 (match_operand 1 "" ""))
11282 (unspec [(match_operand 2 "const_int_operand" "")]
11283 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11284 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11286 "&& reload_completed"
11288 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11289 [(set_attr "type" "call")])
11291 (define_insn "*call"
11292 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11293 (match_operand 1 "" ""))]
11294 "!SIBLING_CALL_P (insn)"
11295 "* return ix86_output_call_insn (insn, operands[0]);"
11296 [(set_attr "type" "call")])
11298 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11299 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11300 (match_operand 1 "" ""))
11301 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11302 (clobber (reg:TI XMM6_REG))
11303 (clobber (reg:TI XMM7_REG))
11304 (clobber (reg:TI XMM8_REG))
11305 (clobber (reg:TI XMM9_REG))
11306 (clobber (reg:TI XMM10_REG))
11307 (clobber (reg:TI XMM11_REG))
11308 (clobber (reg:TI XMM12_REG))
11309 (clobber (reg:TI XMM13_REG))
11310 (clobber (reg:TI XMM14_REG))
11311 (clobber (reg:TI XMM15_REG))
11312 (clobber (reg:DI SI_REG))
11313 (clobber (reg:DI DI_REG))
11314 (unspec [(match_operand 2 "const_int_operand" "")]
11315 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11316 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11318 "&& reload_completed"
11320 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11321 [(set_attr "type" "call")])
11323 (define_insn "*call_rex64_ms_sysv"
11324 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11325 (match_operand 1 "" ""))
11326 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11327 (clobber (reg:TI XMM6_REG))
11328 (clobber (reg:TI XMM7_REG))
11329 (clobber (reg:TI XMM8_REG))
11330 (clobber (reg:TI XMM9_REG))
11331 (clobber (reg:TI XMM10_REG))
11332 (clobber (reg:TI XMM11_REG))
11333 (clobber (reg:TI XMM12_REG))
11334 (clobber (reg:TI XMM13_REG))
11335 (clobber (reg:TI XMM14_REG))
11336 (clobber (reg:TI XMM15_REG))
11337 (clobber (reg:DI SI_REG))
11338 (clobber (reg:DI DI_REG))]
11339 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 "* return ix86_output_call_insn (insn, operands[0]);"
11341 [(set_attr "type" "call")])
11343 (define_insn_and_split "*sibcall_vzeroupper"
11344 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11345 (match_operand 1 "" ""))
11346 (unspec [(match_operand 2 "const_int_operand" "")]
11347 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11348 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11350 "&& reload_completed"
11352 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11353 [(set_attr "type" "call")])
11355 (define_insn "*sibcall"
11356 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11357 (match_operand 1 "" ""))]
11358 "SIBLING_CALL_P (insn)"
11359 "* return ix86_output_call_insn (insn, operands[0]);"
11360 [(set_attr "type" "call")])
11362 (define_expand "call_pop"
11363 [(parallel [(call (match_operand:QI 0 "" "")
11364 (match_operand:SI 1 "" ""))
11365 (set (reg:SI SP_REG)
11366 (plus:SI (reg:SI SP_REG)
11367 (match_operand:SI 3 "" "")))])]
11370 ix86_expand_call (NULL, operands[0], operands[1],
11371 operands[2], operands[3], false);
11375 (define_insn_and_split "*call_pop_vzeroupper"
11376 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11377 (match_operand:SI 1 "" ""))
11378 (set (reg:SI SP_REG)
11379 (plus:SI (reg:SI SP_REG)
11380 (match_operand:SI 2 "immediate_operand" "i")))
11381 (unspec [(match_operand 3 "const_int_operand" "")]
11382 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11383 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385 "&& reload_completed"
11387 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11388 [(set_attr "type" "call")])
11390 (define_insn "*call_pop"
11391 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11392 (match_operand 1 "" ""))
11393 (set (reg:SI SP_REG)
11394 (plus:SI (reg:SI SP_REG)
11395 (match_operand:SI 2 "immediate_operand" "i")))]
11396 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11397 "* return ix86_output_call_insn (insn, operands[0]);"
11398 [(set_attr "type" "call")])
11400 (define_insn_and_split "*sibcall_pop_vzeroupper"
11401 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11402 (match_operand 1 "" ""))
11403 (set (reg:SI SP_REG)
11404 (plus:SI (reg:SI SP_REG)
11405 (match_operand:SI 2 "immediate_operand" "i")))
11406 (unspec [(match_operand 3 "const_int_operand" "")]
11407 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11408 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11410 "&& reload_completed"
11412 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11413 [(set_attr "type" "call")])
11415 (define_insn "*sibcall_pop"
11416 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11417 (match_operand 1 "" ""))
11418 (set (reg:SI SP_REG)
11419 (plus:SI (reg:SI SP_REG)
11420 (match_operand:SI 2 "immediate_operand" "i")))]
11421 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11422 "* return ix86_output_call_insn (insn, operands[0]);"
11423 [(set_attr "type" "call")])
11425 ;; Call subroutine, returning value in operand 0
11427 (define_expand "call_value"
11428 [(set (match_operand 0 "" "")
11429 (call (match_operand:QI 1 "" "")
11430 (match_operand 2 "" "")))
11431 (use (match_operand 3 "" ""))]
11434 ix86_expand_call (operands[0], operands[1], operands[2],
11435 operands[3], NULL, false);
11439 (define_expand "sibcall_value"
11440 [(set (match_operand 0 "" "")
11441 (call (match_operand:QI 1 "" "")
11442 (match_operand 2 "" "")))
11443 (use (match_operand 3 "" ""))]
11446 ix86_expand_call (operands[0], operands[1], operands[2],
11447 operands[3], NULL, true);
11451 (define_insn_and_split "*call_value_vzeroupper"
11452 [(set (match_operand 0 "" "")
11453 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11454 (match_operand 2 "" "")))
11455 (unspec [(match_operand 3 "const_int_operand" "")]
11456 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11457 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11459 "&& reload_completed"
11461 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11462 [(set_attr "type" "callv")])
11464 (define_insn "*call_value"
11465 [(set (match_operand 0 "" "")
11466 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11467 (match_operand 2 "" "")))]
11468 "!SIBLING_CALL_P (insn)"
11469 "* return ix86_output_call_insn (insn, operands[1]);"
11470 [(set_attr "type" "callv")])
11472 (define_insn_and_split "*sibcall_value_vzeroupper"
11473 [(set (match_operand 0 "" "")
11474 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11475 (match_operand 2 "" "")))
11476 (unspec [(match_operand 3 "const_int_operand" "")]
11477 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11478 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11480 "&& reload_completed"
11482 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11483 [(set_attr "type" "callv")])
11485 (define_insn "*sibcall_value"
11486 [(set (match_operand 0 "" "")
11487 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11488 (match_operand 2 "" "")))]
11489 "SIBLING_CALL_P (insn)"
11490 "* return ix86_output_call_insn (insn, operands[1]);"
11491 [(set_attr "type" "callv")])
11493 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11494 [(set (match_operand 0 "" "")
11495 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11496 (match_operand 2 "" "")))
11497 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11498 (clobber (reg:TI XMM6_REG))
11499 (clobber (reg:TI XMM7_REG))
11500 (clobber (reg:TI XMM8_REG))
11501 (clobber (reg:TI XMM9_REG))
11502 (clobber (reg:TI XMM10_REG))
11503 (clobber (reg:TI XMM11_REG))
11504 (clobber (reg:TI XMM12_REG))
11505 (clobber (reg:TI XMM13_REG))
11506 (clobber (reg:TI XMM14_REG))
11507 (clobber (reg:TI XMM15_REG))
11508 (clobber (reg:DI SI_REG))
11509 (clobber (reg:DI DI_REG))
11510 (unspec [(match_operand 3 "const_int_operand" "")]
11511 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11512 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11514 "&& reload_completed"
11516 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11517 [(set_attr "type" "callv")])
11519 (define_insn "*call_value_rex64_ms_sysv"
11520 [(set (match_operand 0 "" "")
11521 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11522 (match_operand 2 "" "")))
11523 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11524 (clobber (reg:TI XMM6_REG))
11525 (clobber (reg:TI XMM7_REG))
11526 (clobber (reg:TI XMM8_REG))
11527 (clobber (reg:TI XMM9_REG))
11528 (clobber (reg:TI XMM10_REG))
11529 (clobber (reg:TI XMM11_REG))
11530 (clobber (reg:TI XMM12_REG))
11531 (clobber (reg:TI XMM13_REG))
11532 (clobber (reg:TI XMM14_REG))
11533 (clobber (reg:TI XMM15_REG))
11534 (clobber (reg:DI SI_REG))
11535 (clobber (reg:DI DI_REG))]
11536 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11537 "* return ix86_output_call_insn (insn, operands[1]);"
11538 [(set_attr "type" "callv")])
11540 (define_expand "call_value_pop"
11541 [(parallel [(set (match_operand 0 "" "")
11542 (call (match_operand:QI 1 "" "")
11543 (match_operand:SI 2 "" "")))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 4 "" "")))])]
11549 ix86_expand_call (operands[0], operands[1], operands[2],
11550 operands[3], operands[4], false);
11554 (define_insn_and_split "*call_value_pop_vzeroupper"
11555 [(set (match_operand 0 "" "")
11556 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11557 (match_operand 2 "" "")))
11558 (set (reg:SI SP_REG)
11559 (plus:SI (reg:SI SP_REG)
11560 (match_operand:SI 3 "immediate_operand" "i")))
11561 (unspec [(match_operand 4 "const_int_operand" "")]
11562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11563 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565 "&& reload_completed"
11567 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11568 [(set_attr "type" "callv")])
11570 (define_insn "*call_value_pop"
11571 [(set (match_operand 0 "" "")
11572 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11573 (match_operand 2 "" "")))
11574 (set (reg:SI SP_REG)
11575 (plus:SI (reg:SI SP_REG)
11576 (match_operand:SI 3 "immediate_operand" "i")))]
11577 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11578 "* return ix86_output_call_insn (insn, operands[1]);"
11579 [(set_attr "type" "callv")])
11581 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11582 [(set (match_operand 0 "" "")
11583 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11584 (match_operand 2 "" "")))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 3 "immediate_operand" "i")))
11588 (unspec [(match_operand 4 "const_int_operand" "")]
11589 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11590 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11592 "&& reload_completed"
11594 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11595 [(set_attr "type" "callv")])
11597 (define_insn "*sibcall_value_pop"
11598 [(set (match_operand 0 "" "")
11599 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11600 (match_operand 2 "" "")))
11601 (set (reg:SI SP_REG)
11602 (plus:SI (reg:SI SP_REG)
11603 (match_operand:SI 3 "immediate_operand" "i")))]
11604 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11605 "* return ix86_output_call_insn (insn, operands[1]);"
11606 [(set_attr "type" "callv")])
11608 ;; Call subroutine returning any type.
11610 (define_expand "untyped_call"
11611 [(parallel [(call (match_operand 0 "" "")
11613 (match_operand 1 "" "")
11614 (match_operand 2 "" "")])]
11619 /* In order to give reg-stack an easier job in validating two
11620 coprocessor registers as containing a possible return value,
11621 simply pretend the untyped call returns a complex long double
11624 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11625 and should have the default ABI. */
11627 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11628 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11629 operands[0], const0_rtx,
11630 GEN_INT ((TARGET_64BIT
11631 ? (ix86_abi == SYSV_ABI
11632 ? X86_64_SSE_REGPARM_MAX
11633 : X86_64_MS_SSE_REGPARM_MAX)
11634 : X86_32_SSE_REGPARM_MAX)
11638 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11640 rtx set = XVECEXP (operands[2], 0, i);
11641 emit_move_insn (SET_DEST (set), SET_SRC (set));
11644 /* The optimizer does not know that the call sets the function value
11645 registers we stored in the result block. We avoid problems by
11646 claiming that all hard registers are used and clobbered at this
11648 emit_insn (gen_blockage ());
11653 ;; Prologue and epilogue instructions
11655 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11656 ;; all of memory. This blocks insns from being moved across this point.
11658 (define_insn "blockage"
11659 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11662 [(set_attr "length" "0")])
11664 ;; Do not schedule instructions accessing memory across this point.
11666 (define_expand "memory_blockage"
11667 [(set (match_dup 0)
11668 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11671 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11672 MEM_VOLATILE_P (operands[0]) = 1;
11675 (define_insn "*memory_blockage"
11676 [(set (match_operand:BLK 0 "" "")
11677 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11680 [(set_attr "length" "0")])
11682 ;; As USE insns aren't meaningful after reload, this is used instead
11683 ;; to prevent deleting instructions setting registers for PIC code
11684 (define_insn "prologue_use"
11685 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11688 [(set_attr "length" "0")])
11690 ;; Insn emitted into the body of a function to return from a function.
11691 ;; This is only done if the function's epilogue is known to be simple.
11692 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11694 (define_expand "return"
11696 "ix86_can_use_return_insn_p ()"
11698 if (crtl->args.pops_args)
11700 rtx popc = GEN_INT (crtl->args.pops_args);
11701 emit_jump_insn (gen_simple_return_pop_internal (popc));
11706 ;; We need to disable this for TARGET_SEH, as otherwise
11707 ;; shrink-wrapped prologue gets enabled too. This might exceed
11708 ;; the maximum size of prologue in unwind information.
11710 (define_expand "simple_return"
11714 if (crtl->args.pops_args)
11716 rtx popc = GEN_INT (crtl->args.pops_args);
11717 emit_jump_insn (gen_simple_return_pop_internal (popc));
11722 (define_insn "simple_return_internal"
11726 [(set_attr "length" "1")
11727 (set_attr "atom_unit" "jeu")
11728 (set_attr "length_immediate" "0")
11729 (set_attr "modrm" "0")])
11731 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11732 ;; instruction Athlon and K8 have.
11734 (define_insn "simple_return_internal_long"
11736 (unspec [(const_int 0)] UNSPEC_REP)]
11739 [(set_attr "length" "2")
11740 (set_attr "atom_unit" "jeu")
11741 (set_attr "length_immediate" "0")
11742 (set_attr "prefix_rep" "1")
11743 (set_attr "modrm" "0")])
11745 (define_insn "simple_return_pop_internal"
11747 (use (match_operand:SI 0 "const_int_operand" ""))]
11750 [(set_attr "length" "3")
11751 (set_attr "atom_unit" "jeu")
11752 (set_attr "length_immediate" "2")
11753 (set_attr "modrm" "0")])
11755 (define_insn "simple_return_indirect_internal"
11757 (use (match_operand:SI 0 "register_operand" "r"))]
11760 [(set_attr "type" "ibr")
11761 (set_attr "length_immediate" "0")])
11767 [(set_attr "length" "1")
11768 (set_attr "length_immediate" "0")
11769 (set_attr "modrm" "0")])
11771 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11772 (define_insn "nops"
11773 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11777 int num = INTVAL (operands[0]);
11779 gcc_assert (num >= 1 && num <= 8);
11782 fputs ("\tnop\n", asm_out_file);
11786 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11787 (set_attr "length_immediate" "0")
11788 (set_attr "modrm" "0")])
11790 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11791 ;; branch prediction penalty for the third jump in a 16-byte
11795 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11798 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11799 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11801 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11802 The align insn is used to avoid 3 jump instructions in the row to improve
11803 branch prediction and the benefits hardly outweigh the cost of extra 8
11804 nops on the average inserted by full alignment pseudo operation. */
11808 [(set_attr "length" "16")])
11810 (define_expand "prologue"
11813 "ix86_expand_prologue (); DONE;")
11815 (define_insn "set_got"
11816 [(set (match_operand:SI 0 "register_operand" "=r")
11817 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11818 (clobber (reg:CC FLAGS_REG))]
11820 "* return output_set_got (operands[0], NULL_RTX);"
11821 [(set_attr "type" "multi")
11822 (set_attr "length" "12")])
11824 (define_insn "set_got_labelled"
11825 [(set (match_operand:SI 0 "register_operand" "=r")
11826 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11828 (clobber (reg:CC FLAGS_REG))]
11830 "* return output_set_got (operands[0], operands[1]);"
11831 [(set_attr "type" "multi")
11832 (set_attr "length" "12")])
11834 (define_insn "set_got_rex64"
11835 [(set (match_operand:DI 0 "register_operand" "=r")
11836 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11838 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11839 [(set_attr "type" "lea")
11840 (set_attr "length_address" "4")
11841 (set_attr "mode" "DI")])
11843 (define_insn "set_rip_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11845 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11847 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11848 [(set_attr "type" "lea")
11849 (set_attr "length_address" "4")
11850 (set_attr "mode" "DI")])
11852 (define_insn "set_got_offset_rex64"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11855 [(label_ref (match_operand 1 "" ""))]
11856 UNSPEC_SET_GOT_OFFSET))]
11858 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11859 [(set_attr "type" "imov")
11860 (set_attr "length_immediate" "0")
11861 (set_attr "length_address" "8")
11862 (set_attr "mode" "DI")])
11864 (define_expand "epilogue"
11867 "ix86_expand_epilogue (1); DONE;")
11869 (define_expand "sibcall_epilogue"
11872 "ix86_expand_epilogue (0); DONE;")
11874 (define_expand "eh_return"
11875 [(use (match_operand 0 "register_operand" ""))]
11878 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11880 /* Tricky bit: we write the address of the handler to which we will
11881 be returning into someone else's stack frame, one word below the
11882 stack address we wish to restore. */
11883 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11884 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11885 tmp = gen_rtx_MEM (Pmode, tmp);
11886 emit_move_insn (tmp, ra);
11888 emit_jump_insn (gen_eh_return_internal ());
11893 (define_insn_and_split "eh_return_internal"
11897 "epilogue_completed"
11899 "ix86_expand_epilogue (2); DONE;")
11901 (define_insn "leave"
11902 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11903 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11904 (clobber (mem:BLK (scratch)))]
11907 [(set_attr "type" "leave")])
11909 (define_insn "leave_rex64"
11910 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11911 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11912 (clobber (mem:BLK (scratch)))]
11915 [(set_attr "type" "leave")])
11917 ;; Handle -fsplit-stack.
11919 (define_expand "split_stack_prologue"
11923 ix86_expand_split_stack_prologue ();
11927 ;; In order to support the call/return predictor, we use a return
11928 ;; instruction which the middle-end doesn't see.
11929 (define_insn "split_stack_return"
11930 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11931 UNSPECV_SPLIT_STACK_RETURN)]
11934 if (operands[0] == const0_rtx)
11939 [(set_attr "atom_unit" "jeu")
11940 (set_attr "modrm" "0")
11941 (set (attr "length")
11942 (if_then_else (match_operand:SI 0 "const0_operand" "")
11945 (set (attr "length_immediate")
11946 (if_then_else (match_operand:SI 0 "const0_operand" "")
11950 ;; If there are operand 0 bytes available on the stack, jump to
11953 (define_expand "split_stack_space_check"
11954 [(set (pc) (if_then_else
11955 (ltu (minus (reg SP_REG)
11956 (match_operand 0 "register_operand" ""))
11957 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11958 (label_ref (match_operand 1 "" ""))
11962 rtx reg, size, limit;
11964 reg = gen_reg_rtx (Pmode);
11965 size = force_reg (Pmode, operands[0]);
11966 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11967 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11968 UNSPEC_STACK_CHECK);
11969 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11970 ix86_expand_branch (GEU, reg, limit, operands[1]);
11975 ;; Bit manipulation instructions.
11977 (define_expand "ffs<mode>2"
11978 [(set (match_dup 2) (const_int -1))
11979 (parallel [(set (reg:CCZ FLAGS_REG)
11981 (match_operand:SWI48 1 "nonimmediate_operand" "")
11983 (set (match_operand:SWI48 0 "register_operand" "")
11984 (ctz:SWI48 (match_dup 1)))])
11985 (set (match_dup 0) (if_then_else:SWI48
11986 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11989 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11990 (clobber (reg:CC FLAGS_REG))])]
11993 if (<MODE>mode == SImode && !TARGET_CMOVE)
11995 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11998 operands[2] = gen_reg_rtx (<MODE>mode);
12001 (define_insn_and_split "ffssi2_no_cmove"
12002 [(set (match_operand:SI 0 "register_operand" "=r")
12003 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12004 (clobber (match_scratch:SI 2 "=&q"))
12005 (clobber (reg:CC FLAGS_REG))]
12008 "&& reload_completed"
12009 [(parallel [(set (reg:CCZ FLAGS_REG)
12010 (compare:CCZ (match_dup 1) (const_int 0)))
12011 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12012 (set (strict_low_part (match_dup 3))
12013 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12014 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12015 (clobber (reg:CC FLAGS_REG))])
12016 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12017 (clobber (reg:CC FLAGS_REG))])
12018 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12019 (clobber (reg:CC FLAGS_REG))])]
12021 operands[3] = gen_lowpart (QImode, operands[2]);
12022 ix86_expand_clear (operands[2]);
12025 (define_insn "*ffs<mode>_1"
12026 [(set (reg:CCZ FLAGS_REG)
12027 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12029 (set (match_operand:SWI48 0 "register_operand" "=r")
12030 (ctz:SWI48 (match_dup 1)))]
12032 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12033 [(set_attr "type" "alu1")
12034 (set_attr "prefix_0f" "1")
12035 (set_attr "mode" "<MODE>")])
12037 (define_insn "ctz<mode>2"
12038 [(set (match_operand:SWI248 0 "register_operand" "=r")
12039 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12040 (clobber (reg:CC FLAGS_REG))]
12044 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12046 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12048 [(set_attr "type" "alu1")
12049 (set_attr "prefix_0f" "1")
12050 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12051 (set_attr "mode" "<MODE>")])
12053 (define_expand "clz<mode>2"
12055 [(set (match_operand:SWI248 0 "register_operand" "")
12058 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12059 (clobber (reg:CC FLAGS_REG))])
12061 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12062 (clobber (reg:CC FLAGS_REG))])]
12067 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12070 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12073 (define_insn "clz<mode>2_lzcnt"
12074 [(set (match_operand:SWI248 0 "register_operand" "=r")
12075 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12076 (clobber (reg:CC FLAGS_REG))]
12078 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12079 [(set_attr "prefix_rep" "1")
12080 (set_attr "type" "bitmanip")
12081 (set_attr "mode" "<MODE>")])
12083 ;; BMI instructions.
12084 (define_insn "*bmi_andn_<mode>"
12085 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (match_operand:SWI48 1 "register_operand" "r"))
12089 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12090 (clobber (reg:CC FLAGS_REG))]
12092 "andn\t{%2, %1, %0|%0, %1, %2}"
12093 [(set_attr "type" "bitmanip")
12094 (set_attr "mode" "<MODE>")])
12096 (define_insn "bmi_bextr_<mode>"
12097 [(set (match_operand:SWI48 0 "register_operand" "=r")
12098 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12099 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12101 (clobber (reg:CC FLAGS_REG))]
12103 "bextr\t{%2, %1, %0|%0, %1, %2}"
12104 [(set_attr "type" "bitmanip")
12105 (set_attr "mode" "<MODE>")])
12107 (define_insn "*bmi_blsi_<mode>"
12108 [(set (match_operand:SWI48 0 "register_operand" "=r")
12111 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12113 (clobber (reg:CC FLAGS_REG))]
12115 "blsi\t{%1, %0|%0, %1}"
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "mode" "<MODE>")])
12119 (define_insn "*bmi_blsmsk_<mode>"
12120 [(set (match_operand:SWI48 0 "register_operand" "=r")
12123 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12126 (clobber (reg:CC FLAGS_REG))]
12128 "blsmsk\t{%1, %0|%0, %1}"
12129 [(set_attr "type" "bitmanip")
12130 (set_attr "mode" "<MODE>")])
12132 (define_insn "*bmi_blsr_<mode>"
12133 [(set (match_operand:SWI48 0 "register_operand" "=r")
12136 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139 (clobber (reg:CC FLAGS_REG))]
12141 "blsr\t{%1, %0|%0, %1}"
12142 [(set_attr "type" "bitmanip")
12143 (set_attr "mode" "<MODE>")])
12145 ;; BMI2 instructions.
12146 (define_insn "bmi2_bzhi_<mode>3"
12147 [(set (match_operand:SWI48 0 "register_operand" "=r")
12148 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12149 (lshiftrt:SWI48 (const_int -1)
12150 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12151 (clobber (reg:CC FLAGS_REG))]
12153 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12154 [(set_attr "type" "bitmanip")
12155 (set_attr "prefix" "vex")
12156 (set_attr "mode" "<MODE>")])
12158 (define_insn "bmi2_pdep_<mode>3"
12159 [(set (match_operand:SWI48 0 "register_operand" "=r")
12160 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12161 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12164 "pdep\t{%2, %1, %0|%0, %1, %2}"
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "prefix" "vex")
12167 (set_attr "mode" "<MODE>")])
12169 (define_insn "bmi2_pext_<mode>3"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12171 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12172 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12175 "pext\t{%2, %1, %0|%0, %1, %2}"
12176 [(set_attr "type" "bitmanip")
12177 (set_attr "prefix" "vex")
12178 (set_attr "mode" "<MODE>")])
12180 ;; TBM instructions.
12181 (define_insn "tbm_bextri_<mode>"
12182 [(set (match_operand:SWI48 0 "register_operand" "=r")
12183 (zero_extract:SWI48
12184 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12186 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12187 (clobber (reg:CC FLAGS_REG))]
12190 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12191 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12193 [(set_attr "type" "bitmanip")
12194 (set_attr "mode" "<MODE>")])
12196 (define_insn "*tbm_blcfill_<mode>"
12197 [(set (match_operand:SWI48 0 "register_operand" "=r")
12200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203 (clobber (reg:CC FLAGS_REG))]
12205 "blcfill\t{%1, %0|%0, %1}"
12206 [(set_attr "type" "bitmanip")
12207 (set_attr "mode" "<MODE>")])
12209 (define_insn "*tbm_blci_<mode>"
12210 [(set (match_operand:SWI48 0 "register_operand" "=r")
12214 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12217 (clobber (reg:CC FLAGS_REG))]
12219 "blci\t{%1, %0|%0, %1}"
12220 [(set_attr "type" "bitmanip")
12221 (set_attr "mode" "<MODE>")])
12223 (define_insn "*tbm_blcic_<mode>"
12224 [(set (match_operand:SWI48 0 "register_operand" "=r")
12227 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231 (clobber (reg:CC FLAGS_REG))]
12233 "blcic\t{%1, %0|%0, %1}"
12234 [(set_attr "type" "bitmanip")
12235 (set_attr "mode" "<MODE>")])
12237 (define_insn "*tbm_blcmsk_<mode>"
12238 [(set (match_operand:SWI48 0 "register_operand" "=r")
12241 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244 (clobber (reg:CC FLAGS_REG))]
12246 "blcmsk\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "bitmanip")
12248 (set_attr "mode" "<MODE>")])
12250 (define_insn "*tbm_blcs_<mode>"
12251 [(set (match_operand:SWI48 0 "register_operand" "=r")
12254 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12257 (clobber (reg:CC FLAGS_REG))]
12259 "blcs\t{%1, %0|%0, %1}"
12260 [(set_attr "type" "bitmanip")
12261 (set_attr "mode" "<MODE>")])
12263 (define_insn "*tbm_blsfill_<mode>"
12264 [(set (match_operand:SWI48 0 "register_operand" "=r")
12267 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12270 (clobber (reg:CC FLAGS_REG))]
12272 "blsfill\t{%1, %0|%0, %1}"
12273 [(set_attr "type" "bitmanip")
12274 (set_attr "mode" "<MODE>")])
12276 (define_insn "*tbm_blsic_<mode>"
12277 [(set (match_operand:SWI48 0 "register_operand" "=r")
12280 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284 (clobber (reg:CC FLAGS_REG))]
12286 "blsic\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "bitmanip")
12288 (set_attr "mode" "<MODE>")])
12290 (define_insn "*tbm_t1mskc_<mode>"
12291 [(set (match_operand:SWI48 0 "register_operand" "=r")
12294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12298 (clobber (reg:CC FLAGS_REG))]
12300 "t1mskc\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "bitmanip")
12302 (set_attr "mode" "<MODE>")])
12304 (define_insn "*tbm_tzmsk_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12312 (clobber (reg:CC FLAGS_REG))]
12314 "tzmsk\t{%1, %0|%0, %1}"
12315 [(set_attr "type" "bitmanip")
12316 (set_attr "mode" "<MODE>")])
12318 (define_insn "bsr_rex64"
12319 [(set (match_operand:DI 0 "register_operand" "=r")
12320 (minus:DI (const_int 63)
12321 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12322 (clobber (reg:CC FLAGS_REG))]
12324 "bsr{q}\t{%1, %0|%0, %1}"
12325 [(set_attr "type" "alu1")
12326 (set_attr "prefix_0f" "1")
12327 (set_attr "mode" "DI")])
12330 [(set (match_operand:SI 0 "register_operand" "=r")
12331 (minus:SI (const_int 31)
12332 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12333 (clobber (reg:CC FLAGS_REG))]
12335 "bsr{l}\t{%1, %0|%0, %1}"
12336 [(set_attr "type" "alu1")
12337 (set_attr "prefix_0f" "1")
12338 (set_attr "mode" "SI")])
12340 (define_insn "*bsrhi"
12341 [(set (match_operand:HI 0 "register_operand" "=r")
12342 (minus:HI (const_int 15)
12343 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12344 (clobber (reg:CC FLAGS_REG))]
12346 "bsr{w}\t{%1, %0|%0, %1}"
12347 [(set_attr "type" "alu1")
12348 (set_attr "prefix_0f" "1")
12349 (set_attr "mode" "HI")])
12351 (define_insn "popcount<mode>2"
12352 [(set (match_operand:SWI248 0 "register_operand" "=r")
12354 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12355 (clobber (reg:CC FLAGS_REG))]
12359 return "popcnt\t{%1, %0|%0, %1}";
12361 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12364 [(set_attr "prefix_rep" "1")
12365 (set_attr "type" "bitmanip")
12366 (set_attr "mode" "<MODE>")])
12368 (define_insn "*popcount<mode>2_cmp"
12369 [(set (reg FLAGS_REG)
12372 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12374 (set (match_operand:SWI248 0 "register_operand" "=r")
12375 (popcount:SWI248 (match_dup 1)))]
12376 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12379 return "popcnt\t{%1, %0|%0, %1}";
12381 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12384 [(set_attr "prefix_rep" "1")
12385 (set_attr "type" "bitmanip")
12386 (set_attr "mode" "<MODE>")])
12388 (define_insn "*popcountsi2_cmp_zext"
12389 [(set (reg FLAGS_REG)
12391 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12393 (set (match_operand:DI 0 "register_operand" "=r")
12394 (zero_extend:DI(popcount:SI (match_dup 1))))]
12395 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12398 return "popcnt\t{%1, %0|%0, %1}";
12400 return "popcnt{l}\t{%1, %0|%0, %1}";
12403 [(set_attr "prefix_rep" "1")
12404 (set_attr "type" "bitmanip")
12405 (set_attr "mode" "SI")])
12407 (define_expand "bswap<mode>2"
12408 [(set (match_operand:SWI48 0 "register_operand" "")
12409 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12412 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12414 rtx x = operands[0];
12416 emit_move_insn (x, operands[1]);
12417 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12418 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12419 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424 (define_insn "*bswap<mode>2_movbe"
12425 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12426 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12431 movbe\t{%1, %0|%0, %1}
12432 movbe\t{%1, %0|%0, %1}"
12433 [(set_attr "type" "bitmanip,imov,imov")
12434 (set_attr "modrm" "0,1,1")
12435 (set_attr "prefix_0f" "*,1,1")
12436 (set_attr "prefix_extra" "*,1,1")
12437 (set_attr "mode" "<MODE>")])
12439 (define_insn "*bswap<mode>2_1"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12441 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12444 [(set_attr "type" "bitmanip")
12445 (set_attr "modrm" "0")
12446 (set_attr "mode" "<MODE>")])
12448 (define_insn "*bswaphi_lowpart_1"
12449 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12450 (bswap:HI (match_dup 0)))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12454 xchg{b}\t{%h0, %b0|%b0, %h0}
12455 rol{w}\t{$8, %0|%0, 8}"
12456 [(set_attr "length" "2,4")
12457 (set_attr "mode" "QI,HI")])
12459 (define_insn "bswaphi_lowpart"
12460 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12461 (bswap:HI (match_dup 0)))
12462 (clobber (reg:CC FLAGS_REG))]
12464 "rol{w}\t{$8, %0|%0, 8}"
12465 [(set_attr "length" "4")
12466 (set_attr "mode" "HI")])
12468 (define_expand "paritydi2"
12469 [(set (match_operand:DI 0 "register_operand" "")
12470 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12473 rtx scratch = gen_reg_rtx (QImode);
12476 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12477 NULL_RTX, operands[1]));
12479 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12480 gen_rtx_REG (CCmode, FLAGS_REG),
12482 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12485 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12488 rtx tmp = gen_reg_rtx (SImode);
12490 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12491 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12496 (define_expand "paritysi2"
12497 [(set (match_operand:SI 0 "register_operand" "")
12498 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12501 rtx scratch = gen_reg_rtx (QImode);
12504 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12506 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12507 gen_rtx_REG (CCmode, FLAGS_REG),
12509 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12511 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12515 (define_insn_and_split "paritydi2_cmp"
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12519 (clobber (match_scratch:DI 0 "=r"))
12520 (clobber (match_scratch:SI 1 "=&r"))
12521 (clobber (match_scratch:HI 2 "=Q"))]
12524 "&& reload_completed"
12526 [(set (match_dup 1)
12527 (xor:SI (match_dup 1) (match_dup 4)))
12528 (clobber (reg:CC FLAGS_REG))])
12530 [(set (reg:CC FLAGS_REG)
12531 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12532 (clobber (match_dup 1))
12533 (clobber (match_dup 2))])]
12535 operands[4] = gen_lowpart (SImode, operands[3]);
12539 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12540 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12543 operands[1] = gen_highpart (SImode, operands[3]);
12546 (define_insn_and_split "paritysi2_cmp"
12547 [(set (reg:CC FLAGS_REG)
12548 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12550 (clobber (match_scratch:SI 0 "=r"))
12551 (clobber (match_scratch:HI 1 "=&Q"))]
12554 "&& reload_completed"
12556 [(set (match_dup 1)
12557 (xor:HI (match_dup 1) (match_dup 3)))
12558 (clobber (reg:CC FLAGS_REG))])
12560 [(set (reg:CC FLAGS_REG)
12561 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12562 (clobber (match_dup 1))])]
12564 operands[3] = gen_lowpart (HImode, operands[2]);
12566 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12567 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12570 (define_insn "*parityhi2_cmp"
12571 [(set (reg:CC FLAGS_REG)
12572 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12574 (clobber (match_scratch:HI 0 "=Q"))]
12576 "xor{b}\t{%h0, %b0|%b0, %h0}"
12577 [(set_attr "length" "2")
12578 (set_attr "mode" "HI")])
12581 ;; Thread-local storage patterns for ELF.
12583 ;; Note that these code sequences must appear exactly as shown
12584 ;; in order to allow linker relaxation.
12586 (define_insn "*tls_global_dynamic_32_gnu"
12587 [(set (match_operand:SI 0 "register_operand" "=a")
12589 [(match_operand:SI 1 "register_operand" "b")
12590 (match_operand:SI 2 "tls_symbolic_operand" "")
12591 (match_operand:SI 3 "constant_call_address_operand" "z")]
12593 (clobber (match_scratch:SI 4 "=d"))
12594 (clobber (match_scratch:SI 5 "=c"))
12595 (clobber (reg:CC FLAGS_REG))]
12596 "!TARGET_64BIT && TARGET_GNU_TLS"
12599 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12600 if (TARGET_SUN_TLS)
12601 #ifdef HAVE_AS_IX86_TLSGDPLT
12602 return "call\t%a2@tlsgdplt";
12604 return "call\t%p3@plt";
12606 return "call\t%P3";
12608 [(set_attr "type" "multi")
12609 (set_attr "length" "12")])
12611 (define_expand "tls_global_dynamic_32"
12613 [(set (match_operand:SI 0 "register_operand" "")
12614 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12615 (match_operand:SI 1 "tls_symbolic_operand" "")
12616 (match_operand:SI 3 "constant_call_address_operand" "")]
12618 (clobber (match_scratch:SI 4 ""))
12619 (clobber (match_scratch:SI 5 ""))
12620 (clobber (reg:CC FLAGS_REG))])])
12622 (define_insn "*tls_global_dynamic_64"
12623 [(set (match_operand:DI 0 "register_operand" "=a")
12625 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12626 (match_operand:DI 3 "" "")))
12627 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12632 fputs (ASM_BYTE "0x66\n", asm_out_file);
12634 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12635 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12636 fputs ("\trex64\n", asm_out_file);
12637 if (TARGET_SUN_TLS)
12638 return "call\t%p2@plt";
12639 return "call\t%P2";
12641 [(set_attr "type" "multi")
12642 (set (attr "length")
12643 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12645 (define_expand "tls_global_dynamic_64"
12647 [(set (match_operand:DI 0 "register_operand" "")
12649 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12651 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12654 (define_insn "*tls_local_dynamic_base_32_gnu"
12655 [(set (match_operand:SI 0 "register_operand" "=a")
12657 [(match_operand:SI 1 "register_operand" "b")
12658 (match_operand:SI 2 "constant_call_address_operand" "z")]
12659 UNSPEC_TLS_LD_BASE))
12660 (clobber (match_scratch:SI 3 "=d"))
12661 (clobber (match_scratch:SI 4 "=c"))
12662 (clobber (reg:CC FLAGS_REG))]
12663 "!TARGET_64BIT && TARGET_GNU_TLS"
12666 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12667 if (TARGET_SUN_TLS)
12668 #ifdef HAVE_AS_IX86_TLSLDMPLT
12669 return "call\t%&@tlsldmplt";
12671 return "call\t%p2@plt";
12673 return "call\t%P2";
12675 [(set_attr "type" "multi")
12676 (set_attr "length" "11")])
12678 (define_expand "tls_local_dynamic_base_32"
12680 [(set (match_operand:SI 0 "register_operand" "")
12682 [(match_operand:SI 1 "register_operand" "")
12683 (match_operand:SI 2 "constant_call_address_operand" "")]
12684 UNSPEC_TLS_LD_BASE))
12685 (clobber (match_scratch:SI 3 ""))
12686 (clobber (match_scratch:SI 4 ""))
12687 (clobber (reg:CC FLAGS_REG))])])
12689 (define_insn "*tls_local_dynamic_base_64"
12690 [(set (match_operand:DI 0 "register_operand" "=a")
12692 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12693 (match_operand:DI 2 "" "")))
12694 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12698 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12699 if (TARGET_SUN_TLS)
12700 return "call\t%p1@plt";
12701 return "call\t%P1";
12703 [(set_attr "type" "multi")
12704 (set_attr "length" "12")])
12706 (define_expand "tls_local_dynamic_base_64"
12708 [(set (match_operand:DI 0 "register_operand" "")
12710 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12712 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12714 ;; Local dynamic of a single variable is a lose. Show combine how
12715 ;; to convert that back to global dynamic.
12717 (define_insn_and_split "*tls_local_dynamic_32_once"
12718 [(set (match_operand:SI 0 "register_operand" "=a")
12720 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12721 (match_operand:SI 2 "constant_call_address_operand" "z")]
12722 UNSPEC_TLS_LD_BASE)
12723 (const:SI (unspec:SI
12724 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12726 (clobber (match_scratch:SI 4 "=d"))
12727 (clobber (match_scratch:SI 5 "=c"))
12728 (clobber (reg:CC FLAGS_REG))]
12733 [(set (match_dup 0)
12734 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12736 (clobber (match_dup 4))
12737 (clobber (match_dup 5))
12738 (clobber (reg:CC FLAGS_REG))])])
12740 ;; Segment register for the thread base ptr load
12741 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12743 ;; Load and add the thread base pointer from %<tp_seg>:0.
12744 (define_insn "*load_tp_x32"
12745 [(set (match_operand:SI 0 "register_operand" "=r")
12746 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12748 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12749 [(set_attr "type" "imov")
12750 (set_attr "modrm" "0")
12751 (set_attr "length" "7")
12752 (set_attr "memory" "load")
12753 (set_attr "imm_disp" "false")])
12755 (define_insn "*load_tp_x32_zext"
12756 [(set (match_operand:DI 0 "register_operand" "=r")
12757 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12759 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12760 [(set_attr "type" "imov")
12761 (set_attr "modrm" "0")
12762 (set_attr "length" "7")
12763 (set_attr "memory" "load")
12764 (set_attr "imm_disp" "false")])
12766 (define_insn "*load_tp_<mode>"
12767 [(set (match_operand:P 0 "register_operand" "=r")
12768 (unspec:P [(const_int 0)] UNSPEC_TP))]
12770 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12771 [(set_attr "type" "imov")
12772 (set_attr "modrm" "0")
12773 (set_attr "length" "7")
12774 (set_attr "memory" "load")
12775 (set_attr "imm_disp" "false")])
12777 (define_insn "*add_tp_x32"
12778 [(set (match_operand:SI 0 "register_operand" "=r")
12779 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12780 (match_operand:SI 1 "register_operand" "0")))
12781 (clobber (reg:CC FLAGS_REG))]
12783 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12784 [(set_attr "type" "alu")
12785 (set_attr "modrm" "0")
12786 (set_attr "length" "7")
12787 (set_attr "memory" "load")
12788 (set_attr "imm_disp" "false")])
12790 (define_insn "*add_tp_x32_zext"
12791 [(set (match_operand:DI 0 "register_operand" "=r")
12793 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12794 (match_operand:SI 1 "register_operand" "0"))))
12795 (clobber (reg:CC FLAGS_REG))]
12797 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12798 [(set_attr "type" "alu")
12799 (set_attr "modrm" "0")
12800 (set_attr "length" "7")
12801 (set_attr "memory" "load")
12802 (set_attr "imm_disp" "false")])
12804 (define_insn "*add_tp_<mode>"
12805 [(set (match_operand:P 0 "register_operand" "=r")
12806 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12807 (match_operand:P 1 "register_operand" "0")))
12808 (clobber (reg:CC FLAGS_REG))]
12810 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12811 [(set_attr "type" "alu")
12812 (set_attr "modrm" "0")
12813 (set_attr "length" "7")
12814 (set_attr "memory" "load")
12815 (set_attr "imm_disp" "false")])
12817 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12818 ;; %rax as destination of the initial executable code sequence.
12819 (define_insn "tls_initial_exec_64_sun"
12820 [(set (match_operand:DI 0 "register_operand" "=a")
12822 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12823 UNSPEC_TLS_IE_SUN))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "TARGET_64BIT && TARGET_SUN_TLS"
12828 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12829 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12831 [(set_attr "type" "multi")])
12833 ;; GNU2 TLS patterns can be split.
12835 (define_expand "tls_dynamic_gnu2_32"
12836 [(set (match_dup 3)
12837 (plus:SI (match_operand:SI 2 "register_operand" "")
12839 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12842 [(set (match_operand:SI 0 "register_operand" "")
12843 (unspec:SI [(match_dup 1) (match_dup 3)
12844 (match_dup 2) (reg:SI SP_REG)]
12846 (clobber (reg:CC FLAGS_REG))])]
12847 "!TARGET_64BIT && TARGET_GNU2_TLS"
12849 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12850 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12853 (define_insn "*tls_dynamic_gnu2_lea_32"
12854 [(set (match_operand:SI 0 "register_operand" "=r")
12855 (plus:SI (match_operand:SI 1 "register_operand" "b")
12857 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12858 UNSPEC_TLSDESC))))]
12859 "!TARGET_64BIT && TARGET_GNU2_TLS"
12860 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12861 [(set_attr "type" "lea")
12862 (set_attr "mode" "SI")
12863 (set_attr "length" "6")
12864 (set_attr "length_address" "4")])
12866 (define_insn "*tls_dynamic_gnu2_call_32"
12867 [(set (match_operand:SI 0 "register_operand" "=a")
12868 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12869 (match_operand:SI 2 "register_operand" "0")
12870 ;; we have to make sure %ebx still points to the GOT
12871 (match_operand:SI 3 "register_operand" "b")
12874 (clobber (reg:CC FLAGS_REG))]
12875 "!TARGET_64BIT && TARGET_GNU2_TLS"
12876 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12877 [(set_attr "type" "call")
12878 (set_attr "length" "2")
12879 (set_attr "length_address" "0")])
12881 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12882 [(set (match_operand:SI 0 "register_operand" "=&a")
12884 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12885 (match_operand:SI 4 "" "")
12886 (match_operand:SI 2 "register_operand" "b")
12889 (const:SI (unspec:SI
12890 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12892 (clobber (reg:CC FLAGS_REG))]
12893 "!TARGET_64BIT && TARGET_GNU2_TLS"
12896 [(set (match_dup 0) (match_dup 5))]
12898 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12899 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12902 (define_expand "tls_dynamic_gnu2_64"
12903 [(set (match_dup 2)
12904 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12907 [(set (match_operand:DI 0 "register_operand" "")
12908 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12910 (clobber (reg:CC FLAGS_REG))])]
12911 "TARGET_64BIT && TARGET_GNU2_TLS"
12913 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12914 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12917 (define_insn "*tls_dynamic_gnu2_lea_64"
12918 [(set (match_operand:DI 0 "register_operand" "=r")
12919 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12921 "TARGET_64BIT && TARGET_GNU2_TLS"
12922 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12923 [(set_attr "type" "lea")
12924 (set_attr "mode" "DI")
12925 (set_attr "length" "7")
12926 (set_attr "length_address" "4")])
12928 (define_insn "*tls_dynamic_gnu2_call_64"
12929 [(set (match_operand:DI 0 "register_operand" "=a")
12930 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12931 (match_operand:DI 2 "register_operand" "0")
12934 (clobber (reg:CC FLAGS_REG))]
12935 "TARGET_64BIT && TARGET_GNU2_TLS"
12936 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12937 [(set_attr "type" "call")
12938 (set_attr "length" "2")
12939 (set_attr "length_address" "0")])
12941 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12942 [(set (match_operand:DI 0 "register_operand" "=&a")
12944 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12945 (match_operand:DI 3 "" "")
12948 (const:DI (unspec:DI
12949 [(match_operand 1 "tls_symbolic_operand" "")]
12951 (clobber (reg:CC FLAGS_REG))]
12952 "TARGET_64BIT && TARGET_GNU2_TLS"
12955 [(set (match_dup 0) (match_dup 4))]
12957 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12958 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12961 ;; These patterns match the binary 387 instructions for addM3, subM3,
12962 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12963 ;; SFmode. The first is the normal insn, the second the same insn but
12964 ;; with one operand a conversion, and the third the same insn but with
12965 ;; the other operand a conversion. The conversion may be SFmode or
12966 ;; SImode if the target mode DFmode, but only SImode if the target mode
12969 ;; Gcc is slightly more smart about handling normal two address instructions
12970 ;; so use special patterns for add and mull.
12972 (define_insn "*fop_<mode>_comm_mixed"
12973 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12974 (match_operator:MODEF 3 "binary_fp_operator"
12975 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12976 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12977 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12978 && COMMUTATIVE_ARITH_P (operands[3])
12979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12980 "* return output_387_binary_op (insn, operands);"
12981 [(set (attr "type")
12982 (if_then_else (eq_attr "alternative" "1,2")
12983 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "ssemul")
12985 (const_string "sseadd"))
12986 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12987 (const_string "fmul")
12988 (const_string "fop"))))
12989 (set_attr "isa" "*,noavx,avx")
12990 (set_attr "prefix" "orig,orig,vex")
12991 (set_attr "mode" "<MODE>")])
12993 (define_insn "*fop_<mode>_comm_sse"
12994 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12995 (match_operator:MODEF 3 "binary_fp_operator"
12996 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12997 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12998 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12999 && COMMUTATIVE_ARITH_P (operands[3])
13000 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13001 "* return output_387_binary_op (insn, operands);"
13002 [(set (attr "type")
13003 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13004 (const_string "ssemul")
13005 (const_string "sseadd")))
13006 (set_attr "isa" "noavx,avx")
13007 (set_attr "prefix" "orig,vex")
13008 (set_attr "mode" "<MODE>")])
13010 (define_insn "*fop_<mode>_comm_i387"
13011 [(set (match_operand:MODEF 0 "register_operand" "=f")
13012 (match_operator:MODEF 3 "binary_fp_operator"
13013 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13014 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13015 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13016 && COMMUTATIVE_ARITH_P (operands[3])
13017 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13018 "* return output_387_binary_op (insn, operands);"
13019 [(set (attr "type")
13020 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13021 (const_string "fmul")
13022 (const_string "fop")))
13023 (set_attr "mode" "<MODE>")])
13025 (define_insn "*fop_<mode>_1_mixed"
13026 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13027 (match_operator:MODEF 3 "binary_fp_operator"
13028 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13029 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13030 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13031 && !COMMUTATIVE_ARITH_P (operands[3])
13032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033 "* return output_387_binary_op (insn, operands);"
13034 [(set (attr "type")
13035 (cond [(and (eq_attr "alternative" "2,3")
13036 (match_operand:MODEF 3 "mult_operator" ""))
13037 (const_string "ssemul")
13038 (and (eq_attr "alternative" "2,3")
13039 (match_operand:MODEF 3 "div_operator" ""))
13040 (const_string "ssediv")
13041 (eq_attr "alternative" "2,3")
13042 (const_string "sseadd")
13043 (match_operand:MODEF 3 "mult_operator" "")
13044 (const_string "fmul")
13045 (match_operand:MODEF 3 "div_operator" "")
13046 (const_string "fdiv")
13048 (const_string "fop")))
13049 (set_attr "isa" "*,*,noavx,avx")
13050 (set_attr "prefix" "orig,orig,orig,vex")
13051 (set_attr "mode" "<MODE>")])
13053 (define_insn "*rcpsf2_sse"
13054 [(set (match_operand:SF 0 "register_operand" "=x")
13055 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13058 "%vrcpss\t{%1, %d0|%d0, %1}"
13059 [(set_attr "type" "sse")
13060 (set_attr "atom_sse_attr" "rcp")
13061 (set_attr "prefix" "maybe_vex")
13062 (set_attr "mode" "SF")])
13064 (define_insn "*fop_<mode>_1_sse"
13065 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "register_operand" "0,x")
13068 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13069 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070 && !COMMUTATIVE_ARITH_P (operands[3])"
13071 "* return output_387_binary_op (insn, operands);"
13072 [(set (attr "type")
13073 (cond [(match_operand:MODEF 3 "mult_operator" "")
13074 (const_string "ssemul")
13075 (match_operand:MODEF 3 "div_operator" "")
13076 (const_string "ssediv")
13078 (const_string "sseadd")))
13079 (set_attr "isa" "noavx,avx")
13080 (set_attr "prefix" "orig,vex")
13081 (set_attr "mode" "<MODE>")])
13083 ;; This pattern is not fully shadowed by the pattern above.
13084 (define_insn "*fop_<mode>_1_i387"
13085 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086 (match_operator:MODEF 3 "binary_fp_operator"
13087 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13088 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13089 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13090 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13091 && !COMMUTATIVE_ARITH_P (operands[3])
13092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13093 "* return output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:MODEF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:MODEF 3 "div_operator" "")
13098 (const_string "fdiv")
13100 (const_string "fop")))
13101 (set_attr "mode" "<MODE>")])
13103 ;; ??? Add SSE splitters for these!
13104 (define_insn "*fop_<MODEF:mode>_2_i387"
13105 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13106 (match_operator:MODEF 3 "binary_fp_operator"
13108 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13109 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13110 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13111 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13112 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13113 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:MODEF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:MODEF 3 "div_operator" "")
13118 (const_string "fdiv")
13120 (const_string "fop")))
13121 (set_attr "fp_int_src" "true")
13122 (set_attr "mode" "<SWI24:MODE>")])
13124 (define_insn "*fop_<MODEF:mode>_3_i387"
13125 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13126 (match_operator:MODEF 3 "binary_fp_operator"
13127 [(match_operand:MODEF 1 "register_operand" "0,0")
13129 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13130 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13131 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13132 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13133 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13134 [(set (attr "type")
13135 (cond [(match_operand:MODEF 3 "mult_operator" "")
13136 (const_string "fmul")
13137 (match_operand:MODEF 3 "div_operator" "")
13138 (const_string "fdiv")
13140 (const_string "fop")))
13141 (set_attr "fp_int_src" "true")
13142 (set_attr "mode" "<MODE>")])
13144 (define_insn "*fop_df_4_i387"
13145 [(set (match_operand:DF 0 "register_operand" "=f,f")
13146 (match_operator:DF 3 "binary_fp_operator"
13148 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13149 (match_operand:DF 2 "register_operand" "0,f")]))]
13150 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13151 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13152 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13153 "* return output_387_binary_op (insn, operands);"
13154 [(set (attr "type")
13155 (cond [(match_operand:DF 3 "mult_operator" "")
13156 (const_string "fmul")
13157 (match_operand:DF 3 "div_operator" "")
13158 (const_string "fdiv")
13160 (const_string "fop")))
13161 (set_attr "mode" "SF")])
13163 (define_insn "*fop_df_5_i387"
13164 [(set (match_operand:DF 0 "register_operand" "=f,f")
13165 (match_operator:DF 3 "binary_fp_operator"
13166 [(match_operand:DF 1 "register_operand" "0,f")
13168 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13169 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13170 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
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_6_i387"
13182 [(set (match_operand:DF 0 "register_operand" "=f,f")
13183 (match_operator:DF 3 "binary_fp_operator"
13185 (match_operand:SF 1 "register_operand" "0,f"))
13187 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13188 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13189 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13190 "* return output_387_binary_op (insn, operands);"
13191 [(set (attr "type")
13192 (cond [(match_operand:DF 3 "mult_operator" "")
13193 (const_string "fmul")
13194 (match_operand:DF 3 "div_operator" "")
13195 (const_string "fdiv")
13197 (const_string "fop")))
13198 (set_attr "mode" "SF")])
13200 (define_insn "*fop_xf_comm_i387"
13201 [(set (match_operand:XF 0 "register_operand" "=f")
13202 (match_operator:XF 3 "binary_fp_operator"
13203 [(match_operand:XF 1 "register_operand" "%0")
13204 (match_operand:XF 2 "register_operand" "f")]))]
13206 && COMMUTATIVE_ARITH_P (operands[3])"
13207 "* return output_387_binary_op (insn, operands);"
13208 [(set (attr "type")
13209 (if_then_else (match_operand:XF 3 "mult_operator" "")
13210 (const_string "fmul")
13211 (const_string "fop")))
13212 (set_attr "mode" "XF")])
13214 (define_insn "*fop_xf_1_i387"
13215 [(set (match_operand:XF 0 "register_operand" "=f,f")
13216 (match_operator:XF 3 "binary_fp_operator"
13217 [(match_operand:XF 1 "register_operand" "0,f")
13218 (match_operand:XF 2 "register_operand" "f,0")]))]
13220 && !COMMUTATIVE_ARITH_P (operands[3])"
13221 "* return output_387_binary_op (insn, operands);"
13222 [(set (attr "type")
13223 (cond [(match_operand:XF 3 "mult_operator" "")
13224 (const_string "fmul")
13225 (match_operand:XF 3 "div_operator" "")
13226 (const_string "fdiv")
13228 (const_string "fop")))
13229 (set_attr "mode" "XF")])
13231 (define_insn "*fop_xf_2_i387"
13232 [(set (match_operand:XF 0 "register_operand" "=f,f")
13233 (match_operator:XF 3 "binary_fp_operator"
13235 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13236 (match_operand:XF 2 "register_operand" "0,0")]))]
13237 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13238 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13239 [(set (attr "type")
13240 (cond [(match_operand:XF 3 "mult_operator" "")
13241 (const_string "fmul")
13242 (match_operand:XF 3 "div_operator" "")
13243 (const_string "fdiv")
13245 (const_string "fop")))
13246 (set_attr "fp_int_src" "true")
13247 (set_attr "mode" "<MODE>")])
13249 (define_insn "*fop_xf_3_i387"
13250 [(set (match_operand:XF 0 "register_operand" "=f,f")
13251 (match_operator:XF 3 "binary_fp_operator"
13252 [(match_operand:XF 1 "register_operand" "0,0")
13254 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
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_4_i387"
13268 [(set (match_operand:XF 0 "register_operand" "=f,f")
13269 (match_operator:XF 3 "binary_fp_operator"
13271 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13272 (match_operand:XF 2 "register_operand" "0,f")]))]
13274 "* return 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 "mode" "<MODE>")])
13284 (define_insn "*fop_xf_5_i387"
13285 [(set (match_operand:XF 0 "register_operand" "=f,f")
13286 (match_operator:XF 3 "binary_fp_operator"
13287 [(match_operand:XF 1 "register_operand" "0,f")
13289 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13291 "* return output_387_binary_op (insn, operands);"
13292 [(set (attr "type")
13293 (cond [(match_operand:XF 3 "mult_operator" "")
13294 (const_string "fmul")
13295 (match_operand:XF 3 "div_operator" "")
13296 (const_string "fdiv")
13298 (const_string "fop")))
13299 (set_attr "mode" "<MODE>")])
13301 (define_insn "*fop_xf_6_i387"
13302 [(set (match_operand:XF 0 "register_operand" "=f,f")
13303 (match_operator:XF 3 "binary_fp_operator"
13305 (match_operand:MODEF 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>")])
13320 [(set (match_operand 0 "register_operand" "")
13321 (match_operator 3 "binary_fp_operator"
13322 [(float (match_operand:SWI24 1 "register_operand" ""))
13323 (match_operand 2 "register_operand" "")]))]
13325 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13326 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13329 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13330 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13331 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13332 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13333 GET_MODE (operands[3]),
13336 ix86_free_from_memory (GET_MODE (operands[1]));
13341 [(set (match_operand 0 "register_operand" "")
13342 (match_operator 3 "binary_fp_operator"
13343 [(match_operand 1 "register_operand" "")
13344 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13346 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13347 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13350 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13351 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13352 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13353 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13354 GET_MODE (operands[3]),
13357 ix86_free_from_memory (GET_MODE (operands[2]));
13361 ;; FPU special functions.
13363 ;; This pattern implements a no-op XFmode truncation for
13364 ;; all fancy i386 XFmode math functions.
13366 (define_insn "truncxf<mode>2_i387_noop_unspec"
13367 [(set (match_operand:MODEF 0 "register_operand" "=f")
13368 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13369 UNSPEC_TRUNC_NOOP))]
13370 "TARGET_USE_FANCY_MATH_387"
13371 "* return output_387_reg_move (insn, operands);"
13372 [(set_attr "type" "fmov")
13373 (set_attr "mode" "<MODE>")])
13375 (define_insn "sqrtxf2"
13376 [(set (match_operand:XF 0 "register_operand" "=f")
13377 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13378 "TARGET_USE_FANCY_MATH_387"
13380 [(set_attr "type" "fpspc")
13381 (set_attr "mode" "XF")
13382 (set_attr "athlon_decode" "direct")
13383 (set_attr "amdfam10_decode" "direct")
13384 (set_attr "bdver1_decode" "direct")])
13386 (define_insn "sqrt_extend<mode>xf2_i387"
13387 [(set (match_operand:XF 0 "register_operand" "=f")
13390 (match_operand:MODEF 1 "register_operand" "0"))))]
13391 "TARGET_USE_FANCY_MATH_387"
13393 [(set_attr "type" "fpspc")
13394 (set_attr "mode" "XF")
13395 (set_attr "athlon_decode" "direct")
13396 (set_attr "amdfam10_decode" "direct")
13397 (set_attr "bdver1_decode" "direct")])
13399 (define_insn "*rsqrtsf2_sse"
13400 [(set (match_operand:SF 0 "register_operand" "=x")
13401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13404 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13405 [(set_attr "type" "sse")
13406 (set_attr "atom_sse_attr" "rcp")
13407 (set_attr "prefix" "maybe_vex")
13408 (set_attr "mode" "SF")])
13410 (define_expand "rsqrtsf2"
13411 [(set (match_operand:SF 0 "register_operand" "")
13412 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13416 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13420 (define_insn "*sqrt<mode>2_sse"
13421 [(set (match_operand:MODEF 0 "register_operand" "=x")
13423 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13425 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13426 [(set_attr "type" "sse")
13427 (set_attr "atom_sse_attr" "sqrt")
13428 (set_attr "prefix" "maybe_vex")
13429 (set_attr "mode" "<MODE>")
13430 (set_attr "athlon_decode" "*")
13431 (set_attr "amdfam10_decode" "*")
13432 (set_attr "bdver1_decode" "*")])
13434 (define_expand "sqrt<mode>2"
13435 [(set (match_operand:MODEF 0 "register_operand" "")
13437 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13438 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13439 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13441 if (<MODE>mode == SFmode
13443 && TARGET_RECIP_SQRT
13444 && !optimize_function_for_size_p (cfun)
13445 && flag_finite_math_only && !flag_trapping_math
13446 && flag_unsafe_math_optimizations)
13448 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13452 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13454 rtx op0 = gen_reg_rtx (XFmode);
13455 rtx op1 = force_reg (<MODE>mode, operands[1]);
13457 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13458 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13463 (define_insn "fpremxf4_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f")
13465 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13466 (match_operand:XF 3 "register_operand" "1")]
13468 (set (match_operand:XF 1 "register_operand" "=u")
13469 (unspec:XF [(match_dup 2) (match_dup 3)]
13471 (set (reg:CCFP FPSR_REG)
13472 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13474 "TARGET_USE_FANCY_MATH_387"
13476 [(set_attr "type" "fpspc")
13477 (set_attr "mode" "XF")])
13479 (define_expand "fmodxf3"
13480 [(use (match_operand:XF 0 "register_operand" ""))
13481 (use (match_operand:XF 1 "general_operand" ""))
13482 (use (match_operand:XF 2 "general_operand" ""))]
13483 "TARGET_USE_FANCY_MATH_387"
13485 rtx label = gen_label_rtx ();
13487 rtx op1 = gen_reg_rtx (XFmode);
13488 rtx op2 = gen_reg_rtx (XFmode);
13490 emit_move_insn (op2, operands[2]);
13491 emit_move_insn (op1, operands[1]);
13493 emit_label (label);
13494 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13495 ix86_emit_fp_unordered_jump (label);
13496 LABEL_NUSES (label) = 1;
13498 emit_move_insn (operands[0], op1);
13502 (define_expand "fmod<mode>3"
13503 [(use (match_operand:MODEF 0 "register_operand" ""))
13504 (use (match_operand:MODEF 1 "general_operand" ""))
13505 (use (match_operand:MODEF 2 "general_operand" ""))]
13506 "TARGET_USE_FANCY_MATH_387"
13508 rtx (*gen_truncxf) (rtx, rtx);
13510 rtx label = gen_label_rtx ();
13512 rtx op1 = gen_reg_rtx (XFmode);
13513 rtx op2 = gen_reg_rtx (XFmode);
13515 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13518 emit_label (label);
13519 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13520 ix86_emit_fp_unordered_jump (label);
13521 LABEL_NUSES (label) = 1;
13523 /* Truncate the result properly for strict SSE math. */
13524 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13525 && !TARGET_MIX_SSE_I387)
13526 gen_truncxf = gen_truncxf<mode>2;
13528 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13530 emit_insn (gen_truncxf (operands[0], op1));
13534 (define_insn "fprem1xf4_i387"
13535 [(set (match_operand:XF 0 "register_operand" "=f")
13536 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13537 (match_operand:XF 3 "register_operand" "1")]
13539 (set (match_operand:XF 1 "register_operand" "=u")
13540 (unspec:XF [(match_dup 2) (match_dup 3)]
13542 (set (reg:CCFP FPSR_REG)
13543 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13545 "TARGET_USE_FANCY_MATH_387"
13547 [(set_attr "type" "fpspc")
13548 (set_attr "mode" "XF")])
13550 (define_expand "remainderxf3"
13551 [(use (match_operand:XF 0 "register_operand" ""))
13552 (use (match_operand:XF 1 "general_operand" ""))
13553 (use (match_operand:XF 2 "general_operand" ""))]
13554 "TARGET_USE_FANCY_MATH_387"
13556 rtx label = gen_label_rtx ();
13558 rtx op1 = gen_reg_rtx (XFmode);
13559 rtx op2 = gen_reg_rtx (XFmode);
13561 emit_move_insn (op2, operands[2]);
13562 emit_move_insn (op1, operands[1]);
13564 emit_label (label);
13565 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13566 ix86_emit_fp_unordered_jump (label);
13567 LABEL_NUSES (label) = 1;
13569 emit_move_insn (operands[0], op1);
13573 (define_expand "remainder<mode>3"
13574 [(use (match_operand:MODEF 0 "register_operand" ""))
13575 (use (match_operand:MODEF 1 "general_operand" ""))
13576 (use (match_operand:MODEF 2 "general_operand" ""))]
13577 "TARGET_USE_FANCY_MATH_387"
13579 rtx (*gen_truncxf) (rtx, rtx);
13581 rtx label = gen_label_rtx ();
13583 rtx op1 = gen_reg_rtx (XFmode);
13584 rtx op2 = gen_reg_rtx (XFmode);
13586 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13587 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13589 emit_label (label);
13591 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13592 ix86_emit_fp_unordered_jump (label);
13593 LABEL_NUSES (label) = 1;
13595 /* Truncate the result properly for strict SSE math. */
13596 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13597 && !TARGET_MIX_SSE_I387)
13598 gen_truncxf = gen_truncxf<mode>2;
13600 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13602 emit_insn (gen_truncxf (operands[0], op1));
13606 (define_insn "*sinxf2_i387"
13607 [(set (match_operand:XF 0 "register_operand" "=f")
13608 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13609 "TARGET_USE_FANCY_MATH_387
13610 && flag_unsafe_math_optimizations"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")])
13615 (define_insn "*sin_extend<mode>xf2_i387"
13616 [(set (match_operand:XF 0 "register_operand" "=f")
13617 (unspec:XF [(float_extend:XF
13618 (match_operand:MODEF 1 "register_operand" "0"))]
13620 "TARGET_USE_FANCY_MATH_387
13621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13622 || TARGET_MIX_SSE_I387)
13623 && flag_unsafe_math_optimizations"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13628 (define_insn "*cosxf2_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13631 "TARGET_USE_FANCY_MATH_387
13632 && flag_unsafe_math_optimizations"
13634 [(set_attr "type" "fpspc")
13635 (set_attr "mode" "XF")])
13637 (define_insn "*cos_extend<mode>xf2_i387"
13638 [(set (match_operand:XF 0 "register_operand" "=f")
13639 (unspec:XF [(float_extend:XF
13640 (match_operand:MODEF 1 "register_operand" "0"))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644 || TARGET_MIX_SSE_I387)
13645 && flag_unsafe_math_optimizations"
13647 [(set_attr "type" "fpspc")
13648 (set_attr "mode" "XF")])
13650 ;; When sincos pattern is defined, sin and cos builtin functions will be
13651 ;; expanded to sincos pattern with one of its outputs left unused.
13652 ;; CSE pass will figure out if two sincos patterns can be combined,
13653 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13654 ;; depending on the unused output.
13656 (define_insn "sincosxf3"
13657 [(set (match_operand:XF 0 "register_operand" "=f")
13658 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "=u")
13661 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13662 "TARGET_USE_FANCY_MATH_387
13663 && flag_unsafe_math_optimizations"
13665 [(set_attr "type" "fpspc")
13666 (set_attr "mode" "XF")])
13669 [(set (match_operand:XF 0 "register_operand" "")
13670 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13671 UNSPEC_SINCOS_COS))
13672 (set (match_operand:XF 1 "register_operand" "")
13673 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13674 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13675 && can_create_pseudo_p ()"
13676 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13679 [(set (match_operand:XF 0 "register_operand" "")
13680 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13681 UNSPEC_SINCOS_COS))
13682 (set (match_operand:XF 1 "register_operand" "")
13683 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13684 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13685 && can_create_pseudo_p ()"
13686 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13688 (define_insn "sincos_extend<mode>xf3_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(float_extend:XF
13691 (match_operand:MODEF 2 "register_operand" "0"))]
13692 UNSPEC_SINCOS_COS))
13693 (set (match_operand:XF 1 "register_operand" "=u")
13694 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695 "TARGET_USE_FANCY_MATH_387
13696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13697 || TARGET_MIX_SSE_I387)
13698 && flag_unsafe_math_optimizations"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13704 [(set (match_operand:XF 0 "register_operand" "")
13705 (unspec:XF [(float_extend:XF
13706 (match_operand:MODEF 2 "register_operand" ""))]
13707 UNSPEC_SINCOS_COS))
13708 (set (match_operand:XF 1 "register_operand" "")
13709 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13710 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13711 && can_create_pseudo_p ()"
13712 [(set (match_dup 1)
13713 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13716 [(set (match_operand:XF 0 "register_operand" "")
13717 (unspec:XF [(float_extend:XF
13718 (match_operand:MODEF 2 "register_operand" ""))]
13719 UNSPEC_SINCOS_COS))
13720 (set (match_operand:XF 1 "register_operand" "")
13721 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13722 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13723 && can_create_pseudo_p ()"
13724 [(set (match_dup 0)
13725 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13727 (define_expand "sincos<mode>3"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))
13730 (use (match_operand:MODEF 2 "register_operand" ""))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733 || TARGET_MIX_SSE_I387)
13734 && flag_unsafe_math_optimizations"
13736 rtx op0 = gen_reg_rtx (XFmode);
13737 rtx op1 = gen_reg_rtx (XFmode);
13739 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13745 (define_insn "fptanxf4_i387"
13746 [(set (match_operand:XF 0 "register_operand" "=f")
13747 (match_operand:XF 3 "const_double_operand" "F"))
13748 (set (match_operand:XF 1 "register_operand" "=u")
13749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13751 "TARGET_USE_FANCY_MATH_387
13752 && flag_unsafe_math_optimizations
13753 && standard_80387_constant_p (operands[3]) == 2"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13758 (define_insn "fptan_extend<mode>xf4_i387"
13759 [(set (match_operand:MODEF 0 "register_operand" "=f")
13760 (match_operand:MODEF 3 "const_double_operand" "F"))
13761 (set (match_operand:XF 1 "register_operand" "=u")
13762 (unspec:XF [(float_extend:XF
13763 (match_operand:MODEF 2 "register_operand" "0"))]
13765 "TARGET_USE_FANCY_MATH_387
13766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767 || TARGET_MIX_SSE_I387)
13768 && flag_unsafe_math_optimizations
13769 && standard_80387_constant_p (operands[3]) == 2"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "tanxf2"
13775 [(use (match_operand:XF 0 "register_operand" ""))
13776 (use (match_operand:XF 1 "register_operand" ""))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13780 rtx one = gen_reg_rtx (XFmode);
13781 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13783 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13787 (define_expand "tan<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand" ""))
13789 (use (match_operand:MODEF 1 "register_operand" ""))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13795 rtx op0 = gen_reg_rtx (XFmode);
13797 rtx one = gen_reg_rtx (<MODE>mode);
13798 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13800 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13801 operands[1], op2));
13802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13806 (define_insn "*fpatanxf3_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13809 (match_operand:XF 2 "register_operand" "u")]
13811 (clobber (match_scratch:XF 3 "=2"))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && flag_unsafe_math_optimizations"
13815 [(set_attr "type" "fpspc")
13816 (set_attr "mode" "XF")])
13818 (define_insn "fpatan_extend<mode>xf3_i387"
13819 [(set (match_operand:XF 0 "register_operand" "=f")
13820 (unspec:XF [(float_extend:XF
13821 (match_operand:MODEF 1 "register_operand" "0"))
13823 (match_operand:MODEF 2 "register_operand" "u"))]
13825 (clobber (match_scratch:XF 3 "=2"))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13834 (define_expand "atan2xf3"
13835 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13836 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13837 (match_operand:XF 1 "register_operand" "")]
13839 (clobber (match_scratch:XF 3 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations")
13843 (define_expand "atan2<mode>3"
13844 [(use (match_operand:MODEF 0 "register_operand" ""))
13845 (use (match_operand:MODEF 1 "register_operand" ""))
13846 (use (match_operand:MODEF 2 "register_operand" ""))]
13847 "TARGET_USE_FANCY_MATH_387
13848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13849 || TARGET_MIX_SSE_I387)
13850 && flag_unsafe_math_optimizations"
13852 rtx op0 = gen_reg_rtx (XFmode);
13854 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13855 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13859 (define_expand "atanxf2"
13860 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13861 (unspec:XF [(match_dup 2)
13862 (match_operand:XF 1 "register_operand" "")]
13864 (clobber (match_scratch:XF 3 ""))])]
13865 "TARGET_USE_FANCY_MATH_387
13866 && flag_unsafe_math_optimizations"
13868 operands[2] = gen_reg_rtx (XFmode);
13869 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13872 (define_expand "atan<mode>2"
13873 [(use (match_operand:MODEF 0 "register_operand" ""))
13874 (use (match_operand:MODEF 1 "register_operand" ""))]
13875 "TARGET_USE_FANCY_MATH_387
13876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13877 || TARGET_MIX_SSE_I387)
13878 && flag_unsafe_math_optimizations"
13880 rtx op0 = gen_reg_rtx (XFmode);
13882 rtx op2 = gen_reg_rtx (<MODE>mode);
13883 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13885 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13886 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13890 (define_expand "asinxf2"
13891 [(set (match_dup 2)
13892 (mult:XF (match_operand:XF 1 "register_operand" "")
13894 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13895 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13896 (parallel [(set (match_operand:XF 0 "register_operand" "")
13897 (unspec:XF [(match_dup 5) (match_dup 1)]
13899 (clobber (match_scratch:XF 6 ""))])]
13900 "TARGET_USE_FANCY_MATH_387
13901 && flag_unsafe_math_optimizations"
13905 if (optimize_insn_for_size_p ())
13908 for (i = 2; i < 6; i++)
13909 operands[i] = gen_reg_rtx (XFmode);
13911 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13914 (define_expand "asin<mode>2"
13915 [(use (match_operand:MODEF 0 "register_operand" ""))
13916 (use (match_operand:MODEF 1 "general_operand" ""))]
13917 "TARGET_USE_FANCY_MATH_387
13918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13919 || TARGET_MIX_SSE_I387)
13920 && flag_unsafe_math_optimizations"
13922 rtx op0 = gen_reg_rtx (XFmode);
13923 rtx op1 = gen_reg_rtx (XFmode);
13925 if (optimize_insn_for_size_p ())
13928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13929 emit_insn (gen_asinxf2 (op0, op1));
13930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13934 (define_expand "acosxf2"
13935 [(set (match_dup 2)
13936 (mult:XF (match_operand:XF 1 "register_operand" "")
13938 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13939 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13940 (parallel [(set (match_operand:XF 0 "register_operand" "")
13941 (unspec:XF [(match_dup 1) (match_dup 5)]
13943 (clobber (match_scratch:XF 6 ""))])]
13944 "TARGET_USE_FANCY_MATH_387
13945 && flag_unsafe_math_optimizations"
13949 if (optimize_insn_for_size_p ())
13952 for (i = 2; i < 6; i++)
13953 operands[i] = gen_reg_rtx (XFmode);
13955 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13958 (define_expand "acos<mode>2"
13959 [(use (match_operand:MODEF 0 "register_operand" ""))
13960 (use (match_operand:MODEF 1 "general_operand" ""))]
13961 "TARGET_USE_FANCY_MATH_387
13962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13963 || TARGET_MIX_SSE_I387)
13964 && flag_unsafe_math_optimizations"
13966 rtx op0 = gen_reg_rtx (XFmode);
13967 rtx op1 = gen_reg_rtx (XFmode);
13969 if (optimize_insn_for_size_p ())
13972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13973 emit_insn (gen_acosxf2 (op0, op1));
13974 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13978 (define_insn "fyl2xxf3_i387"
13979 [(set (match_operand:XF 0 "register_operand" "=f")
13980 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13981 (match_operand:XF 2 "register_operand" "u")]
13983 (clobber (match_scratch:XF 3 "=2"))]
13984 "TARGET_USE_FANCY_MATH_387
13985 && flag_unsafe_math_optimizations"
13987 [(set_attr "type" "fpspc")
13988 (set_attr "mode" "XF")])
13990 (define_insn "fyl2x_extend<mode>xf3_i387"
13991 [(set (match_operand:XF 0 "register_operand" "=f")
13992 (unspec:XF [(float_extend:XF
13993 (match_operand:MODEF 1 "register_operand" "0"))
13994 (match_operand:XF 2 "register_operand" "u")]
13996 (clobber (match_scratch:XF 3 "=2"))]
13997 "TARGET_USE_FANCY_MATH_387
13998 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13999 || TARGET_MIX_SSE_I387)
14000 && flag_unsafe_math_optimizations"
14002 [(set_attr "type" "fpspc")
14003 (set_attr "mode" "XF")])
14005 (define_expand "logxf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14017 (define_expand "log<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14025 rtx op0 = gen_reg_rtx (XFmode);
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14035 (define_expand "log10xf2"
14036 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14038 (match_dup 2)] UNSPEC_FYL2X))
14039 (clobber (match_scratch:XF 3 ""))])]
14040 "TARGET_USE_FANCY_MATH_387
14041 && flag_unsafe_math_optimizations"
14043 operands[2] = gen_reg_rtx (XFmode);
14044 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14047 (define_expand "log10<mode>2"
14048 [(use (match_operand:MODEF 0 "register_operand" ""))
14049 (use (match_operand:MODEF 1 "register_operand" ""))]
14050 "TARGET_USE_FANCY_MATH_387
14051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14052 || TARGET_MIX_SSE_I387)
14053 && flag_unsafe_math_optimizations"
14055 rtx op0 = gen_reg_rtx (XFmode);
14057 rtx op2 = gen_reg_rtx (XFmode);
14058 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14060 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14065 (define_expand "log2xf2"
14066 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14067 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14068 (match_dup 2)] UNSPEC_FYL2X))
14069 (clobber (match_scratch:XF 3 ""))])]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14073 operands[2] = gen_reg_rtx (XFmode);
14074 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14077 (define_expand "log2<mode>2"
14078 [(use (match_operand:MODEF 0 "register_operand" ""))
14079 (use (match_operand:MODEF 1 "register_operand" ""))]
14080 "TARGET_USE_FANCY_MATH_387
14081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14082 || TARGET_MIX_SSE_I387)
14083 && flag_unsafe_math_optimizations"
14085 rtx op0 = gen_reg_rtx (XFmode);
14087 rtx op2 = gen_reg_rtx (XFmode);
14088 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14090 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14095 (define_insn "fyl2xp1xf3_i387"
14096 [(set (match_operand:XF 0 "register_operand" "=f")
14097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14098 (match_operand:XF 2 "register_operand" "u")]
14100 (clobber (match_scratch:XF 3 "=2"))]
14101 "TARGET_USE_FANCY_MATH_387
14102 && flag_unsafe_math_optimizations"
14104 [(set_attr "type" "fpspc")
14105 (set_attr "mode" "XF")])
14107 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14108 [(set (match_operand:XF 0 "register_operand" "=f")
14109 (unspec:XF [(float_extend:XF
14110 (match_operand:MODEF 1 "register_operand" "0"))
14111 (match_operand:XF 2 "register_operand" "u")]
14113 (clobber (match_scratch:XF 3 "=2"))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116 || TARGET_MIX_SSE_I387)
14117 && flag_unsafe_math_optimizations"
14119 [(set_attr "type" "fpspc")
14120 (set_attr "mode" "XF")])
14122 (define_expand "log1pxf2"
14123 [(use (match_operand:XF 0 "register_operand" ""))
14124 (use (match_operand:XF 1 "register_operand" ""))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && flag_unsafe_math_optimizations"
14128 if (optimize_insn_for_size_p ())
14131 ix86_emit_i387_log1p (operands[0], operands[1]);
14135 (define_expand "log1p<mode>2"
14136 [(use (match_operand:MODEF 0 "register_operand" ""))
14137 (use (match_operand:MODEF 1 "register_operand" ""))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140 || TARGET_MIX_SSE_I387)
14141 && flag_unsafe_math_optimizations"
14145 if (optimize_insn_for_size_p ())
14148 op0 = gen_reg_rtx (XFmode);
14150 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14152 ix86_emit_i387_log1p (op0, operands[1]);
14153 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14157 (define_insn "fxtractxf3_i387"
14158 [(set (match_operand:XF 0 "register_operand" "=f")
14159 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14160 UNSPEC_XTRACT_FRACT))
14161 (set (match_operand:XF 1 "register_operand" "=u")
14162 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14163 "TARGET_USE_FANCY_MATH_387
14164 && flag_unsafe_math_optimizations"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "XF")])
14169 (define_insn "fxtract_extend<mode>xf3_i387"
14170 [(set (match_operand:XF 0 "register_operand" "=f")
14171 (unspec:XF [(float_extend:XF
14172 (match_operand:MODEF 2 "register_operand" "0"))]
14173 UNSPEC_XTRACT_FRACT))
14174 (set (match_operand:XF 1 "register_operand" "=u")
14175 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178 || TARGET_MIX_SSE_I387)
14179 && flag_unsafe_math_optimizations"
14181 [(set_attr "type" "fpspc")
14182 (set_attr "mode" "XF")])
14184 (define_expand "logbxf2"
14185 [(parallel [(set (match_dup 2)
14186 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14187 UNSPEC_XTRACT_FRACT))
14188 (set (match_operand:XF 0 "register_operand" "")
14189 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14190 "TARGET_USE_FANCY_MATH_387
14191 && flag_unsafe_math_optimizations"
14192 "operands[2] = gen_reg_rtx (XFmode);")
14194 (define_expand "logb<mode>2"
14195 [(use (match_operand:MODEF 0 "register_operand" ""))
14196 (use (match_operand:MODEF 1 "register_operand" ""))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14199 || TARGET_MIX_SSE_I387)
14200 && flag_unsafe_math_optimizations"
14202 rtx op0 = gen_reg_rtx (XFmode);
14203 rtx op1 = gen_reg_rtx (XFmode);
14205 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14210 (define_expand "ilogbxf2"
14211 [(use (match_operand:SI 0 "register_operand" ""))
14212 (use (match_operand:XF 1 "register_operand" ""))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && flag_unsafe_math_optimizations"
14218 if (optimize_insn_for_size_p ())
14221 op0 = gen_reg_rtx (XFmode);
14222 op1 = gen_reg_rtx (XFmode);
14224 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14225 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14229 (define_expand "ilogb<mode>2"
14230 [(use (match_operand:SI 0 "register_operand" ""))
14231 (use (match_operand:MODEF 1 "register_operand" ""))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14234 || TARGET_MIX_SSE_I387)
14235 && flag_unsafe_math_optimizations"
14239 if (optimize_insn_for_size_p ())
14242 op0 = gen_reg_rtx (XFmode);
14243 op1 = gen_reg_rtx (XFmode);
14245 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14246 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14250 (define_insn "*f2xm1xf2_i387"
14251 [(set (match_operand:XF 0 "register_operand" "=f")
14252 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14257 [(set_attr "type" "fpspc")
14258 (set_attr "mode" "XF")])
14260 (define_insn "*fscalexf4_i387"
14261 [(set (match_operand:XF 0 "register_operand" "=f")
14262 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14263 (match_operand:XF 3 "register_operand" "1")]
14264 UNSPEC_FSCALE_FRACT))
14265 (set (match_operand:XF 1 "register_operand" "=u")
14266 (unspec:XF [(match_dup 2) (match_dup 3)]
14267 UNSPEC_FSCALE_EXP))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && flag_unsafe_math_optimizations"
14271 [(set_attr "type" "fpspc")
14272 (set_attr "mode" "XF")])
14274 (define_expand "expNcorexf3"
14275 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14276 (match_operand:XF 2 "register_operand" "")))
14277 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14278 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14279 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14280 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14281 (parallel [(set (match_operand:XF 0 "register_operand" "")
14282 (unspec:XF [(match_dup 8) (match_dup 4)]
14283 UNSPEC_FSCALE_FRACT))
14285 (unspec:XF [(match_dup 8) (match_dup 4)]
14286 UNSPEC_FSCALE_EXP))])]
14287 "TARGET_USE_FANCY_MATH_387
14288 && flag_unsafe_math_optimizations"
14292 if (optimize_insn_for_size_p ())
14295 for (i = 3; i < 10; i++)
14296 operands[i] = gen_reg_rtx (XFmode);
14298 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14301 (define_expand "expxf2"
14302 [(use (match_operand:XF 0 "register_operand" ""))
14303 (use (match_operand:XF 1 "register_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14309 if (optimize_insn_for_size_p ())
14312 op2 = gen_reg_rtx (XFmode);
14313 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14315 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14319 (define_expand "exp<mode>2"
14320 [(use (match_operand:MODEF 0 "register_operand" ""))
14321 (use (match_operand:MODEF 1 "general_operand" ""))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14324 || TARGET_MIX_SSE_I387)
14325 && flag_unsafe_math_optimizations"
14329 if (optimize_insn_for_size_p ())
14332 op0 = gen_reg_rtx (XFmode);
14333 op1 = gen_reg_rtx (XFmode);
14335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14336 emit_insn (gen_expxf2 (op0, op1));
14337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14341 (define_expand "exp10xf2"
14342 [(use (match_operand:XF 0 "register_operand" ""))
14343 (use (match_operand:XF 1 "register_operand" ""))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 op2 = gen_reg_rtx (XFmode);
14353 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14355 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14359 (define_expand "exp10<mode>2"
14360 [(use (match_operand:MODEF 0 "register_operand" ""))
14361 (use (match_operand:MODEF 1 "general_operand" ""))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14369 if (optimize_insn_for_size_p ())
14372 op0 = gen_reg_rtx (XFmode);
14373 op1 = gen_reg_rtx (XFmode);
14375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_insn (gen_exp10xf2 (op0, op1));
14377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14381 (define_expand "exp2xf2"
14382 [(use (match_operand:XF 0 "register_operand" ""))
14383 (use (match_operand:XF 1 "register_operand" ""))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 op2 = gen_reg_rtx (XFmode);
14393 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14395 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14399 (define_expand "exp2<mode>2"
14400 [(use (match_operand:MODEF 0 "register_operand" ""))
14401 (use (match_operand:MODEF 1 "general_operand" ""))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404 || TARGET_MIX_SSE_I387)
14405 && flag_unsafe_math_optimizations"
14409 if (optimize_insn_for_size_p ())
14412 op0 = gen_reg_rtx (XFmode);
14413 op1 = gen_reg_rtx (XFmode);
14415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14416 emit_insn (gen_exp2xf2 (op0, op1));
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421 (define_expand "expm1xf2"
14422 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14424 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14425 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14426 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14427 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14428 (parallel [(set (match_dup 7)
14429 (unspec:XF [(match_dup 6) (match_dup 4)]
14430 UNSPEC_FSCALE_FRACT))
14432 (unspec:XF [(match_dup 6) (match_dup 4)]
14433 UNSPEC_FSCALE_EXP))])
14434 (parallel [(set (match_dup 10)
14435 (unspec:XF [(match_dup 9) (match_dup 8)]
14436 UNSPEC_FSCALE_FRACT))
14437 (set (match_dup 11)
14438 (unspec:XF [(match_dup 9) (match_dup 8)]
14439 UNSPEC_FSCALE_EXP))])
14440 (set (match_dup 12) (minus:XF (match_dup 10)
14441 (float_extend:XF (match_dup 13))))
14442 (set (match_operand:XF 0 "register_operand" "")
14443 (plus:XF (match_dup 12) (match_dup 7)))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14449 if (optimize_insn_for_size_p ())
14452 for (i = 2; i < 13; i++)
14453 operands[i] = gen_reg_rtx (XFmode);
14456 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14458 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14461 (define_expand "expm1<mode>2"
14462 [(use (match_operand:MODEF 0 "register_operand" ""))
14463 (use (match_operand:MODEF 1 "general_operand" ""))]
14464 "TARGET_USE_FANCY_MATH_387
14465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14466 || TARGET_MIX_SSE_I387)
14467 && flag_unsafe_math_optimizations"
14471 if (optimize_insn_for_size_p ())
14474 op0 = gen_reg_rtx (XFmode);
14475 op1 = gen_reg_rtx (XFmode);
14477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14478 emit_insn (gen_expm1xf2 (op0, op1));
14479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14483 (define_expand "ldexpxf3"
14484 [(set (match_dup 3)
14485 (float:XF (match_operand:SI 2 "register_operand" "")))
14486 (parallel [(set (match_operand:XF 0 " register_operand" "")
14487 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14489 UNSPEC_FSCALE_FRACT))
14491 (unspec:XF [(match_dup 1) (match_dup 3)]
14492 UNSPEC_FSCALE_EXP))])]
14493 "TARGET_USE_FANCY_MATH_387
14494 && flag_unsafe_math_optimizations"
14496 if (optimize_insn_for_size_p ())
14499 operands[3] = gen_reg_rtx (XFmode);
14500 operands[4] = gen_reg_rtx (XFmode);
14503 (define_expand "ldexp<mode>3"
14504 [(use (match_operand:MODEF 0 "register_operand" ""))
14505 (use (match_operand:MODEF 1 "general_operand" ""))
14506 (use (match_operand:SI 2 "register_operand" ""))]
14507 "TARGET_USE_FANCY_MATH_387
14508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509 || TARGET_MIX_SSE_I387)
14510 && flag_unsafe_math_optimizations"
14514 if (optimize_insn_for_size_p ())
14517 op0 = gen_reg_rtx (XFmode);
14518 op1 = gen_reg_rtx (XFmode);
14520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14521 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14526 (define_expand "scalbxf3"
14527 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14528 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14529 (match_operand:XF 2 "register_operand" "")]
14530 UNSPEC_FSCALE_FRACT))
14532 (unspec:XF [(match_dup 1) (match_dup 2)]
14533 UNSPEC_FSCALE_EXP))])]
14534 "TARGET_USE_FANCY_MATH_387
14535 && flag_unsafe_math_optimizations"
14537 if (optimize_insn_for_size_p ())
14540 operands[3] = gen_reg_rtx (XFmode);
14543 (define_expand "scalb<mode>3"
14544 [(use (match_operand:MODEF 0 "register_operand" ""))
14545 (use (match_operand:MODEF 1 "general_operand" ""))
14546 (use (match_operand:MODEF 2 "general_operand" ""))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14549 || TARGET_MIX_SSE_I387)
14550 && flag_unsafe_math_optimizations"
14554 if (optimize_insn_for_size_p ())
14557 op0 = gen_reg_rtx (XFmode);
14558 op1 = gen_reg_rtx (XFmode);
14559 op2 = gen_reg_rtx (XFmode);
14561 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14562 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14563 emit_insn (gen_scalbxf3 (op0, op1, op2));
14564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14568 (define_expand "significandxf2"
14569 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14570 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14571 UNSPEC_XTRACT_FRACT))
14573 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14574 "TARGET_USE_FANCY_MATH_387
14575 && flag_unsafe_math_optimizations"
14576 "operands[2] = gen_reg_rtx (XFmode);")
14578 (define_expand "significand<mode>2"
14579 [(use (match_operand:MODEF 0 "register_operand" ""))
14580 (use (match_operand:MODEF 1 "register_operand" ""))]
14581 "TARGET_USE_FANCY_MATH_387
14582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14583 || TARGET_MIX_SSE_I387)
14584 && flag_unsafe_math_optimizations"
14586 rtx op0 = gen_reg_rtx (XFmode);
14587 rtx op1 = gen_reg_rtx (XFmode);
14589 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14590 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14595 (define_insn "sse4_1_round<mode>2"
14596 [(set (match_operand:MODEF 0 "register_operand" "=x")
14597 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14598 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14601 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14602 [(set_attr "type" "ssecvt")
14603 (set_attr "prefix_extra" "1")
14604 (set_attr "prefix" "maybe_vex")
14605 (set_attr "mode" "<MODE>")])
14607 (define_insn "rintxf2"
14608 [(set (match_operand:XF 0 "register_operand" "=f")
14609 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14611 "TARGET_USE_FANCY_MATH_387
14612 && flag_unsafe_math_optimizations"
14614 [(set_attr "type" "fpspc")
14615 (set_attr "mode" "XF")])
14617 (define_expand "rint<mode>2"
14618 [(use (match_operand:MODEF 0 "register_operand" ""))
14619 (use (match_operand:MODEF 1 "register_operand" ""))]
14620 "(TARGET_USE_FANCY_MATH_387
14621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14622 || TARGET_MIX_SSE_I387)
14623 && flag_unsafe_math_optimizations)
14624 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14625 && !flag_trapping_math)"
14627 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14628 && !flag_trapping_math)
14631 emit_insn (gen_sse4_1_round<mode>2
14632 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14633 else if (optimize_insn_for_size_p ())
14636 ix86_expand_rint (operand0, operand1);
14640 rtx op0 = gen_reg_rtx (XFmode);
14641 rtx op1 = gen_reg_rtx (XFmode);
14643 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14644 emit_insn (gen_rintxf2 (op0, op1));
14646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14651 (define_expand "round<mode>2"
14652 [(match_operand:X87MODEF 0 "register_operand" "")
14653 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14654 "(TARGET_USE_FANCY_MATH_387
14655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14656 || TARGET_MIX_SSE_I387)
14657 && flag_unsafe_math_optimizations)
14658 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14659 && !flag_trapping_math && !flag_rounding_math)"
14661 if (optimize_insn_for_size_p ())
14664 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665 && !flag_trapping_math && !flag_rounding_math)
14669 operands[1] = force_reg (<MODE>mode, operands[1]);
14670 ix86_expand_round_sse4 (operands[0], operands[1]);
14672 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14673 ix86_expand_round (operands[0], operands[1]);
14675 ix86_expand_rounddf_32 (operands[0], operands[1]);
14679 operands[1] = force_reg (<MODE>mode, operands[1]);
14680 ix86_emit_i387_round (operands[0], operands[1]);
14685 (define_insn_and_split "*fistdi2_1"
14686 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14689 "TARGET_USE_FANCY_MATH_387
14690 && can_create_pseudo_p ()"
14695 if (memory_operand (operands[0], VOIDmode))
14696 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14699 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14700 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "DI")])
14708 (define_insn "fistdi2"
14709 [(set (match_operand:DI 0 "memory_operand" "=m")
14710 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14712 (clobber (match_scratch:XF 2 "=&1f"))]
14713 "TARGET_USE_FANCY_MATH_387"
14714 "* return output_fix_trunc (insn, operands, false);"
14715 [(set_attr "type" "fpspc")
14716 (set_attr "mode" "DI")])
14718 (define_insn "fistdi2_with_temp"
14719 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14720 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14722 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14723 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14724 "TARGET_USE_FANCY_MATH_387"
14726 [(set_attr "type" "fpspc")
14727 (set_attr "mode" "DI")])
14730 [(set (match_operand:DI 0 "register_operand" "")
14731 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14733 (clobber (match_operand:DI 2 "memory_operand" ""))
14734 (clobber (match_scratch 3 ""))]
14736 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14737 (clobber (match_dup 3))])
14738 (set (match_dup 0) (match_dup 2))])
14741 [(set (match_operand:DI 0 "memory_operand" "")
14742 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14744 (clobber (match_operand:DI 2 "memory_operand" ""))
14745 (clobber (match_scratch 3 ""))]
14747 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14748 (clobber (match_dup 3))])])
14750 (define_insn_and_split "*fist<mode>2_1"
14751 [(set (match_operand:SWI24 0 "register_operand" "")
14752 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14754 "TARGET_USE_FANCY_MATH_387
14755 && can_create_pseudo_p ()"
14760 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14761 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14765 [(set_attr "type" "fpspc")
14766 (set_attr "mode" "<MODE>")])
14768 (define_insn "fist<mode>2"
14769 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14772 "TARGET_USE_FANCY_MATH_387"
14773 "* return output_fix_trunc (insn, operands, false);"
14774 [(set_attr "type" "fpspc")
14775 (set_attr "mode" "<MODE>")])
14777 (define_insn "fist<mode>2_with_temp"
14778 [(set (match_operand:SWI24 0 "register_operand" "=r")
14779 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14781 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14782 "TARGET_USE_FANCY_MATH_387"
14784 [(set_attr "type" "fpspc")
14785 (set_attr "mode" "<MODE>")])
14788 [(set (match_operand:SWI24 0 "register_operand" "")
14789 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14791 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14793 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14794 (set (match_dup 0) (match_dup 2))])
14797 [(set (match_operand:SWI24 0 "memory_operand" "")
14798 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14800 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14802 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14804 (define_expand "lrintxf<mode>2"
14805 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14806 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14808 "TARGET_USE_FANCY_MATH_387")
14810 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14811 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14812 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14813 UNSPEC_FIX_NOTRUNC))]
14814 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14815 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14817 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14818 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14819 (match_operand:X87MODEF 1 "register_operand" "")]
14820 "(TARGET_USE_FANCY_MATH_387
14821 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14822 || TARGET_MIX_SSE_I387)
14823 && flag_unsafe_math_optimizations)
14824 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14825 && <SWI248x:MODE>mode != HImode
14826 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14827 && !flag_trapping_math && !flag_rounding_math)"
14829 if (optimize_insn_for_size_p ())
14832 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14833 && <SWI248x:MODE>mode != HImode
14834 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14835 && !flag_trapping_math && !flag_rounding_math)
14836 ix86_expand_lround (operand0, operand1);
14838 ix86_emit_i387_round (operands[0], operands[1]);
14842 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14843 (define_insn_and_split "frndintxf2_floor"
14844 [(set (match_operand:XF 0 "register_operand" "")
14845 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14846 UNSPEC_FRNDINT_FLOOR))
14847 (clobber (reg:CC FLAGS_REG))]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations
14850 && can_create_pseudo_p ()"
14855 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14857 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14858 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14860 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14861 operands[2], operands[3]));
14864 [(set_attr "type" "frndint")
14865 (set_attr "i387_cw" "floor")
14866 (set_attr "mode" "XF")])
14868 (define_insn "frndintxf2_floor_i387"
14869 [(set (match_operand:XF 0 "register_operand" "=f")
14870 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14871 UNSPEC_FRNDINT_FLOOR))
14872 (use (match_operand:HI 2 "memory_operand" "m"))
14873 (use (match_operand:HI 3 "memory_operand" "m"))]
14874 "TARGET_USE_FANCY_MATH_387
14875 && flag_unsafe_math_optimizations"
14876 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14877 [(set_attr "type" "frndint")
14878 (set_attr "i387_cw" "floor")
14879 (set_attr "mode" "XF")])
14881 (define_expand "floorxf2"
14882 [(use (match_operand:XF 0 "register_operand" ""))
14883 (use (match_operand:XF 1 "register_operand" ""))]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations"
14887 if (optimize_insn_for_size_p ())
14889 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14893 (define_expand "floor<mode>2"
14894 [(use (match_operand:MODEF 0 "register_operand" ""))
14895 (use (match_operand:MODEF 1 "register_operand" ""))]
14896 "(TARGET_USE_FANCY_MATH_387
14897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14898 || TARGET_MIX_SSE_I387)
14899 && flag_unsafe_math_optimizations)
14900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14901 && !flag_trapping_math)"
14903 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14904 && !flag_trapping_math)
14907 emit_insn (gen_sse4_1_round<mode>2
14908 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14909 else if (optimize_insn_for_size_p ())
14911 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14912 ix86_expand_floorceil (operand0, operand1, true);
14914 ix86_expand_floorceildf_32 (operand0, operand1, true);
14920 if (optimize_insn_for_size_p ())
14923 op0 = gen_reg_rtx (XFmode);
14924 op1 = gen_reg_rtx (XFmode);
14925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14926 emit_insn (gen_frndintxf2_floor (op0, op1));
14928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14933 (define_insn_and_split "*fist<mode>2_floor_1"
14934 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14935 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14936 UNSPEC_FIST_FLOOR))
14937 (clobber (reg:CC FLAGS_REG))]
14938 "TARGET_USE_FANCY_MATH_387
14939 && flag_unsafe_math_optimizations
14940 && can_create_pseudo_p ()"
14945 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14947 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14948 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14949 if (memory_operand (operands[0], VOIDmode))
14950 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14951 operands[2], operands[3]));
14954 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14955 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14956 operands[2], operands[3],
14961 [(set_attr "type" "fistp")
14962 (set_attr "i387_cw" "floor")
14963 (set_attr "mode" "<MODE>")])
14965 (define_insn "fistdi2_floor"
14966 [(set (match_operand:DI 0 "memory_operand" "=m")
14967 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14968 UNSPEC_FIST_FLOOR))
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))
14971 (clobber (match_scratch:XF 4 "=&1f"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14974 "* return output_fix_trunc (insn, operands, false);"
14975 [(set_attr "type" "fistp")
14976 (set_attr "i387_cw" "floor")
14977 (set_attr "mode" "DI")])
14979 (define_insn "fistdi2_floor_with_temp"
14980 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14981 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14982 UNSPEC_FIST_FLOOR))
14983 (use (match_operand:HI 2 "memory_operand" "m,m"))
14984 (use (match_operand:HI 3 "memory_operand" "m,m"))
14985 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14986 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14987 "TARGET_USE_FANCY_MATH_387
14988 && flag_unsafe_math_optimizations"
14990 [(set_attr "type" "fistp")
14991 (set_attr "i387_cw" "floor")
14992 (set_attr "mode" "DI")])
14995 [(set (match_operand:DI 0 "register_operand" "")
14996 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14997 UNSPEC_FIST_FLOOR))
14998 (use (match_operand:HI 2 "memory_operand" ""))
14999 (use (match_operand:HI 3 "memory_operand" ""))
15000 (clobber (match_operand:DI 4 "memory_operand" ""))
15001 (clobber (match_scratch 5 ""))]
15003 [(parallel [(set (match_dup 4)
15004 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15005 (use (match_dup 2))
15006 (use (match_dup 3))
15007 (clobber (match_dup 5))])
15008 (set (match_dup 0) (match_dup 4))])
15011 [(set (match_operand:DI 0 "memory_operand" "")
15012 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15013 UNSPEC_FIST_FLOOR))
15014 (use (match_operand:HI 2 "memory_operand" ""))
15015 (use (match_operand:HI 3 "memory_operand" ""))
15016 (clobber (match_operand:DI 4 "memory_operand" ""))
15017 (clobber (match_scratch 5 ""))]
15019 [(parallel [(set (match_dup 0)
15020 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))
15023 (clobber (match_dup 5))])])
15025 (define_insn "fist<mode>2_floor"
15026 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15028 UNSPEC_FIST_FLOOR))
15029 (use (match_operand:HI 2 "memory_operand" "m"))
15030 (use (match_operand:HI 3 "memory_operand" "m"))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && flag_unsafe_math_optimizations"
15033 "* return output_fix_trunc (insn, operands, false);"
15034 [(set_attr "type" "fistp")
15035 (set_attr "i387_cw" "floor")
15036 (set_attr "mode" "<MODE>")])
15038 (define_insn "fist<mode>2_floor_with_temp"
15039 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15040 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15041 UNSPEC_FIST_FLOOR))
15042 (use (match_operand:HI 2 "memory_operand" "m,m"))
15043 (use (match_operand:HI 3 "memory_operand" "m,m"))
15044 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15045 "TARGET_USE_FANCY_MATH_387
15046 && flag_unsafe_math_optimizations"
15048 [(set_attr "type" "fistp")
15049 (set_attr "i387_cw" "floor")
15050 (set_attr "mode" "<MODE>")])
15053 [(set (match_operand:SWI24 0 "register_operand" "")
15054 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15055 UNSPEC_FIST_FLOOR))
15056 (use (match_operand:HI 2 "memory_operand" ""))
15057 (use (match_operand:HI 3 "memory_operand" ""))
15058 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15060 [(parallel [(set (match_dup 4)
15061 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15062 (use (match_dup 2))
15063 (use (match_dup 3))])
15064 (set (match_dup 0) (match_dup 4))])
15067 [(set (match_operand:SWI24 0 "memory_operand" "")
15068 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15069 UNSPEC_FIST_FLOOR))
15070 (use (match_operand:HI 2 "memory_operand" ""))
15071 (use (match_operand:HI 3 "memory_operand" ""))
15072 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15074 [(parallel [(set (match_dup 0)
15075 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15076 (use (match_dup 2))
15077 (use (match_dup 3))])])
15079 (define_expand "lfloorxf<mode>2"
15080 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15081 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15082 UNSPEC_FIST_FLOOR))
15083 (clobber (reg:CC FLAGS_REG))])]
15084 "TARGET_USE_FANCY_MATH_387
15085 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15086 && flag_unsafe_math_optimizations")
15088 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15089 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15090 (match_operand:MODEF 1 "register_operand" "")]
15091 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15092 && !flag_trapping_math"
15094 if (TARGET_64BIT && optimize_insn_for_size_p ())
15096 ix86_expand_lfloorceil (operand0, operand1, true);
15100 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15101 (define_insn_and_split "frndintxf2_ceil"
15102 [(set (match_operand:XF 0 "register_operand" "")
15103 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15104 UNSPEC_FRNDINT_CEIL))
15105 (clobber (reg:CC FLAGS_REG))]
15106 "TARGET_USE_FANCY_MATH_387
15107 && flag_unsafe_math_optimizations
15108 && can_create_pseudo_p ()"
15113 ix86_optimize_mode_switching[I387_CEIL] = 1;
15115 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15116 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15118 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15119 operands[2], operands[3]));
15122 [(set_attr "type" "frndint")
15123 (set_attr "i387_cw" "ceil")
15124 (set_attr "mode" "XF")])
15126 (define_insn "frndintxf2_ceil_i387"
15127 [(set (match_operand:XF 0 "register_operand" "=f")
15128 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15129 UNSPEC_FRNDINT_CEIL))
15130 (use (match_operand:HI 2 "memory_operand" "m"))
15131 (use (match_operand:HI 3 "memory_operand" "m"))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15134 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15135 [(set_attr "type" "frndint")
15136 (set_attr "i387_cw" "ceil")
15137 (set_attr "mode" "XF")])
15139 (define_expand "ceilxf2"
15140 [(use (match_operand:XF 0 "register_operand" ""))
15141 (use (match_operand:XF 1 "register_operand" ""))]
15142 "TARGET_USE_FANCY_MATH_387
15143 && flag_unsafe_math_optimizations"
15145 if (optimize_insn_for_size_p ())
15147 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15151 (define_expand "ceil<mode>2"
15152 [(use (match_operand:MODEF 0 "register_operand" ""))
15153 (use (match_operand:MODEF 1 "register_operand" ""))]
15154 "(TARGET_USE_FANCY_MATH_387
15155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156 || TARGET_MIX_SSE_I387)
15157 && flag_unsafe_math_optimizations)
15158 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15159 && !flag_trapping_math)"
15161 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15162 && !flag_trapping_math)
15165 emit_insn (gen_sse4_1_round<mode>2
15166 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15167 else if (optimize_insn_for_size_p ())
15169 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15170 ix86_expand_floorceil (operand0, operand1, false);
15172 ix86_expand_floorceildf_32 (operand0, operand1, false);
15178 if (optimize_insn_for_size_p ())
15181 op0 = gen_reg_rtx (XFmode);
15182 op1 = gen_reg_rtx (XFmode);
15183 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15184 emit_insn (gen_frndintxf2_ceil (op0, op1));
15186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15191 (define_insn_and_split "*fist<mode>2_ceil_1"
15192 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15193 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15195 (clobber (reg:CC FLAGS_REG))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && flag_unsafe_math_optimizations
15198 && can_create_pseudo_p ()"
15203 ix86_optimize_mode_switching[I387_CEIL] = 1;
15205 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15206 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15207 if (memory_operand (operands[0], VOIDmode))
15208 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15209 operands[2], operands[3]));
15212 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15213 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15214 operands[2], operands[3],
15219 [(set_attr "type" "fistp")
15220 (set_attr "i387_cw" "ceil")
15221 (set_attr "mode" "<MODE>")])
15223 (define_insn "fistdi2_ceil"
15224 [(set (match_operand:DI 0 "memory_operand" "=m")
15225 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15227 (use (match_operand:HI 2 "memory_operand" "m"))
15228 (use (match_operand:HI 3 "memory_operand" "m"))
15229 (clobber (match_scratch:XF 4 "=&1f"))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && flag_unsafe_math_optimizations"
15232 "* return output_fix_trunc (insn, operands, false);"
15233 [(set_attr "type" "fistp")
15234 (set_attr "i387_cw" "ceil")
15235 (set_attr "mode" "DI")])
15237 (define_insn "fistdi2_ceil_with_temp"
15238 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15239 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15241 (use (match_operand:HI 2 "memory_operand" "m,m"))
15242 (use (match_operand:HI 3 "memory_operand" "m,m"))
15243 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15244 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15245 "TARGET_USE_FANCY_MATH_387
15246 && flag_unsafe_math_optimizations"
15248 [(set_attr "type" "fistp")
15249 (set_attr "i387_cw" "ceil")
15250 (set_attr "mode" "DI")])
15253 [(set (match_operand:DI 0 "register_operand" "")
15254 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15256 (use (match_operand:HI 2 "memory_operand" ""))
15257 (use (match_operand:HI 3 "memory_operand" ""))
15258 (clobber (match_operand:DI 4 "memory_operand" ""))
15259 (clobber (match_scratch 5 ""))]
15261 [(parallel [(set (match_dup 4)
15262 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15263 (use (match_dup 2))
15264 (use (match_dup 3))
15265 (clobber (match_dup 5))])
15266 (set (match_dup 0) (match_dup 4))])
15269 [(set (match_operand:DI 0 "memory_operand" "")
15270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15272 (use (match_operand:HI 2 "memory_operand" ""))
15273 (use (match_operand:HI 3 "memory_operand" ""))
15274 (clobber (match_operand:DI 4 "memory_operand" ""))
15275 (clobber (match_scratch 5 ""))]
15277 [(parallel [(set (match_dup 0)
15278 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15279 (use (match_dup 2))
15280 (use (match_dup 3))
15281 (clobber (match_dup 5))])])
15283 (define_insn "fist<mode>2_ceil"
15284 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15285 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15287 (use (match_operand:HI 2 "memory_operand" "m"))
15288 (use (match_operand:HI 3 "memory_operand" "m"))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && flag_unsafe_math_optimizations"
15291 "* return output_fix_trunc (insn, operands, false);"
15292 [(set_attr "type" "fistp")
15293 (set_attr "i387_cw" "ceil")
15294 (set_attr "mode" "<MODE>")])
15296 (define_insn "fist<mode>2_ceil_with_temp"
15297 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15298 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15300 (use (match_operand:HI 2 "memory_operand" "m,m"))
15301 (use (match_operand:HI 3 "memory_operand" "m,m"))
15302 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && flag_unsafe_math_optimizations"
15306 [(set_attr "type" "fistp")
15307 (set_attr "i387_cw" "ceil")
15308 (set_attr "mode" "<MODE>")])
15311 [(set (match_operand:SWI24 0 "register_operand" "")
15312 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15314 (use (match_operand:HI 2 "memory_operand" ""))
15315 (use (match_operand:HI 3 "memory_operand" ""))
15316 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15318 [(parallel [(set (match_dup 4)
15319 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15320 (use (match_dup 2))
15321 (use (match_dup 3))])
15322 (set (match_dup 0) (match_dup 4))])
15325 [(set (match_operand:SWI24 0 "memory_operand" "")
15326 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15328 (use (match_operand:HI 2 "memory_operand" ""))
15329 (use (match_operand:HI 3 "memory_operand" ""))
15330 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15332 [(parallel [(set (match_dup 0)
15333 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15334 (use (match_dup 2))
15335 (use (match_dup 3))])])
15337 (define_expand "lceilxf<mode>2"
15338 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15339 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15341 (clobber (reg:CC FLAGS_REG))])]
15342 "TARGET_USE_FANCY_MATH_387
15343 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15344 && flag_unsafe_math_optimizations")
15346 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15347 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15348 (match_operand:MODEF 1 "register_operand" "")]
15349 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15350 && !flag_trapping_math"
15352 ix86_expand_lfloorceil (operand0, operand1, false);
15356 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15357 (define_insn_and_split "frndintxf2_trunc"
15358 [(set (match_operand:XF 0 "register_operand" "")
15359 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15360 UNSPEC_FRNDINT_TRUNC))
15361 (clobber (reg:CC FLAGS_REG))]
15362 "TARGET_USE_FANCY_MATH_387
15363 && flag_unsafe_math_optimizations
15364 && can_create_pseudo_p ()"
15369 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15371 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15372 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15374 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15375 operands[2], operands[3]));
15378 [(set_attr "type" "frndint")
15379 (set_attr "i387_cw" "trunc")
15380 (set_attr "mode" "XF")])
15382 (define_insn "frndintxf2_trunc_i387"
15383 [(set (match_operand:XF 0 "register_operand" "=f")
15384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15385 UNSPEC_FRNDINT_TRUNC))
15386 (use (match_operand:HI 2 "memory_operand" "m"))
15387 (use (match_operand:HI 3 "memory_operand" "m"))]
15388 "TARGET_USE_FANCY_MATH_387
15389 && flag_unsafe_math_optimizations"
15390 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15391 [(set_attr "type" "frndint")
15392 (set_attr "i387_cw" "trunc")
15393 (set_attr "mode" "XF")])
15395 (define_expand "btruncxf2"
15396 [(use (match_operand:XF 0 "register_operand" ""))
15397 (use (match_operand:XF 1 "register_operand" ""))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations"
15401 if (optimize_insn_for_size_p ())
15403 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15407 (define_expand "btrunc<mode>2"
15408 [(use (match_operand:MODEF 0 "register_operand" ""))
15409 (use (match_operand:MODEF 1 "register_operand" ""))]
15410 "(TARGET_USE_FANCY_MATH_387
15411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15412 || TARGET_MIX_SSE_I387)
15413 && flag_unsafe_math_optimizations)
15414 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15415 && !flag_trapping_math)"
15417 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15418 && !flag_trapping_math)
15421 emit_insn (gen_sse4_1_round<mode>2
15422 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15423 else if (optimize_insn_for_size_p ())
15425 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15426 ix86_expand_trunc (operand0, operand1);
15428 ix86_expand_truncdf_32 (operand0, operand1);
15434 if (optimize_insn_for_size_p ())
15437 op0 = gen_reg_rtx (XFmode);
15438 op1 = gen_reg_rtx (XFmode);
15439 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15440 emit_insn (gen_frndintxf2_trunc (op0, op1));
15442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15447 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15448 (define_insn_and_split "frndintxf2_mask_pm"
15449 [(set (match_operand:XF 0 "register_operand" "")
15450 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15451 UNSPEC_FRNDINT_MASK_PM))
15452 (clobber (reg:CC FLAGS_REG))]
15453 "TARGET_USE_FANCY_MATH_387
15454 && flag_unsafe_math_optimizations
15455 && can_create_pseudo_p ()"
15460 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15462 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15463 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15465 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15466 operands[2], operands[3]));
15469 [(set_attr "type" "frndint")
15470 (set_attr "i387_cw" "mask_pm")
15471 (set_attr "mode" "XF")])
15473 (define_insn "frndintxf2_mask_pm_i387"
15474 [(set (match_operand:XF 0 "register_operand" "=f")
15475 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15476 UNSPEC_FRNDINT_MASK_PM))
15477 (use (match_operand:HI 2 "memory_operand" "m"))
15478 (use (match_operand:HI 3 "memory_operand" "m"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && flag_unsafe_math_optimizations"
15481 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15482 [(set_attr "type" "frndint")
15483 (set_attr "i387_cw" "mask_pm")
15484 (set_attr "mode" "XF")])
15486 (define_expand "nearbyintxf2"
15487 [(use (match_operand:XF 0 "register_operand" ""))
15488 (use (match_operand:XF 1 "register_operand" ""))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && flag_unsafe_math_optimizations"
15492 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15496 (define_expand "nearbyint<mode>2"
15497 [(use (match_operand:MODEF 0 "register_operand" ""))
15498 (use (match_operand:MODEF 1 "register_operand" ""))]
15499 "TARGET_USE_FANCY_MATH_387
15500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15501 || TARGET_MIX_SSE_I387)
15502 && flag_unsafe_math_optimizations"
15504 rtx op0 = gen_reg_rtx (XFmode);
15505 rtx op1 = gen_reg_rtx (XFmode);
15507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15508 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15510 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15514 (define_insn "fxam<mode>2_i387"
15515 [(set (match_operand:HI 0 "register_operand" "=a")
15517 [(match_operand:X87MODEF 1 "register_operand" "f")]
15519 "TARGET_USE_FANCY_MATH_387"
15520 "fxam\n\tfnstsw\t%0"
15521 [(set_attr "type" "multi")
15522 (set_attr "length" "4")
15523 (set_attr "unit" "i387")
15524 (set_attr "mode" "<MODE>")])
15526 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15527 [(set (match_operand:HI 0 "register_operand" "")
15529 [(match_operand:MODEF 1 "memory_operand" "")]
15531 "TARGET_USE_FANCY_MATH_387
15532 && can_create_pseudo_p ()"
15535 [(set (match_dup 2)(match_dup 1))
15537 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15539 operands[2] = gen_reg_rtx (<MODE>mode);
15541 MEM_VOLATILE_P (operands[1]) = 1;
15543 [(set_attr "type" "multi")
15544 (set_attr "unit" "i387")
15545 (set_attr "mode" "<MODE>")])
15547 (define_expand "isinfxf2"
15548 [(use (match_operand:SI 0 "register_operand" ""))
15549 (use (match_operand:XF 1 "register_operand" ""))]
15550 "TARGET_USE_FANCY_MATH_387
15551 && TARGET_C99_FUNCTIONS"
15553 rtx mask = GEN_INT (0x45);
15554 rtx val = GEN_INT (0x05);
15558 rtx scratch = gen_reg_rtx (HImode);
15559 rtx res = gen_reg_rtx (QImode);
15561 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15563 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15564 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15565 cond = gen_rtx_fmt_ee (EQ, QImode,
15566 gen_rtx_REG (CCmode, FLAGS_REG),
15568 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15569 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15573 (define_expand "isinf<mode>2"
15574 [(use (match_operand:SI 0 "register_operand" ""))
15575 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && TARGET_C99_FUNCTIONS
15578 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15580 rtx mask = GEN_INT (0x45);
15581 rtx val = GEN_INT (0x05);
15585 rtx scratch = gen_reg_rtx (HImode);
15586 rtx res = gen_reg_rtx (QImode);
15588 /* Remove excess precision by forcing value through memory. */
15589 if (memory_operand (operands[1], VOIDmode))
15590 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15593 enum ix86_stack_slot slot = (virtuals_instantiated
15596 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15598 emit_move_insn (temp, operands[1]);
15599 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15602 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15603 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15604 cond = gen_rtx_fmt_ee (EQ, QImode,
15605 gen_rtx_REG (CCmode, FLAGS_REG),
15607 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15608 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15612 (define_expand "signbitxf2"
15613 [(use (match_operand:SI 0 "register_operand" ""))
15614 (use (match_operand:XF 1 "register_operand" ""))]
15615 "TARGET_USE_FANCY_MATH_387"
15617 rtx scratch = gen_reg_rtx (HImode);
15619 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15620 emit_insn (gen_andsi3 (operands[0],
15621 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15625 (define_insn "movmsk_df"
15626 [(set (match_operand:SI 0 "register_operand" "=r")
15628 [(match_operand:DF 1 "register_operand" "x")]
15630 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15631 "%vmovmskpd\t{%1, %0|%0, %1}"
15632 [(set_attr "type" "ssemov")
15633 (set_attr "prefix" "maybe_vex")
15634 (set_attr "mode" "DF")])
15636 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15637 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15638 (define_expand "signbitdf2"
15639 [(use (match_operand:SI 0 "register_operand" ""))
15640 (use (match_operand:DF 1 "register_operand" ""))]
15641 "TARGET_USE_FANCY_MATH_387
15642 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15644 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15646 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15647 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15651 rtx scratch = gen_reg_rtx (HImode);
15653 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15654 emit_insn (gen_andsi3 (operands[0],
15655 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15660 (define_expand "signbitsf2"
15661 [(use (match_operand:SI 0 "register_operand" ""))
15662 (use (match_operand:SF 1 "register_operand" ""))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15666 rtx scratch = gen_reg_rtx (HImode);
15668 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15669 emit_insn (gen_andsi3 (operands[0],
15670 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15674 ;; Block operation instructions
15677 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15680 [(set_attr "length" "1")
15681 (set_attr "length_immediate" "0")
15682 (set_attr "modrm" "0")])
15684 (define_expand "movmem<mode>"
15685 [(use (match_operand:BLK 0 "memory_operand" ""))
15686 (use (match_operand:BLK 1 "memory_operand" ""))
15687 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15688 (use (match_operand:SWI48 3 "const_int_operand" ""))
15689 (use (match_operand:SI 4 "const_int_operand" ""))
15690 (use (match_operand:SI 5 "const_int_operand" ""))]
15693 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15694 operands[4], operands[5]))
15700 ;; Most CPUs don't like single string operations
15701 ;; Handle this case here to simplify previous expander.
15703 (define_expand "strmov"
15704 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15705 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15706 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15707 (clobber (reg:CC FLAGS_REG))])
15708 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15709 (clobber (reg:CC FLAGS_REG))])]
15712 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15714 /* If .md ever supports :P for Pmode, these can be directly
15715 in the pattern above. */
15716 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15717 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15719 /* Can't use this if the user has appropriated esi or edi. */
15720 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15721 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15723 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15724 operands[2], operands[3],
15725 operands[5], operands[6]));
15729 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15732 (define_expand "strmov_singleop"
15733 [(parallel [(set (match_operand 1 "memory_operand" "")
15734 (match_operand 3 "memory_operand" ""))
15735 (set (match_operand 0 "register_operand" "")
15736 (match_operand 4 "" ""))
15737 (set (match_operand 2 "register_operand" "")
15738 (match_operand 5 "" ""))])]
15740 "ix86_current_function_needs_cld = 1;")
15742 (define_insn "*strmovdi_rex_1"
15743 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15744 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15745 (set (match_operand:DI 0 "register_operand" "=D")
15746 (plus:DI (match_dup 2)
15748 (set (match_operand:DI 1 "register_operand" "=S")
15749 (plus:DI (match_dup 3)
15752 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15754 [(set_attr "type" "str")
15755 (set_attr "memory" "both")
15756 (set_attr "mode" "DI")])
15758 (define_insn "*strmovsi_1"
15759 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15760 (mem:SI (match_operand:P 3 "register_operand" "1")))
15761 (set (match_operand:P 0 "register_operand" "=D")
15762 (plus:P (match_dup 2)
15764 (set (match_operand:P 1 "register_operand" "=S")
15765 (plus:P (match_dup 3)
15767 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "both")
15771 (set_attr "mode" "SI")])
15773 (define_insn "*strmovhi_1"
15774 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15775 (mem:HI (match_operand:P 3 "register_operand" "1")))
15776 (set (match_operand:P 0 "register_operand" "=D")
15777 (plus:P (match_dup 2)
15779 (set (match_operand:P 1 "register_operand" "=S")
15780 (plus:P (match_dup 3)
15782 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15784 [(set_attr "type" "str")
15785 (set_attr "memory" "both")
15786 (set_attr "mode" "HI")])
15788 (define_insn "*strmovqi_1"
15789 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15790 (mem:QI (match_operand:P 3 "register_operand" "1")))
15791 (set (match_operand:P 0 "register_operand" "=D")
15792 (plus:P (match_dup 2)
15794 (set (match_operand:P 1 "register_operand" "=S")
15795 (plus:P (match_dup 3)
15797 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15799 [(set_attr "type" "str")
15800 (set_attr "memory" "both")
15801 (set (attr "prefix_rex")
15803 (match_test "<P:MODE>mode == DImode")
15805 (const_string "*")))
15806 (set_attr "mode" "QI")])
15808 (define_expand "rep_mov"
15809 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15810 (set (match_operand 0 "register_operand" "")
15811 (match_operand 5 "" ""))
15812 (set (match_operand 2 "register_operand" "")
15813 (match_operand 6 "" ""))
15814 (set (match_operand 1 "memory_operand" "")
15815 (match_operand 3 "memory_operand" ""))
15816 (use (match_dup 4))])]
15818 "ix86_current_function_needs_cld = 1;")
15820 (define_insn "*rep_movdi_rex64"
15821 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15822 (set (match_operand:DI 0 "register_operand" "=D")
15823 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15825 (match_operand:DI 3 "register_operand" "0")))
15826 (set (match_operand:DI 1 "register_operand" "=S")
15827 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15828 (match_operand:DI 4 "register_operand" "1")))
15829 (set (mem:BLK (match_dup 3))
15830 (mem:BLK (match_dup 4)))
15831 (use (match_dup 5))]
15833 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15835 [(set_attr "type" "str")
15836 (set_attr "prefix_rep" "1")
15837 (set_attr "memory" "both")
15838 (set_attr "mode" "DI")])
15840 (define_insn "*rep_movsi"
15841 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15842 (set (match_operand:P 0 "register_operand" "=D")
15843 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15845 (match_operand:P 3 "register_operand" "0")))
15846 (set (match_operand:P 1 "register_operand" "=S")
15847 (plus:P (ashift:P (match_dup 5) (const_int 2))
15848 (match_operand:P 4 "register_operand" "1")))
15849 (set (mem:BLK (match_dup 3))
15850 (mem:BLK (match_dup 4)))
15851 (use (match_dup 5))]
15852 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15853 "rep{%;} movs{l|d}"
15854 [(set_attr "type" "str")
15855 (set_attr "prefix_rep" "1")
15856 (set_attr "memory" "both")
15857 (set_attr "mode" "SI")])
15859 (define_insn "*rep_movqi"
15860 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15861 (set (match_operand:P 0 "register_operand" "=D")
15862 (plus:P (match_operand:P 3 "register_operand" "0")
15863 (match_operand:P 5 "register_operand" "2")))
15864 (set (match_operand:P 1 "register_operand" "=S")
15865 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15866 (set (mem:BLK (match_dup 3))
15867 (mem:BLK (match_dup 4)))
15868 (use (match_dup 5))]
15869 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15871 [(set_attr "type" "str")
15872 (set_attr "prefix_rep" "1")
15873 (set_attr "memory" "both")
15874 (set_attr "mode" "QI")])
15876 (define_expand "setmem<mode>"
15877 [(use (match_operand:BLK 0 "memory_operand" ""))
15878 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15879 (use (match_operand:QI 2 "nonmemory_operand" ""))
15880 (use (match_operand 3 "const_int_operand" ""))
15881 (use (match_operand:SI 4 "const_int_operand" ""))
15882 (use (match_operand:SI 5 "const_int_operand" ""))]
15885 if (ix86_expand_setmem (operands[0], operands[1],
15886 operands[2], operands[3],
15887 operands[4], operands[5]))
15893 ;; Most CPUs don't like single string operations
15894 ;; Handle this case here to simplify previous expander.
15896 (define_expand "strset"
15897 [(set (match_operand 1 "memory_operand" "")
15898 (match_operand 2 "register_operand" ""))
15899 (parallel [(set (match_operand 0 "register_operand" "")
15901 (clobber (reg:CC FLAGS_REG))])]
15904 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15905 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15907 /* If .md ever supports :P for Pmode, this can be directly
15908 in the pattern above. */
15909 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15910 GEN_INT (GET_MODE_SIZE (GET_MODE
15912 /* Can't use this if the user has appropriated eax or edi. */
15913 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15914 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15916 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15922 (define_expand "strset_singleop"
15923 [(parallel [(set (match_operand 1 "memory_operand" "")
15924 (match_operand 2 "register_operand" ""))
15925 (set (match_operand 0 "register_operand" "")
15926 (match_operand 3 "" ""))])]
15928 "ix86_current_function_needs_cld = 1;")
15930 (define_insn "*strsetdi_rex_1"
15931 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15932 (match_operand:DI 2 "register_operand" "a"))
15933 (set (match_operand:DI 0 "register_operand" "=D")
15934 (plus:DI (match_dup 1)
15937 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15939 [(set_attr "type" "str")
15940 (set_attr "memory" "store")
15941 (set_attr "mode" "DI")])
15943 (define_insn "*strsetsi_1"
15944 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15945 (match_operand:SI 2 "register_operand" "a"))
15946 (set (match_operand:P 0 "register_operand" "=D")
15947 (plus:P (match_dup 1)
15949 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15951 [(set_attr "type" "str")
15952 (set_attr "memory" "store")
15953 (set_attr "mode" "SI")])
15955 (define_insn "*strsethi_1"
15956 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15957 (match_operand:HI 2 "register_operand" "a"))
15958 (set (match_operand:P 0 "register_operand" "=D")
15959 (plus:P (match_dup 1)
15961 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15963 [(set_attr "type" "str")
15964 (set_attr "memory" "store")
15965 (set_attr "mode" "HI")])
15967 (define_insn "*strsetqi_1"
15968 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15969 (match_operand:QI 2 "register_operand" "a"))
15970 (set (match_operand:P 0 "register_operand" "=D")
15971 (plus:P (match_dup 1)
15973 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15975 [(set_attr "type" "str")
15976 (set_attr "memory" "store")
15977 (set (attr "prefix_rex")
15979 (match_test "<P:MODE>mode == DImode")
15981 (const_string "*")))
15982 (set_attr "mode" "QI")])
15984 (define_expand "rep_stos"
15985 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15986 (set (match_operand 0 "register_operand" "")
15987 (match_operand 4 "" ""))
15988 (set (match_operand 2 "memory_operand" "") (const_int 0))
15989 (use (match_operand 3 "register_operand" ""))
15990 (use (match_dup 1))])]
15992 "ix86_current_function_needs_cld = 1;")
15994 (define_insn "*rep_stosdi_rex64"
15995 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15996 (set (match_operand:DI 0 "register_operand" "=D")
15997 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15999 (match_operand:DI 3 "register_operand" "0")))
16000 (set (mem:BLK (match_dup 3))
16002 (use (match_operand:DI 2 "register_operand" "a"))
16003 (use (match_dup 4))]
16005 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16007 [(set_attr "type" "str")
16008 (set_attr "prefix_rep" "1")
16009 (set_attr "memory" "store")
16010 (set_attr "mode" "DI")])
16012 (define_insn "*rep_stossi"
16013 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:P 0 "register_operand" "=D")
16015 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16017 (match_operand:P 3 "register_operand" "0")))
16018 (set (mem:BLK (match_dup 3))
16020 (use (match_operand:SI 2 "register_operand" "a"))
16021 (use (match_dup 4))]
16022 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16023 "rep{%;} stos{l|d}"
16024 [(set_attr "type" "str")
16025 (set_attr "prefix_rep" "1")
16026 (set_attr "memory" "store")
16027 (set_attr "mode" "SI")])
16029 (define_insn "*rep_stosqi"
16030 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16031 (set (match_operand:P 0 "register_operand" "=D")
16032 (plus:P (match_operand:P 3 "register_operand" "0")
16033 (match_operand:P 4 "register_operand" "1")))
16034 (set (mem:BLK (match_dup 3))
16036 (use (match_operand:QI 2 "register_operand" "a"))
16037 (use (match_dup 4))]
16038 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16040 [(set_attr "type" "str")
16041 (set_attr "prefix_rep" "1")
16042 (set_attr "memory" "store")
16043 (set (attr "prefix_rex")
16045 (match_test "<P:MODE>mode == DImode")
16047 (const_string "*")))
16048 (set_attr "mode" "QI")])
16050 (define_expand "cmpstrnsi"
16051 [(set (match_operand:SI 0 "register_operand" "")
16052 (compare:SI (match_operand:BLK 1 "general_operand" "")
16053 (match_operand:BLK 2 "general_operand" "")))
16054 (use (match_operand 3 "general_operand" ""))
16055 (use (match_operand 4 "immediate_operand" ""))]
16058 rtx addr1, addr2, out, outlow, count, countreg, align;
16060 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16063 /* Can't use this if the user has appropriated ecx, esi or edi. */
16064 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16069 out = gen_reg_rtx (SImode);
16071 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16072 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16073 if (addr1 != XEXP (operands[1], 0))
16074 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16075 if (addr2 != XEXP (operands[2], 0))
16076 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16078 count = operands[3];
16079 countreg = ix86_zero_extend_to_Pmode (count);
16081 /* %%% Iff we are testing strict equality, we can use known alignment
16082 to good advantage. This may be possible with combine, particularly
16083 once cc0 is dead. */
16084 align = operands[4];
16086 if (CONST_INT_P (count))
16088 if (INTVAL (count) == 0)
16090 emit_move_insn (operands[0], const0_rtx);
16093 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16094 operands[1], operands[2]));
16098 rtx (*gen_cmp) (rtx, rtx);
16100 gen_cmp = (TARGET_64BIT
16101 ? gen_cmpdi_1 : gen_cmpsi_1);
16103 emit_insn (gen_cmp (countreg, countreg));
16104 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16105 operands[1], operands[2]));
16108 outlow = gen_lowpart (QImode, out);
16109 emit_insn (gen_cmpintqi (outlow));
16110 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16112 if (operands[0] != out)
16113 emit_move_insn (operands[0], out);
16118 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16120 (define_expand "cmpintqi"
16121 [(set (match_dup 1)
16122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16125 (parallel [(set (match_operand:QI 0 "register_operand" "")
16126 (minus:QI (match_dup 1)
16128 (clobber (reg:CC FLAGS_REG))])]
16131 operands[1] = gen_reg_rtx (QImode);
16132 operands[2] = gen_reg_rtx (QImode);
16135 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16136 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16138 (define_expand "cmpstrnqi_nz_1"
16139 [(parallel [(set (reg:CC FLAGS_REG)
16140 (compare:CC (match_operand 4 "memory_operand" "")
16141 (match_operand 5 "memory_operand" "")))
16142 (use (match_operand 2 "register_operand" ""))
16143 (use (match_operand:SI 3 "immediate_operand" ""))
16144 (clobber (match_operand 0 "register_operand" ""))
16145 (clobber (match_operand 1 "register_operand" ""))
16146 (clobber (match_dup 2))])]
16148 "ix86_current_function_needs_cld = 1;")
16150 (define_insn "*cmpstrnqi_nz_1"
16151 [(set (reg:CC FLAGS_REG)
16152 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16153 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16154 (use (match_operand:P 6 "register_operand" "2"))
16155 (use (match_operand:SI 3 "immediate_operand" "i"))
16156 (clobber (match_operand:P 0 "register_operand" "=S"))
16157 (clobber (match_operand:P 1 "register_operand" "=D"))
16158 (clobber (match_operand:P 2 "register_operand" "=c"))]
16159 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16161 [(set_attr "type" "str")
16162 (set_attr "mode" "QI")
16163 (set (attr "prefix_rex")
16165 (match_test "<P:MODE>mode == DImode")
16167 (const_string "*")))
16168 (set_attr "prefix_rep" "1")])
16170 ;; The same, but the count is not known to not be zero.
16172 (define_expand "cmpstrnqi_1"
16173 [(parallel [(set (reg:CC FLAGS_REG)
16174 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16176 (compare:CC (match_operand 4 "memory_operand" "")
16177 (match_operand 5 "memory_operand" ""))
16179 (use (match_operand:SI 3 "immediate_operand" ""))
16180 (use (reg:CC FLAGS_REG))
16181 (clobber (match_operand 0 "register_operand" ""))
16182 (clobber (match_operand 1 "register_operand" ""))
16183 (clobber (match_dup 2))])]
16185 "ix86_current_function_needs_cld = 1;")
16187 (define_insn "*cmpstrnqi_1"
16188 [(set (reg:CC FLAGS_REG)
16189 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16191 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16192 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16194 (use (match_operand:SI 3 "immediate_operand" "i"))
16195 (use (reg:CC FLAGS_REG))
16196 (clobber (match_operand:P 0 "register_operand" "=S"))
16197 (clobber (match_operand:P 1 "register_operand" "=D"))
16198 (clobber (match_operand:P 2 "register_operand" "=c"))]
16199 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16201 [(set_attr "type" "str")
16202 (set_attr "mode" "QI")
16203 (set (attr "prefix_rex")
16205 (match_test "<P:MODE>mode == DImode")
16207 (const_string "*")))
16208 (set_attr "prefix_rep" "1")])
16210 (define_expand "strlen<mode>"
16211 [(set (match_operand:P 0 "register_operand" "")
16212 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16213 (match_operand:QI 2 "immediate_operand" "")
16214 (match_operand 3 "immediate_operand" "")]
16218 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16224 (define_expand "strlenqi_1"
16225 [(parallel [(set (match_operand 0 "register_operand" "")
16226 (match_operand 2 "" ""))
16227 (clobber (match_operand 1 "register_operand" ""))
16228 (clobber (reg:CC FLAGS_REG))])]
16230 "ix86_current_function_needs_cld = 1;")
16232 (define_insn "*strlenqi_1"
16233 [(set (match_operand:P 0 "register_operand" "=&c")
16234 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16235 (match_operand:QI 2 "register_operand" "a")
16236 (match_operand:P 3 "immediate_operand" "i")
16237 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16238 (clobber (match_operand:P 1 "register_operand" "=D"))
16239 (clobber (reg:CC FLAGS_REG))]
16240 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16242 [(set_attr "type" "str")
16243 (set_attr "mode" "QI")
16244 (set (attr "prefix_rex")
16246 (match_test "<P:MODE>mode == DImode")
16248 (const_string "*")))
16249 (set_attr "prefix_rep" "1")])
16251 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16252 ;; handled in combine, but it is not currently up to the task.
16253 ;; When used for their truth value, the cmpstrn* expanders generate
16262 ;; The intermediate three instructions are unnecessary.
16264 ;; This one handles cmpstrn*_nz_1...
16267 (set (reg:CC FLAGS_REG)
16268 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16269 (mem:BLK (match_operand 5 "register_operand" ""))))
16270 (use (match_operand 6 "register_operand" ""))
16271 (use (match_operand:SI 3 "immediate_operand" ""))
16272 (clobber (match_operand 0 "register_operand" ""))
16273 (clobber (match_operand 1 "register_operand" ""))
16274 (clobber (match_operand 2 "register_operand" ""))])
16275 (set (match_operand:QI 7 "register_operand" "")
16276 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16277 (set (match_operand:QI 8 "register_operand" "")
16278 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16279 (set (reg FLAGS_REG)
16280 (compare (match_dup 7) (match_dup 8)))
16282 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16284 (set (reg:CC FLAGS_REG)
16285 (compare:CC (mem:BLK (match_dup 4))
16286 (mem:BLK (match_dup 5))))
16287 (use (match_dup 6))
16288 (use (match_dup 3))
16289 (clobber (match_dup 0))
16290 (clobber (match_dup 1))
16291 (clobber (match_dup 2))])])
16293 ;; ...and this one handles cmpstrn*_1.
16296 (set (reg:CC FLAGS_REG)
16297 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16299 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16300 (mem:BLK (match_operand 5 "register_operand" "")))
16302 (use (match_operand:SI 3 "immediate_operand" ""))
16303 (use (reg:CC FLAGS_REG))
16304 (clobber (match_operand 0 "register_operand" ""))
16305 (clobber (match_operand 1 "register_operand" ""))
16306 (clobber (match_operand 2 "register_operand" ""))])
16307 (set (match_operand:QI 7 "register_operand" "")
16308 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16309 (set (match_operand:QI 8 "register_operand" "")
16310 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16311 (set (reg FLAGS_REG)
16312 (compare (match_dup 7) (match_dup 8)))
16314 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16316 (set (reg:CC FLAGS_REG)
16317 (if_then_else:CC (ne (match_dup 6)
16319 (compare:CC (mem:BLK (match_dup 4))
16320 (mem:BLK (match_dup 5)))
16322 (use (match_dup 3))
16323 (use (reg:CC FLAGS_REG))
16324 (clobber (match_dup 0))
16325 (clobber (match_dup 1))
16326 (clobber (match_dup 2))])])
16328 ;; Conditional move instructions.
16330 (define_expand "mov<mode>cc"
16331 [(set (match_operand:SWIM 0 "register_operand" "")
16332 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16333 (match_operand:SWIM 2 "<general_operand>" "")
16334 (match_operand:SWIM 3 "<general_operand>" "")))]
16336 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16338 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16339 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16340 ;; So just document what we're doing explicitly.
16342 (define_expand "x86_mov<mode>cc_0_m1"
16344 [(set (match_operand:SWI48 0 "register_operand" "")
16345 (if_then_else:SWI48
16346 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16347 [(match_operand 1 "flags_reg_operand" "")
16351 (clobber (reg:CC FLAGS_REG))])])
16353 (define_insn "*x86_mov<mode>cc_0_m1"
16354 [(set (match_operand:SWI48 0 "register_operand" "=r")
16355 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16356 [(reg FLAGS_REG) (const_int 0)])
16359 (clobber (reg:CC FLAGS_REG))]
16361 "sbb{<imodesuffix>}\t%0, %0"
16362 ; Since we don't have the proper number of operands for an alu insn,
16363 ; fill in all the blanks.
16364 [(set_attr "type" "alu")
16365 (set_attr "use_carry" "1")
16366 (set_attr "pent_pair" "pu")
16367 (set_attr "memory" "none")
16368 (set_attr "imm_disp" "false")
16369 (set_attr "mode" "<MODE>")
16370 (set_attr "length_immediate" "0")])
16372 (define_insn "*x86_mov<mode>cc_0_m1_se"
16373 [(set (match_operand:SWI48 0 "register_operand" "=r")
16374 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16375 [(reg FLAGS_REG) (const_int 0)])
16378 (clobber (reg:CC FLAGS_REG))]
16380 "sbb{<imodesuffix>}\t%0, %0"
16381 [(set_attr "type" "alu")
16382 (set_attr "use_carry" "1")
16383 (set_attr "pent_pair" "pu")
16384 (set_attr "memory" "none")
16385 (set_attr "imm_disp" "false")
16386 (set_attr "mode" "<MODE>")
16387 (set_attr "length_immediate" "0")])
16389 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16390 [(set (match_operand:SWI48 0 "register_operand" "=r")
16391 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16392 [(reg FLAGS_REG) (const_int 0)])))]
16394 "sbb{<imodesuffix>}\t%0, %0"
16395 [(set_attr "type" "alu")
16396 (set_attr "use_carry" "1")
16397 (set_attr "pent_pair" "pu")
16398 (set_attr "memory" "none")
16399 (set_attr "imm_disp" "false")
16400 (set_attr "mode" "<MODE>")
16401 (set_attr "length_immediate" "0")])
16403 (define_insn "*mov<mode>cc_noc"
16404 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16405 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16406 [(reg FLAGS_REG) (const_int 0)])
16407 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16408 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16409 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16411 cmov%O2%C1\t{%2, %0|%0, %2}
16412 cmov%O2%c1\t{%3, %0|%0, %3}"
16413 [(set_attr "type" "icmov")
16414 (set_attr "mode" "<MODE>")])
16416 (define_insn_and_split "*movqicc_noc"
16417 [(set (match_operand:QI 0 "register_operand" "=r,r")
16418 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16419 [(match_operand 4 "flags_reg_operand" "")
16421 (match_operand:QI 2 "register_operand" "r,0")
16422 (match_operand:QI 3 "register_operand" "0,r")))]
16423 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16425 "&& reload_completed"
16426 [(set (match_dup 0)
16427 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16430 "operands[0] = gen_lowpart (SImode, operands[0]);
16431 operands[2] = gen_lowpart (SImode, operands[2]);
16432 operands[3] = gen_lowpart (SImode, operands[3]);"
16433 [(set_attr "type" "icmov")
16434 (set_attr "mode" "SI")])
16436 (define_expand "mov<mode>cc"
16437 [(set (match_operand:X87MODEF 0 "register_operand" "")
16438 (if_then_else:X87MODEF
16439 (match_operand 1 "ix86_fp_comparison_operator" "")
16440 (match_operand:X87MODEF 2 "register_operand" "")
16441 (match_operand:X87MODEF 3 "register_operand" "")))]
16442 "(TARGET_80387 && TARGET_CMOVE)
16443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16444 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16446 (define_insn "*movxfcc_1"
16447 [(set (match_operand:XF 0 "register_operand" "=f,f")
16448 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand:XF 2 "register_operand" "f,0")
16451 (match_operand:XF 3 "register_operand" "0,f")))]
16452 "TARGET_80387 && TARGET_CMOVE"
16454 fcmov%F1\t{%2, %0|%0, %2}
16455 fcmov%f1\t{%3, %0|%0, %3}"
16456 [(set_attr "type" "fcmov")
16457 (set_attr "mode" "XF")])
16459 (define_insn "*movdfcc_1_rex64"
16460 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16461 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16463 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16464 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16465 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16466 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16468 fcmov%F1\t{%2, %0|%0, %2}
16469 fcmov%f1\t{%3, %0|%0, %3}
16470 cmov%O2%C1\t{%2, %0|%0, %2}
16471 cmov%O2%c1\t{%3, %0|%0, %3}"
16472 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16473 (set_attr "mode" "DF,DF,DI,DI")])
16475 (define_insn "*movdfcc_1"
16476 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16488 [(set_attr "type" "fcmov,fcmov,multi,multi")
16489 (set_attr "mode" "DF,DF,DI,DI")])
16492 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16494 [(match_operand 4 "flags_reg_operand" "")
16496 (match_operand:DF 2 "nonimmediate_operand" "")
16497 (match_operand:DF 3 "nonimmediate_operand" "")))]
16498 "!TARGET_64BIT && reload_completed"
16499 [(set (match_dup 2)
16500 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16504 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16508 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16509 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16512 (define_insn "*movsfcc_1_387"
16513 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16516 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518 "TARGET_80387 && TARGET_CMOVE
16519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16521 fcmov%F1\t{%2, %0|%0, %2}
16522 fcmov%f1\t{%3, %0|%0, %3}
16523 cmov%O2%C1\t{%2, %0|%0, %2}
16524 cmov%O2%c1\t{%3, %0|%0, %3}"
16525 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526 (set_attr "mode" "SF,SF,SI,SI")])
16528 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529 ;; the scalar versions to have only XMM registers as operands.
16531 ;; XOP conditional move
16532 (define_insn "*xop_pcmov_<mode>"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x")
16534 (if_then_else:MODEF
16535 (match_operand:MODEF 1 "register_operand" "x")
16536 (match_operand:MODEF 2 "register_operand" "x")
16537 (match_operand:MODEF 3 "register_operand" "x")))]
16539 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540 [(set_attr "type" "sse4arg")])
16542 ;; These versions of the min/max patterns are intentionally ignorant of
16543 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545 ;; are undefined in this condition, we're certain this is correct.
16547 (define_insn "<code><mode>3"
16548 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16550 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16554 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556 [(set_attr "isa" "noavx,avx")
16557 (set_attr "prefix" "orig,vex")
16558 (set_attr "type" "sseadd")
16559 (set_attr "mode" "<MODE>")])
16561 ;; These versions of the min/max patterns implement exactly the operations
16562 ;; min = (op1 < op2 ? op1 : op2)
16563 ;; max = (!(op1 < op2) ? op1 : op2)
16564 ;; Their operands are not commutative, and thus they may be used in the
16565 ;; presence of -0.0 and NaN.
16567 (define_insn "*ieee_smin<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16575 min<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "*ieee_smax<mode>3"
16583 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16585 [(match_operand:MODEF 1 "register_operand" "0,x")
16586 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16590 max<ssemodesuffix>\t{%2, %0|%0, %2}
16591 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16597 ;; Make two stack loads independent:
16599 ;; fld %st(0) -> fld bb
16600 ;; fmul bb fmul %st(1), %st
16602 ;; Actually we only match the last two instructions for simplicity.
16604 [(set (match_operand 0 "fp_register_operand" "")
16605 (match_operand 1 "fp_register_operand" ""))
16607 (match_operator 2 "binary_fp_operator"
16609 (match_operand 3 "memory_operand" "")]))]
16610 "REGNO (operands[0]) != REGNO (operands[1])"
16611 [(set (match_dup 0) (match_dup 3))
16612 (set (match_dup 0) (match_dup 4))]
16614 ;; The % modifier is not operational anymore in peephole2's, so we have to
16615 ;; swap the operands manually in the case of addition and multiplication.
16616 "if (COMMUTATIVE_ARITH_P (operands[2]))
16617 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16618 GET_MODE (operands[2]),
16619 operands[0], operands[1]);
16621 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16622 GET_MODE (operands[2]),
16623 operands[1], operands[0]);")
16625 ;; Conditional addition patterns
16626 (define_expand "add<mode>cc"
16627 [(match_operand:SWI 0 "register_operand" "")
16628 (match_operand 1 "ordered_comparison_operator" "")
16629 (match_operand:SWI 2 "register_operand" "")
16630 (match_operand:SWI 3 "const_int_operand" "")]
16632 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16634 ;; Misc patterns (?)
16636 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16637 ;; Otherwise there will be nothing to keep
16639 ;; [(set (reg ebp) (reg esp))]
16640 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16641 ;; (clobber (eflags)]
16642 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16644 ;; in proper program order.
16646 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16647 [(set (match_operand:P 0 "register_operand" "=r,r")
16648 (plus:P (match_operand:P 1 "register_operand" "0,r")
16649 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16650 (clobber (reg:CC FLAGS_REG))
16651 (clobber (mem:BLK (scratch)))]
16654 switch (get_attr_type (insn))
16657 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16660 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16661 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16662 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16664 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16667 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16668 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16671 [(set (attr "type")
16672 (cond [(and (eq_attr "alternative" "0")
16673 (not (match_test "TARGET_OPT_AGU")))
16674 (const_string "alu")
16675 (match_operand:<MODE> 2 "const0_operand" "")
16676 (const_string "imov")
16678 (const_string "lea")))
16679 (set (attr "length_immediate")
16680 (cond [(eq_attr "type" "imov")
16682 (and (eq_attr "type" "alu")
16683 (match_operand 2 "const128_operand" ""))
16686 (const_string "*")))
16687 (set_attr "mode" "<MODE>")])
16689 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16690 [(set (match_operand:P 0 "register_operand" "=r")
16691 (minus:P (match_operand:P 1 "register_operand" "0")
16692 (match_operand:P 2 "register_operand" "r")))
16693 (clobber (reg:CC FLAGS_REG))
16694 (clobber (mem:BLK (scratch)))]
16696 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16697 [(set_attr "type" "alu")
16698 (set_attr "mode" "<MODE>")])
16700 (define_insn "allocate_stack_worker_probe_<mode>"
16701 [(set (match_operand:P 0 "register_operand" "=a")
16702 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16703 UNSPECV_STACK_PROBE))
16704 (clobber (reg:CC FLAGS_REG))]
16705 "ix86_target_stack_probe ()"
16706 "call\t___chkstk_ms"
16707 [(set_attr "type" "multi")
16708 (set_attr "length" "5")])
16710 (define_expand "allocate_stack"
16711 [(match_operand 0 "register_operand" "")
16712 (match_operand 1 "general_operand" "")]
16713 "ix86_target_stack_probe ()"
16717 #ifndef CHECK_STACK_LIMIT
16718 #define CHECK_STACK_LIMIT 0
16721 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16722 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16724 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16725 stack_pointer_rtx, 0, OPTAB_DIRECT);
16726 if (x != stack_pointer_rtx)
16727 emit_move_insn (stack_pointer_rtx, x);
16731 x = copy_to_mode_reg (Pmode, operands[1]);
16733 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16735 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16736 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16737 stack_pointer_rtx, 0, OPTAB_DIRECT);
16738 if (x != stack_pointer_rtx)
16739 emit_move_insn (stack_pointer_rtx, x);
16742 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16746 ;; Use IOR for stack probes, this is shorter.
16747 (define_expand "probe_stack"
16748 [(match_operand 0 "memory_operand" "")]
16751 rtx (*gen_ior3) (rtx, rtx, rtx);
16753 gen_ior3 = (GET_MODE (operands[0]) == DImode
16754 ? gen_iordi3 : gen_iorsi3);
16756 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16760 (define_insn "adjust_stack_and_probe<mode>"
16761 [(set (match_operand:P 0 "register_operand" "=r")
16762 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16763 UNSPECV_PROBE_STACK_RANGE))
16764 (set (reg:P SP_REG)
16765 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16766 (clobber (reg:CC FLAGS_REG))
16767 (clobber (mem:BLK (scratch)))]
16769 "* return output_adjust_stack_and_probe (operands[0]);"
16770 [(set_attr "type" "multi")])
16772 (define_insn "probe_stack_range<mode>"
16773 [(set (match_operand:P 0 "register_operand" "=r")
16774 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16775 (match_operand:P 2 "const_int_operand" "n")]
16776 UNSPECV_PROBE_STACK_RANGE))
16777 (clobber (reg:CC FLAGS_REG))]
16779 "* return output_probe_stack_range (operands[0], operands[2]);"
16780 [(set_attr "type" "multi")])
16782 (define_expand "builtin_setjmp_receiver"
16783 [(label_ref (match_operand 0 "" ""))]
16784 "!TARGET_64BIT && flag_pic"
16790 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16791 rtx label_rtx = gen_label_rtx ();
16792 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16793 xops[0] = xops[1] = picreg;
16794 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16795 ix86_expand_binary_operator (MINUS, SImode, xops);
16799 emit_insn (gen_set_got (pic_offset_table_rtx));
16803 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16806 [(set (match_operand 0 "register_operand" "")
16807 (match_operator 3 "promotable_binary_operator"
16808 [(match_operand 1 "register_operand" "")
16809 (match_operand 2 "aligned_operand" "")]))
16810 (clobber (reg:CC FLAGS_REG))]
16811 "! TARGET_PARTIAL_REG_STALL && reload_completed
16812 && ((GET_MODE (operands[0]) == HImode
16813 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16814 /* ??? next two lines just !satisfies_constraint_K (...) */
16815 || !CONST_INT_P (operands[2])
16816 || satisfies_constraint_K (operands[2])))
16817 || (GET_MODE (operands[0]) == QImode
16818 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16819 [(parallel [(set (match_dup 0)
16820 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16821 (clobber (reg:CC FLAGS_REG))])]
16822 "operands[0] = gen_lowpart (SImode, operands[0]);
16823 operands[1] = gen_lowpart (SImode, operands[1]);
16824 if (GET_CODE (operands[3]) != ASHIFT)
16825 operands[2] = gen_lowpart (SImode, operands[2]);
16826 PUT_MODE (operands[3], SImode);")
16828 ; Promote the QImode tests, as i386 has encoding of the AND
16829 ; instruction with 32-bit sign-extended immediate and thus the
16830 ; instruction size is unchanged, except in the %eax case for
16831 ; which it is increased by one byte, hence the ! optimize_size.
16833 [(set (match_operand 0 "flags_reg_operand" "")
16834 (match_operator 2 "compare_operator"
16835 [(and (match_operand 3 "aligned_operand" "")
16836 (match_operand 4 "const_int_operand" ""))
16838 (set (match_operand 1 "register_operand" "")
16839 (and (match_dup 3) (match_dup 4)))]
16840 "! TARGET_PARTIAL_REG_STALL && reload_completed
16841 && optimize_insn_for_speed_p ()
16842 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16843 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16844 /* Ensure that the operand will remain sign-extended immediate. */
16845 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16846 [(parallel [(set (match_dup 0)
16847 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16850 (and:SI (match_dup 3) (match_dup 4)))])]
16853 = gen_int_mode (INTVAL (operands[4])
16854 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16855 operands[1] = gen_lowpart (SImode, operands[1]);
16856 operands[3] = gen_lowpart (SImode, operands[3]);
16859 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16860 ; the TEST instruction with 32-bit sign-extended immediate and thus
16861 ; the instruction size would at least double, which is not what we
16862 ; want even with ! optimize_size.
16864 [(set (match_operand 0 "flags_reg_operand" "")
16865 (match_operator 1 "compare_operator"
16866 [(and (match_operand:HI 2 "aligned_operand" "")
16867 (match_operand:HI 3 "const_int_operand" ""))
16869 "! TARGET_PARTIAL_REG_STALL && reload_completed
16870 && ! TARGET_FAST_PREFIX
16871 && optimize_insn_for_speed_p ()
16872 /* Ensure that the operand will remain sign-extended immediate. */
16873 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16874 [(set (match_dup 0)
16875 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16879 = gen_int_mode (INTVAL (operands[3])
16880 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16881 operands[2] = gen_lowpart (SImode, operands[2]);
16885 [(set (match_operand 0 "register_operand" "")
16886 (neg (match_operand 1 "register_operand" "")))
16887 (clobber (reg:CC FLAGS_REG))]
16888 "! TARGET_PARTIAL_REG_STALL && reload_completed
16889 && (GET_MODE (operands[0]) == HImode
16890 || (GET_MODE (operands[0]) == QImode
16891 && (TARGET_PROMOTE_QImode
16892 || optimize_insn_for_size_p ())))"
16893 [(parallel [(set (match_dup 0)
16894 (neg:SI (match_dup 1)))
16895 (clobber (reg:CC FLAGS_REG))])]
16896 "operands[0] = gen_lowpart (SImode, operands[0]);
16897 operands[1] = gen_lowpart (SImode, operands[1]);")
16900 [(set (match_operand 0 "register_operand" "")
16901 (not (match_operand 1 "register_operand" "")))]
16902 "! TARGET_PARTIAL_REG_STALL && reload_completed
16903 && (GET_MODE (operands[0]) == HImode
16904 || (GET_MODE (operands[0]) == QImode
16905 && (TARGET_PROMOTE_QImode
16906 || optimize_insn_for_size_p ())))"
16907 [(set (match_dup 0)
16908 (not:SI (match_dup 1)))]
16909 "operands[0] = gen_lowpart (SImode, operands[0]);
16910 operands[1] = gen_lowpart (SImode, operands[1]);")
16913 [(set (match_operand 0 "register_operand" "")
16914 (if_then_else (match_operator 1 "ordered_comparison_operator"
16915 [(reg FLAGS_REG) (const_int 0)])
16916 (match_operand 2 "register_operand" "")
16917 (match_operand 3 "register_operand" "")))]
16918 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16919 && (GET_MODE (operands[0]) == HImode
16920 || (GET_MODE (operands[0]) == QImode
16921 && (TARGET_PROMOTE_QImode
16922 || optimize_insn_for_size_p ())))"
16923 [(set (match_dup 0)
16924 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16925 "operands[0] = gen_lowpart (SImode, operands[0]);
16926 operands[2] = gen_lowpart (SImode, operands[2]);
16927 operands[3] = gen_lowpart (SImode, operands[3]);")
16929 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16930 ;; transform a complex memory operation into two memory to register operations.
16932 ;; Don't push memory operands
16934 [(set (match_operand:SWI 0 "push_operand" "")
16935 (match_operand:SWI 1 "memory_operand" ""))
16936 (match_scratch:SWI 2 "<r>")]
16937 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16938 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16939 [(set (match_dup 2) (match_dup 1))
16940 (set (match_dup 0) (match_dup 2))])
16942 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16945 [(set (match_operand:SF 0 "push_operand" "")
16946 (match_operand:SF 1 "memory_operand" ""))
16947 (match_scratch:SF 2 "r")]
16948 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16949 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16950 [(set (match_dup 2) (match_dup 1))
16951 (set (match_dup 0) (match_dup 2))])
16953 ;; Don't move an immediate directly to memory when the instruction
16956 [(match_scratch:SWI124 1 "<r>")
16957 (set (match_operand:SWI124 0 "memory_operand" "")
16959 "optimize_insn_for_speed_p ()
16960 && !TARGET_USE_MOV0
16961 && TARGET_SPLIT_LONG_MOVES
16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16963 && peep2_regno_dead_p (0, FLAGS_REG)"
16964 [(parallel [(set (match_dup 2) (const_int 0))
16965 (clobber (reg:CC FLAGS_REG))])
16966 (set (match_dup 0) (match_dup 1))]
16967 "operands[2] = gen_lowpart (SImode, operands[1]);")
16970 [(match_scratch:SWI124 2 "<r>")
16971 (set (match_operand:SWI124 0 "memory_operand" "")
16972 (match_operand:SWI124 1 "immediate_operand" ""))]
16973 "optimize_insn_for_speed_p ()
16974 && TARGET_SPLIT_LONG_MOVES
16975 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16976 [(set (match_dup 2) (match_dup 1))
16977 (set (match_dup 0) (match_dup 2))])
16979 ;; Don't compare memory with zero, load and use a test instead.
16981 [(set (match_operand 0 "flags_reg_operand" "")
16982 (match_operator 1 "compare_operator"
16983 [(match_operand:SI 2 "memory_operand" "")
16985 (match_scratch:SI 3 "r")]
16986 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16987 [(set (match_dup 3) (match_dup 2))
16988 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16990 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16991 ;; Don't split NOTs with a displacement operand, because resulting XOR
16992 ;; will not be pairable anyway.
16994 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16995 ;; represented using a modRM byte. The XOR replacement is long decoded,
16996 ;; so this split helps here as well.
16998 ;; Note: Can't do this as a regular split because we can't get proper
16999 ;; lifetime information then.
17002 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17003 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17004 "optimize_insn_for_speed_p ()
17005 && ((TARGET_NOT_UNPAIRABLE
17006 && (!MEM_P (operands[0])
17007 || !memory_displacement_operand (operands[0], <MODE>mode)))
17008 || (TARGET_NOT_VECTORMODE
17009 && long_memory_operand (operands[0], <MODE>mode)))
17010 && peep2_regno_dead_p (0, FLAGS_REG)"
17011 [(parallel [(set (match_dup 0)
17012 (xor:SWI124 (match_dup 1) (const_int -1)))
17013 (clobber (reg:CC FLAGS_REG))])])
17015 ;; Non pairable "test imm, reg" instructions can be translated to
17016 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17017 ;; byte opcode instead of two, have a short form for byte operands),
17018 ;; so do it for other CPUs as well. Given that the value was dead,
17019 ;; this should not create any new dependencies. Pass on the sub-word
17020 ;; versions if we're concerned about partial register stalls.
17023 [(set (match_operand 0 "flags_reg_operand" "")
17024 (match_operator 1 "compare_operator"
17025 [(and:SI (match_operand:SI 2 "register_operand" "")
17026 (match_operand:SI 3 "immediate_operand" ""))
17028 "ix86_match_ccmode (insn, CCNOmode)
17029 && (true_regnum (operands[2]) != AX_REG
17030 || satisfies_constraint_K (operands[3]))
17031 && peep2_reg_dead_p (1, operands[2])"
17033 [(set (match_dup 0)
17034 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17037 (and:SI (match_dup 2) (match_dup 3)))])])
17039 ;; We don't need to handle HImode case, because it will be promoted to SImode
17040 ;; on ! TARGET_PARTIAL_REG_STALL
17043 [(set (match_operand 0 "flags_reg_operand" "")
17044 (match_operator 1 "compare_operator"
17045 [(and:QI (match_operand:QI 2 "register_operand" "")
17046 (match_operand:QI 3 "immediate_operand" ""))
17048 "! TARGET_PARTIAL_REG_STALL
17049 && ix86_match_ccmode (insn, CCNOmode)
17050 && true_regnum (operands[2]) != AX_REG
17051 && peep2_reg_dead_p (1, operands[2])"
17053 [(set (match_dup 0)
17054 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17057 (and:QI (match_dup 2) (match_dup 3)))])])
17060 [(set (match_operand 0 "flags_reg_operand" "")
17061 (match_operator 1 "compare_operator"
17064 (match_operand 2 "ext_register_operand" "")
17067 (match_operand 3 "const_int_operand" ""))
17069 "! TARGET_PARTIAL_REG_STALL
17070 && ix86_match_ccmode (insn, CCNOmode)
17071 && true_regnum (operands[2]) != AX_REG
17072 && peep2_reg_dead_p (1, operands[2])"
17073 [(parallel [(set (match_dup 0)
17082 (set (zero_extract:SI (match_dup 2)
17090 (match_dup 3)))])])
17092 ;; Don't do logical operations with memory inputs.
17094 [(match_scratch:SI 2 "r")
17095 (parallel [(set (match_operand:SI 0 "register_operand" "")
17096 (match_operator:SI 3 "arith_or_logical_operator"
17098 (match_operand:SI 1 "memory_operand" "")]))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17101 [(set (match_dup 2) (match_dup 1))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17104 (clobber (reg:CC FLAGS_REG))])])
17107 [(match_scratch:SI 2 "r")
17108 (parallel [(set (match_operand:SI 0 "register_operand" "")
17109 (match_operator:SI 3 "arith_or_logical_operator"
17110 [(match_operand:SI 1 "memory_operand" "")
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17114 [(set (match_dup 2) (match_dup 1))
17115 (parallel [(set (match_dup 0)
17116 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17117 (clobber (reg:CC FLAGS_REG))])])
17119 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17120 ;; refers to the destination of the load!
17123 [(set (match_operand:SI 0 "register_operand" "")
17124 (match_operand:SI 1 "register_operand" ""))
17125 (parallel [(set (match_dup 0)
17126 (match_operator:SI 3 "commutative_operator"
17128 (match_operand:SI 2 "memory_operand" "")]))
17129 (clobber (reg:CC FLAGS_REG))])]
17130 "REGNO (operands[0]) != REGNO (operands[1])
17131 && GENERAL_REGNO_P (REGNO (operands[0]))
17132 && GENERAL_REGNO_P (REGNO (operands[1]))"
17133 [(set (match_dup 0) (match_dup 4))
17134 (parallel [(set (match_dup 0)
17135 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17136 (clobber (reg:CC FLAGS_REG))])]
17137 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17140 [(set (match_operand 0 "register_operand" "")
17141 (match_operand 1 "register_operand" ""))
17143 (match_operator 3 "commutative_operator"
17145 (match_operand 2 "memory_operand" "")]))]
17146 "REGNO (operands[0]) != REGNO (operands[1])
17147 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17148 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17149 [(set (match_dup 0) (match_dup 2))
17151 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17153 ; Don't do logical operations with memory outputs
17155 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17156 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17157 ; the same decoder scheduling characteristics as the original.
17160 [(match_scratch:SI 2 "r")
17161 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17162 (match_operator:SI 3 "arith_or_logical_operator"
17164 (match_operand:SI 1 "nonmemory_operand" "")]))
17165 (clobber (reg:CC FLAGS_REG))])]
17166 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17167 /* Do not split stack checking probes. */
17168 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17169 [(set (match_dup 2) (match_dup 0))
17170 (parallel [(set (match_dup 2)
17171 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17172 (clobber (reg:CC FLAGS_REG))])
17173 (set (match_dup 0) (match_dup 2))])
17176 [(match_scratch:SI 2 "r")
17177 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17178 (match_operator:SI 3 "arith_or_logical_operator"
17179 [(match_operand:SI 1 "nonmemory_operand" "")
17181 (clobber (reg:CC FLAGS_REG))])]
17182 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17183 /* Do not split stack checking probes. */
17184 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17185 [(set (match_dup 2) (match_dup 0))
17186 (parallel [(set (match_dup 2)
17187 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17188 (clobber (reg:CC FLAGS_REG))])
17189 (set (match_dup 0) (match_dup 2))])
17191 ;; Attempt to use arith or logical operations with memory outputs with
17192 ;; setting of flags.
17194 [(set (match_operand:SWI 0 "register_operand" "")
17195 (match_operand:SWI 1 "memory_operand" ""))
17196 (parallel [(set (match_dup 0)
17197 (match_operator:SWI 3 "plusminuslogic_operator"
17199 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17200 (clobber (reg:CC FLAGS_REG))])
17201 (set (match_dup 1) (match_dup 0))
17202 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17203 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17204 && peep2_reg_dead_p (4, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (3),
17207 (GET_CODE (operands[3]) == PLUS
17208 || GET_CODE (operands[3]) == MINUS)
17209 ? CCGOCmode : CCNOmode)"
17210 [(parallel [(set (match_dup 4) (match_dup 5))
17211 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17212 (match_dup 2)]))])]
17213 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17214 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[2]));
17217 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17218 operands[5], const0_rtx);")
17221 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17222 (match_operator:SWI 2 "plusminuslogic_operator"
17224 (match_operand:SWI 1 "memory_operand" "")]))
17225 (clobber (reg:CC FLAGS_REG))])
17226 (set (match_dup 1) (match_dup 0))
17227 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17228 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17229 && GET_CODE (operands[2]) != MINUS
17230 && peep2_reg_dead_p (3, operands[0])
17231 && !reg_overlap_mentioned_p (operands[0], operands[1])
17232 && ix86_match_ccmode (peep2_next_insn (2),
17233 GET_CODE (operands[2]) == PLUS
17234 ? CCGOCmode : CCNOmode)"
17235 [(parallel [(set (match_dup 3) (match_dup 4))
17236 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17237 (match_dup 0)]))])]
17238 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17239 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17240 copy_rtx (operands[1]),
17241 copy_rtx (operands[0]));
17242 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17243 operands[4], const0_rtx);")
17246 [(set (match_operand:SWI12 0 "register_operand" "")
17247 (match_operand:SWI12 1 "memory_operand" ""))
17248 (parallel [(set (match_operand:SI 4 "register_operand" "")
17249 (match_operator:SI 3 "plusminuslogic_operator"
17251 (match_operand:SI 2 "nonmemory_operand" "")]))
17252 (clobber (reg:CC FLAGS_REG))])
17253 (set (match_dup 1) (match_dup 0))
17254 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17255 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17256 && REG_P (operands[0]) && REG_P (operands[4])
17257 && REGNO (operands[0]) == REGNO (operands[4])
17258 && peep2_reg_dead_p (4, operands[0])
17259 && !reg_overlap_mentioned_p (operands[0], operands[1])
17260 && ix86_match_ccmode (peep2_next_insn (3),
17261 (GET_CODE (operands[3]) == PLUS
17262 || GET_CODE (operands[3]) == MINUS)
17263 ? CCGOCmode : CCNOmode)"
17264 [(parallel [(set (match_dup 4) (match_dup 5))
17265 (set (match_dup 1) (match_dup 6))])]
17266 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17267 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17268 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17269 copy_rtx (operands[1]), operands[2]);
17270 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17271 operands[5], const0_rtx);
17272 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]),
17274 copy_rtx (operands[2]));")
17276 ;; Attempt to always use XOR for zeroing registers.
17278 [(set (match_operand 0 "register_operand" "")
17279 (match_operand 1 "const0_operand" ""))]
17280 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17281 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17282 && GENERAL_REG_P (operands[0])
17283 && peep2_regno_dead_p (0, FLAGS_REG)"
17284 [(parallel [(set (match_dup 0) (const_int 0))
17285 (clobber (reg:CC FLAGS_REG))])]
17286 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17289 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17291 "(GET_MODE (operands[0]) == QImode
17292 || GET_MODE (operands[0]) == HImode)
17293 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17294 && peep2_regno_dead_p (0, FLAGS_REG)"
17295 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17296 (clobber (reg:CC FLAGS_REG))])])
17298 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17300 [(set (match_operand:SWI248 0 "register_operand" "")
17302 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17303 && peep2_regno_dead_p (0, FLAGS_REG)"
17304 [(parallel [(set (match_dup 0) (const_int -1))
17305 (clobber (reg:CC FLAGS_REG))])]
17307 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17308 operands[0] = gen_lowpart (SImode, operands[0]);
17311 ;; Attempt to convert simple lea to add/shift.
17312 ;; These can be created by move expanders.
17315 [(set (match_operand:SWI48 0 "register_operand" "")
17316 (plus:SWI48 (match_dup 0)
17317 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17318 "peep2_regno_dead_p (0, FLAGS_REG)"
17319 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17320 (clobber (reg:CC FLAGS_REG))])])
17323 [(set (match_operand:SI 0 "register_operand" "")
17324 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17325 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17327 && peep2_regno_dead_p (0, FLAGS_REG)
17328 && REGNO (operands[0]) == REGNO (operands[1])"
17329 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[2] = gen_lowpart (SImode, operands[2]);")
17334 [(set (match_operand:SWI48 0 "register_operand" "")
17335 (mult:SWI48 (match_dup 0)
17336 (match_operand:SWI48 1 "const_int_operand" "")))]
17337 "exact_log2 (INTVAL (operands[1])) >= 0
17338 && peep2_regno_dead_p (0, FLAGS_REG)"
17339 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17340 (clobber (reg:CC FLAGS_REG))])]
17341 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17344 [(set (match_operand:SI 0 "register_operand" "")
17345 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17346 (match_operand:DI 2 "const_int_operand" "")) 0))]
17348 && exact_log2 (INTVAL (operands[2])) >= 0
17349 && REGNO (operands[0]) == REGNO (operands[1])
17350 && peep2_regno_dead_p (0, FLAGS_REG)"
17351 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17352 (clobber (reg:CC FLAGS_REG))])]
17353 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17355 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17356 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17357 ;; On many CPUs it is also faster, since special hardware to avoid esp
17358 ;; dependencies is present.
17360 ;; While some of these conversions may be done using splitters, we use
17361 ;; peepholes in order to allow combine_stack_adjustments pass to see
17362 ;; nonobfuscated RTL.
17364 ;; Convert prologue esp subtractions to push.
17365 ;; We need register to push. In order to keep verify_flow_info happy we have
17367 ;; - use scratch and clobber it in order to avoid dependencies
17368 ;; - use already live register
17369 ;; We can't use the second way right now, since there is no reliable way how to
17370 ;; verify that given register is live. First choice will also most likely in
17371 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17372 ;; call clobbered registers are dead. We may want to use base pointer as an
17373 ;; alternative when no register is available later.
17376 [(match_scratch:P 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand" "")))
17380 (clobber (reg:CC FLAGS_REG))
17381 (clobber (mem:BLK (scratch)))])]
17382 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17383 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17384 [(clobber (match_dup 1))
17385 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17386 (clobber (mem:BLK (scratch)))])])
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17397 [(clobber (match_dup 1))
17398 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17400 (clobber (mem:BLK (scratch)))])])
17402 ;; Convert esp subtractions to push.
17404 [(match_scratch:P 1 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand" "")))
17408 (clobber (reg:CC FLAGS_REG))])]
17409 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17410 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17411 [(clobber (match_dup 1))
17412 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17415 [(match_scratch:P 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand" "")))
17419 (clobber (reg:CC FLAGS_REG))])]
17420 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17421 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17422 [(clobber (match_dup 1))
17423 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17424 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17426 ;; Convert epilogue deallocator to pop.
17428 [(match_scratch:P 1 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand" "")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17436 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])])
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17442 [(match_scratch:P 1 "r")
17443 (match_scratch:P 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand" "")))
17447 (clobber (reg:CC FLAGS_REG))
17448 (clobber (mem:BLK (scratch)))])]
17449 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17450 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17451 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17452 (clobber (mem:BLK (scratch)))])
17453 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17456 [(match_scratch:P 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))
17461 (clobber (mem:BLK (scratch)))])]
17462 "optimize_insn_for_size_p ()
17463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17464 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17465 (clobber (mem:BLK (scratch)))])
17466 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17468 ;; Convert esp additions to pop.
17470 [(match_scratch:P 1 "r")
17471 (parallel [(set (reg:P SP_REG)
17472 (plus:P (reg:P SP_REG)
17473 (match_operand:P 0 "const_int_operand" "")))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17476 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17478 ;; Two pops case is tricky, since pop causes dependency
17479 ;; on destination register. We use two registers if available.
17481 [(match_scratch:P 1 "r")
17482 (match_scratch:P 2 "r")
17483 (parallel [(set (reg:P SP_REG)
17484 (plus:P (reg:P SP_REG)
17485 (match_operand:P 0 "const_int_operand" "")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17488 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17489 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17492 [(match_scratch:P 1 "r")
17493 (parallel [(set (reg:P SP_REG)
17494 (plus:P (reg:P SP_REG)
17495 (match_operand:P 0 "const_int_operand" "")))
17496 (clobber (reg:CC FLAGS_REG))])]
17497 "optimize_insn_for_size_p ()
17498 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17499 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17500 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17502 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17503 ;; required and register dies. Similarly for 128 to -128.
17505 [(set (match_operand 0 "flags_reg_operand" "")
17506 (match_operator 1 "compare_operator"
17507 [(match_operand 2 "register_operand" "")
17508 (match_operand 3 "const_int_operand" "")]))]
17509 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17510 && incdec_operand (operands[3], GET_MODE (operands[3])))
17511 || (!TARGET_FUSE_CMP_AND_BRANCH
17512 && INTVAL (operands[3]) == 128))
17513 && ix86_match_ccmode (insn, CCGCmode)
17514 && peep2_reg_dead_p (1, operands[2])"
17515 [(parallel [(set (match_dup 0)
17516 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17517 (clobber (match_dup 2))])])
17519 ;; Convert imul by three, five and nine into lea
17522 [(set (match_operand:SWI48 0 "register_operand" "")
17523 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17524 (match_operand:SWI48 2 "const359_operand" "")))
17525 (clobber (reg:CC FLAGS_REG))])]
17526 "!TARGET_PARTIAL_REG_STALL
17527 || <MODE>mode == SImode
17528 || optimize_function_for_size_p (cfun)"
17529 [(set (match_dup 0)
17530 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17532 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17536 [(set (match_operand:SWI48 0 "register_operand" "")
17537 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17538 (match_operand:SWI48 2 "const359_operand" "")))
17539 (clobber (reg:CC FLAGS_REG))])]
17540 "optimize_insn_for_speed_p ()
17541 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17542 [(set (match_dup 0) (match_dup 1))
17544 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17546 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17548 ;; imul $32bit_imm, mem, reg is vector decoded, while
17549 ;; imul $32bit_imm, reg, reg is direct decoded.
17551 [(match_scratch:SWI48 3 "r")
17552 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17553 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17554 (match_operand:SWI48 2 "immediate_operand" "")))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17557 && !satisfies_constraint_K (operands[2])"
17558 [(set (match_dup 3) (match_dup 1))
17559 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17560 (clobber (reg:CC FLAGS_REG))])])
17563 [(match_scratch:SI 3 "r")
17564 (parallel [(set (match_operand:DI 0 "register_operand" "")
17566 (mult:SI (match_operand:SI 1 "memory_operand" "")
17567 (match_operand:SI 2 "immediate_operand" ""))))
17568 (clobber (reg:CC FLAGS_REG))])]
17570 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17571 && !satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17575 (clobber (reg:CC FLAGS_REG))])])
17577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17578 ;; Convert it into imul reg, reg
17579 ;; It would be better to force assembler to encode instruction using long
17580 ;; immediate, but there is apparently no way to do so.
17582 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17584 (match_operand:SWI248 1 "nonimmediate_operand" "")
17585 (match_operand:SWI248 2 "const_int_operand" "")))
17586 (clobber (reg:CC FLAGS_REG))])
17587 (match_scratch:SWI248 3 "r")]
17588 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17589 && satisfies_constraint_K (operands[2])"
17590 [(set (match_dup 3) (match_dup 2))
17591 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17592 (clobber (reg:CC FLAGS_REG))])]
17594 if (!rtx_equal_p (operands[0], operands[1]))
17595 emit_move_insn (operands[0], operands[1]);
17598 ;; After splitting up read-modify operations, array accesses with memory
17599 ;; operands might end up in form:
17601 ;; movl 4(%esp), %edx
17603 ;; instead of pre-splitting:
17605 ;; addl 4(%esp), %eax
17607 ;; movl 4(%esp), %edx
17608 ;; leal (%edx,%eax,4), %eax
17611 [(match_scratch:P 5 "r")
17612 (parallel [(set (match_operand 0 "register_operand" "")
17613 (ashift (match_operand 1 "register_operand" "")
17614 (match_operand 2 "const_int_operand" "")))
17615 (clobber (reg:CC FLAGS_REG))])
17616 (parallel [(set (match_operand 3 "register_operand" "")
17617 (plus (match_dup 0)
17618 (match_operand 4 "x86_64_general_operand" "")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17621 /* Validate MODE for lea. */
17622 && ((!TARGET_PARTIAL_REG_STALL
17623 && (GET_MODE (operands[0]) == QImode
17624 || GET_MODE (operands[0]) == HImode))
17625 || GET_MODE (operands[0]) == SImode
17626 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17627 && (rtx_equal_p (operands[0], operands[3])
17628 || peep2_reg_dead_p (2, operands[0]))
17629 /* We reorder load and the shift. */
17630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17631 [(set (match_dup 5) (match_dup 4))
17632 (set (match_dup 0) (match_dup 1))]
17634 enum machine_mode op1mode = GET_MODE (operands[1]);
17635 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17636 int scale = 1 << INTVAL (operands[2]);
17637 rtx index = gen_lowpart (Pmode, operands[1]);
17638 rtx base = gen_lowpart (Pmode, operands[5]);
17639 rtx dest = gen_lowpart (mode, operands[3]);
17641 operands[1] = gen_rtx_PLUS (Pmode, base,
17642 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17643 operands[5] = base;
17645 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17646 if (op1mode != Pmode)
17647 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17648 operands[0] = dest;
17651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17653 ;; caught for use by garbage collectors and the like. Using an insn that
17654 ;; maps to SIGILL makes it more likely the program will rightfully die.
17655 ;; Keeping with tradition, "6" is in honor of #UD.
17656 (define_insn "trap"
17657 [(trap_if (const_int 1) (const_int 6))]
17659 { return ASM_SHORT "0x0b0f"; }
17660 [(set_attr "length" "2")])
17662 (define_expand "prefetch"
17663 [(prefetch (match_operand 0 "address_operand" "")
17664 (match_operand:SI 1 "const_int_operand" "")
17665 (match_operand:SI 2 "const_int_operand" ""))]
17666 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17668 int rw = INTVAL (operands[1]);
17669 int locality = INTVAL (operands[2]);
17671 gcc_assert (rw == 0 || rw == 1);
17672 gcc_assert (locality >= 0 && locality <= 3);
17673 gcc_assert (GET_MODE (operands[0]) == Pmode
17674 || GET_MODE (operands[0]) == VOIDmode);
17676 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17677 supported by SSE counterpart or the SSE prefetch is not available
17678 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17680 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17681 operands[2] = GEN_INT (3);
17683 operands[1] = const0_rtx;
17686 (define_insn "*prefetch_sse_<mode>"
17687 [(prefetch (match_operand:P 0 "address_operand" "p")
17689 (match_operand:SI 1 "const_int_operand" ""))]
17690 "TARGET_PREFETCH_SSE"
17692 static const char * const patterns[4] = {
17693 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17696 int locality = INTVAL (operands[1]);
17697 gcc_assert (locality >= 0 && locality <= 3);
17699 return patterns[locality];
17701 [(set_attr "type" "sse")
17702 (set_attr "atom_sse_attr" "prefetch")
17703 (set (attr "length_address")
17704 (symbol_ref "memory_address_length (operands[0])"))
17705 (set_attr "memory" "none")])
17707 (define_insn "*prefetch_3dnow_<mode>"
17708 [(prefetch (match_operand:P 0 "address_operand" "p")
17709 (match_operand:SI 1 "const_int_operand" "n")
17713 if (INTVAL (operands[1]) == 0)
17714 return "prefetch\t%a0";
17716 return "prefetchw\t%a0";
17718 [(set_attr "type" "mmx")
17719 (set (attr "length_address")
17720 (symbol_ref "memory_address_length (operands[0])"))
17721 (set_attr "memory" "none")])
17723 (define_expand "stack_protect_set"
17724 [(match_operand 0 "memory_operand" "")
17725 (match_operand 1 "memory_operand" "")]
17728 rtx (*insn)(rtx, rtx);
17730 #ifdef TARGET_THREAD_SSP_OFFSET
17731 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17732 insn = (TARGET_LP64
17733 ? gen_stack_tls_protect_set_di
17734 : gen_stack_tls_protect_set_si);
17736 insn = (TARGET_LP64
17737 ? gen_stack_protect_set_di
17738 : gen_stack_protect_set_si);
17741 emit_insn (insn (operands[0], operands[1]));
17745 (define_insn "stack_protect_set_<mode>"
17746 [(set (match_operand:PTR 0 "memory_operand" "=m")
17747 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17749 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17750 (clobber (reg:CC FLAGS_REG))]
17752 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17753 [(set_attr "type" "multi")])
17755 (define_insn "stack_tls_protect_set_<mode>"
17756 [(set (match_operand:PTR 0 "memory_operand" "=m")
17757 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17758 UNSPEC_SP_TLS_SET))
17759 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17760 (clobber (reg:CC FLAGS_REG))]
17762 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17763 [(set_attr "type" "multi")])
17765 (define_expand "stack_protect_test"
17766 [(match_operand 0 "memory_operand" "")
17767 (match_operand 1 "memory_operand" "")
17768 (match_operand 2 "" "")]
17771 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17773 rtx (*insn)(rtx, rtx, rtx);
17775 #ifdef TARGET_THREAD_SSP_OFFSET
17776 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17777 insn = (TARGET_LP64
17778 ? gen_stack_tls_protect_test_di
17779 : gen_stack_tls_protect_test_si);
17781 insn = (TARGET_LP64
17782 ? gen_stack_protect_test_di
17783 : gen_stack_protect_test_si);
17786 emit_insn (insn (flags, operands[0], operands[1]));
17788 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17789 flags, const0_rtx, operands[2]));
17793 (define_insn "stack_protect_test_<mode>"
17794 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17795 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17796 (match_operand:PTR 2 "memory_operand" "m")]
17798 (clobber (match_scratch:PTR 3 "=&r"))]
17800 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17801 [(set_attr "type" "multi")])
17803 (define_insn "stack_tls_protect_test_<mode>"
17804 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17805 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17806 (match_operand:PTR 2 "const_int_operand" "i")]
17807 UNSPEC_SP_TLS_TEST))
17808 (clobber (match_scratch:PTR 3 "=r"))]
17810 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17811 [(set_attr "type" "multi")])
17813 (define_insn "sse4_2_crc32<mode>"
17814 [(set (match_operand:SI 0 "register_operand" "=r")
17816 [(match_operand:SI 1 "register_operand" "0")
17817 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17819 "TARGET_SSE4_2 || TARGET_CRC32"
17820 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17821 [(set_attr "type" "sselog1")
17822 (set_attr "prefix_rep" "1")
17823 (set_attr "prefix_extra" "1")
17824 (set (attr "prefix_data16")
17825 (if_then_else (match_operand:HI 2 "" "")
17827 (const_string "*")))
17828 (set (attr "prefix_rex")
17829 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17831 (const_string "*")))
17832 (set_attr "mode" "SI")])
17834 (define_insn "sse4_2_crc32di"
17835 [(set (match_operand:DI 0 "register_operand" "=r")
17837 [(match_operand:DI 1 "register_operand" "0")
17838 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17840 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17841 "crc32{q}\t{%2, %0|%0, %2}"
17842 [(set_attr "type" "sselog1")
17843 (set_attr "prefix_rep" "1")
17844 (set_attr "prefix_extra" "1")
17845 (set_attr "mode" "DI")])
17847 (define_expand "rdpmc"
17848 [(match_operand:DI 0 "register_operand" "")
17849 (match_operand:SI 1 "register_operand" "")]
17852 rtx reg = gen_reg_rtx (DImode);
17855 /* Force operand 1 into ECX. */
17856 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17857 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17858 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17863 rtvec vec = rtvec_alloc (2);
17864 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17865 rtx upper = gen_reg_rtx (DImode);
17866 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17867 gen_rtvec (1, const0_rtx),
17869 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17870 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17872 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17873 NULL, 1, OPTAB_DIRECT);
17874 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17878 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17879 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17883 (define_insn "*rdpmc"
17884 [(set (match_operand:DI 0 "register_operand" "=A")
17885 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17889 [(set_attr "type" "other")
17890 (set_attr "length" "2")])
17892 (define_insn "*rdpmc_rex64"
17893 [(set (match_operand:DI 0 "register_operand" "=a")
17894 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17896 (set (match_operand:DI 1 "register_operand" "=d")
17897 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17903 (define_expand "rdtsc"
17904 [(set (match_operand:DI 0 "register_operand" "")
17905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17910 rtvec vec = rtvec_alloc (2);
17911 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17912 rtx upper = gen_reg_rtx (DImode);
17913 rtx lower = gen_reg_rtx (DImode);
17914 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17915 gen_rtvec (1, const0_rtx),
17917 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17918 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17920 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17921 NULL, 1, OPTAB_DIRECT);
17922 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17929 (define_insn "*rdtsc"
17930 [(set (match_operand:DI 0 "register_operand" "=A")
17931 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17934 [(set_attr "type" "other")
17935 (set_attr "length" "2")])
17937 (define_insn "*rdtsc_rex64"
17938 [(set (match_operand:DI 0 "register_operand" "=a")
17939 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17940 (set (match_operand:DI 1 "register_operand" "=d")
17941 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17944 [(set_attr "type" "other")
17945 (set_attr "length" "2")])
17947 (define_expand "rdtscp"
17948 [(match_operand:DI 0 "register_operand" "")
17949 (match_operand:SI 1 "memory_operand" "")]
17952 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17953 gen_rtvec (1, const0_rtx),
17955 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17956 gen_rtvec (1, const0_rtx),
17958 rtx reg = gen_reg_rtx (DImode);
17959 rtx tmp = gen_reg_rtx (SImode);
17963 rtvec vec = rtvec_alloc (3);
17964 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17965 rtx upper = gen_reg_rtx (DImode);
17966 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17967 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17968 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17970 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17971 NULL, 1, OPTAB_DIRECT);
17972 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17977 rtvec vec = rtvec_alloc (2);
17978 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17979 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17980 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17983 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17984 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17988 (define_insn "*rdtscp"
17989 [(set (match_operand:DI 0 "register_operand" "=A")
17990 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17991 (set (match_operand:SI 1 "register_operand" "=c")
17992 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17995 [(set_attr "type" "other")
17996 (set_attr "length" "3")])
17998 (define_insn "*rdtscp_rex64"
17999 [(set (match_operand:DI 0 "register_operand" "=a")
18000 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18001 (set (match_operand:DI 1 "register_operand" "=d")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18003 (set (match_operand:SI 2 "register_operand" "=c")
18004 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18007 [(set_attr "type" "other")
18008 (set_attr "length" "3")])
18010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18012 ;; LWP instructions
18014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18016 (define_expand "lwp_llwpcb"
18017 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18018 UNSPECV_LLWP_INTRINSIC)]
18021 (define_insn "*lwp_llwpcb<mode>1"
18022 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18023 UNSPECV_LLWP_INTRINSIC)]
18026 [(set_attr "type" "lwp")
18027 (set_attr "mode" "<MODE>")
18028 (set_attr "length" "5")])
18030 (define_expand "lwp_slwpcb"
18031 [(set (match_operand 0 "register_operand" "=r")
18032 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18037 insn = (TARGET_64BIT
18039 : gen_lwp_slwpcbsi);
18041 emit_insn (insn (operands[0]));
18045 (define_insn "lwp_slwpcb<mode>"
18046 [(set (match_operand:P 0 "register_operand" "=r")
18047 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18050 [(set_attr "type" "lwp")
18051 (set_attr "mode" "<MODE>")
18052 (set_attr "length" "5")])
18054 (define_expand "lwp_lwpval<mode>3"
18055 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18056 (match_operand:SI 2 "nonimmediate_operand" "rm")
18057 (match_operand:SI 3 "const_int_operand" "i")]
18058 UNSPECV_LWPVAL_INTRINSIC)]
18060 "/* Avoid unused variable warning. */
18063 (define_insn "*lwp_lwpval<mode>3_1"
18064 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18065 (match_operand:SI 1 "nonimmediate_operand" "rm")
18066 (match_operand:SI 2 "const_int_operand" "i")]
18067 UNSPECV_LWPVAL_INTRINSIC)]
18069 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18070 [(set_attr "type" "lwp")
18071 (set_attr "mode" "<MODE>")
18072 (set (attr "length")
18073 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18075 (define_expand "lwp_lwpins<mode>3"
18076 [(set (reg:CCC FLAGS_REG)
18077 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18078 (match_operand:SI 2 "nonimmediate_operand" "rm")
18079 (match_operand:SI 3 "const_int_operand" "i")]
18080 UNSPECV_LWPINS_INTRINSIC))
18081 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18082 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18085 (define_insn "*lwp_lwpins<mode>3_1"
18086 [(set (reg:CCC FLAGS_REG)
18087 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18088 (match_operand:SI 1 "nonimmediate_operand" "rm")
18089 (match_operand:SI 2 "const_int_operand" "i")]
18090 UNSPECV_LWPINS_INTRINSIC))]
18092 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18093 [(set_attr "type" "lwp")
18094 (set_attr "mode" "<MODE>")
18095 (set (attr "length")
18096 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18098 (define_insn "rdfsbase<mode>"
18099 [(set (match_operand:SWI48 0 "register_operand" "=r")
18100 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18101 "TARGET_64BIT && TARGET_FSGSBASE"
18103 [(set_attr "type" "other")
18104 (set_attr "prefix_extra" "2")])
18106 (define_insn "rdgsbase<mode>"
18107 [(set (match_operand:SWI48 0 "register_operand" "=r")
18108 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18109 "TARGET_64BIT && TARGET_FSGSBASE"
18111 [(set_attr "type" "other")
18112 (set_attr "prefix_extra" "2")])
18114 (define_insn "wrfsbase<mode>"
18115 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18117 "TARGET_64BIT && TARGET_FSGSBASE"
18119 [(set_attr "type" "other")
18120 (set_attr "prefix_extra" "2")])
18122 (define_insn "wrgsbase<mode>"
18123 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18125 "TARGET_64BIT && TARGET_FSGSBASE"
18127 [(set_attr "type" "other")
18128 (set_attr "prefix_extra" "2")])
18130 (define_insn "rdrand<mode>_1"
18131 [(set (match_operand:SWI248 0 "register_operand" "=r")
18132 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18133 (set (reg:CCC FLAGS_REG)
18134 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "1")])
18140 (define_expand "pause"
18141 [(set (match_dup 0)
18142 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18145 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18146 MEM_VOLATILE_P (operands[0]) = 1;
18149 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18150 ;; They have the same encoding.
18151 (define_insn "*pause"
18152 [(set (match_operand:BLK 0 "" "")
18153 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18156 [(set_attr "length" "2")
18157 (set_attr "memory" "unknown")])
18161 (include "sync.md")