1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
132 UNSPEC_MS_TO_SYSV_CALL
134 ;; Generic math support
136 UNSPEC_IEEE_MIN ; not commutative
137 UNSPEC_IEEE_MAX ; not commutative
139 ;; x87 Floating point
155 UNSPEC_FRNDINT_MASK_PM
159 ;; x87 Double output FP
191 ;; For SSE4.1 support
201 ;; For SSE4.2 support
208 UNSPEC_XOP_UNSIGNED_CMP
219 UNSPEC_AESKEYGENASSIST
221 ;; For PCLMUL support
245 ;; For RDRAND support
253 (define_c_enum "unspecv" [
256 UNSPECV_PROBE_STACK_RANGE
276 UNSPECV_LLWP_INTRINSIC
277 UNSPECV_SLWP_INTRINSIC
278 UNSPECV_LWPVAL_INTRINSIC
279 UNSPECV_LWPINS_INTRINSIC
284 UNSPECV_SPLIT_STACK_RETURN
287 ;; Constants to represent rounding modes in the ROUND instruction
296 ;; Constants to represent pcomtrue/pcomfalse variants
306 ;; Constants used in the XOP pperm instruction
308 [(PPERM_SRC 0x00) /* copy source */
309 (PPERM_INVERT 0x20) /* invert source */
310 (PPERM_REVERSE 0x40) /* bit reverse source */
311 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
312 (PPERM_ZERO 0x80) /* all 0's */
313 (PPERM_ONES 0xa0) /* all 1's */
314 (PPERM_SIGN 0xc0) /* propagate sign bit */
315 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
316 (PPERM_SRC1 0x00) /* use first source byte */
317 (PPERM_SRC2 0x10) /* use second source byte */
320 ;; Registers by name.
373 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
376 ;; In C guard expressions, put expressions which may be compile-time
377 ;; constants first. This allows for better optimization. For
378 ;; example, write "TARGET_64BIT && reload_completed", not
379 ;; "reload_completed && TARGET_64BIT".
383 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
384 atom,generic64,amdfam10,bdver1,bdver2,btver1"
385 (const (symbol_ref "ix86_schedule")))
387 ;; A basic instruction type. Refinements due to arguments to be
388 ;; provided in other attributes.
391 alu,alu1,negnot,imov,imovx,lea,
392 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
393 icmp,test,ibr,setcc,icmov,
394 push,pop,call,callv,leave,
396 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
397 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
398 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
399 ssemuladd,sse4arg,lwp,
400 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
401 (const_string "other"))
403 ;; Main data type used by the insn
405 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
406 (const_string "unknown"))
408 ;; The CPU unit operations uses.
409 (define_attr "unit" "integer,i387,sse,mmx,unknown"
410 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
411 (const_string "i387")
412 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
413 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
414 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
416 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
418 (eq_attr "type" "other")
419 (const_string "unknown")]
420 (const_string "integer")))
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
427 (eq_attr "unit" "i387,sse,mmx")
429 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430 rotate,rotatex,rotate1,imul,icmp,push,pop")
431 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432 (eq_attr "type" "imov,test")
433 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434 (eq_attr "type" "call")
435 (if_then_else (match_operand 0 "constant_call_address_operand" "")
438 (eq_attr "type" "callv")
439 (if_then_else (match_operand 1 "constant_call_address_operand" "")
442 ;; We don't know the size before shorten_branches. Expect
443 ;; the instruction to fit for better scheduling.
444 (eq_attr "type" "ibr")
447 (symbol_ref "/* Update immediate_length and other attributes! */
448 gcc_unreachable (),1")))
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452 (cond [(eq_attr "type" "str,other,multi,fxch")
454 (and (eq_attr "type" "call")
455 (match_operand 0 "constant_call_address_operand" ""))
457 (and (eq_attr "type" "callv")
458 (match_operand 1 "constant_call_address_operand" ""))
461 (symbol_ref "ix86_attr_length_address_default (insn)")))
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
467 (eq_attr "mode" "HI")
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
478 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
486 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
487 (eq_attr "unit" "sse,mmx"))
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493 (cond [(not (match_test "TARGET_64BIT"))
495 (and (eq_attr "mode" "DI")
496 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497 (eq_attr "unit" "!mmx")))
499 (and (eq_attr "mode" "QI")
500 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
502 (match_test "x86_extended_reg_mentioned_p (insn)")
504 (and (eq_attr "type" "imovx")
505 (match_operand:QI 1 "ext_QIreg_operand" ""))
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg")
517 (eq_attr "type" "sseiadd1,ssecvt1")
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex"
524 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
526 (const_string "orig")))
528 ;; VEX W bit is used.
529 (define_attr "prefix_vex_w" "" (const_int 0))
531 ;; The length of VEX prefix
532 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
533 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
534 ;; still prefix_0f 1, with prefix_extra 1.
535 (define_attr "length_vex" ""
536 (if_then_else (and (eq_attr "prefix_0f" "1")
537 (eq_attr "prefix_extra" "0"))
538 (if_then_else (eq_attr "prefix_vex_w" "1")
539 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
540 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
541 (if_then_else (eq_attr "prefix_vex_w" "1")
542 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
543 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
545 ;; Set when modrm byte is used.
546 (define_attr "modrm" ""
547 (cond [(eq_attr "type" "str,leave")
549 (eq_attr "unit" "i387")
551 (and (eq_attr "type" "incdec")
552 (and (not (match_test "TARGET_64BIT"))
553 (ior (match_operand:SI 1 "register_operand" "")
554 (match_operand:HI 1 "register_operand" ""))))
556 (and (eq_attr "type" "push")
557 (not (match_operand 1 "memory_operand" "")))
559 (and (eq_attr "type" "pop")
560 (not (match_operand 0 "memory_operand" "")))
562 (and (eq_attr "type" "imov")
563 (and (not (eq_attr "mode" "DI"))
564 (ior (and (match_operand 0 "register_operand" "")
565 (match_operand 1 "immediate_operand" ""))
566 (ior (and (match_operand 0 "ax_reg_operand" "")
567 (match_operand 1 "memory_displacement_only_operand" ""))
568 (and (match_operand 0 "memory_displacement_only_operand" "")
569 (match_operand 1 "ax_reg_operand" ""))))))
571 (and (eq_attr "type" "call")
572 (match_operand 0 "constant_call_address_operand" ""))
574 (and (eq_attr "type" "callv")
575 (match_operand 1 "constant_call_address_operand" ""))
577 (and (eq_attr "type" "alu,alu1,icmp,test")
578 (match_operand 0 "ax_reg_operand" ""))
579 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
583 ;; The (bounding maximum) length of an instruction in bytes.
584 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
585 ;; Later we may want to split them and compute proper length as for
587 (define_attr "length" ""
588 (cond [(eq_attr "type" "other,multi,fistp,frndint")
590 (eq_attr "type" "fcmp")
592 (eq_attr "unit" "i387")
594 (plus (attr "prefix_data16")
595 (attr "length_address")))
596 (ior (eq_attr "prefix" "vex")
597 (and (eq_attr "prefix" "maybe_vex")
598 (match_test "TARGET_AVX")))
599 (plus (attr "length_vex")
600 (plus (attr "length_immediate")
602 (attr "length_address"))))]
603 (plus (plus (attr "modrm")
604 (plus (attr "prefix_0f")
605 (plus (attr "prefix_rex")
606 (plus (attr "prefix_extra")
608 (plus (attr "prefix_rep")
609 (plus (attr "prefix_data16")
610 (plus (attr "length_immediate")
611 (attr "length_address")))))))
613 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
614 ;; `store' if there is a simple memory reference therein, or `unknown'
615 ;; if the instruction is complex.
617 (define_attr "memory" "none,load,store,both,unknown"
618 (cond [(eq_attr "type" "other,multi,str,lwp")
619 (const_string "unknown")
620 (eq_attr "type" "lea,fcmov,fpspc")
621 (const_string "none")
622 (eq_attr "type" "fistp,leave")
623 (const_string "both")
624 (eq_attr "type" "frndint")
625 (const_string "load")
626 (eq_attr "type" "push")
627 (if_then_else (match_operand 1 "memory_operand" "")
628 (const_string "both")
629 (const_string "store"))
630 (eq_attr "type" "pop")
631 (if_then_else (match_operand 0 "memory_operand" "")
632 (const_string "both")
633 (const_string "load"))
634 (eq_attr "type" "setcc")
635 (if_then_else (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (const_string "none"))
638 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
639 (if_then_else (ior (match_operand 0 "memory_operand" "")
640 (match_operand 1 "memory_operand" ""))
641 (const_string "load")
642 (const_string "none"))
643 (eq_attr "type" "ibr")
644 (if_then_else (match_operand 0 "memory_operand" "")
645 (const_string "load")
646 (const_string "none"))
647 (eq_attr "type" "call")
648 (if_then_else (match_operand 0 "constant_call_address_operand" "")
649 (const_string "none")
650 (const_string "load"))
651 (eq_attr "type" "callv")
652 (if_then_else (match_operand 1 "constant_call_address_operand" "")
653 (const_string "none")
654 (const_string "load"))
655 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
656 (match_operand 1 "memory_operand" ""))
657 (const_string "both")
658 (and (match_operand 0 "memory_operand" "")
659 (match_operand 1 "memory_operand" ""))
660 (const_string "both")
661 (match_operand 0 "memory_operand" "")
662 (const_string "store")
663 (match_operand 1 "memory_operand" "")
664 (const_string "load")
666 "!alu1,negnot,ishift1,
667 imov,imovx,icmp,test,bitmanip,
669 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
670 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
671 (match_operand 2 "memory_operand" ""))
672 (const_string "load")
673 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
674 (match_operand 3 "memory_operand" ""))
675 (const_string "load")
677 (const_string "none")))
679 ;; Indicates if an instruction has both an immediate and a displacement.
681 (define_attr "imm_disp" "false,true,unknown"
682 (cond [(eq_attr "type" "other,multi")
683 (const_string "unknown")
684 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
685 (and (match_operand 0 "memory_displacement_operand" "")
686 (match_operand 1 "immediate_operand" "")))
687 (const_string "true")
688 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
689 (and (match_operand 0 "memory_displacement_operand" "")
690 (match_operand 2 "immediate_operand" "")))
691 (const_string "true")
693 (const_string "false")))
695 ;; Indicates if an FP operation has an integer source.
697 (define_attr "fp_int_src" "false,true"
698 (const_string "false"))
700 ;; Defines rounding mode of an FP operation.
702 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
703 (const_string "any"))
705 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
706 (define_attr "use_carry" "0,1" (const_string "0"))
708 ;; Define attribute to indicate unaligned ssemov insns
709 (define_attr "movu" "0,1" (const_string "0"))
711 ;; Used to control the "enabled" attribute on a per-instruction basis.
712 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
713 (const_string "base"))
715 (define_attr "enabled" ""
716 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
717 (eq_attr "isa" "sse2_noavx")
718 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
719 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
720 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
721 (eq_attr "isa" "sse4_noavx")
722 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
723 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
724 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
725 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
729 ;; Describe a user's asm statement.
730 (define_asm_attributes
731 [(set_attr "length" "128")
732 (set_attr "type" "multi")])
734 (define_code_iterator plusminus [plus minus])
736 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
738 ;; Base name for define_insn
739 (define_code_attr plusminus_insn
740 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
741 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr plusminus_mnemonic
745 [(plus "add") (ss_plus "adds") (us_plus "addus")
746 (minus "sub") (ss_minus "subs") (us_minus "subus")])
747 (define_code_attr plusminus_carry_mnemonic
748 [(plus "adc") (minus "sbb")])
750 ;; Mark commutative operators as such in constraints.
751 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
752 (minus "") (ss_minus "") (us_minus "")])
754 ;; Mapping of max and min
755 (define_code_iterator maxmin [smax smin umax umin])
757 ;; Mapping of signed max and min
758 (define_code_iterator smaxmin [smax smin])
760 ;; Mapping of unsigned max and min
761 (define_code_iterator umaxmin [umax umin])
763 ;; Base name for integer and FP insn mnemonic
764 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
765 (umax "maxu") (umin "minu")])
766 (define_code_attr maxmin_float [(smax "max") (smin "min")])
768 ;; Mapping of logic operators
769 (define_code_iterator any_logic [and ior xor])
770 (define_code_iterator any_or [ior xor])
772 ;; Base name for insn mnemonic.
773 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
775 ;; Mapping of shift-right operators
776 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
778 ;; Base name for define_insn
779 (define_code_attr shift_insn
780 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
782 ;; Base name for insn mnemonic.
783 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
785 ;; Mapping of rotate operators
786 (define_code_iterator any_rotate [rotate rotatert])
788 ;; Base name for define_insn
789 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
791 ;; Base name for insn mnemonic.
792 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
794 ;; Mapping of abs neg operators
795 (define_code_iterator absneg [abs neg])
797 ;; Base name for x87 insn mnemonic.
798 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
800 ;; Used in signed and unsigned widening multiplications.
801 (define_code_iterator any_extend [sign_extend zero_extend])
803 ;; Prefix for insn menmonic.
804 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
806 ;; Prefix for define_insn
807 (define_code_attr u [(sign_extend "") (zero_extend "u")])
808 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
810 ;; All integer modes.
811 (define_mode_iterator SWI1248x [QI HI SI DI])
813 ;; All integer modes without QImode.
814 (define_mode_iterator SWI248x [HI SI DI])
816 ;; All integer modes without QImode and HImode.
817 (define_mode_iterator SWI48x [SI DI])
819 ;; All integer modes without SImode and DImode.
820 (define_mode_iterator SWI12 [QI HI])
822 ;; All integer modes without DImode.
823 (define_mode_iterator SWI124 [QI HI SI])
825 ;; All integer modes without QImode and DImode.
826 (define_mode_iterator SWI24 [HI SI])
828 ;; Single word integer modes.
829 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
831 ;; Single word integer modes without QImode.
832 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
834 ;; Single word integer modes without QImode and HImode.
835 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
837 ;; All math-dependant single and double word integer modes.
838 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
839 (HI "TARGET_HIMODE_MATH")
840 SI DI (TI "TARGET_64BIT")])
842 ;; Math-dependant single word integer modes.
843 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
844 (HI "TARGET_HIMODE_MATH")
845 SI (DI "TARGET_64BIT")])
847 ;; Math-dependant integer modes without DImode.
848 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
849 (HI "TARGET_HIMODE_MATH")
852 ;; Math-dependant single word integer modes without QImode.
853 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
854 SI (DI "TARGET_64BIT")])
856 ;; Double word integer modes.
857 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
858 (TI "TARGET_64BIT")])
860 ;; Double word integer modes as mode attribute.
861 (define_mode_attr DWI [(SI "DI") (DI "TI")])
862 (define_mode_attr dwi [(SI "di") (DI "ti")])
864 ;; Half mode for double word integer modes.
865 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
866 (DI "TARGET_64BIT")])
868 ;; Instruction suffix for integer modes.
869 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
871 ;; Pointer size prefix for integer modes (Intel asm dialect)
872 (define_mode_attr iptrsize [(QI "BYTE")
877 ;; Register class for integer modes.
878 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
880 ;; Immediate operand constraint for integer modes.
881 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
883 ;; General operand constraint for word modes.
884 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
886 ;; Immediate operand constraint for double integer modes.
887 (define_mode_attr di [(SI "nF") (DI "e")])
889 ;; Immediate operand constraint for shifts.
890 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
892 ;; General operand predicate for integer modes.
893 (define_mode_attr general_operand
894 [(QI "general_operand")
895 (HI "general_operand")
896 (SI "x86_64_general_operand")
897 (DI "x86_64_general_operand")
898 (TI "x86_64_general_operand")])
900 ;; General sign/zero extend operand predicate for integer modes.
901 (define_mode_attr general_szext_operand
902 [(QI "general_operand")
903 (HI "general_operand")
904 (SI "x86_64_szext_general_operand")
905 (DI "x86_64_szext_general_operand")])
907 ;; Immediate operand predicate for integer modes.
908 (define_mode_attr immediate_operand
909 [(QI "immediate_operand")
910 (HI "immediate_operand")
911 (SI "x86_64_immediate_operand")
912 (DI "x86_64_immediate_operand")])
914 ;; Nonmemory operand predicate for integer modes.
915 (define_mode_attr nonmemory_operand
916 [(QI "nonmemory_operand")
917 (HI "nonmemory_operand")
918 (SI "x86_64_nonmemory_operand")
919 (DI "x86_64_nonmemory_operand")])
921 ;; Operand predicate for shifts.
922 (define_mode_attr shift_operand
923 [(QI "nonimmediate_operand")
924 (HI "nonimmediate_operand")
925 (SI "nonimmediate_operand")
926 (DI "shiftdi_operand")
927 (TI "register_operand")])
929 ;; Operand predicate for shift argument.
930 (define_mode_attr shift_immediate_operand
931 [(QI "const_1_to_31_operand")
932 (HI "const_1_to_31_operand")
933 (SI "const_1_to_31_operand")
934 (DI "const_1_to_63_operand")])
936 ;; Input operand predicate for arithmetic left shifts.
937 (define_mode_attr ashl_input_operand
938 [(QI "nonimmediate_operand")
939 (HI "nonimmediate_operand")
940 (SI "nonimmediate_operand")
941 (DI "ashldi_input_operand")
942 (TI "reg_or_pm1_operand")])
944 ;; SSE and x87 SFmode and DFmode floating point modes
945 (define_mode_iterator MODEF [SF DF])
947 ;; All x87 floating point modes
948 (define_mode_iterator X87MODEF [SF DF XF])
950 ;; SSE instruction suffix for various modes
951 (define_mode_attr ssemodesuffix
953 (V8SF "ps") (V4DF "pd")
954 (V4SF "ps") (V2DF "pd")
955 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
956 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
958 ;; SSE vector suffix for floating point modes
959 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
961 ;; SSE vector mode corresponding to a scalar mode
962 (define_mode_attr ssevecmode
963 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
965 ;; Instruction suffix for REX 64bit operators.
966 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
968 ;; This mode iterator allows :P to be used for patterns that operate on
969 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
970 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
972 ;; This mode iterator allows :PTR to be used for patterns that operate on
973 ;; ptr_mode sized quantities.
974 (define_mode_iterator PTR
975 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
977 ;; Scheduling descriptions
979 (include "pentium.md")
982 (include "athlon.md")
983 (include "bdver1.md")
989 ;; Operand and operator predicates and constraints
991 (include "predicates.md")
992 (include "constraints.md")
995 ;; Compare and branch/compare and store instructions.
997 (define_expand "cbranch<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1000 (match_operand:SDWIM 2 "<general_operand>" "")))
1001 (set (pc) (if_then_else
1002 (match_operator 0 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)])
1004 (label_ref (match_operand 3 "" ""))
1008 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1009 operands[1] = force_reg (<MODE>mode, operands[1]);
1010 ix86_expand_branch (GET_CODE (operands[0]),
1011 operands[1], operands[2], operands[3]);
1015 (define_expand "cstore<mode>4"
1016 [(set (reg:CC FLAGS_REG)
1017 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1018 (match_operand:SWIM 3 "<general_operand>" "")))
1019 (set (match_operand:QI 0 "register_operand" "")
1020 (match_operator 1 "ordered_comparison_operator"
1021 [(reg:CC FLAGS_REG) (const_int 0)]))]
1024 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1025 operands[2] = force_reg (<MODE>mode, operands[2]);
1026 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1027 operands[2], operands[3]);
1031 (define_expand "cmp<mode>_1"
1032 [(set (reg:CC FLAGS_REG)
1033 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1034 (match_operand:SWI48 1 "<general_operand>" "")))])
1036 (define_insn "*cmp<mode>_ccno_1"
1037 [(set (reg FLAGS_REG)
1038 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1039 (match_operand:SWI 1 "const0_operand" "")))]
1040 "ix86_match_ccmode (insn, CCNOmode)"
1042 test{<imodesuffix>}\t%0, %0
1043 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1044 [(set_attr "type" "test,icmp")
1045 (set_attr "length_immediate" "0,1")
1046 (set_attr "mode" "<MODE>")])
1048 (define_insn "*cmp<mode>_1"
1049 [(set (reg FLAGS_REG)
1050 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1051 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1052 "ix86_match_ccmode (insn, CCmode)"
1053 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1054 [(set_attr "type" "icmp")
1055 (set_attr "mode" "<MODE>")])
1057 (define_insn "*cmp<mode>_minus_1"
1058 [(set (reg FLAGS_REG)
1060 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1061 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1063 "ix86_match_ccmode (insn, CCGOCmode)"
1064 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1065 [(set_attr "type" "icmp")
1066 (set_attr "mode" "<MODE>")])
1068 (define_insn "*cmpqi_ext_1"
1069 [(set (reg FLAGS_REG)
1071 (match_operand:QI 0 "general_operand" "Qm")
1074 (match_operand 1 "ext_register_operand" "Q")
1076 (const_int 8)) 0)))]
1077 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078 "cmp{b}\t{%h1, %0|%0, %h1}"
1079 [(set_attr "type" "icmp")
1080 (set_attr "mode" "QI")])
1082 (define_insn "*cmpqi_ext_1_rex64"
1083 [(set (reg FLAGS_REG)
1085 (match_operand:QI 0 "register_operand" "Q")
1088 (match_operand 1 "ext_register_operand" "Q")
1090 (const_int 8)) 0)))]
1091 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1092 "cmp{b}\t{%h1, %0|%0, %h1}"
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "QI")])
1096 (define_insn "*cmpqi_ext_2"
1097 [(set (reg FLAGS_REG)
1101 (match_operand 0 "ext_register_operand" "Q")
1104 (match_operand:QI 1 "const0_operand" "")))]
1105 "ix86_match_ccmode (insn, CCNOmode)"
1107 [(set_attr "type" "test")
1108 (set_attr "length_immediate" "0")
1109 (set_attr "mode" "QI")])
1111 (define_expand "cmpqi_ext_3"
1112 [(set (reg:CC FLAGS_REG)
1116 (match_operand 0 "ext_register_operand" "")
1119 (match_operand:QI 1 "immediate_operand" "")))])
1121 (define_insn "*cmpqi_ext_3_insn"
1122 [(set (reg FLAGS_REG)
1126 (match_operand 0 "ext_register_operand" "Q")
1129 (match_operand:QI 1 "general_operand" "Qmn")))]
1130 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1131 "cmp{b}\t{%1, %h0|%h0, %1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "modrm" "1")
1134 (set_attr "mode" "QI")])
1136 (define_insn "*cmpqi_ext_3_insn_rex64"
1137 [(set (reg FLAGS_REG)
1141 (match_operand 0 "ext_register_operand" "Q")
1144 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1145 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1146 "cmp{b}\t{%1, %h0|%h0, %1}"
1147 [(set_attr "type" "icmp")
1148 (set_attr "modrm" "1")
1149 (set_attr "mode" "QI")])
1151 (define_insn "*cmpqi_ext_4"
1152 [(set (reg FLAGS_REG)
1156 (match_operand 0 "ext_register_operand" "Q")
1161 (match_operand 1 "ext_register_operand" "Q")
1163 (const_int 8)) 0)))]
1164 "ix86_match_ccmode (insn, CCmode)"
1165 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1166 [(set_attr "type" "icmp")
1167 (set_attr "mode" "QI")])
1169 ;; These implement float point compares.
1170 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1171 ;; which would allow mix and match FP modes on the compares. Which is what
1172 ;; the old patterns did, but with many more of them.
1174 (define_expand "cbranchxf4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1177 (match_operand:XF 2 "nonmemory_operand" "")))
1178 (set (pc) (if_then_else
1179 (match_operator 0 "ix86_fp_comparison_operator"
1182 (label_ref (match_operand 3 "" ""))
1186 ix86_expand_branch (GET_CODE (operands[0]),
1187 operands[1], operands[2], operands[3]);
1191 (define_expand "cstorexf4"
1192 [(set (reg:CC FLAGS_REG)
1193 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1194 (match_operand:XF 3 "nonmemory_operand" "")))
1195 (set (match_operand:QI 0 "register_operand" "")
1196 (match_operator 1 "ix86_fp_comparison_operator"
1201 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1202 operands[2], operands[3]);
1206 (define_expand "cbranch<mode>4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1209 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1210 (set (pc) (if_then_else
1211 (match_operator 0 "ix86_fp_comparison_operator"
1214 (label_ref (match_operand 3 "" ""))
1216 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1218 ix86_expand_branch (GET_CODE (operands[0]),
1219 operands[1], operands[2], operands[3]);
1223 (define_expand "cstore<mode>4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1226 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1227 (set (match_operand:QI 0 "register_operand" "")
1228 (match_operator 1 "ix86_fp_comparison_operator"
1231 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1233 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234 operands[2], operands[3]);
1238 (define_expand "cbranchcc4"
1239 [(set (pc) (if_then_else
1240 (match_operator 0 "comparison_operator"
1241 [(match_operand 1 "flags_reg_operand" "")
1242 (match_operand 2 "const0_operand" "")])
1243 (label_ref (match_operand 3 "" ""))
1247 ix86_expand_branch (GET_CODE (operands[0]),
1248 operands[1], operands[2], operands[3]);
1252 (define_expand "cstorecc4"
1253 [(set (match_operand:QI 0 "register_operand" "")
1254 (match_operator 1 "comparison_operator"
1255 [(match_operand 2 "flags_reg_operand" "")
1256 (match_operand 3 "const0_operand" "")]))]
1259 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1260 operands[2], operands[3]);
1265 ;; FP compares, step 1:
1266 ;; Set the FP condition codes.
1268 ;; CCFPmode compare with exceptions
1269 ;; CCFPUmode compare with no exceptions
1271 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1272 ;; used to manage the reg stack popping would not be preserved.
1274 (define_insn "*cmpfp_0"
1275 [(set (match_operand:HI 0 "register_operand" "=a")
1278 (match_operand 1 "register_operand" "f")
1279 (match_operand 2 "const0_operand" ""))]
1281 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1282 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1283 "* return output_fp_compare (insn, operands, false, false);"
1284 [(set_attr "type" "multi")
1285 (set_attr "unit" "i387")
1287 (cond [(match_operand:SF 1 "" "")
1289 (match_operand:DF 1 "" "")
1292 (const_string "XF")))])
1294 (define_insn_and_split "*cmpfp_0_cc"
1295 [(set (reg:CCFP FLAGS_REG)
1297 (match_operand 1 "register_operand" "f")
1298 (match_operand 2 "const0_operand" "")))
1299 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1300 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1301 && TARGET_SAHF && !TARGET_CMOVE
1302 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1304 "&& reload_completed"
1307 [(compare:CCFP (match_dup 1)(match_dup 2))]
1309 (set (reg:CC FLAGS_REG)
1310 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312 [(set_attr "type" "multi")
1313 (set_attr "unit" "i387")
1315 (cond [(match_operand:SF 1 "" "")
1317 (match_operand:DF 1 "" "")
1320 (const_string "XF")))])
1322 (define_insn "*cmpfp_xf"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1326 (match_operand:XF 1 "register_operand" "f")
1327 (match_operand:XF 2 "register_operand" "f"))]
1330 "* return output_fp_compare (insn, operands, false, false);"
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "XF")])
1335 (define_insn_and_split "*cmpfp_xf_cc"
1336 [(set (reg:CCFP FLAGS_REG)
1338 (match_operand:XF 1 "register_operand" "f")
1339 (match_operand:XF 2 "register_operand" "f")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342 && TARGET_SAHF && !TARGET_CMOVE"
1344 "&& reload_completed"
1347 [(compare:CCFP (match_dup 1)(match_dup 2))]
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "mode" "XF")])
1356 (define_insn "*cmpfp_<mode>"
1357 [(set (match_operand:HI 0 "register_operand" "=a")
1360 (match_operand:MODEF 1 "register_operand" "f")
1361 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1364 "* return output_fp_compare (insn, operands, false, false);"
1365 [(set_attr "type" "multi")
1366 (set_attr "unit" "i387")
1367 (set_attr "mode" "<MODE>")])
1369 (define_insn_and_split "*cmpfp_<mode>_cc"
1370 [(set (reg:CCFP FLAGS_REG)
1372 (match_operand:MODEF 1 "register_operand" "f")
1373 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1374 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1376 && TARGET_SAHF && !TARGET_CMOVE"
1378 "&& reload_completed"
1381 [(compare:CCFP (match_dup 1)(match_dup 2))]
1383 (set (reg:CC FLAGS_REG)
1384 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1386 [(set_attr "type" "multi")
1387 (set_attr "unit" "i387")
1388 (set_attr "mode" "<MODE>")])
1390 (define_insn "*cmpfp_u"
1391 [(set (match_operand:HI 0 "register_operand" "=a")
1394 (match_operand 1 "register_operand" "f")
1395 (match_operand 2 "register_operand" "f"))]
1397 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1398 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1399 "* return output_fp_compare (insn, operands, false, true);"
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1403 (cond [(match_operand:SF 1 "" "")
1405 (match_operand:DF 1 "" "")
1408 (const_string "XF")))])
1410 (define_insn_and_split "*cmpfp_u_cc"
1411 [(set (reg:CCFPU FLAGS_REG)
1413 (match_operand 1 "register_operand" "f")
1414 (match_operand 2 "register_operand" "f")))
1415 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417 && TARGET_SAHF && !TARGET_CMOVE
1418 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1420 "&& reload_completed"
1423 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1425 (set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1431 (cond [(match_operand:SF 1 "" "")
1433 (match_operand:DF 1 "" "")
1436 (const_string "XF")))])
1438 (define_insn "*cmpfp_<mode>"
1439 [(set (match_operand:HI 0 "register_operand" "=a")
1442 (match_operand 1 "register_operand" "f")
1443 (match_operator 3 "float_operator"
1444 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1448 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1449 "* return output_fp_compare (insn, operands, false, false);"
1450 [(set_attr "type" "multi")
1451 (set_attr "unit" "i387")
1452 (set_attr "fp_int_src" "true")
1453 (set_attr "mode" "<MODE>")])
1455 (define_insn_and_split "*cmpfp_<mode>_cc"
1456 [(set (reg:CCFP FLAGS_REG)
1458 (match_operand 1 "register_operand" "f")
1459 (match_operator 3 "float_operator"
1460 [(match_operand:SWI24 2 "memory_operand" "m")])))
1461 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1462 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1463 && TARGET_SAHF && !TARGET_CMOVE
1464 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1465 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1467 "&& reload_completed"
1472 (match_op_dup 3 [(match_dup 2)]))]
1474 (set (reg:CC FLAGS_REG)
1475 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1477 [(set_attr "type" "multi")
1478 (set_attr "unit" "i387")
1479 (set_attr "fp_int_src" "true")
1480 (set_attr "mode" "<MODE>")])
1482 ;; FP compares, step 2
1483 ;; Move the fpsw to ax.
1485 (define_insn "x86_fnstsw_1"
1486 [(set (match_operand:HI 0 "register_operand" "=a")
1487 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1490 [(set (attr "length")
1491 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1492 (set_attr "mode" "SI")
1493 (set_attr "unit" "i387")])
1495 ;; FP compares, step 3
1496 ;; Get ax into flags, general case.
1498 (define_insn "x86_sahf_1"
1499 [(set (reg:CC FLAGS_REG)
1500 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1504 #ifndef HAVE_AS_IX86_SAHF
1506 return ASM_BYTE "0x9e";
1511 [(set_attr "length" "1")
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "direct")
1515 (set_attr "mode" "SI")])
1517 ;; Pentium Pro can do steps 1 through 3 in one go.
1518 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1519 ;; (these i387 instructions set flags directly)
1520 (define_insn "*cmpfp_i_mixed"
1521 [(set (reg:CCFP FLAGS_REG)
1522 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1523 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1524 "TARGET_MIX_SSE_I387
1525 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, true, false);"
1528 [(set_attr "type" "fcmp,ssecomi")
1529 (set_attr "prefix" "orig,maybe_vex")
1531 (if_then_else (match_operand:SF 1 "" "")
1533 (const_string "DF")))
1534 (set (attr "prefix_rep")
1535 (if_then_else (eq_attr "type" "ssecomi")
1537 (const_string "*")))
1538 (set (attr "prefix_data16")
1539 (cond [(eq_attr "type" "fcmp")
1541 (eq_attr "mode" "DF")
1544 (const_string "0")))
1545 (set_attr "athlon_decode" "vector")
1546 (set_attr "amdfam10_decode" "direct")
1547 (set_attr "bdver1_decode" "double")])
1549 (define_insn "*cmpfp_i_sse"
1550 [(set (reg:CCFP FLAGS_REG)
1551 (compare:CCFP (match_operand 0 "register_operand" "x")
1552 (match_operand 1 "nonimmediate_operand" "xm")))]
1554 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "ssecomi")
1558 (set_attr "prefix" "maybe_vex")
1560 (if_then_else (match_operand:SF 1 "" "")
1562 (const_string "DF")))
1563 (set_attr "prefix_rep" "0")
1564 (set (attr "prefix_data16")
1565 (if_then_else (eq_attr "mode" "DF")
1567 (const_string "0")))
1568 (set_attr "athlon_decode" "vector")
1569 (set_attr "amdfam10_decode" "direct")
1570 (set_attr "bdver1_decode" "double")])
1572 (define_insn "*cmpfp_i_i387"
1573 [(set (reg:CCFP FLAGS_REG)
1574 (compare:CCFP (match_operand 0 "register_operand" "f")
1575 (match_operand 1 "register_operand" "f")))]
1576 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1578 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, false);"
1581 [(set_attr "type" "fcmp")
1583 (cond [(match_operand:SF 1 "" "")
1585 (match_operand:DF 1 "" "")
1588 (const_string "XF")))
1589 (set_attr "athlon_decode" "vector")
1590 (set_attr "amdfam10_decode" "direct")
1591 (set_attr "bdver1_decode" "double")])
1593 (define_insn "*cmpfp_iu_mixed"
1594 [(set (reg:CCFPU FLAGS_REG)
1595 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1596 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1597 "TARGET_MIX_SSE_I387
1598 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1599 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600 "* return output_fp_compare (insn, operands, true, true);"
1601 [(set_attr "type" "fcmp,ssecomi")
1602 (set_attr "prefix" "orig,maybe_vex")
1604 (if_then_else (match_operand:SF 1 "" "")
1606 (const_string "DF")))
1607 (set (attr "prefix_rep")
1608 (if_then_else (eq_attr "type" "ssecomi")
1610 (const_string "*")))
1611 (set (attr "prefix_data16")
1612 (cond [(eq_attr "type" "fcmp")
1614 (eq_attr "mode" "DF")
1617 (const_string "0")))
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "double")])
1622 (define_insn "*cmpfp_iu_sse"
1623 [(set (reg:CCFPU FLAGS_REG)
1624 (compare:CCFPU (match_operand 0 "register_operand" "x")
1625 (match_operand 1 "nonimmediate_operand" "xm")))]
1627 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "ssecomi")
1631 (set_attr "prefix" "maybe_vex")
1633 (if_then_else (match_operand:SF 1 "" "")
1635 (const_string "DF")))
1636 (set_attr "prefix_rep" "0")
1637 (set (attr "prefix_data16")
1638 (if_then_else (eq_attr "mode" "DF")
1640 (const_string "0")))
1641 (set_attr "athlon_decode" "vector")
1642 (set_attr "amdfam10_decode" "direct")
1643 (set_attr "bdver1_decode" "double")])
1645 (define_insn "*cmpfp_iu_387"
1646 [(set (reg:CCFPU FLAGS_REG)
1647 (compare:CCFPU (match_operand 0 "register_operand" "f")
1648 (match_operand 1 "register_operand" "f")))]
1649 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1651 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1652 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1653 "* return output_fp_compare (insn, operands, true, true);"
1654 [(set_attr "type" "fcmp")
1656 (cond [(match_operand:SF 1 "" "")
1658 (match_operand:DF 1 "" "")
1661 (const_string "XF")))
1662 (set_attr "athlon_decode" "vector")
1663 (set_attr "amdfam10_decode" "direct")
1664 (set_attr "bdver1_decode" "direct")])
1666 ;; Push/pop instructions.
1668 (define_insn "*push<mode>2"
1669 [(set (match_operand:DWI 0 "push_operand" "=<")
1670 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1673 [(set_attr "type" "multi")
1674 (set_attr "mode" "<MODE>")])
1677 [(set (match_operand:TI 0 "push_operand" "")
1678 (match_operand:TI 1 "general_operand" ""))]
1679 "TARGET_64BIT && reload_completed
1680 && !SSE_REG_P (operands[1])"
1682 "ix86_split_long_move (operands); DONE;")
1684 (define_insn "*pushdi2_rex64"
1685 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1686 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1691 [(set_attr "type" "push,multi")
1692 (set_attr "mode" "DI")])
1694 ;; Convert impossible pushes of immediate to existing instructions.
1695 ;; First try to get scratch register and go through it. In case this
1696 ;; fails, push sign extended lower part first and then overwrite
1697 ;; upper part by 32bit move.
1699 [(match_scratch:DI 2 "r")
1700 (set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1703 && !x86_64_immediate_operand (operands[1], DImode)"
1704 [(set (match_dup 2) (match_dup 1))
1705 (set (match_dup 0) (match_dup 2))])
1707 ;; We need to define this as both peepholer and splitter for case
1708 ;; peephole2 pass is not run.
1709 ;; "&& 1" is needed to keep it from matching the previous pattern.
1711 [(set (match_operand:DI 0 "push_operand" "")
1712 (match_operand:DI 1 "immediate_operand" ""))]
1713 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1714 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1715 [(set (match_dup 0) (match_dup 1))
1716 (set (match_dup 2) (match_dup 3))]
1718 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1720 operands[1] = gen_lowpart (DImode, operands[2]);
1721 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1726 [(set (match_operand:DI 0 "push_operand" "")
1727 (match_operand:DI 1 "immediate_operand" ""))]
1728 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1729 ? epilogue_completed : reload_completed)
1730 && !symbolic_operand (operands[1], DImode)
1731 && !x86_64_immediate_operand (operands[1], DImode)"
1732 [(set (match_dup 0) (match_dup 1))
1733 (set (match_dup 2) (match_dup 3))]
1735 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1737 operands[1] = gen_lowpart (DImode, operands[2]);
1738 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1743 [(set (match_operand:DI 0 "push_operand" "")
1744 (match_operand:DI 1 "general_operand" ""))]
1745 "!TARGET_64BIT && reload_completed
1746 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1748 "ix86_split_long_move (operands); DONE;")
1750 (define_insn "*pushsi2"
1751 [(set (match_operand:SI 0 "push_operand" "=<")
1752 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "SI")])
1758 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1759 ;; "push a byte/word". But actually we use pushl, which has the effect
1760 ;; of rounding the amount pushed up to a word.
1762 ;; For TARGET_64BIT we always round up to 8 bytes.
1763 (define_insn "*push<mode>2_rex64"
1764 [(set (match_operand:SWI124 0 "push_operand" "=X")
1765 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1768 [(set_attr "type" "push")
1769 (set_attr "mode" "DI")])
1771 (define_insn "*push<mode>2"
1772 [(set (match_operand:SWI12 0 "push_operand" "=X")
1773 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1776 [(set_attr "type" "push")
1777 (set_attr "mode" "SI")])
1779 (define_insn "*push<mode>2_prologue"
1780 [(set (match_operand:P 0 "push_operand" "=<")
1781 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1782 (clobber (mem:BLK (scratch)))]
1784 "push{<imodesuffix>}\t%1"
1785 [(set_attr "type" "push")
1786 (set_attr "mode" "<MODE>")])
1788 (define_insn "*pop<mode>1"
1789 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1790 (match_operand:P 1 "pop_operand" ">"))]
1792 "pop{<imodesuffix>}\t%0"
1793 [(set_attr "type" "pop")
1794 (set_attr "mode" "<MODE>")])
1796 (define_insn "*pop<mode>1_epilogue"
1797 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1798 (match_operand:P 1 "pop_operand" ">"))
1799 (clobber (mem:BLK (scratch)))]
1801 "pop{<imodesuffix>}\t%0"
1802 [(set_attr "type" "pop")
1803 (set_attr "mode" "<MODE>")])
1805 ;; Move instructions.
1807 (define_expand "movoi"
1808 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1809 (match_operand:OI 1 "general_operand" ""))]
1811 "ix86_expand_move (OImode, operands); DONE;")
1813 (define_expand "movti"
1814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1815 (match_operand:TI 1 "nonimmediate_operand" ""))]
1816 "TARGET_64BIT || TARGET_SSE"
1819 ix86_expand_move (TImode, operands);
1820 else if (push_operand (operands[0], TImode))
1821 ix86_expand_push (TImode, operands[1]);
1823 ix86_expand_vector_move (TImode, operands);
1827 ;; This expands to what emit_move_complex would generate if we didn't
1828 ;; have a movti pattern. Having this avoids problems with reload on
1829 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1830 ;; to have around all the time.
1831 (define_expand "movcdi"
1832 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1833 (match_operand:CDI 1 "general_operand" ""))]
1836 if (push_operand (operands[0], CDImode))
1837 emit_move_complex_push (CDImode, operands[0], operands[1]);
1839 emit_move_complex_parts (operands[0], operands[1]);
1843 (define_expand "mov<mode>"
1844 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1845 (match_operand:SWI1248x 1 "general_operand" ""))]
1847 "ix86_expand_move (<MODE>mode, operands); DONE;")
1849 (define_insn "*mov<mode>_xor"
1850 [(set (match_operand:SWI48 0 "register_operand" "=r")
1851 (match_operand:SWI48 1 "const0_operand" ""))
1852 (clobber (reg:CC FLAGS_REG))]
1855 [(set_attr "type" "alu1")
1856 (set_attr "mode" "SI")
1857 (set_attr "length_immediate" "0")])
1859 (define_insn "*mov<mode>_or"
1860 [(set (match_operand:SWI48 0 "register_operand" "=r")
1861 (match_operand:SWI48 1 "const_int_operand" ""))
1862 (clobber (reg:CC FLAGS_REG))]
1864 && operands[1] == constm1_rtx"
1865 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1866 [(set_attr "type" "alu1")
1867 (set_attr "mode" "<MODE>")
1868 (set_attr "length_immediate" "1")])
1870 (define_insn "*movoi_internal_avx"
1871 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1872 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1873 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1875 switch (which_alternative)
1878 return standard_sse_constant_opcode (insn, operands[1]);
1881 if (misaligned_operand (operands[0], OImode)
1882 || misaligned_operand (operands[1], OImode))
1883 return "vmovdqu\t{%1, %0|%0, %1}";
1885 return "vmovdqa\t{%1, %0|%0, %1}";
1890 [(set_attr "type" "sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "vex")
1892 (set_attr "mode" "OI")])
1894 (define_insn "*movti_internal_rex64"
1895 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1896 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1897 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1899 switch (which_alternative)
1905 return standard_sse_constant_opcode (insn, operands[1]);
1908 /* TDmode values are passed as TImode on the stack. Moving them
1909 to stack may result in unaligned memory access. */
1910 if (misaligned_operand (operands[0], TImode)
1911 || misaligned_operand (operands[1], TImode))
1913 if (get_attr_mode (insn) == MODE_V4SF)
1914 return "%vmovups\t{%1, %0|%0, %1}";
1916 return "%vmovdqu\t{%1, %0|%0, %1}";
1920 if (get_attr_mode (insn) == MODE_V4SF)
1921 return "%vmovaps\t{%1, %0|%0, %1}";
1923 return "%vmovdqa\t{%1, %0|%0, %1}";
1929 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1930 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1932 (cond [(eq_attr "alternative" "2,3")
1934 (match_test "optimize_function_for_size_p (cfun)")
1935 (const_string "V4SF")
1936 (const_string "TI"))
1937 (eq_attr "alternative" "4")
1939 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1940 (match_test "optimize_function_for_size_p (cfun)"))
1941 (const_string "V4SF")
1942 (const_string "TI"))]
1943 (const_string "DI")))])
1946 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1947 (match_operand:TI 1 "general_operand" ""))]
1949 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1951 "ix86_split_long_move (operands); DONE;")
1953 (define_insn "*movti_internal_sse"
1954 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1955 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1956 "TARGET_SSE && !TARGET_64BIT
1957 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1959 switch (which_alternative)
1962 return standard_sse_constant_opcode (insn, operands[1]);
1965 /* TDmode values are passed as TImode on the stack. Moving them
1966 to stack may result in unaligned memory access. */
1967 if (misaligned_operand (operands[0], TImode)
1968 || misaligned_operand (operands[1], TImode))
1970 if (get_attr_mode (insn) == MODE_V4SF)
1971 return "%vmovups\t{%1, %0|%0, %1}";
1973 return "%vmovdqu\t{%1, %0|%0, %1}";
1977 if (get_attr_mode (insn) == MODE_V4SF)
1978 return "%vmovaps\t{%1, %0|%0, %1}";
1980 return "%vmovdqa\t{%1, %0|%0, %1}";
1986 [(set_attr "type" "sselog1,ssemov,ssemov")
1987 (set_attr "prefix" "maybe_vex")
1989 (cond [(ior (not (match_test "TARGET_SSE2"))
1990 (match_test "optimize_function_for_size_p (cfun)"))
1991 (const_string "V4SF")
1992 (and (eq_attr "alternative" "2")
1993 (match_test "TARGET_SSE_TYPELESS_STORES"))
1994 (const_string "V4SF")]
1995 (const_string "TI")))])
1997 (define_insn "*movdi_internal_rex64"
1998 [(set (match_operand:DI 0 "nonimmediate_operand"
1999 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2000 (match_operand:DI 1 "general_operand"
2001 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
2002 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2004 switch (get_attr_type (insn))
2007 if (SSE_REG_P (operands[0]))
2008 return "movq2dq\t{%1, %0|%0, %1}";
2010 return "movdq2q\t{%1, %0|%0, %1}";
2013 if (get_attr_mode (insn) == MODE_TI)
2014 return "%vmovdqa\t{%1, %0|%0, %1}";
2015 /* Handle broken assemblers that require movd instead of movq. */
2016 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2017 return "%vmovd\t{%1, %0|%0, %1}";
2019 return "%vmovq\t{%1, %0|%0, %1}";
2022 /* Handle broken assemblers that require movd instead of movq. */
2023 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024 return "movd\t{%1, %0|%0, %1}";
2026 return "movq\t{%1, %0|%0, %1}";
2029 return standard_sse_constant_opcode (insn, operands[1]);
2032 return "pxor\t%0, %0";
2038 return "lea{q}\t{%a1, %0|%0, %a1}";
2041 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2042 if (get_attr_mode (insn) == MODE_SI)
2043 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2044 else if (which_alternative == 2)
2045 return "movabs{q}\t{%1, %0|%0, %1}";
2047 return "mov{q}\t{%1, %0|%0, %1}";
2051 (cond [(eq_attr "alternative" "4")
2052 (const_string "multi")
2053 (eq_attr "alternative" "5")
2054 (const_string "mmx")
2055 (eq_attr "alternative" "6,7,8,9")
2056 (const_string "mmxmov")
2057 (eq_attr "alternative" "10")
2058 (const_string "sselog1")
2059 (eq_attr "alternative" "11,12,13,14,15")
2060 (const_string "ssemov")
2061 (eq_attr "alternative" "16,17")
2062 (const_string "ssecvt")
2063 (match_operand 1 "pic_32bit_operand" "")
2064 (const_string "lea")
2066 (const_string "imov")))
2069 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2071 (const_string "*")))
2072 (set (attr "length_immediate")
2074 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2076 (const_string "*")))
2077 (set (attr "prefix_rex")
2078 (if_then_else (eq_attr "alternative" "8,9")
2080 (const_string "*")))
2081 (set (attr "prefix_data16")
2082 (if_then_else (eq_attr "alternative" "11")
2084 (const_string "*")))
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2087 (const_string "maybe_vex")
2088 (const_string "orig")))
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2091 ;; Reload patterns to support multi-word load/store
2092 ;; with non-offsetable address.
2093 (define_expand "reload_noff_store"
2094 [(parallel [(match_operand 0 "memory_operand" "=m")
2095 (match_operand 1 "register_operand" "r")
2096 (match_operand:DI 2 "register_operand" "=&r")])]
2099 rtx mem = operands[0];
2100 rtx addr = XEXP (mem, 0);
2102 emit_move_insn (operands[2], addr);
2103 mem = replace_equiv_address_nv (mem, operands[2]);
2105 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2109 (define_expand "reload_noff_load"
2110 [(parallel [(match_operand 0 "register_operand" "=r")
2111 (match_operand 1 "memory_operand" "m")
2112 (match_operand:DI 2 "register_operand" "=r")])]
2115 rtx mem = operands[1];
2116 rtx addr = XEXP (mem, 0);
2118 emit_move_insn (operands[2], addr);
2119 mem = replace_equiv_address_nv (mem, operands[2]);
2121 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2125 ;; Convert impossible stores of immediate to existing instructions.
2126 ;; First try to get scratch register and go through it. In case this
2127 ;; fails, move by 32bit parts.
2129 [(match_scratch:DI 2 "r")
2130 (set (match_operand:DI 0 "memory_operand" "")
2131 (match_operand:DI 1 "immediate_operand" ""))]
2132 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2133 && !x86_64_immediate_operand (operands[1], DImode)"
2134 [(set (match_dup 2) (match_dup 1))
2135 (set (match_dup 0) (match_dup 2))])
2137 ;; We need to define this as both peepholer and splitter for case
2138 ;; peephole2 pass is not run.
2139 ;; "&& 1" is needed to keep it from matching the previous pattern.
2141 [(set (match_operand:DI 0 "memory_operand" "")
2142 (match_operand:DI 1 "immediate_operand" ""))]
2143 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2144 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2145 [(set (match_dup 2) (match_dup 3))
2146 (set (match_dup 4) (match_dup 5))]
2147 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2150 [(set (match_operand:DI 0 "memory_operand" "")
2151 (match_operand:DI 1 "immediate_operand" ""))]
2152 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2153 ? epilogue_completed : reload_completed)
2154 && !symbolic_operand (operands[1], DImode)
2155 && !x86_64_immediate_operand (operands[1], DImode)"
2156 [(set (match_dup 2) (match_dup 3))
2157 (set (match_dup 4) (match_dup 5))]
2158 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2160 (define_insn "*movdi_internal"
2161 [(set (match_operand:DI 0 "nonimmediate_operand"
2162 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2163 (match_operand:DI 1 "general_operand"
2164 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2165 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2167 switch (get_attr_type (insn))
2170 if (SSE_REG_P (operands[0]))
2171 return "movq2dq\t{%1, %0|%0, %1}";
2173 return "movdq2q\t{%1, %0|%0, %1}";
2176 switch (get_attr_mode (insn))
2179 return "%vmovdqa\t{%1, %0|%0, %1}";
2181 return "%vmovq\t{%1, %0|%0, %1}";
2183 return "movaps\t{%1, %0|%0, %1}";
2185 return "movlps\t{%1, %0|%0, %1}";
2191 return "movq\t{%1, %0|%0, %1}";
2194 return standard_sse_constant_opcode (insn, operands[1]);
2197 return "pxor\t%0, %0";
2207 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2208 (const_string "sse2")
2209 (eq_attr "alternative" "9,10,11,12")
2210 (const_string "noavx")
2212 (const_string "*")))
2214 (cond [(eq_attr "alternative" "0,1")
2215 (const_string "multi")
2216 (eq_attr "alternative" "2")
2217 (const_string "mmx")
2218 (eq_attr "alternative" "3,4")
2219 (const_string "mmxmov")
2220 (eq_attr "alternative" "5,9")
2221 (const_string "sselog1")
2222 (eq_attr "alternative" "13,14")
2223 (const_string "ssecvt")
2225 (const_string "ssemov")))
2226 (set (attr "prefix")
2227 (if_then_else (eq_attr "alternative" "5,6,7,8")
2228 (const_string "maybe_vex")
2229 (const_string "orig")))
2230 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2233 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2234 (match_operand:DI 1 "general_operand" ""))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2239 "ix86_split_long_move (operands); DONE;")
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2248 switch (get_attr_type (insn))
2251 return standard_sse_constant_opcode (insn, operands[1]);
2254 switch (get_attr_mode (insn))
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2261 return "%vmovd\t{%1, %0|%0, %1}";
2263 return "%vmovss\t{%1, %0|%0, %1}";
2269 return "pxor\t%0, %0";
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2277 return "lea{l}\t{%a1, %0|%0, %a1}";
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 return "mov{l}\t{%1, %0|%0, %1}";
2285 (cond [(eq_attr "alternative" "2")
2286 (const_string "mmx")
2287 (eq_attr "alternative" "3,4,5")
2288 (const_string "mmxmov")
2289 (eq_attr "alternative" "6")
2290 (const_string "sselog1")
2291 (eq_attr "alternative" "7,8,9,10,11")
2292 (const_string "ssemov")
2293 (match_operand 1 "pic_32bit_operand" "")
2294 (const_string "lea")
2296 (const_string "imov")))
2297 (set (attr "prefix")
2298 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2299 (const_string "orig")
2300 (const_string "maybe_vex")))
2301 (set (attr "prefix_data16")
2302 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2304 (const_string "*")))
2306 (cond [(eq_attr "alternative" "2,3")
2308 (eq_attr "alternative" "6,7")
2310 (not (match_test "TARGET_SSE2"))
2311 (const_string "V4SF")
2312 (const_string "TI"))
2313 (and (eq_attr "alternative" "8,9,10,11")
2314 (not (match_test "TARGET_SSE2")))
2317 (const_string "SI")))])
2319 (define_insn "*movhi_internal"
2320 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2321 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2322 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2324 switch (get_attr_type (insn))
2327 /* movzwl is faster than movw on p2 due to partial word stalls,
2328 though not as fast as an aligned movl. */
2329 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2331 if (get_attr_mode (insn) == MODE_SI)
2332 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2334 return "mov{w}\t{%1, %0|%0, %1}";
2338 (cond [(match_test "optimize_function_for_size_p (cfun)")
2339 (const_string "imov")
2340 (and (eq_attr "alternative" "0")
2341 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2342 (not (match_test "TARGET_HIMODE_MATH"))))
2343 (const_string "imov")
2344 (and (eq_attr "alternative" "1,2")
2345 (match_operand:HI 1 "aligned_operand" ""))
2346 (const_string "imov")
2347 (and (match_test "TARGET_MOVX")
2348 (eq_attr "alternative" "0,2"))
2349 (const_string "imovx")
2351 (const_string "imov")))
2353 (cond [(eq_attr "type" "imovx")
2355 (and (eq_attr "alternative" "1,2")
2356 (match_operand:HI 1 "aligned_operand" ""))
2358 (and (eq_attr "alternative" "0")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_HIMODE_MATH"))))
2363 (const_string "HI")))])
2365 ;; Situation is quite tricky about when to choose full sized (SImode) move
2366 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2367 ;; partial register dependency machines (such as AMD Athlon), where QImode
2368 ;; moves issue extra dependency and for partial register stalls machines
2369 ;; that don't use QImode patterns (and QImode move cause stall on the next
2372 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2373 ;; register stall machines with, where we use QImode instructions, since
2374 ;; partial register stall can be caused there. Then we use movzx.
2375 (define_insn "*movqi_internal"
2376 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2377 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2378 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2380 switch (get_attr_type (insn))
2383 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2384 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2386 if (get_attr_mode (insn) == MODE_SI)
2387 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2389 return "mov{b}\t{%1, %0|%0, %1}";
2393 (cond [(and (eq_attr "alternative" "5")
2394 (not (match_operand:QI 1 "aligned_operand" "")))
2395 (const_string "imovx")
2396 (match_test "optimize_function_for_size_p (cfun)")
2397 (const_string "imov")
2398 (and (eq_attr "alternative" "3")
2399 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2400 (not (match_test "TARGET_QIMODE_MATH"))))
2401 (const_string "imov")
2402 (eq_attr "alternative" "3,5")
2403 (const_string "imovx")
2404 (and (match_test "TARGET_MOVX")
2405 (eq_attr "alternative" "2"))
2406 (const_string "imovx")
2408 (const_string "imov")))
2410 (cond [(eq_attr "alternative" "3,4,5")
2412 (eq_attr "alternative" "6")
2414 (eq_attr "type" "imovx")
2416 (and (eq_attr "type" "imov")
2417 (and (eq_attr "alternative" "0,1")
2418 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2419 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2420 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2422 ;; Avoid partial register stalls when not using QImode arithmetic
2423 (and (eq_attr "type" "imov")
2424 (and (eq_attr "alternative" "0,1")
2425 (and (match_test "TARGET_PARTIAL_REG_STALL")
2426 (not (match_test "TARGET_QIMODE_MATH")))))
2429 (const_string "QI")))])
2431 ;; Stores and loads of ax to arbitrary constant address.
2432 ;; We fake an second form of instruction to force reload to load address
2433 ;; into register when rax is not available
2434 (define_insn "*movabs<mode>_1"
2435 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2436 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2437 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2439 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2440 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2441 [(set_attr "type" "imov")
2442 (set_attr "modrm" "0,*")
2443 (set_attr "length_address" "8,0")
2444 (set_attr "length_immediate" "0,*")
2445 (set_attr "memory" "store")
2446 (set_attr "mode" "<MODE>")])
2448 (define_insn "*movabs<mode>_2"
2449 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2450 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2451 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2453 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2454 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2455 [(set_attr "type" "imov")
2456 (set_attr "modrm" "0,*")
2457 (set_attr "length_address" "8,0")
2458 (set_attr "length_immediate" "0")
2459 (set_attr "memory" "load")
2460 (set_attr "mode" "<MODE>")])
2462 (define_insn "*swap<mode>"
2463 [(set (match_operand:SWI48 0 "register_operand" "+r")
2464 (match_operand:SWI48 1 "register_operand" "+r"))
2468 "xchg{<imodesuffix>}\t%1, %0"
2469 [(set_attr "type" "imov")
2470 (set_attr "mode" "<MODE>")
2471 (set_attr "pent_pair" "np")
2472 (set_attr "athlon_decode" "vector")
2473 (set_attr "amdfam10_decode" "double")
2474 (set_attr "bdver1_decode" "double")])
2476 (define_insn "*swap<mode>_1"
2477 [(set (match_operand:SWI12 0 "register_operand" "+r")
2478 (match_operand:SWI12 1 "register_operand" "+r"))
2481 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "SI")
2485 (set_attr "pent_pair" "np")
2486 (set_attr "athlon_decode" "vector")
2487 (set_attr "amdfam10_decode" "double")
2488 (set_attr "bdver1_decode" "double")])
2490 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2491 ;; is disabled for AMDFAM10
2492 (define_insn "*swap<mode>_2"
2493 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2494 (match_operand:SWI12 1 "register_operand" "+<r>"))
2497 "TARGET_PARTIAL_REG_STALL"
2498 "xchg{<imodesuffix>}\t%1, %0"
2499 [(set_attr "type" "imov")
2500 (set_attr "mode" "<MODE>")
2501 (set_attr "pent_pair" "np")
2502 (set_attr "athlon_decode" "vector")])
2504 (define_expand "movstrict<mode>"
2505 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2506 (match_operand:SWI12 1 "general_operand" ""))]
2509 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2511 if (GET_CODE (operands[0]) == SUBREG
2512 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2514 /* Don't generate memory->memory moves, go through a register */
2515 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2516 operands[1] = force_reg (<MODE>mode, operands[1]);
2519 (define_insn "*movstrict<mode>_1"
2520 [(set (strict_low_part
2521 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2522 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2524 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2525 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2526 [(set_attr "type" "imov")
2527 (set_attr "mode" "<MODE>")])
2529 (define_insn "*movstrict<mode>_xor"
2530 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2531 (match_operand:SWI12 1 "const0_operand" ""))
2532 (clobber (reg:CC FLAGS_REG))]
2534 "xor{<imodesuffix>}\t%0, %0"
2535 [(set_attr "type" "alu1")
2536 (set_attr "mode" "<MODE>")
2537 (set_attr "length_immediate" "0")])
2539 (define_insn "*mov<mode>_extv_1"
2540 [(set (match_operand:SWI24 0 "register_operand" "=R")
2541 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2545 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2546 [(set_attr "type" "imovx")
2547 (set_attr "mode" "SI")])
2549 (define_insn "*movqi_extv_1_rex64"
2550 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2551 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2556 switch (get_attr_type (insn))
2559 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2561 return "mov{b}\t{%h1, %0|%0, %h1}";
2565 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2566 (match_test "TARGET_MOVX"))
2567 (const_string "imovx")
2568 (const_string "imov")))
2570 (if_then_else (eq_attr "type" "imovx")
2572 (const_string "QI")))])
2574 (define_insn "*movqi_extv_1"
2575 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2576 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2581 switch (get_attr_type (insn))
2584 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2586 return "mov{b}\t{%h1, %0|%0, %h1}";
2590 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2591 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2592 (match_test "TARGET_MOVX")))
2593 (const_string "imovx")
2594 (const_string "imov")))
2596 (if_then_else (eq_attr "type" "imovx")
2598 (const_string "QI")))])
2600 (define_insn "*mov<mode>_extzv_1"
2601 [(set (match_operand:SWI48 0 "register_operand" "=R")
2602 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2606 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2607 [(set_attr "type" "imovx")
2608 (set_attr "mode" "SI")])
2610 (define_insn "*movqi_extzv_2_rex64"
2611 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2613 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2618 switch (get_attr_type (insn))
2621 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2623 return "mov{b}\t{%h1, %0|%0, %h1}";
2627 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2628 (match_test "TARGET_MOVX"))
2629 (const_string "imovx")
2630 (const_string "imov")))
2632 (if_then_else (eq_attr "type" "imovx")
2634 (const_string "QI")))])
2636 (define_insn "*movqi_extzv_2"
2637 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2639 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2644 switch (get_attr_type (insn))
2647 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2649 return "mov{b}\t{%h1, %0|%0, %h1}";
2653 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2654 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2655 (match_test "TARGET_MOVX")))
2656 (const_string "imovx")
2657 (const_string "imov")))
2659 (if_then_else (eq_attr "type" "imovx")
2661 (const_string "QI")))])
2663 (define_expand "mov<mode>_insv_1"
2664 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2667 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2669 (define_insn "*mov<mode>_insv_1_rex64"
2670 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2673 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2675 "mov{b}\t{%b1, %h0|%h0, %b1}"
2676 [(set_attr "type" "imov")
2677 (set_attr "mode" "QI")])
2679 (define_insn "*movsi_insv_1"
2680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2683 (match_operand:SI 1 "general_operand" "Qmn"))]
2685 "mov{b}\t{%b1, %h0|%h0, %b1}"
2686 [(set_attr "type" "imov")
2687 (set_attr "mode" "QI")])
2689 (define_insn "*movqi_insv_2"
2690 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2693 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2696 "mov{b}\t{%h1, %h0|%h0, %h1}"
2697 [(set_attr "type" "imov")
2698 (set_attr "mode" "QI")])
2700 ;; Floating point push instructions.
2702 (define_insn "*pushtf"
2703 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2704 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2707 /* This insn should be already split before reg-stack. */
2710 [(set_attr "type" "multi")
2711 (set_attr "unit" "sse,*,*")
2712 (set_attr "mode" "TF,SI,SI")])
2714 ;; %%% Kill this when call knows how to work this out.
2716 [(set (match_operand:TF 0 "push_operand" "")
2717 (match_operand:TF 1 "sse_reg_operand" ""))]
2718 "TARGET_SSE2 && reload_completed"
2719 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2720 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2722 (define_insn "*pushxf"
2723 [(set (match_operand:XF 0 "push_operand" "=<,<")
2724 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2725 "optimize_function_for_speed_p (cfun)"
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*")
2732 (set_attr "mode" "XF,SI")])
2734 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2735 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2736 ;; Pushing using integer instructions is longer except for constants
2737 ;; and direct memory references (assuming that any given constant is pushed
2738 ;; only once, but this ought to be handled elsewhere).
2740 (define_insn "*pushxf_nointeger"
2741 [(set (match_operand:XF 0 "push_operand" "=<,<")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2743 "optimize_function_for_size_p (cfun)"
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*")
2750 (set_attr "mode" "XF,SI")])
2752 ;; %%% Kill this when call knows how to work this out.
2754 [(set (match_operand:XF 0 "push_operand" "")
2755 (match_operand:XF 1 "fp_register_operand" ""))]
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2761 (define_insn "*pushdf_rex64"
2762 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2763 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2766 /* This insn should be already split before reg-stack. */
2769 [(set_attr "type" "multi")
2770 (set_attr "unit" "i387,*,*")
2771 (set_attr "mode" "DF,DI,DF")])
2773 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2774 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2775 ;; On the average, pushdf using integers can be still shorter.
2777 (define_insn "*pushdf"
2778 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2779 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2782 /* This insn should be already split before reg-stack. */
2785 [(set_attr "isa" "*,*,sse2")
2786 (set_attr "type" "multi")
2787 (set_attr "unit" "i387,*,*")
2788 (set_attr "mode" "DF,DI,DF")])
2790 ;; %%% Kill this when call knows how to work this out.
2792 [(set (match_operand:DF 0 "push_operand" "")
2793 (match_operand:DF 1 "any_fp_register_operand" ""))]
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2796 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2798 (define_insn "*pushsf_rex64"
2799 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2800 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2803 /* Anything else should be already split before reg-stack. */
2804 gcc_assert (which_alternative == 1);
2805 return "push{q}\t%q1";
2807 [(set_attr "type" "multi,push,multi")
2808 (set_attr "unit" "i387,*,*")
2809 (set_attr "mode" "SF,DI,SF")])
2811 (define_insn "*pushsf"
2812 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2813 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2816 /* Anything else should be already split before reg-stack. */
2817 gcc_assert (which_alternative == 1);
2818 return "push{l}\t%1";
2820 [(set_attr "type" "multi,push,multi")
2821 (set_attr "unit" "i387,*,*")
2822 (set_attr "mode" "SF,SI,SF")])
2824 ;; %%% Kill this when call knows how to work this out.
2826 [(set (match_operand:SF 0 "push_operand" "")
2827 (match_operand:SF 1 "any_fp_register_operand" ""))]
2829 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2830 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2831 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2834 [(set (match_operand:SF 0 "push_operand" "")
2835 (match_operand:SF 1 "memory_operand" ""))]
2837 && (operands[2] = find_constant_src (insn))"
2838 [(set (match_dup 0) (match_dup 2))])
2841 [(set (match_operand 0 "push_operand" "")
2842 (match_operand 1 "general_operand" ""))]
2844 && (GET_MODE (operands[0]) == TFmode
2845 || GET_MODE (operands[0]) == XFmode
2846 || GET_MODE (operands[0]) == DFmode)
2847 && !ANY_FP_REG_P (operands[1])"
2849 "ix86_split_long_move (operands); DONE;")
2851 ;; Floating point move instructions.
2853 (define_expand "movtf"
2854 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2855 (match_operand:TF 1 "nonimmediate_operand" ""))]
2858 ix86_expand_move (TFmode, operands);
2862 (define_expand "mov<mode>"
2863 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2864 (match_operand:X87MODEF 1 "general_operand" ""))]
2866 "ix86_expand_move (<MODE>mode, operands); DONE;")
2868 (define_insn "*movtf_internal"
2869 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2870 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (!can_create_pseudo_p ()
2874 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || (optimize_function_for_size_p (cfun)
2877 && standard_sse_constant_p (operands[1])
2878 && !memory_operand (operands[0], TFmode))
2879 || (!TARGET_MEMORY_MISMATCH_STALL
2880 && memory_operand (operands[0], TFmode)))"
2882 switch (which_alternative)
2886 /* Handle misaligned load/store since we
2887 don't have movmisaligntf pattern. */
2888 if (misaligned_operand (operands[0], TFmode)
2889 || misaligned_operand (operands[1], TFmode))
2891 if (get_attr_mode (insn) == MODE_V4SF)
2892 return "%vmovups\t{%1, %0|%0, %1}";
2894 return "%vmovdqu\t{%1, %0|%0, %1}";
2898 if (get_attr_mode (insn) == MODE_V4SF)
2899 return "%vmovaps\t{%1, %0|%0, %1}";
2901 return "%vmovdqa\t{%1, %0|%0, %1}";
2905 return standard_sse_constant_opcode (insn, operands[1]);
2915 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2916 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2918 (cond [(eq_attr "alternative" "0,2")
2920 (match_test "optimize_function_for_size_p (cfun)")
2921 (const_string "V4SF")
2922 (const_string "TI"))
2923 (eq_attr "alternative" "1")
2925 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2926 (match_test "optimize_function_for_size_p (cfun)"))
2927 (const_string "V4SF")
2928 (const_string "TI"))]
2929 (const_string "DI")))])
2931 ;; Possible store forwarding (partial memory) stall in alternative 4.
2932 (define_insn "*movxf_internal"
2933 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2934 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2936 && (!can_create_pseudo_p ()
2937 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2938 || GET_CODE (operands[1]) != CONST_DOUBLE
2939 || (optimize_function_for_size_p (cfun)
2940 && standard_80387_constant_p (operands[1]) > 0
2941 && !memory_operand (operands[0], XFmode))
2942 || (!TARGET_MEMORY_MISMATCH_STALL
2943 && memory_operand (operands[0], XFmode)))"
2945 switch (which_alternative)
2949 return output_387_reg_move (insn, operands);
2952 return standard_80387_constant_opcode (operands[1]);
2962 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2963 (set_attr "mode" "XF,XF,XF,SI,SI")])
2965 (define_insn "*movdf_internal_rex64"
2966 [(set (match_operand:DF 0 "nonimmediate_operand"
2967 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2968 (match_operand:DF 1 "general_operand"
2969 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2971 && (!can_create_pseudo_p ()
2972 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2973 || GET_CODE (operands[1]) != CONST_DOUBLE
2974 || (optimize_function_for_size_p (cfun)
2975 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2976 && standard_80387_constant_p (operands[1]) > 0)
2977 || (TARGET_SSE2 && TARGET_SSE_MATH
2978 && standard_sse_constant_p (operands[1]))))
2979 || memory_operand (operands[0], DFmode))"
2981 switch (which_alternative)
2985 return output_387_reg_move (insn, operands);
2988 return standard_80387_constant_opcode (operands[1]);
2992 return "mov{q}\t{%1, %0|%0, %1}";
2995 return "movabs{q}\t{%1, %0|%0, %1}";
3001 return standard_sse_constant_opcode (insn, operands[1]);
3006 switch (get_attr_mode (insn))
3009 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3010 return "%vmovapd\t{%1, %0|%0, %1}";
3012 return "%vmovaps\t{%1, %0|%0, %1}";
3015 return "%vmovq\t{%1, %0|%0, %1}";
3017 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3018 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3019 return "%vmovsd\t{%1, %0|%0, %1}";
3021 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3023 return "%vmovlps\t{%1, %d0|%d0, %1}";
3030 /* Handle broken assemblers that require movd instead of movq. */
3031 return "%vmovd\t{%1, %0|%0, %1}";
3038 (cond [(eq_attr "alternative" "0,1,2")
3039 (const_string "fmov")
3040 (eq_attr "alternative" "3,4,5")
3041 (const_string "imov")
3042 (eq_attr "alternative" "6")
3043 (const_string "multi")
3044 (eq_attr "alternative" "7")
3045 (const_string "sselog1")
3047 (const_string "ssemov")))
3050 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3052 (const_string "*")))
3053 (set (attr "length_immediate")
3055 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3057 (const_string "*")))
3058 (set (attr "prefix")
3059 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3060 (const_string "orig")
3061 (const_string "maybe_vex")))
3062 (set (attr "prefix_data16")
3063 (if_then_else (eq_attr "mode" "V1DF")
3065 (const_string "*")))
3067 (cond [(eq_attr "alternative" "0,1,2")
3069 (eq_attr "alternative" "3,4,5,6,11,12")
3072 /* xorps is one byte shorter. */
3073 (eq_attr "alternative" "7")
3074 (cond [(match_test "optimize_function_for_size_p (cfun)")
3075 (const_string "V4SF")
3076 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3079 (const_string "V2DF"))
3081 /* For architectures resolving dependencies on
3082 whole SSE registers use APD move to break dependency
3083 chains, otherwise use short move to avoid extra work.
3085 movaps encodes one byte shorter. */
3086 (eq_attr "alternative" "8")
3088 [(match_test "optimize_function_for_size_p (cfun)")
3089 (const_string "V4SF")
3090 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3091 (const_string "V2DF")
3093 (const_string "DF"))
3094 /* For architectures resolving dependencies on register
3095 parts we may avoid extra work to zero out upper part
3097 (eq_attr "alternative" "9")
3099 (match_test "TARGET_SSE_SPLIT_REGS")
3100 (const_string "V1DF")
3101 (const_string "DF"))
3103 (const_string "DF")))])
3105 ;; Possible store forwarding (partial memory) stall in alternative 4.
3106 (define_insn "*movdf_internal"
3107 [(set (match_operand:DF 0 "nonimmediate_operand"
3108 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3109 (match_operand:DF 1 "general_operand"
3110 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3111 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3112 && (!can_create_pseudo_p ()
3113 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3114 || GET_CODE (operands[1]) != CONST_DOUBLE
3115 || (optimize_function_for_size_p (cfun)
3116 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3117 && standard_80387_constant_p (operands[1]) > 0)
3118 || (TARGET_SSE2 && TARGET_SSE_MATH
3119 && standard_sse_constant_p (operands[1])))
3120 && !memory_operand (operands[0], DFmode))
3121 || (!TARGET_MEMORY_MISMATCH_STALL
3122 && memory_operand (operands[0], DFmode)))"
3124 switch (which_alternative)
3128 return output_387_reg_move (insn, operands);
3131 return standard_80387_constant_opcode (operands[1]);
3139 return standard_sse_constant_opcode (insn, operands[1]);
3147 switch (get_attr_mode (insn))
3150 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3151 return "%vmovapd\t{%1, %0|%0, %1}";
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3156 return "%vmovq\t{%1, %0|%0, %1}";
3158 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3159 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3160 return "%vmovsd\t{%1, %0|%0, %1}";
3162 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3164 return "%vmovlps\t{%1, %d0|%d0, %1}";
3174 (if_then_else (eq_attr "alternative" "5,6,7,8")
3175 (const_string "sse2")
3176 (const_string "*")))
3178 (cond [(eq_attr "alternative" "0,1,2")
3179 (const_string "fmov")
3180 (eq_attr "alternative" "3,4")
3181 (const_string "multi")
3182 (eq_attr "alternative" "5,9")
3183 (const_string "sselog1")
3185 (const_string "ssemov")))
3186 (set (attr "prefix")
3187 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188 (const_string "orig")
3189 (const_string "maybe_vex")))
3190 (set (attr "prefix_data16")
3191 (if_then_else (eq_attr "mode" "V1DF")
3193 (const_string "*")))
3195 (cond [(eq_attr "alternative" "0,1,2")
3197 (eq_attr "alternative" "3,4")
3200 /* For SSE1, we have many fewer alternatives. */
3201 (not (match_test "TARGET_SSE2"))
3203 (eq_attr "alternative" "5,6,9,10")
3204 (const_string "V4SF")
3205 (const_string "V2SF"))
3207 /* xorps is one byte shorter. */
3208 (eq_attr "alternative" "5,9")
3209 (cond [(match_test "optimize_function_for_size_p (cfun)")
3210 (const_string "V4SF")
3211 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3214 (const_string "V2DF"))
3216 /* For architectures resolving dependencies on
3217 whole SSE registers use APD move to break dependency
3218 chains, otherwise use short move to avoid extra work.
3220 movaps encodes one byte shorter. */
3221 (eq_attr "alternative" "6,10")
3223 [(match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3226 (const_string "V2DF")
3228 (const_string "DF"))
3229 /* For architectures resolving dependencies on register
3230 parts we may avoid extra work to zero out upper part
3232 (eq_attr "alternative" "7,11")
3234 (match_test "TARGET_SSE_SPLIT_REGS")
3235 (const_string "V1DF")
3236 (const_string "DF"))
3238 (const_string "DF")))])
3240 (define_insn "*movsf_internal"
3241 [(set (match_operand:SF 0 "nonimmediate_operand"
3242 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3243 (match_operand:SF 1 "general_operand"
3244 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3246 && (!can_create_pseudo_p ()
3247 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3248 || GET_CODE (operands[1]) != CONST_DOUBLE
3249 || (optimize_function_for_size_p (cfun)
3250 && ((!TARGET_SSE_MATH
3251 && standard_80387_constant_p (operands[1]) > 0)
3253 && standard_sse_constant_p (operands[1]))))
3254 || memory_operand (operands[0], SFmode))"
3256 switch (which_alternative)
3260 return output_387_reg_move (insn, operands);
3263 return standard_80387_constant_opcode (operands[1]);
3267 return "mov{l}\t{%1, %0|%0, %1}";
3270 return standard_sse_constant_opcode (insn, operands[1]);
3273 if (get_attr_mode (insn) == MODE_V4SF)
3274 return "%vmovaps\t{%1, %0|%0, %1}";
3276 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3280 return "%vmovss\t{%1, %0|%0, %1}";
3286 return "movd\t{%1, %0|%0, %1}";
3289 return "movq\t{%1, %0|%0, %1}";
3293 return "%vmovd\t{%1, %0|%0, %1}";
3300 (cond [(eq_attr "alternative" "0,1,2")
3301 (const_string "fmov")
3302 (eq_attr "alternative" "3,4")
3303 (const_string "multi")
3304 (eq_attr "alternative" "5")
3305 (const_string "sselog1")
3306 (eq_attr "alternative" "9,10,11,14,15")
3307 (const_string "mmxmov")
3309 (const_string "ssemov")))
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3312 (const_string "maybe_vex")
3313 (const_string "orig")))
3315 (cond [(eq_attr "alternative" "3,4,9,10")
3317 (eq_attr "alternative" "5")
3319 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3320 (match_test "TARGET_SSE2"))
3321 (not (match_test "optimize_function_for_size_p (cfun)")))
3323 (const_string "V4SF"))
3324 /* For architectures resolving dependencies on
3325 whole SSE registers use APS move to break dependency
3326 chains, otherwise use short move to avoid extra work.
3328 Do the same for architectures resolving dependencies on
3329 the parts. While in DF mode it is better to always handle
3330 just register parts, the SF mode is different due to lack
3331 of instructions to load just part of the register. It is
3332 better to maintain the whole registers in single format
3333 to avoid problems on using packed logical operations. */
3334 (eq_attr "alternative" "6")
3336 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3337 (match_test "TARGET_SSE_SPLIT_REGS"))
3338 (const_string "V4SF")
3339 (const_string "SF"))
3340 (eq_attr "alternative" "11")
3341 (const_string "DI")]
3342 (const_string "SF")))])
3345 [(set (match_operand 0 "any_fp_register_operand" "")
3346 (match_operand 1 "memory_operand" ""))]
3348 && (GET_MODE (operands[0]) == TFmode
3349 || GET_MODE (operands[0]) == XFmode
3350 || GET_MODE (operands[0]) == DFmode
3351 || GET_MODE (operands[0]) == SFmode)
3352 && (operands[2] = find_constant_src (insn))"
3353 [(set (match_dup 0) (match_dup 2))]
3355 rtx c = operands[2];
3356 int r = REGNO (operands[0]);
3358 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3359 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3364 [(set (match_operand 0 "any_fp_register_operand" "")
3365 (float_extend (match_operand 1 "memory_operand" "")))]
3367 && (GET_MODE (operands[0]) == TFmode
3368 || GET_MODE (operands[0]) == XFmode
3369 || GET_MODE (operands[0]) == DFmode)
3370 && (operands[2] = find_constant_src (insn))"
3371 [(set (match_dup 0) (match_dup 2))]
3373 rtx c = operands[2];
3374 int r = REGNO (operands[0]);
3376 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3377 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3381 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3383 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3384 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3386 && (standard_80387_constant_p (operands[1]) == 8
3387 || standard_80387_constant_p (operands[1]) == 9)"
3388 [(set (match_dup 0)(match_dup 1))
3390 (neg:X87MODEF (match_dup 0)))]
3394 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3395 if (real_isnegzero (&r))
3396 operands[1] = CONST0_RTX (<MODE>mode);
3398 operands[1] = CONST1_RTX (<MODE>mode);
3402 [(set (match_operand 0 "nonimmediate_operand" "")
3403 (match_operand 1 "general_operand" ""))]
3405 && (GET_MODE (operands[0]) == TFmode
3406 || GET_MODE (operands[0]) == XFmode
3407 || GET_MODE (operands[0]) == DFmode)
3408 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3410 "ix86_split_long_move (operands); DONE;")
3412 (define_insn "swapxf"
3413 [(set (match_operand:XF 0 "register_operand" "+f")
3414 (match_operand:XF 1 "register_operand" "+f"))
3419 if (STACK_TOP_P (operands[0]))
3424 [(set_attr "type" "fxch")
3425 (set_attr "mode" "XF")])
3427 (define_insn "*swap<mode>"
3428 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3429 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3432 "TARGET_80387 || reload_completed"
3434 if (STACK_TOP_P (operands[0]))
3439 [(set_attr "type" "fxch")
3440 (set_attr "mode" "<MODE>")])
3442 ;; Zero extension instructions
3444 (define_expand "zero_extendsidi2"
3445 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3446 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3451 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3456 (define_insn "*zero_extendsidi2_rex64"
3457 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3459 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3462 mov\t{%k1, %k0|%k0, %k1}
3464 movd\t{%1, %0|%0, %1}
3465 movd\t{%1, %0|%0, %1}
3466 %vmovd\t{%1, %0|%0, %1}
3467 %vmovd\t{%1, %0|%0, %1}"
3468 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3469 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3470 (set_attr "prefix_0f" "0,*,*,*,*,*")
3471 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3474 [(set (match_operand:DI 0 "memory_operand" "")
3475 (zero_extend:DI (match_dup 0)))]
3477 [(set (match_dup 4) (const_int 0))]
3478 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3480 ;; %%% Kill me once multi-word ops are sane.
3481 (define_insn "zero_extendsidi2_1"
3482 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3484 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3485 (clobber (reg:CC FLAGS_REG))]
3491 movd\t{%1, %0|%0, %1}
3492 movd\t{%1, %0|%0, %1}
3493 %vmovd\t{%1, %0|%0, %1}
3494 %vmovd\t{%1, %0|%0, %1}"
3495 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3496 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3497 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3498 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3501 [(set (match_operand:DI 0 "register_operand" "")
3502 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3503 (clobber (reg:CC FLAGS_REG))]
3504 "!TARGET_64BIT && reload_completed
3505 && true_regnum (operands[0]) == true_regnum (operands[1])"
3506 [(set (match_dup 4) (const_int 0))]
3507 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3510 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3511 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "!TARGET_64BIT && reload_completed
3514 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3515 [(set (match_dup 3) (match_dup 1))
3516 (set (match_dup 4) (const_int 0))]
3517 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3519 (define_insn "zero_extend<mode>di2"
3520 [(set (match_operand:DI 0 "register_operand" "=r")
3522 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3524 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3525 [(set_attr "type" "imovx")
3526 (set_attr "mode" "SI")])
3528 (define_expand "zero_extendhisi2"
3529 [(set (match_operand:SI 0 "register_operand" "")
3530 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3533 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3535 operands[1] = force_reg (HImode, operands[1]);
3536 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3541 (define_insn_and_split "zero_extendhisi2_and"
3542 [(set (match_operand:SI 0 "register_operand" "=r")
3543 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3544 (clobber (reg:CC FLAGS_REG))]
3545 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3547 "&& reload_completed"
3548 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3549 (clobber (reg:CC FLAGS_REG))])]
3551 [(set_attr "type" "alu1")
3552 (set_attr "mode" "SI")])
3554 (define_insn "*zero_extendhisi2_movzwl"
3555 [(set (match_operand:SI 0 "register_operand" "=r")
3556 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3557 "!TARGET_ZERO_EXTEND_WITH_AND
3558 || optimize_function_for_size_p (cfun)"
3559 "movz{wl|x}\t{%1, %0|%0, %1}"
3560 [(set_attr "type" "imovx")
3561 (set_attr "mode" "SI")])
3563 (define_expand "zero_extendqi<mode>2"
3565 [(set (match_operand:SWI24 0 "register_operand" "")
3566 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3567 (clobber (reg:CC FLAGS_REG))])])
3569 (define_insn "*zero_extendqi<mode>2_and"
3570 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3572 (clobber (reg:CC FLAGS_REG))]
3573 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3575 [(set_attr "type" "alu1")
3576 (set_attr "mode" "<MODE>")])
3578 ;; When source and destination does not overlap, clear destination
3579 ;; first and then do the movb
3581 [(set (match_operand:SWI24 0 "register_operand" "")
3582 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3583 (clobber (reg:CC FLAGS_REG))]
3585 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3586 && ANY_QI_REG_P (operands[0])
3587 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3588 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3589 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3591 operands[2] = gen_lowpart (QImode, operands[0]);
3592 ix86_expand_clear (operands[0]);
3595 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3596 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3597 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3598 (clobber (reg:CC FLAGS_REG))]
3599 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3601 [(set_attr "type" "imovx,alu1")
3602 (set_attr "mode" "<MODE>")])
3604 ;; For the movzbl case strip only the clobber
3606 [(set (match_operand:SWI24 0 "register_operand" "")
3607 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))]
3610 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3611 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3613 (zero_extend:SWI24 (match_dup 1)))])
3615 ; zero extend to SImode to avoid partial register stalls
3616 (define_insn "*zero_extendqi<mode>2_movzbl"
3617 [(set (match_operand:SWI24 0 "register_operand" "=r")
3618 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3620 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3621 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3622 [(set_attr "type" "imovx")
3623 (set_attr "mode" "SI")])
3625 ;; Rest is handled by single and.
3627 [(set (match_operand:SWI24 0 "register_operand" "")
3628 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3629 (clobber (reg:CC FLAGS_REG))]
3631 && true_regnum (operands[0]) == true_regnum (operands[1])"
3632 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3633 (clobber (reg:CC FLAGS_REG))])])
3635 ;; Sign extension instructions
3637 (define_expand "extendsidi2"
3638 [(set (match_operand:DI 0 "register_operand" "")
3639 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3644 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3649 (define_insn "*extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3651 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3655 movs{lq|x}\t{%1, %0|%0, %1}"
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "DI")
3658 (set_attr "prefix_0f" "0")
3659 (set_attr "modrm" "0,1")])
3661 (define_insn "extendsidi2_1"
3662 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3663 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3664 (clobber (reg:CC FLAGS_REG))
3665 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3669 ;; Extend to memory case when source register does die.
3671 [(set (match_operand:DI 0 "memory_operand" "")
3672 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3673 (clobber (reg:CC FLAGS_REG))
3674 (clobber (match_operand:SI 2 "register_operand" ""))]
3676 && dead_or_set_p (insn, operands[1])
3677 && !reg_mentioned_p (operands[1], operands[0]))"
3678 [(set (match_dup 3) (match_dup 1))
3679 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3680 (clobber (reg:CC FLAGS_REG))])
3681 (set (match_dup 4) (match_dup 1))]
3682 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3684 ;; Extend to memory case when source register does not die.
3686 [(set (match_operand:DI 0 "memory_operand" "")
3687 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3688 (clobber (reg:CC FLAGS_REG))
3689 (clobber (match_operand:SI 2 "register_operand" ""))]
3693 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3695 emit_move_insn (operands[3], operands[1]);
3697 /* Generate a cltd if possible and doing so it profitable. */
3698 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3699 && true_regnum (operands[1]) == AX_REG
3700 && true_regnum (operands[2]) == DX_REG)
3702 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3706 emit_move_insn (operands[2], operands[1]);
3707 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3709 emit_move_insn (operands[4], operands[2]);
3713 ;; Extend to register case. Optimize case where source and destination
3714 ;; registers match and cases where we can use cltd.
3716 [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC FLAGS_REG))
3719 (clobber (match_scratch:SI 2 ""))]
3723 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3725 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3726 emit_move_insn (operands[3], operands[1]);
3728 /* Generate a cltd if possible and doing so it profitable. */
3729 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3730 && true_regnum (operands[3]) == AX_REG
3731 && true_regnum (operands[4]) == DX_REG)
3733 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3737 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3738 emit_move_insn (operands[4], operands[1]);
3740 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3744 (define_insn "extend<mode>di2"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3749 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "DI")])
3753 (define_insn "extendhisi2"
3754 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3755 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3758 switch (get_attr_prefix_0f (insn))
3761 return "{cwtl|cwde}";
3763 return "movs{wl|x}\t{%1, %0|%0, %1}";
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "SI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3773 (const_string "1")))
3775 (if_then_else (eq_attr "prefix_0f" "0")
3777 (const_string "1")))])
3779 (define_insn "*extendhisi2_zext"
3780 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3783 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3786 switch (get_attr_prefix_0f (insn))
3789 return "{cwtl|cwde}";
3791 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")
3796 (set (attr "prefix_0f")
3797 ;; movsx is short decodable while cwtl is vector decoded.
3798 (if_then_else (and (eq_attr "cpu" "!k6")
3799 (eq_attr "alternative" "0"))
3801 (const_string "1")))
3803 (if_then_else (eq_attr "prefix_0f" "0")
3805 (const_string "1")))])
3807 (define_insn "extendqisi2"
3808 [(set (match_operand:SI 0 "register_operand" "=r")
3809 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811 "movs{bl|x}\t{%1, %0|%0, %1}"
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")])
3815 (define_insn "*extendqisi2_zext"
3816 [(set (match_operand:DI 0 "register_operand" "=r")
3818 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3820 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3821 [(set_attr "type" "imovx")
3822 (set_attr "mode" "SI")])
3824 (define_insn "extendqihi2"
3825 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3826 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3829 switch (get_attr_prefix_0f (insn))
3832 return "{cbtw|cbw}";
3834 return "movs{bw|x}\t{%1, %0|%0, %1}";
3837 [(set_attr "type" "imovx")
3838 (set_attr "mode" "HI")
3839 (set (attr "prefix_0f")
3840 ;; movsx is short decodable while cwtl is vector decoded.
3841 (if_then_else (and (eq_attr "cpu" "!k6")
3842 (eq_attr "alternative" "0"))
3844 (const_string "1")))
3846 (if_then_else (eq_attr "prefix_0f" "0")
3848 (const_string "1")))])
3850 ;; Conversions between float and double.
3852 ;; These are all no-ops in the model used for the 80387.
3853 ;; So just emit moves.
3855 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3857 [(set (match_operand:DF 0 "push_operand" "")
3858 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3860 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3861 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3864 [(set (match_operand:XF 0 "push_operand" "")
3865 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3867 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3868 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3869 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3871 (define_expand "extendsfdf2"
3872 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3873 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3874 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3876 /* ??? Needed for compress_float_constant since all fp constants
3877 are TARGET_LEGITIMATE_CONSTANT_P. */
3878 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3880 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3881 && standard_80387_constant_p (operands[1]) > 0)
3883 operands[1] = simplify_const_unary_operation
3884 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3885 emit_move_insn_1 (operands[0], operands[1]);
3888 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3892 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3894 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3896 We do the conversion post reload to avoid producing of 128bit spills
3897 that might lead to ICE on 32bit target. The sequence unlikely combine
3900 [(set (match_operand:DF 0 "register_operand" "")
3902 (match_operand:SF 1 "nonimmediate_operand" "")))]
3903 "TARGET_USE_VECTOR_FP_CONVERTS
3904 && optimize_insn_for_speed_p ()
3905 && reload_completed && SSE_REG_P (operands[0])"
3910 (parallel [(const_int 0) (const_int 1)]))))]
3912 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3913 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3914 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3915 Try to avoid move when unpacking can be done in source. */
3916 if (REG_P (operands[1]))
3918 /* If it is unsafe to overwrite upper half of source, we need
3919 to move to destination and unpack there. */
3920 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3921 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3922 && true_regnum (operands[0]) != true_regnum (operands[1]))
3924 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3925 emit_move_insn (tmp, operands[1]);
3928 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3929 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3933 emit_insn (gen_vec_setv4sf_0 (operands[3],
3934 CONST0_RTX (V4SFmode), operands[1]));
3937 (define_insn "*extendsfdf2_mixed"
3938 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3940 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3941 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3943 switch (which_alternative)
3947 return output_387_reg_move (insn, operands);
3950 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3956 [(set_attr "type" "fmov,fmov,ssecvt")
3957 (set_attr "prefix" "orig,orig,maybe_vex")
3958 (set_attr "mode" "SF,XF,DF")])
3960 (define_insn "*extendsfdf2_sse"
3961 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3962 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3963 "TARGET_SSE2 && TARGET_SSE_MATH"
3964 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3965 [(set_attr "type" "ssecvt")
3966 (set_attr "prefix" "maybe_vex")
3967 (set_attr "mode" "DF")])
3969 (define_insn "*extendsfdf2_i387"
3970 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3971 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3973 "* return output_387_reg_move (insn, operands);"
3974 [(set_attr "type" "fmov")
3975 (set_attr "mode" "SF,XF")])
3977 (define_expand "extend<mode>xf2"
3978 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3979 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3982 /* ??? Needed for compress_float_constant since all fp constants
3983 are TARGET_LEGITIMATE_CONSTANT_P. */
3984 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3986 if (standard_80387_constant_p (operands[1]) > 0)
3988 operands[1] = simplify_const_unary_operation
3989 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3990 emit_move_insn_1 (operands[0], operands[1]);
3993 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3997 (define_insn "*extend<mode>xf2_i387"
3998 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4000 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4002 "* return output_387_reg_move (insn, operands);"
4003 [(set_attr "type" "fmov")
4004 (set_attr "mode" "<MODE>,XF")])
4006 ;; %%% This seems bad bad news.
4007 ;; This cannot output into an f-reg because there is no way to be sure
4008 ;; of truncating in that case. Otherwise this is just like a simple move
4009 ;; insn. So we pretend we can output to a reg in order to get better
4010 ;; register preferencing, but we really use a stack slot.
4012 ;; Conversion from DFmode to SFmode.
4014 (define_expand "truncdfsf2"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4017 (match_operand:DF 1 "nonimmediate_operand" "")))]
4018 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4020 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4022 else if (flag_unsafe_math_optimizations)
4026 enum ix86_stack_slot slot = (virtuals_instantiated
4029 rtx temp = assign_386_stack_local (SFmode, slot);
4030 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4035 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4037 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4039 We do the conversion post reload to avoid producing of 128bit spills
4040 that might lead to ICE on 32bit target. The sequence unlikely combine
4043 [(set (match_operand:SF 0 "register_operand" "")
4045 (match_operand:DF 1 "nonimmediate_operand" "")))]
4046 "TARGET_USE_VECTOR_FP_CONVERTS
4047 && optimize_insn_for_speed_p ()
4048 && reload_completed && SSE_REG_P (operands[0])"
4051 (float_truncate:V2SF
4055 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4056 operands[3] = CONST0_RTX (V2SFmode);
4057 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4058 /* Use movsd for loading from memory, unpcklpd for registers.
4059 Try to avoid move when unpacking can be done in source, or SSE3
4060 movddup is available. */
4061 if (REG_P (operands[1]))
4064 && true_regnum (operands[0]) != true_regnum (operands[1])
4065 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4066 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4068 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4069 emit_move_insn (tmp, operands[1]);
4072 else if (!TARGET_SSE3)
4073 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4074 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4077 emit_insn (gen_sse2_loadlpd (operands[4],
4078 CONST0_RTX (V2DFmode), operands[1]));
4081 (define_expand "truncdfsf2_with_temp"
4082 [(parallel [(set (match_operand:SF 0 "" "")
4083 (float_truncate:SF (match_operand:DF 1 "" "")))
4084 (clobber (match_operand:SF 2 "" ""))])])
4086 (define_insn "*truncdfsf_fast_mixed"
4087 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4089 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4090 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4092 switch (which_alternative)
4095 return output_387_reg_move (insn, operands);
4097 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4102 [(set_attr "type" "fmov,ssecvt")
4103 (set_attr "prefix" "orig,maybe_vex")
4104 (set_attr "mode" "SF")])
4106 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4107 ;; because nothing we do here is unsafe.
4108 (define_insn "*truncdfsf_fast_sse"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4111 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4112 "TARGET_SSE2 && TARGET_SSE_MATH"
4113 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4114 [(set_attr "type" "ssecvt")
4115 (set_attr "prefix" "maybe_vex")
4116 (set_attr "mode" "SF")])
4118 (define_insn "*truncdfsf_fast_i387"
4119 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4121 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4122 "TARGET_80387 && flag_unsafe_math_optimizations"
4123 "* return output_387_reg_move (insn, operands);"
4124 [(set_attr "type" "fmov")
4125 (set_attr "mode" "SF")])
4127 (define_insn "*truncdfsf_mixed"
4128 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4130 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4131 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4132 "TARGET_MIX_SSE_I387"
4134 switch (which_alternative)
4137 return output_387_reg_move (insn, operands);
4139 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4145 [(set_attr "isa" "*,sse2,*,*,*")
4146 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4147 (set_attr "unit" "*,*,i387,i387,i387")
4148 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4149 (set_attr "mode" "SF")])
4151 (define_insn "*truncdfsf_i387"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4154 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4155 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4158 switch (which_alternative)
4161 return output_387_reg_move (insn, operands);
4167 [(set_attr "type" "fmov,multi,multi,multi")
4168 (set_attr "unit" "*,i387,i387,i387")
4169 (set_attr "mode" "SF")])
4171 (define_insn "*truncdfsf2_i387_1"
4172 [(set (match_operand:SF 0 "memory_operand" "=m")
4174 (match_operand:DF 1 "register_operand" "f")))]
4176 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4177 && !TARGET_MIX_SSE_I387"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "SF")])
4183 [(set (match_operand:SF 0 "register_operand" "")
4185 (match_operand:DF 1 "fp_register_operand" "")))
4186 (clobber (match_operand 2 "" ""))]
4188 [(set (match_dup 2) (match_dup 1))
4189 (set (match_dup 0) (match_dup 2))]
4190 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4192 ;; Conversion from XFmode to {SF,DF}mode
4194 (define_expand "truncxf<mode>2"
4195 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_dup 2))])]
4201 if (flag_unsafe_math_optimizations)
4203 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4204 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4205 if (reg != operands[0])
4206 emit_move_insn (operands[0], reg);
4211 enum ix86_stack_slot slot = (virtuals_instantiated
4214 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4218 (define_insn "*truncxfsf2_mixed"
4219 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4221 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4222 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4225 gcc_assert (!which_alternative);
4226 return output_387_reg_move (insn, operands);
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "unit" "*,i387,i387,i387")
4230 (set_attr "mode" "SF")])
4232 (define_insn "*truncxfdf2_mixed"
4233 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4235 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4236 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4239 gcc_assert (!which_alternative);
4240 return output_387_reg_move (insn, operands);
4242 [(set_attr "isa" "*,*,sse2,*")
4243 (set_attr "type" "fmov,multi,multi,multi")
4244 (set_attr "unit" "*,i387,i387,i387")
4245 (set_attr "mode" "DF")])
4247 (define_insn "truncxf<mode>2_i387_noop"
4248 [(set (match_operand:MODEF 0 "register_operand" "=f")
4249 (float_truncate:MODEF
4250 (match_operand:XF 1 "register_operand" "f")))]
4251 "TARGET_80387 && flag_unsafe_math_optimizations"
4252 "* return output_387_reg_move (insn, operands);"
4253 [(set_attr "type" "fmov")
4254 (set_attr "mode" "<MODE>")])
4256 (define_insn "*truncxf<mode>2_i387"
4257 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4258 (float_truncate:MODEF
4259 (match_operand:XF 1 "register_operand" "f")))]
4261 "* return output_387_reg_move (insn, operands);"
4262 [(set_attr "type" "fmov")
4263 (set_attr "mode" "<MODE>")])
4266 [(set (match_operand:MODEF 0 "register_operand" "")
4267 (float_truncate:MODEF
4268 (match_operand:XF 1 "register_operand" "")))
4269 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4270 "TARGET_80387 && reload_completed"
4271 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4272 (set (match_dup 0) (match_dup 2))])
4275 [(set (match_operand:MODEF 0 "memory_operand" "")
4276 (float_truncate:MODEF
4277 (match_operand:XF 1 "register_operand" "")))
4278 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4280 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4282 ;; Signed conversion to DImode.
4284 (define_expand "fix_truncxfdi2"
4285 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4286 (fix:DI (match_operand:XF 1 "register_operand" "")))
4287 (clobber (reg:CC FLAGS_REG))])]
4292 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4297 (define_expand "fix_trunc<mode>di2"
4298 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4299 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4300 (clobber (reg:CC FLAGS_REG))])]
4301 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4304 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4306 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4309 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4311 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4312 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4313 if (out != operands[0])
4314 emit_move_insn (operands[0], out);
4319 ;; Signed conversion to SImode.
4321 (define_expand "fix_truncxfsi2"
4322 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4323 (fix:SI (match_operand:XF 1 "register_operand" "")))
4324 (clobber (reg:CC FLAGS_REG))])]
4329 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4334 (define_expand "fix_trunc<mode>si2"
4335 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4336 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4337 (clobber (reg:CC FLAGS_REG))])]
4338 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4341 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4343 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4346 if (SSE_FLOAT_MODE_P (<MODE>mode))
4348 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4349 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4350 if (out != operands[0])
4351 emit_move_insn (operands[0], out);
4356 ;; Signed conversion to HImode.
4358 (define_expand "fix_trunc<mode>hi2"
4359 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4360 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4361 (clobber (reg:CC FLAGS_REG))])]
4363 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4367 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4372 ;; Unsigned conversion to SImode.
4374 (define_expand "fixuns_trunc<mode>si2"
4376 [(set (match_operand:SI 0 "register_operand" "")
4378 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4380 (clobber (match_scratch:<ssevecmode> 3 ""))
4381 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4382 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4384 enum machine_mode mode = <MODE>mode;
4385 enum machine_mode vecmode = <ssevecmode>mode;
4386 REAL_VALUE_TYPE TWO31r;
4389 if (optimize_insn_for_size_p ())
4392 real_ldexp (&TWO31r, &dconst1, 31);
4393 two31 = const_double_from_real_value (TWO31r, mode);
4394 two31 = ix86_build_const_vector (vecmode, true, two31);
4395 operands[2] = force_reg (vecmode, two31);
4398 (define_insn_and_split "*fixuns_trunc<mode>_1"
4399 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4401 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4402 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4403 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4404 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4405 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4406 && optimize_function_for_speed_p (cfun)"
4408 "&& reload_completed"
4411 ix86_split_convert_uns_si_sse (operands);
4415 ;; Unsigned conversion to HImode.
4416 ;; Without these patterns, we'll try the unsigned SI conversion which
4417 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4419 (define_expand "fixuns_trunc<mode>hi2"
4421 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4422 (set (match_operand:HI 0 "nonimmediate_operand" "")
4423 (subreg:HI (match_dup 2) 0))]
4424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4425 "operands[2] = gen_reg_rtx (SImode);")
4427 ;; When SSE is available, it is always faster to use it!
4428 (define_insn "fix_trunc<mode>di_sse"
4429 [(set (match_operand:DI 0 "register_operand" "=r,r")
4430 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4431 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4432 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4433 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4434 [(set_attr "type" "sseicvt")
4435 (set_attr "prefix" "maybe_vex")
4436 (set_attr "prefix_rex" "1")
4437 (set_attr "mode" "<MODE>")
4438 (set_attr "athlon_decode" "double,vector")
4439 (set_attr "amdfam10_decode" "double,double")
4440 (set_attr "bdver1_decode" "double,double")])
4442 (define_insn "fix_trunc<mode>si_sse"
4443 [(set (match_operand:SI 0 "register_operand" "=r,r")
4444 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4445 "SSE_FLOAT_MODE_P (<MODE>mode)
4446 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4447 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4448 [(set_attr "type" "sseicvt")
4449 (set_attr "prefix" "maybe_vex")
4450 (set_attr "mode" "<MODE>")
4451 (set_attr "athlon_decode" "double,vector")
4452 (set_attr "amdfam10_decode" "double,double")
4453 (set_attr "bdver1_decode" "double,double")])
4455 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4457 [(set (match_operand:MODEF 0 "register_operand" "")
4458 (match_operand:MODEF 1 "memory_operand" ""))
4459 (set (match_operand:SWI48x 2 "register_operand" "")
4460 (fix:SWI48x (match_dup 0)))]
4461 "TARGET_SHORTEN_X87_SSE
4462 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4463 && peep2_reg_dead_p (2, operands[0])"
4464 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4466 ;; Avoid vector decoded forms of the instruction.
4468 [(match_scratch:DF 2 "x")
4469 (set (match_operand:SWI48x 0 "register_operand" "")
4470 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4471 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4472 [(set (match_dup 2) (match_dup 1))
4473 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4476 [(match_scratch:SF 2 "x")
4477 (set (match_operand:SWI48x 0 "register_operand" "")
4478 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4479 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4480 [(set (match_dup 2) (match_dup 1))
4481 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4483 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4484 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4485 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4486 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4489 && (TARGET_64BIT || <MODE>mode != DImode))
4491 && can_create_pseudo_p ()"
4496 if (memory_operand (operands[0], VOIDmode))
4497 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4500 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4507 [(set_attr "type" "fisttp")
4508 (set_attr "mode" "<MODE>")])
4510 (define_insn "fix_trunc<mode>_i387_fisttp"
4511 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4512 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4513 (clobber (match_scratch:XF 2 "=&1f"))]
4514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && (TARGET_64BIT || <MODE>mode != DImode))
4518 && TARGET_SSE_MATH)"
4519 "* return output_fix_trunc (insn, operands, true);"
4520 [(set_attr "type" "fisttp")
4521 (set_attr "mode" "<MODE>")])
4523 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4524 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4525 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4526 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4527 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && (TARGET_64BIT || <MODE>mode != DImode))
4532 && TARGET_SSE_MATH)"
4534 [(set_attr "type" "fisttp")
4535 (set_attr "mode" "<MODE>")])
4538 [(set (match_operand:SWI248x 0 "register_operand" "")
4539 (fix:SWI248x (match_operand 1 "register_operand" "")))
4540 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4541 (clobber (match_scratch 3 ""))]
4543 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4544 (clobber (match_dup 3))])
4545 (set (match_dup 0) (match_dup 2))])
4548 [(set (match_operand:SWI248x 0 "memory_operand" "")
4549 (fix:SWI248x (match_operand 1 "register_operand" "")))
4550 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4551 (clobber (match_scratch 3 ""))]
4553 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4554 (clobber (match_dup 3))])])
4556 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4557 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4558 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4559 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4560 ;; function in i386.c.
4561 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4562 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4563 (fix:SWI248x (match_operand 1 "register_operand" "")))
4564 (clobber (reg:CC FLAGS_REG))]
4565 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4567 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && (TARGET_64BIT || <MODE>mode != DImode))
4569 && can_create_pseudo_p ()"
4574 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4576 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4577 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4578 if (memory_operand (operands[0], VOIDmode))
4579 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4580 operands[2], operands[3]));
4583 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4584 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4585 operands[2], operands[3],
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4594 (define_insn "fix_truncdi_i387"
4595 [(set (match_operand:DI 0 "memory_operand" "=m")
4596 (fix:DI (match_operand 1 "register_operand" "f")))
4597 (use (match_operand:HI 2 "memory_operand" "m"))
4598 (use (match_operand:HI 3 "memory_operand" "m"))
4599 (clobber (match_scratch:XF 4 "=&1f"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4603 "* return output_fix_trunc (insn, operands, false);"
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "DI")])
4608 (define_insn "fix_truncdi_i387_with_temp"
4609 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4610 (fix:DI (match_operand 1 "register_operand" "f,f")))
4611 (use (match_operand:HI 2 "memory_operand" "m,m"))
4612 (use (match_operand:HI 3 "memory_operand" "m,m"))
4613 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4614 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4619 [(set_attr "type" "fistp")
4620 (set_attr "i387_cw" "trunc")
4621 (set_attr "mode" "DI")])
4624 [(set (match_operand:DI 0 "register_operand" "")
4625 (fix:DI (match_operand 1 "register_operand" "")))
4626 (use (match_operand:HI 2 "memory_operand" ""))
4627 (use (match_operand:HI 3 "memory_operand" ""))
4628 (clobber (match_operand:DI 4 "memory_operand" ""))
4629 (clobber (match_scratch 5 ""))]
4631 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4634 (clobber (match_dup 5))])
4635 (set (match_dup 0) (match_dup 4))])
4638 [(set (match_operand:DI 0 "memory_operand" "")
4639 (fix:DI (match_operand 1 "register_operand" "")))
4640 (use (match_operand:HI 2 "memory_operand" ""))
4641 (use (match_operand:HI 3 "memory_operand" ""))
4642 (clobber (match_operand:DI 4 "memory_operand" ""))
4643 (clobber (match_scratch 5 ""))]
4645 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4648 (clobber (match_dup 5))])])
4650 (define_insn "fix_trunc<mode>_i387"
4651 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4652 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4653 (use (match_operand:HI 2 "memory_operand" "m"))
4654 (use (match_operand:HI 3 "memory_operand" "m"))]
4655 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4657 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4658 "* return output_fix_trunc (insn, operands, false);"
4659 [(set_attr "type" "fistp")
4660 (set_attr "i387_cw" "trunc")
4661 (set_attr "mode" "<MODE>")])
4663 (define_insn "fix_trunc<mode>_i387_with_temp"
4664 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4665 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4666 (use (match_operand:HI 2 "memory_operand" "m,m"))
4667 (use (match_operand:HI 3 "memory_operand" "m,m"))
4668 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4669 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4671 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4673 [(set_attr "type" "fistp")
4674 (set_attr "i387_cw" "trunc")
4675 (set_attr "mode" "<MODE>")])
4678 [(set (match_operand:SWI24 0 "register_operand" "")
4679 (fix:SWI24 (match_operand 1 "register_operand" "")))
4680 (use (match_operand:HI 2 "memory_operand" ""))
4681 (use (match_operand:HI 3 "memory_operand" ""))
4682 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4684 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4686 (use (match_dup 3))])
4687 (set (match_dup 0) (match_dup 4))])
4690 [(set (match_operand:SWI24 0 "memory_operand" "")
4691 (fix:SWI24 (match_operand 1 "register_operand" "")))
4692 (use (match_operand:HI 2 "memory_operand" ""))
4693 (use (match_operand:HI 3 "memory_operand" ""))
4694 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4696 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4698 (use (match_dup 3))])])
4700 (define_insn "x86_fnstcw_1"
4701 [(set (match_operand:HI 0 "memory_operand" "=m")
4702 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4705 [(set (attr "length")
4706 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4707 (set_attr "mode" "HI")
4708 (set_attr "unit" "i387")
4709 (set_attr "bdver1_decode" "vector")])
4711 (define_insn "x86_fldcw_1"
4712 [(set (reg:HI FPCR_REG)
4713 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4716 [(set (attr "length")
4717 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4718 (set_attr "mode" "HI")
4719 (set_attr "unit" "i387")
4720 (set_attr "athlon_decode" "vector")
4721 (set_attr "amdfam10_decode" "vector")
4722 (set_attr "bdver1_decode" "vector")])
4724 ;; Conversion between fixed point and floating point.
4726 ;; Even though we only accept memory inputs, the backend _really_
4727 ;; wants to be able to do this between registers.
4729 (define_expand "floathi<mode>2"
4730 [(set (match_operand:X87MODEF 0 "register_operand" "")
4731 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4734 || TARGET_MIX_SSE_I387)")
4736 ;; Pre-reload splitter to add memory clobber to the pattern.
4737 (define_insn_and_split "*floathi<mode>2_1"
4738 [(set (match_operand:X87MODEF 0 "register_operand" "")
4739 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4741 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4742 || TARGET_MIX_SSE_I387)
4743 && can_create_pseudo_p ()"
4746 [(parallel [(set (match_dup 0)
4747 (float:X87MODEF (match_dup 1)))
4748 (clobber (match_dup 2))])]
4749 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4751 (define_insn "*floathi<mode>2_i387_with_temp"
4752 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4753 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4754 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4757 || TARGET_MIX_SSE_I387)"
4759 [(set_attr "type" "fmov,multi")
4760 (set_attr "mode" "<MODE>")
4761 (set_attr "unit" "*,i387")
4762 (set_attr "fp_int_src" "true")])
4764 (define_insn "*floathi<mode>2_i387"
4765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4766 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4769 || TARGET_MIX_SSE_I387)"
4771 [(set_attr "type" "fmov")
4772 (set_attr "mode" "<MODE>")
4773 (set_attr "fp_int_src" "true")])
4776 [(set (match_operand:X87MODEF 0 "register_operand" "")
4777 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4778 (clobber (match_operand:HI 2 "memory_operand" ""))]
4780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4781 || TARGET_MIX_SSE_I387)
4782 && reload_completed"
4783 [(set (match_dup 2) (match_dup 1))
4784 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4787 [(set (match_operand:X87MODEF 0 "register_operand" "")
4788 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4789 (clobber (match_operand:HI 2 "memory_operand" ""))]
4791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4792 || TARGET_MIX_SSE_I387)
4793 && reload_completed"
4794 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4796 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4797 [(set (match_operand:X87MODEF 0 "register_operand" "")
4799 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4801 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4802 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4804 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4805 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4806 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4808 rtx reg = gen_reg_rtx (XFmode);
4809 rtx (*insn)(rtx, rtx);
4811 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4813 if (<X87MODEF:MODE>mode == SFmode)
4814 insn = gen_truncxfsf2;
4815 else if (<X87MODEF:MODE>mode == DFmode)
4816 insn = gen_truncxfdf2;
4820 emit_insn (insn (operands[0], reg));
4825 ;; Pre-reload splitter to add memory clobber to the pattern.
4826 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "")
4828 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4830 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4831 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4832 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4833 || TARGET_MIX_SSE_I387))
4834 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4835 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4836 && ((<SWI48x:MODE>mode == SImode
4837 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4838 && optimize_function_for_speed_p (cfun)
4839 && flag_trapping_math)
4840 || !(TARGET_INTER_UNIT_CONVERSIONS
4841 || optimize_function_for_size_p (cfun)))))
4842 && can_create_pseudo_p ()"
4845 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4846 (clobber (match_dup 2))])]
4848 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4850 /* Avoid store forwarding (partial memory) stall penalty
4851 by passing DImode value through XMM registers. */
4852 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4853 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4854 && optimize_function_for_speed_p (cfun))
4856 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4863 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4864 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4866 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4867 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4868 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4869 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4871 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4872 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4873 (set_attr "unit" "*,i387,*,*,*")
4874 (set_attr "athlon_decode" "*,*,double,direct,double")
4875 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4876 (set_attr "bdver1_decode" "*,*,double,direct,double")
4877 (set_attr "fp_int_src" "true")])
4879 (define_insn "*floatsi<mode>2_vector_mixed"
4880 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4881 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4882 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4883 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4887 [(set_attr "type" "fmov,sseicvt")
4888 (set_attr "mode" "<MODE>,<ssevecmode>")
4889 (set_attr "unit" "i387,*")
4890 (set_attr "athlon_decode" "*,direct")
4891 (set_attr "amdfam10_decode" "*,double")
4892 (set_attr "bdver1_decode" "*,direct")
4893 (set_attr "fp_int_src" "true")])
4895 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4896 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4898 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4899 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4900 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4901 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4903 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set_attr "unit" "*,i387,*,*")
4906 (set_attr "athlon_decode" "*,*,double,direct")
4907 (set_attr "amdfam10_decode" "*,*,vector,double")
4908 (set_attr "bdver1_decode" "*,*,double,direct")
4909 (set_attr "fp_int_src" "true")])
4912 [(set (match_operand:MODEF 0 "register_operand" "")
4913 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4914 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4915 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4917 && TARGET_INTER_UNIT_CONVERSIONS
4919 && (SSE_REG_P (operands[0])
4920 || (GET_CODE (operands[0]) == SUBREG
4921 && SSE_REG_P (operands[0])))"
4922 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4925 [(set (match_operand:MODEF 0 "register_operand" "")
4926 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4927 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4928 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4930 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4932 && (SSE_REG_P (operands[0])
4933 || (GET_CODE (operands[0]) == SUBREG
4934 && SSE_REG_P (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_REG_P (operands[0])
5024 || (GET_CODE (operands[0]) == SUBREG
5025 && SSE_REG_P (operands[0])))"
5028 rtx op1 = operands[1];
5030 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5032 if (GET_CODE (op1) == SUBREG)
5033 op1 = SUBREG_REG (op1);
5035 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5037 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5038 emit_insn (gen_sse2_loadld (operands[4],
5039 CONST0_RTX (V4SImode), operands[1]));
5041 /* We can ignore possible trapping value in the
5042 high part of SSE register for non-trapping math. */
5043 else if (SSE_REG_P (op1) && !flag_trapping_math)
5044 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5048 emit_move_insn (operands[2], operands[1]);
5049 emit_insn (gen_sse2_loadld (operands[4],
5050 CONST0_RTX (V4SImode), operands[2]));
5053 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (operands[0])))"
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5076 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5087 || (GET_CODE (operands[0]) == SUBREG
5088 && SSE_REG_P (operands[0])))"
5091 rtx op1 = operands[1];
5093 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5095 if (GET_CODE (op1) == SUBREG)
5096 op1 = SUBREG_REG (op1);
5098 if (GENERAL_REG_P (op1))
5100 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5101 if (TARGET_INTER_UNIT_MOVES)
5102 emit_insn (gen_sse2_loadld (operands[4],
5103 CONST0_RTX (V4SImode), operands[1]));
5106 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5108 emit_insn (gen_sse2_loadld (operands[4],
5109 CONST0_RTX (V4SImode), operands[5]));
5110 ix86_free_from_memory (GET_MODE (operands[1]));
5113 /* We can ignore possible trapping value in the
5114 high part of SSE register for non-trapping math. */
5115 else if (SSE_REG_P (op1) && !flag_trapping_math)
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5120 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5131 || (GET_CODE (operands[0]) == SUBREG
5132 && SSE_REG_P (operands[0])))"
5135 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5137 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5139 emit_insn (gen_sse2_loadld (operands[4],
5140 CONST0_RTX (V4SImode), operands[1]));
5142 (gen_sse2_cvtdq2<ssevecmodesuffix> (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_REG_P (operands[0])
5192 || (GET_CODE (operands[0]) == SUBREG
5193 && SSE_REG_P (operands[0])))"
5194 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5196 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5197 [(set (match_operand:MODEF 0 "register_operand" "=x")
5199 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5201 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5202 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5203 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5204 [(set_attr "type" "sseicvt")
5205 (set_attr "prefix" "maybe_vex")
5206 (set_attr "mode" "<MODEF:MODE>")
5207 (set (attr "prefix_rex")
5209 (and (eq_attr "prefix" "maybe_vex")
5210 (match_test "<SWI48x:MODE>mode == DImode"))
5212 (const_string "*")))
5213 (set_attr "athlon_decode" "direct")
5214 (set_attr "amdfam10_decode" "double")
5215 (set_attr "bdver1_decode" "direct")
5216 (set_attr "fp_int_src" "true")])
5219 [(set (match_operand:MODEF 0 "register_operand" "")
5220 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5221 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5222 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5223 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5224 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5226 && (SSE_REG_P (operands[0])
5227 || (GET_CODE (operands[0]) == SUBREG
5228 && SSE_REG_P (operands[0])))"
5229 [(set (match_dup 2) (match_dup 1))
5230 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5233 [(set (match_operand:MODEF 0 "register_operand" "")
5234 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5235 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5236 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5237 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5239 && (SSE_REG_P (operands[0])
5240 || (GET_CODE (operands[0]) == SUBREG
5241 && SSE_REG_P (operands[0])))"
5242 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5244 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5245 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5247 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5248 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5250 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5254 [(set_attr "type" "fmov,multi")
5255 (set_attr "mode" "<X87MODEF:MODE>")
5256 (set_attr "unit" "*,i387")
5257 (set_attr "fp_int_src" "true")])
5259 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5260 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5262 (match_operand:SWI48x 1 "memory_operand" "m")))]
5264 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5266 [(set_attr "type" "fmov")
5267 (set_attr "mode" "<X87MODEF:MODE>")
5268 (set_attr "fp_int_src" "true")])
5271 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5273 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276 && reload_completed"
5277 [(set (match_dup 2) (match_dup 1))
5278 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5282 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5283 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5285 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5286 && reload_completed"
5287 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5289 ;; Avoid store forwarding (partial memory) stall penalty
5290 ;; by passing DImode value through XMM registers. */
5292 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5293 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5295 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5296 (clobber (match_scratch:V4SI 3 "=X,x"))
5297 (clobber (match_scratch:V4SI 4 "=X,x"))
5298 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5299 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5301 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5303 [(set_attr "type" "multi")
5304 (set_attr "mode" "<X87MODEF:MODE>")
5305 (set_attr "unit" "i387")
5306 (set_attr "fp_int_src" "true")])
5309 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5310 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5311 (clobber (match_scratch:V4SI 3 ""))
5312 (clobber (match_scratch:V4SI 4 ""))
5313 (clobber (match_operand:DI 2 "memory_operand" ""))]
5314 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5316 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5317 && reload_completed"
5318 [(set (match_dup 2) (match_dup 3))
5319 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5321 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5322 Assemble the 64-bit DImode value in an xmm register. */
5323 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5324 gen_rtx_SUBREG (SImode, operands[1], 0)));
5325 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5326 gen_rtx_SUBREG (SImode, operands[1], 4)));
5327 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5330 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5334 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5335 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5336 (clobber (match_scratch:V4SI 3 ""))
5337 (clobber (match_scratch:V4SI 4 ""))
5338 (clobber (match_operand:DI 2 "memory_operand" ""))]
5339 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5341 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5342 && reload_completed"
5343 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5345 ;; Avoid store forwarding (partial memory) stall penalty by extending
5346 ;; SImode value to DImode through XMM register instead of pushing two
5347 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5348 ;; targets benefit from this optimization. Also note that fild
5349 ;; loads from memory only.
5351 (define_insn "*floatunssi<mode>2_1"
5352 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5353 (unsigned_float:X87MODEF
5354 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5355 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5356 (clobber (match_scratch:SI 3 "=X,x"))]
5358 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5361 [(set_attr "type" "multi")
5362 (set_attr "mode" "<MODE>")])
5365 [(set (match_operand:X87MODEF 0 "register_operand" "")
5366 (unsigned_float:X87MODEF
5367 (match_operand:SI 1 "register_operand" "")))
5368 (clobber (match_operand:DI 2 "memory_operand" ""))
5369 (clobber (match_scratch:SI 3 ""))]
5371 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5373 && reload_completed"
5374 [(set (match_dup 2) (match_dup 1))
5376 (float:X87MODEF (match_dup 2)))]
5377 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5380 [(set (match_operand:X87MODEF 0 "register_operand" "")
5381 (unsigned_float:X87MODEF
5382 (match_operand:SI 1 "memory_operand" "")))
5383 (clobber (match_operand:DI 2 "memory_operand" ""))
5384 (clobber (match_scratch:SI 3 ""))]
5386 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5388 && reload_completed"
5389 [(set (match_dup 2) (match_dup 3))
5391 (float:X87MODEF (match_dup 2)))]
5393 emit_move_insn (operands[3], operands[1]);
5394 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5397 (define_expand "floatunssi<mode>2"
5399 [(set (match_operand:X87MODEF 0 "register_operand" "")
5400 (unsigned_float:X87MODEF
5401 (match_operand:SI 1 "nonimmediate_operand" "")))
5402 (clobber (match_dup 2))
5403 (clobber (match_scratch:SI 3 ""))])]
5405 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5407 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5409 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5411 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5416 enum ix86_stack_slot slot = (virtuals_instantiated
5419 operands[2] = assign_386_stack_local (DImode, slot);
5423 (define_expand "floatunsdisf2"
5424 [(use (match_operand:SF 0 "register_operand" ""))
5425 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5426 "TARGET_64BIT && TARGET_SSE_MATH"
5427 "x86_emit_floatuns (operands); DONE;")
5429 (define_expand "floatunsdidf2"
5430 [(use (match_operand:DF 0 "register_operand" ""))
5431 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5432 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5433 && TARGET_SSE2 && TARGET_SSE_MATH"
5436 x86_emit_floatuns (operands);
5438 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5444 (define_expand "add<mode>3"
5445 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5446 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5447 (match_operand:SDWIM 2 "<general_operand>" "")))]
5449 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5451 (define_insn_and_split "*add<dwi>3_doubleword"
5452 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5454 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5455 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5456 (clobber (reg:CC FLAGS_REG))]
5457 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5460 [(parallel [(set (reg:CC FLAGS_REG)
5461 (unspec:CC [(match_dup 1) (match_dup 2)]
5464 (plus:DWIH (match_dup 1) (match_dup 2)))])
5465 (parallel [(set (match_dup 3)
5469 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5471 (clobber (reg:CC FLAGS_REG))])]
5472 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5474 (define_insn "*add<mode>3_cc"
5475 [(set (reg:CC FLAGS_REG)
5477 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5478 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5480 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5481 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5482 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5483 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5484 [(set_attr "type" "alu")
5485 (set_attr "mode" "<MODE>")])
5487 (define_insn "addqi3_cc"
5488 [(set (reg:CC FLAGS_REG)
5490 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5491 (match_operand:QI 2 "general_operand" "qn,qm")]
5493 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5494 (plus:QI (match_dup 1) (match_dup 2)))]
5495 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5496 "add{b}\t{%2, %0|%0, %2}"
5497 [(set_attr "type" "alu")
5498 (set_attr "mode" "QI")])
5500 (define_insn_and_split "*lea_1"
5501 [(set (match_operand:SI 0 "register_operand" "=r")
5502 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5504 "lea{l}\t{%a1, %0|%0, %a1}"
5505 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5508 ix86_split_lea_for_addr (operands, SImode);
5511 [(set_attr "type" "lea")
5512 (set_attr "mode" "SI")])
5514 (define_insn_and_split "*lea<mode>_2"
5515 [(set (match_operand:SWI48 0 "register_operand" "=r")
5516 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5518 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5519 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5522 ix86_split_lea_for_addr (operands, <MODE>mode);
5525 [(set_attr "type" "lea")
5526 (set_attr "mode" "<MODE>")])
5528 (define_insn "*lea_3_zext"
5529 [(set (match_operand:DI 0 "register_operand" "=r")
5531 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5533 "lea{l}\t{%a1, %k0|%k0, %a1}"
5534 [(set_attr "type" "lea")
5535 (set_attr "mode" "SI")])
5537 (define_insn "*lea_4_zext"
5538 [(set (match_operand:DI 0 "register_operand" "=r")
5540 (match_operand:SI 1 "lea_address_operand" "p")))]
5542 "lea{l}\t{%a1, %k0|%k0, %a1}"
5543 [(set_attr "type" "lea")
5544 (set_attr "mode" "SI")])
5546 (define_insn "*lea_5_zext"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5549 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5550 (match_operand:DI 2 "const_32bit_mask" "n")))]
5552 "lea{l}\t{%a1, %k0|%k0, %a1}"
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5556 (define_insn "*lea_6_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (match_operand:DI 1 "lea_address_operand" "p")
5560 (match_operand:DI 2 "const_32bit_mask" "n")))]
5562 "lea{l}\t{%a1, %k0|%k0, %a1}"
5563 [(set_attr "type" "lea")
5564 (set_attr "mode" "SI")])
5566 (define_insn "*add<mode>_1"
5567 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5569 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5570 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5571 (clobber (reg:CC FLAGS_REG))]
5572 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5574 switch (get_attr_type (insn))
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (operands[2] == const1_rtx)
5582 return "inc{<imodesuffix>}\t%0";
5585 gcc_assert (operands[2] == constm1_rtx);
5586 return "dec{<imodesuffix>}\t%0";
5590 /* For most processors, ADD is faster than LEA. This alternative
5591 was added to use ADD as much as possible. */
5592 if (which_alternative == 2)
5595 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5600 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5602 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5606 (cond [(eq_attr "alternative" "3")
5607 (const_string "lea")
5608 (match_operand:SWI48 2 "incdec_operand" "")
5609 (const_string "incdec")
5611 (const_string "alu")))
5612 (set (attr "length_immediate")
5614 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5616 (const_string "*")))
5617 (set_attr "mode" "<MODE>")])
5619 ;; It may seem that nonimmediate operand is proper one for operand 1.
5620 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5621 ;; we take care in ix86_binary_operator_ok to not allow two memory
5622 ;; operands so proper swapping will be done in reload. This allow
5623 ;; patterns constructed from addsi_1 to match.
5625 (define_insn "addsi_1_zext"
5626 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5628 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5629 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5630 (clobber (reg:CC FLAGS_REG))]
5631 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5633 switch (get_attr_type (insn))
5639 if (operands[2] == const1_rtx)
5640 return "inc{l}\t%k0";
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{l}\t%k0";
5648 /* For most processors, ADD is faster than LEA. This alternative
5649 was added to use ADD as much as possible. */
5650 if (which_alternative == 1)
5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5656 if (x86_maybe_negate_const_int (&operands[2], SImode))
5657 return "sub{l}\t{%2, %k0|%k0, %2}";
5659 return "add{l}\t{%2, %k0|%k0, %2}";
5663 (cond [(eq_attr "alternative" "2")
5664 (const_string "lea")
5665 (match_operand:SI 2 "incdec_operand" "")
5666 (const_string "incdec")
5668 (const_string "alu")))
5669 (set (attr "length_immediate")
5671 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673 (const_string "*")))
5674 (set_attr "mode" "SI")])
5676 (define_insn "*addhi_1"
5677 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5678 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5679 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5680 (clobber (reg:CC FLAGS_REG))]
5681 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5683 switch (get_attr_type (insn))
5689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690 if (operands[2] == const1_rtx)
5691 return "inc{w}\t%0";
5694 gcc_assert (operands[2] == constm1_rtx);
5695 return "dec{w}\t%0";
5699 /* For most processors, ADD is faster than LEA. This alternative
5700 was added to use ADD as much as possible. */
5701 if (which_alternative == 2)
5704 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5707 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5708 if (x86_maybe_negate_const_int (&operands[2], HImode))
5709 return "sub{w}\t{%2, %0|%0, %2}";
5711 return "add{w}\t{%2, %0|%0, %2}";
5715 (cond [(eq_attr "alternative" "3")
5716 (const_string "lea")
5717 (match_operand:HI 2 "incdec_operand" "")
5718 (const_string "incdec")
5720 (const_string "alu")))
5721 (set (attr "length_immediate")
5723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5725 (const_string "*")))
5726 (set_attr "mode" "HI,HI,HI,SI")])
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5729 (define_insn "*addqi_1"
5730 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5731 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5732 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5733 (clobber (reg:CC FLAGS_REG))]
5734 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5736 bool widen = (which_alternative == 3 || which_alternative == 4);
5738 switch (get_attr_type (insn))
5744 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745 if (operands[2] == const1_rtx)
5746 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5749 gcc_assert (operands[2] == constm1_rtx);
5750 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5754 /* For most processors, ADD is faster than LEA. These alternatives
5755 were added to use ADD as much as possible. */
5756 if (which_alternative == 2 || which_alternative == 4)
5759 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5762 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5763 if (x86_maybe_negate_const_int (&operands[2], QImode))
5766 return "sub{l}\t{%2, %k0|%k0, %2}";
5768 return "sub{b}\t{%2, %0|%0, %2}";
5771 return "add{l}\t{%k2, %k0|%k0, %k2}";
5773 return "add{b}\t{%2, %0|%0, %2}";
5777 (cond [(eq_attr "alternative" "5")
5778 (const_string "lea")
5779 (match_operand:QI 2 "incdec_operand" "")
5780 (const_string "incdec")
5782 (const_string "alu")))
5783 (set (attr "length_immediate")
5785 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5787 (const_string "*")))
5788 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5790 (define_insn "*addqi_1_slp"
5791 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5792 (plus:QI (match_dup 0)
5793 (match_operand:QI 1 "general_operand" "qn,qm")))
5794 (clobber (reg:CC FLAGS_REG))]
5795 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5796 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5798 switch (get_attr_type (insn))
5801 if (operands[1] == const1_rtx)
5802 return "inc{b}\t%0";
5805 gcc_assert (operands[1] == constm1_rtx);
5806 return "dec{b}\t%0";
5810 if (x86_maybe_negate_const_int (&operands[1], QImode))
5811 return "sub{b}\t{%1, %0|%0, %1}";
5813 return "add{b}\t{%1, %0|%0, %1}";
5817 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5818 (const_string "incdec")
5819 (const_string "alu1")))
5820 (set (attr "memory")
5821 (if_then_else (match_operand 1 "memory_operand" "")
5822 (const_string "load")
5823 (const_string "none")))
5824 (set_attr "mode" "QI")])
5826 ;; Split non destructive adds if we cannot use lea.
5828 [(set (match_operand:SWI48 0 "register_operand" "")
5829 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5830 (match_operand:SWI48 2 "nonmemory_operand" "")))
5831 (clobber (reg:CC FLAGS_REG))]
5832 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5833 [(set (match_dup 0) (match_dup 1))
5834 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5835 (clobber (reg:CC FLAGS_REG))])])
5837 ;; Convert add to the lea pattern to avoid flags dependency.
5839 [(set (match_operand:SWI 0 "register_operand" "")
5840 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5841 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5846 enum machine_mode mode = <MODE>mode;
5849 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5852 operands[0] = gen_lowpart (mode, operands[0]);
5853 operands[1] = gen_lowpart (mode, operands[1]);
5854 operands[2] = gen_lowpart (mode, operands[2]);
5857 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5863 ;; Convert add to the lea pattern to avoid flags dependency.
5865 [(set (match_operand:DI 0 "register_operand" "")
5867 (plus:SI (match_operand:SI 1 "register_operand" "")
5868 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5872 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5874 (define_insn "*add<mode>_2"
5875 [(set (reg FLAGS_REG)
5878 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5879 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5881 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5882 (plus:SWI (match_dup 1) (match_dup 2)))]
5883 "ix86_match_ccmode (insn, CCGOCmode)
5884 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5886 switch (get_attr_type (insn))
5889 if (operands[2] == const1_rtx)
5890 return "inc{<imodesuffix>}\t%0";
5893 gcc_assert (operands[2] == constm1_rtx);
5894 return "dec{<imodesuffix>}\t%0";
5898 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5899 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5901 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5905 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5906 (const_string "incdec")
5907 (const_string "alu")))
5908 (set (attr "length_immediate")
5910 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5912 (const_string "*")))
5913 (set_attr "mode" "<MODE>")])
5915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5916 (define_insn "*addsi_2_zext"
5917 [(set (reg FLAGS_REG)
5919 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5920 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5922 (set (match_operand:DI 0 "register_operand" "=r")
5923 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5924 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5925 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5927 switch (get_attr_type (insn))
5930 if (operands[2] == const1_rtx)
5931 return "inc{l}\t%k0";
5934 gcc_assert (operands[2] == constm1_rtx);
5935 return "dec{l}\t%k0";
5939 if (x86_maybe_negate_const_int (&operands[2], SImode))
5940 return "sub{l}\t{%2, %k0|%k0, %2}";
5942 return "add{l}\t{%2, %k0|%k0, %2}";
5946 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5947 (const_string "incdec")
5948 (const_string "alu")))
5949 (set (attr "length_immediate")
5951 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5953 (const_string "*")))
5954 (set_attr "mode" "SI")])
5956 (define_insn "*add<mode>_3"
5957 [(set (reg FLAGS_REG)
5959 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5960 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5961 (clobber (match_scratch:SWI 0 "=<r>"))]
5962 "ix86_match_ccmode (insn, CCZmode)
5963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5965 switch (get_attr_type (insn))
5968 if (operands[2] == const1_rtx)
5969 return "inc{<imodesuffix>}\t%0";
5972 gcc_assert (operands[2] == constm1_rtx);
5973 return "dec{<imodesuffix>}\t%0";
5977 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5978 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5980 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5984 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set (attr "length_immediate")
5989 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5991 (const_string "*")))
5992 (set_attr "mode" "<MODE>")])
5994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5995 (define_insn "*addsi_3_zext"
5996 [(set (reg FLAGS_REG)
5998 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5999 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6000 (set (match_operand:DI 0 "register_operand" "=r")
6001 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6002 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6003 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6005 switch (get_attr_type (insn))
6008 if (operands[2] == const1_rtx)
6009 return "inc{l}\t%k0";
6012 gcc_assert (operands[2] == constm1_rtx);
6013 return "dec{l}\t%k0";
6017 if (x86_maybe_negate_const_int (&operands[2], SImode))
6018 return "sub{l}\t{%2, %k0|%k0, %2}";
6020 return "add{l}\t{%2, %k0|%k0, %2}";
6024 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6025 (const_string "incdec")
6026 (const_string "alu")))
6027 (set (attr "length_immediate")
6029 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6031 (const_string "*")))
6032 (set_attr "mode" "SI")])
6034 ; For comparisons against 1, -1 and 128, we may generate better code
6035 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6036 ; is matched then. We can't accept general immediate, because for
6037 ; case of overflows, the result is messed up.
6038 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6039 ; only for comparisons not depending on it.
6041 (define_insn "*adddi_4"
6042 [(set (reg FLAGS_REG)
6044 (match_operand:DI 1 "nonimmediate_operand" "0")
6045 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6046 (clobber (match_scratch:DI 0 "=rm"))]
6048 && ix86_match_ccmode (insn, CCGCmode)"
6050 switch (get_attr_type (insn))
6053 if (operands[2] == constm1_rtx)
6054 return "inc{q}\t%0";
6057 gcc_assert (operands[2] == const1_rtx);
6058 return "dec{q}\t%0";
6062 if (x86_maybe_negate_const_int (&operands[2], DImode))
6063 return "add{q}\t{%2, %0|%0, %2}";
6065 return "sub{q}\t{%2, %0|%0, %2}";
6069 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set (attr "length_immediate")
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6076 (const_string "*")))
6077 (set_attr "mode" "DI")])
6079 ; For comparisons against 1, -1 and 128, we may generate better code
6080 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6081 ; is matched then. We can't accept general immediate, because for
6082 ; case of overflows, the result is messed up.
6083 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6084 ; only for comparisons not depending on it.
6086 (define_insn "*add<mode>_4"
6087 [(set (reg FLAGS_REG)
6089 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6090 (match_operand:SWI124 2 "const_int_operand" "n")))
6091 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6092 "ix86_match_ccmode (insn, CCGCmode)"
6094 switch (get_attr_type (insn))
6097 if (operands[2] == constm1_rtx)
6098 return "inc{<imodesuffix>}\t%0";
6101 gcc_assert (operands[2] == const1_rtx);
6102 return "dec{<imodesuffix>}\t%0";
6106 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6107 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6109 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6113 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6114 (const_string "incdec")
6115 (const_string "alu")))
6116 (set (attr "length_immediate")
6118 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6120 (const_string "*")))
6121 (set_attr "mode" "<MODE>")])
6123 (define_insn "*add<mode>_5"
6124 [(set (reg FLAGS_REG)
6127 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6128 (match_operand:SWI 2 "<general_operand>" "<g>"))
6130 (clobber (match_scratch:SWI 0 "=<r>"))]
6131 "ix86_match_ccmode (insn, CCGOCmode)
6132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6134 switch (get_attr_type (insn))
6137 if (operands[2] == const1_rtx)
6138 return "inc{<imodesuffix>}\t%0";
6141 gcc_assert (operands[2] == constm1_rtx);
6142 return "dec{<imodesuffix>}\t%0";
6146 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6147 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6149 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6153 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6154 (const_string "incdec")
6155 (const_string "alu")))
6156 (set (attr "length_immediate")
6158 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6160 (const_string "*")))
6161 (set_attr "mode" "<MODE>")])
6163 (define_insn "*addqi_ext_1_rex64"
6164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6169 (match_operand 1 "ext_register_operand" "0")
6172 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6173 (clobber (reg:CC FLAGS_REG))]
6176 switch (get_attr_type (insn))
6179 if (operands[2] == const1_rtx)
6180 return "inc{b}\t%h0";
6183 gcc_assert (operands[2] == constm1_rtx);
6184 return "dec{b}\t%h0";
6188 return "add{b}\t{%2, %h0|%h0, %2}";
6192 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "modrm" "1")
6196 (set_attr "mode" "QI")])
6198 (define_insn "addqi_ext_1"
6199 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6204 (match_operand 1 "ext_register_operand" "0")
6207 (match_operand:QI 2 "general_operand" "Qmn")))
6208 (clobber (reg:CC FLAGS_REG))]
6211 switch (get_attr_type (insn))
6214 if (operands[2] == const1_rtx)
6215 return "inc{b}\t%h0";
6218 gcc_assert (operands[2] == constm1_rtx);
6219 return "dec{b}\t%h0";
6223 return "add{b}\t{%2, %h0|%h0, %2}";
6227 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6228 (const_string "incdec")
6229 (const_string "alu")))
6230 (set_attr "modrm" "1")
6231 (set_attr "mode" "QI")])
6233 (define_insn "*addqi_ext_2"
6234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6239 (match_operand 1 "ext_register_operand" "%0")
6243 (match_operand 2 "ext_register_operand" "Q")
6246 (clobber (reg:CC FLAGS_REG))]
6248 "add{b}\t{%h2, %h0|%h0, %h2}"
6249 [(set_attr "type" "alu")
6250 (set_attr "mode" "QI")])
6252 ;; The lea patterns for modes less than 32 bits need to be matched by
6253 ;; several insns converted to real lea by splitters.
6255 (define_insn_and_split "*lea_general_1"
6256 [(set (match_operand 0 "register_operand" "=r")
6257 (plus (plus (match_operand 1 "index_register_operand" "l")
6258 (match_operand 2 "register_operand" "r"))
6259 (match_operand 3 "immediate_operand" "i")))]
6260 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6261 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6262 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6263 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6267 "&& reload_completed"
6270 enum machine_mode mode = SImode;
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[2] = gen_lowpart (mode, operands[2]);
6276 operands[3] = gen_lowpart (mode, operands[3]);
6278 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6281 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6284 [(set_attr "type" "lea")
6285 (set_attr "mode" "SI")])
6287 (define_insn_and_split "*lea_general_2"
6288 [(set (match_operand 0 "register_operand" "=r")
6289 (plus (mult (match_operand 1 "index_register_operand" "l")
6290 (match_operand 2 "const248_operand" "n"))
6291 (match_operand 3 "nonmemory_operand" "ri")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6296 || GET_MODE (operands[3]) == VOIDmode)"
6298 "&& reload_completed"
6301 enum machine_mode mode = SImode;
6304 operands[0] = gen_lowpart (mode, operands[0]);
6305 operands[1] = gen_lowpart (mode, operands[1]);
6306 operands[3] = gen_lowpart (mode, operands[3]);
6308 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6311 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6314 [(set_attr "type" "lea")
6315 (set_attr "mode" "SI")])
6317 (define_insn_and_split "*lea_general_3"
6318 [(set (match_operand 0 "register_operand" "=r")
6319 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6320 (match_operand 2 "const248_operand" "n"))
6321 (match_operand 3 "register_operand" "r"))
6322 (match_operand 4 "immediate_operand" "i")))]
6323 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6324 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6325 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6326 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6328 "&& reload_completed"
6331 enum machine_mode mode = SImode;
6334 operands[0] = gen_lowpart (mode, operands[0]);
6335 operands[1] = gen_lowpart (mode, operands[1]);
6336 operands[3] = gen_lowpart (mode, operands[3]);
6337 operands[4] = gen_lowpart (mode, operands[4]);
6339 pat = gen_rtx_PLUS (mode,
6341 gen_rtx_MULT (mode, operands[1],
6346 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6349 [(set_attr "type" "lea")
6350 (set_attr "mode" "SI")])
6352 (define_insn_and_split "*lea_general_4"
6353 [(set (match_operand 0 "register_operand" "=r")
6355 (match_operand 1 "index_register_operand" "l")
6356 (match_operand 2 "const_int_operand" "n"))
6357 (match_operand 3 "const_int_operand" "n")))]
6358 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6359 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6360 || GET_MODE (operands[0]) == SImode
6361 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6362 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6363 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6364 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6365 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6367 "&& reload_completed"
6370 enum machine_mode mode = GET_MODE (operands[0]);
6373 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6376 operands[0] = gen_lowpart (mode, operands[0]);
6377 operands[1] = gen_lowpart (mode, operands[1]);
6380 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6382 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6383 INTVAL (operands[3]));
6385 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6388 [(set_attr "type" "lea")
6390 (if_then_else (match_operand:DI 0 "" "")
6392 (const_string "SI")))])
6394 ;; Subtract instructions
6396 (define_expand "sub<mode>3"
6397 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6398 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6399 (match_operand:SDWIM 2 "<general_operand>" "")))]
6401 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6403 (define_insn_and_split "*sub<dwi>3_doubleword"
6404 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6406 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6407 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6408 (clobber (reg:CC FLAGS_REG))]
6409 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6412 [(parallel [(set (reg:CC FLAGS_REG)
6413 (compare:CC (match_dup 1) (match_dup 2)))
6415 (minus:DWIH (match_dup 1) (match_dup 2)))])
6416 (parallel [(set (match_dup 3)
6420 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6422 (clobber (reg:CC FLAGS_REG))])]
6423 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6425 (define_insn "*sub<mode>_1"
6426 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6428 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6429 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6430 (clobber (reg:CC FLAGS_REG))]
6431 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6432 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6433 [(set_attr "type" "alu")
6434 (set_attr "mode" "<MODE>")])
6436 (define_insn "*subsi_1_zext"
6437 [(set (match_operand:DI 0 "register_operand" "=r")
6439 (minus:SI (match_operand:SI 1 "register_operand" "0")
6440 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6441 (clobber (reg:CC FLAGS_REG))]
6442 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6443 "sub{l}\t{%2, %k0|%k0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "SI")])
6447 (define_insn "*subqi_1_slp"
6448 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6449 (minus:QI (match_dup 0)
6450 (match_operand:QI 1 "general_operand" "qn,qm")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6454 "sub{b}\t{%1, %0|%0, %1}"
6455 [(set_attr "type" "alu1")
6456 (set_attr "mode" "QI")])
6458 (define_insn "*sub<mode>_2"
6459 [(set (reg FLAGS_REG)
6462 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6463 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6465 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6466 (minus:SWI (match_dup 1) (match_dup 2)))]
6467 "ix86_match_ccmode (insn, CCGOCmode)
6468 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6469 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6470 [(set_attr "type" "alu")
6471 (set_attr "mode" "<MODE>")])
6473 (define_insn "*subsi_2_zext"
6474 [(set (reg FLAGS_REG)
6476 (minus:SI (match_operand:SI 1 "register_operand" "0")
6477 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6479 (set (match_operand:DI 0 "register_operand" "=r")
6481 (minus:SI (match_dup 1)
6483 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6484 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6485 "sub{l}\t{%2, %k0|%k0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "mode" "SI")])
6489 (define_insn "*sub<mode>_3"
6490 [(set (reg FLAGS_REG)
6491 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6493 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6494 (minus:SWI (match_dup 1) (match_dup 2)))]
6495 "ix86_match_ccmode (insn, CCmode)
6496 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6497 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "mode" "<MODE>")])
6501 (define_insn "*subsi_3_zext"
6502 [(set (reg FLAGS_REG)
6503 (compare (match_operand:SI 1 "register_operand" "0")
6504 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6505 (set (match_operand:DI 0 "register_operand" "=r")
6507 (minus:SI (match_dup 1)
6509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6510 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6511 "sub{l}\t{%2, %1|%1, %2}"
6512 [(set_attr "type" "alu")
6513 (set_attr "mode" "SI")])
6515 ;; Add with carry and subtract with borrow
6517 (define_expand "<plusminus_insn><mode>3_carry"
6519 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6521 (match_operand:SWI 1 "nonimmediate_operand" "")
6522 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6523 [(match_operand 3 "flags_reg_operand" "")
6525 (match_operand:SWI 2 "<general_operand>" ""))))
6526 (clobber (reg:CC FLAGS_REG))])]
6527 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6529 (define_insn "*<plusminus_insn><mode>3_carry"
6530 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6532 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6534 (match_operator 3 "ix86_carry_flag_operator"
6535 [(reg FLAGS_REG) (const_int 0)])
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6537 (clobber (reg:CC FLAGS_REG))]
6538 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6539 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6540 [(set_attr "type" "alu")
6541 (set_attr "use_carry" "1")
6542 (set_attr "pent_pair" "pu")
6543 (set_attr "mode" "<MODE>")])
6545 (define_insn "*addsi3_carry_zext"
6546 [(set (match_operand:DI 0 "register_operand" "=r")
6548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6549 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6550 [(reg FLAGS_REG) (const_int 0)])
6551 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6552 (clobber (reg:CC FLAGS_REG))]
6553 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6554 "adc{l}\t{%2, %k0|%k0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "use_carry" "1")
6557 (set_attr "pent_pair" "pu")
6558 (set_attr "mode" "SI")])
6560 (define_insn "*subsi3_carry_zext"
6561 [(set (match_operand:DI 0 "register_operand" "=r")
6563 (minus:SI (match_operand:SI 1 "register_operand" "0")
6564 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6565 [(reg FLAGS_REG) (const_int 0)])
6566 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6569 "sbb{l}\t{%2, %k0|%k0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "SI")])
6574 ;; Overflow setting add and subtract instructions
6576 (define_insn "*add<mode>3_cconly_overflow"
6577 [(set (reg:CCC FLAGS_REG)
6580 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6581 (match_operand:SWI 2 "<general_operand>" "<g>"))
6583 (clobber (match_scratch:SWI 0 "=<r>"))]
6584 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6585 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6586 [(set_attr "type" "alu")
6587 (set_attr "mode" "<MODE>")])
6589 (define_insn "*sub<mode>3_cconly_overflow"
6590 [(set (reg:CCC FLAGS_REG)
6593 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6594 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6597 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6598 [(set_attr "type" "icmp")
6599 (set_attr "mode" "<MODE>")])
6601 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6602 [(set (reg:CCC FLAGS_REG)
6605 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6606 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6608 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6609 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6610 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6611 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6612 [(set_attr "type" "alu")
6613 (set_attr "mode" "<MODE>")])
6615 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6616 [(set (reg:CCC FLAGS_REG)
6619 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6620 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6622 (set (match_operand:DI 0 "register_operand" "=r")
6623 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6624 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6625 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6629 ;; The patterns that match these are at the end of this file.
6631 (define_expand "<plusminus_insn>xf3"
6632 [(set (match_operand:XF 0 "register_operand" "")
6634 (match_operand:XF 1 "register_operand" "")
6635 (match_operand:XF 2 "register_operand" "")))]
6638 (define_expand "<plusminus_insn><mode>3"
6639 [(set (match_operand:MODEF 0 "register_operand" "")
6641 (match_operand:MODEF 1 "register_operand" "")
6642 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6643 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6644 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6646 ;; Multiply instructions
6648 (define_expand "mul<mode>3"
6649 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6651 (match_operand:SWIM248 1 "register_operand" "")
6652 (match_operand:SWIM248 2 "<general_operand>" "")))
6653 (clobber (reg:CC FLAGS_REG))])])
6655 (define_expand "mulqi3"
6656 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6658 (match_operand:QI 1 "register_operand" "")
6659 (match_operand:QI 2 "nonimmediate_operand" "")))
6660 (clobber (reg:CC FLAGS_REG))])]
6661 "TARGET_QIMODE_MATH")
6664 ;; IMUL reg32/64, reg32/64, imm8 Direct
6665 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6666 ;; IMUL reg32/64, reg32/64, imm32 Direct
6667 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6668 ;; IMUL reg32/64, reg32/64 Direct
6669 ;; IMUL reg32/64, mem32/64 Direct
6671 ;; On BDVER1, all above IMULs use DirectPath
6673 (define_insn "*mul<mode>3_1"
6674 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6676 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6677 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6678 (clobber (reg:CC FLAGS_REG))]
6679 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6682 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6683 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand" ""))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand" ""))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "<MODE>")])
6703 (define_insn "*mulsi3_1_zext"
6704 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6706 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6707 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6708 (clobber (reg:CC FLAGS_REG))]
6710 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6712 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6713 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6714 imul{l}\t{%2, %k0|%k0, %2}"
6715 [(set_attr "type" "imul")
6716 (set_attr "prefix_0f" "0,0,1")
6717 (set (attr "athlon_decode")
6718 (cond [(eq_attr "cpu" "athlon")
6719 (const_string "vector")
6720 (eq_attr "alternative" "1")
6721 (const_string "vector")
6722 (and (eq_attr "alternative" "2")
6723 (match_operand 1 "memory_operand" ""))
6724 (const_string "vector")]
6725 (const_string "direct")))
6726 (set (attr "amdfam10_decode")
6727 (cond [(and (eq_attr "alternative" "0,1")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set_attr "bdver1_decode" "direct")
6732 (set_attr "mode" "SI")])
6735 ;; IMUL reg16, reg16, imm8 VectorPath
6736 ;; IMUL reg16, mem16, imm8 VectorPath
6737 ;; IMUL reg16, reg16, imm16 VectorPath
6738 ;; IMUL reg16, mem16, imm16 VectorPath
6739 ;; IMUL reg16, reg16 Direct
6740 ;; IMUL reg16, mem16 Direct
6742 ;; On BDVER1, all HI MULs use DoublePath
6744 (define_insn "*mulhi3_1"
6745 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6746 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6747 (match_operand:HI 2 "general_operand" "K,n,mr")))
6748 (clobber (reg:CC FLAGS_REG))]
6750 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6752 imul{w}\t{%2, %1, %0|%0, %1, %2}
6753 imul{w}\t{%2, %1, %0|%0, %1, %2}
6754 imul{w}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "imul")
6756 (set_attr "prefix_0f" "0,0,1")
6757 (set (attr "athlon_decode")
6758 (cond [(eq_attr "cpu" "athlon")
6759 (const_string "vector")
6760 (eq_attr "alternative" "1,2")
6761 (const_string "vector")]
6762 (const_string "direct")))
6763 (set (attr "amdfam10_decode")
6764 (cond [(eq_attr "alternative" "0,1")
6765 (const_string "vector")]
6766 (const_string "direct")))
6767 (set_attr "bdver1_decode" "double")
6768 (set_attr "mode" "HI")])
6770 ;;On AMDFAM10 and BDVER1
6774 (define_insn "*mulqi3_1"
6775 [(set (match_operand:QI 0 "register_operand" "=a")
6776 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6777 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6778 (clobber (reg:CC FLAGS_REG))]
6780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6782 [(set_attr "type" "imul")
6783 (set_attr "length_immediate" "0")
6784 (set (attr "athlon_decode")
6785 (if_then_else (eq_attr "cpu" "athlon")
6786 (const_string "vector")
6787 (const_string "direct")))
6788 (set_attr "amdfam10_decode" "direct")
6789 (set_attr "bdver1_decode" "direct")
6790 (set_attr "mode" "QI")])
6792 (define_expand "<u>mul<mode><dwi>3"
6793 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6796 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6798 (match_operand:DWIH 2 "register_operand" ""))))
6799 (clobber (reg:CC FLAGS_REG))])])
6801 (define_expand "<u>mulqihi3"
6802 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6805 (match_operand:QI 1 "nonimmediate_operand" ""))
6807 (match_operand:QI 2 "register_operand" ""))))
6808 (clobber (reg:CC FLAGS_REG))])]
6809 "TARGET_QIMODE_MATH")
6811 (define_insn "*bmi2_umulditi3_1"
6812 [(set (match_operand:DI 0 "register_operand" "=r")
6814 (match_operand:DI 2 "nonimmediate_operand" "%d")
6815 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6816 (set (match_operand:DI 1 "register_operand" "=r")
6819 (mult:TI (zero_extend:TI (match_dup 2))
6820 (zero_extend:TI (match_dup 3)))
6822 "TARGET_64BIT && TARGET_BMI2
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824 "mulx\t{%3, %0, %1|%1, %0, %3}"
6825 [(set_attr "type" "imulx")
6826 (set_attr "prefix" "vex")
6827 (set_attr "mode" "DI")])
6829 (define_insn "*bmi2_umulsidi3_1"
6830 [(set (match_operand:SI 0 "register_operand" "=r")
6832 (match_operand:SI 2 "nonimmediate_operand" "%d")
6833 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6834 (set (match_operand:SI 1 "register_operand" "=r")
6837 (mult:DI (zero_extend:DI (match_dup 2))
6838 (zero_extend:DI (match_dup 3)))
6840 "!TARGET_64BIT && TARGET_BMI2
6841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6842 "mulx\t{%3, %0, %1|%1, %0, %3}"
6843 [(set_attr "type" "imulx")
6844 (set_attr "prefix" "vex")
6845 (set_attr "mode" "SI")])
6847 (define_insn "*umul<mode><dwi>3_1"
6848 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6851 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6853 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6857 mul{<imodesuffix>}\t%2
6859 [(set_attr "isa" "*,bmi2")
6860 (set_attr "type" "imul,imulx")
6861 (set_attr "length_immediate" "0,*")
6862 (set (attr "athlon_decode")
6863 (cond [(eq_attr "alternative" "0")
6864 (if_then_else (eq_attr "cpu" "athlon")
6865 (const_string "vector")
6866 (const_string "double"))]
6867 (const_string "*")))
6868 (set_attr "amdfam10_decode" "double,*")
6869 (set_attr "bdver1_decode" "direct,*")
6870 (set_attr "prefix" "orig,vex")
6871 (set_attr "mode" "<MODE>")])
6873 ;; Convert mul to the mulx pattern to avoid flags dependency.
6875 [(set (match_operand:<DWI> 0 "register_operand" "")
6878 (match_operand:DWIH 1 "register_operand" ""))
6880 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "TARGET_BMI2 && reload_completed
6883 && true_regnum (operands[1]) == DX_REG"
6884 [(parallel [(set (match_dup 3)
6885 (mult:DWIH (match_dup 1) (match_dup 2)))
6889 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6890 (zero_extend:<DWI> (match_dup 2)))
6893 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6895 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6898 (define_insn "*mul<mode><dwi>3_1"
6899 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6902 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6904 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6905 (clobber (reg:CC FLAGS_REG))]
6906 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6907 "imul{<imodesuffix>}\t%2"
6908 [(set_attr "type" "imul")
6909 (set_attr "length_immediate" "0")
6910 (set (attr "athlon_decode")
6911 (if_then_else (eq_attr "cpu" "athlon")
6912 (const_string "vector")
6913 (const_string "double")))
6914 (set_attr "amdfam10_decode" "double")
6915 (set_attr "bdver1_decode" "direct")
6916 (set_attr "mode" "<MODE>")])
6918 (define_insn "*<u>mulqihi3_1"
6919 [(set (match_operand:HI 0 "register_operand" "=a")
6922 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6924 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6925 (clobber (reg:CC FLAGS_REG))]
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "<sgnprefix>mul{b}\t%2"
6929 [(set_attr "type" "imul")
6930 (set_attr "length_immediate" "0")
6931 (set (attr "athlon_decode")
6932 (if_then_else (eq_attr "cpu" "athlon")
6933 (const_string "vector")
6934 (const_string "direct")))
6935 (set_attr "amdfam10_decode" "direct")
6936 (set_attr "bdver1_decode" "direct")
6937 (set_attr "mode" "QI")])
6939 (define_expand "<s>mul<mode>3_highpart"
6940 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6945 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6947 (match_operand:SWI48 2 "register_operand" "")))
6949 (clobber (match_scratch:SWI48 3 ""))
6950 (clobber (reg:CC FLAGS_REG))])]
6952 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6954 (define_insn "*<s>muldi3_highpart_1"
6955 [(set (match_operand:DI 0 "register_operand" "=d")
6960 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6962 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6964 (clobber (match_scratch:DI 3 "=1"))
6965 (clobber (reg:CC FLAGS_REG))]
6967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968 "<sgnprefix>mul{q}\t%2"
6969 [(set_attr "type" "imul")
6970 (set_attr "length_immediate" "0")
6971 (set (attr "athlon_decode")
6972 (if_then_else (eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (const_string "double")))
6975 (set_attr "amdfam10_decode" "double")
6976 (set_attr "bdver1_decode" "direct")
6977 (set_attr "mode" "DI")])
6979 (define_insn "*<s>mulsi3_highpart_1"
6980 [(set (match_operand:SI 0 "register_operand" "=d")
6985 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6987 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6989 (clobber (match_scratch:SI 3 "=1"))
6990 (clobber (reg:CC FLAGS_REG))]
6991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992 "<sgnprefix>mul{l}\t%2"
6993 [(set_attr "type" "imul")
6994 (set_attr "length_immediate" "0")
6995 (set (attr "athlon_decode")
6996 (if_then_else (eq_attr "cpu" "athlon")
6997 (const_string "vector")
6998 (const_string "double")))
6999 (set_attr "amdfam10_decode" "double")
7000 (set_attr "bdver1_decode" "direct")
7001 (set_attr "mode" "SI")])
7003 (define_insn "*<s>mulsi3_highpart_zext"
7004 [(set (match_operand:DI 0 "register_operand" "=d")
7005 (zero_extend:DI (truncate:SI
7007 (mult:DI (any_extend:DI
7008 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7010 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7012 (clobber (match_scratch:SI 3 "=1"))
7013 (clobber (reg:CC FLAGS_REG))]
7015 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7016 "<sgnprefix>mul{l}\t%2"
7017 [(set_attr "type" "imul")
7018 (set_attr "length_immediate" "0")
7019 (set (attr "athlon_decode")
7020 (if_then_else (eq_attr "cpu" "athlon")
7021 (const_string "vector")
7022 (const_string "double")))
7023 (set_attr "amdfam10_decode" "double")
7024 (set_attr "bdver1_decode" "direct")
7025 (set_attr "mode" "SI")])
7027 ;; The patterns that match these are at the end of this file.
7029 (define_expand "mulxf3"
7030 [(set (match_operand:XF 0 "register_operand" "")
7031 (mult:XF (match_operand:XF 1 "register_operand" "")
7032 (match_operand:XF 2 "register_operand" "")))]
7035 (define_expand "mul<mode>3"
7036 [(set (match_operand:MODEF 0 "register_operand" "")
7037 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7038 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7039 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7040 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7042 ;; Divide instructions
7044 ;; The patterns that match these are at the end of this file.
7046 (define_expand "divxf3"
7047 [(set (match_operand:XF 0 "register_operand" "")
7048 (div:XF (match_operand:XF 1 "register_operand" "")
7049 (match_operand:XF 2 "register_operand" "")))]
7052 (define_expand "divdf3"
7053 [(set (match_operand:DF 0 "register_operand" "")
7054 (div:DF (match_operand:DF 1 "register_operand" "")
7055 (match_operand:DF 2 "nonimmediate_operand" "")))]
7056 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7057 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7059 (define_expand "divsf3"
7060 [(set (match_operand:SF 0 "register_operand" "")
7061 (div:SF (match_operand:SF 1 "register_operand" "")
7062 (match_operand:SF 2 "nonimmediate_operand" "")))]
7063 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7068 && optimize_insn_for_speed_p ()
7069 && flag_finite_math_only && !flag_trapping_math
7070 && flag_unsafe_math_optimizations)
7072 ix86_emit_swdivsf (operands[0], operands[1],
7073 operands[2], SFmode);
7078 ;; Divmod instructions.
7080 (define_expand "divmod<mode>4"
7081 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7083 (match_operand:SWIM248 1 "register_operand" "")
7084 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7085 (set (match_operand:SWIM248 3 "register_operand" "")
7086 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7087 (clobber (reg:CC FLAGS_REG))])])
7089 ;; Split with 8bit unsigned divide:
7090 ;; if (dividend an divisor are in [0-255])
7091 ;; use 8bit unsigned integer divide
7093 ;; use original integer divide
7095 [(set (match_operand:SWI48 0 "register_operand" "")
7096 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7097 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7098 (set (match_operand:SWI48 1 "register_operand" "")
7099 (mod:SWI48 (match_dup 2) (match_dup 3)))
7100 (clobber (reg:CC FLAGS_REG))]
7101 "TARGET_USE_8BIT_IDIV
7102 && TARGET_QIMODE_MATH
7103 && can_create_pseudo_p ()
7104 && !optimize_insn_for_size_p ()"
7106 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7108 (define_insn_and_split "divmod<mode>4_1"
7109 [(set (match_operand:SWI48 0 "register_operand" "=a")
7110 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7111 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7112 (set (match_operand:SWI48 1 "register_operand" "=&d")
7113 (mod:SWI48 (match_dup 2) (match_dup 3)))
7114 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7115 (clobber (reg:CC FLAGS_REG))]
7119 [(parallel [(set (match_dup 1)
7120 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7121 (clobber (reg:CC FLAGS_REG))])
7122 (parallel [(set (match_dup 0)
7123 (div:SWI48 (match_dup 2) (match_dup 3)))
7125 (mod:SWI48 (match_dup 2) (match_dup 3)))
7127 (clobber (reg:CC FLAGS_REG))])]
7129 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7131 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7132 operands[4] = operands[2];
7135 /* Avoid use of cltd in favor of a mov+shift. */
7136 emit_move_insn (operands[1], operands[2]);
7137 operands[4] = operands[1];
7140 [(set_attr "type" "multi")
7141 (set_attr "mode" "<MODE>")])
7143 (define_insn_and_split "*divmod<mode>4"
7144 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7145 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7146 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7147 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7148 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7149 (clobber (reg:CC FLAGS_REG))]
7153 [(parallel [(set (match_dup 1)
7154 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7155 (clobber (reg:CC FLAGS_REG))])
7156 (parallel [(set (match_dup 0)
7157 (div:SWIM248 (match_dup 2) (match_dup 3)))
7159 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7161 (clobber (reg:CC FLAGS_REG))])]
7163 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7165 if (<MODE>mode != HImode
7166 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7167 operands[4] = operands[2];
7170 /* Avoid use of cltd in favor of a mov+shift. */
7171 emit_move_insn (operands[1], operands[2]);
7172 operands[4] = operands[1];
7175 [(set_attr "type" "multi")
7176 (set_attr "mode" "<MODE>")])
7178 (define_insn "*divmod<mode>4_noext"
7179 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7180 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7181 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7182 (set (match_operand:SWIM248 1 "register_operand" "=d")
7183 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7184 (use (match_operand:SWIM248 4 "register_operand" "1"))
7185 (clobber (reg:CC FLAGS_REG))]
7187 "idiv{<imodesuffix>}\t%3"
7188 [(set_attr "type" "idiv")
7189 (set_attr "mode" "<MODE>")])
7191 (define_expand "divmodqi4"
7192 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7194 (match_operand:QI 1 "register_operand" "")
7195 (match_operand:QI 2 "nonimmediate_operand" "")))
7196 (set (match_operand:QI 3 "register_operand" "")
7197 (mod:QI (match_dup 1) (match_dup 2)))
7198 (clobber (reg:CC FLAGS_REG))])]
7199 "TARGET_QIMODE_MATH"
7204 tmp0 = gen_reg_rtx (HImode);
7205 tmp1 = gen_reg_rtx (HImode);
7207 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7209 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7210 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7212 /* Extract remainder from AH. */
7213 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7214 insn = emit_move_insn (operands[3], tmp1);
7216 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7217 set_unique_reg_note (insn, REG_EQUAL, mod);
7219 /* Extract quotient from AL. */
7220 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7222 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7223 set_unique_reg_note (insn, REG_EQUAL, div);
7228 ;; Divide AX by r/m8, with result stored in
7231 ;; Change div/mod to HImode and extend the second argument to HImode
7232 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7233 ;; combine may fail.
7234 (define_insn "divmodhiqi3"
7235 [(set (match_operand:HI 0 "register_operand" "=a")
7240 (mod:HI (match_operand:HI 1 "register_operand" "0")
7242 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7246 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "TARGET_QIMODE_MATH"
7250 [(set_attr "type" "idiv")
7251 (set_attr "mode" "QI")])
7253 (define_expand "udivmod<mode>4"
7254 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7256 (match_operand:SWIM248 1 "register_operand" "")
7257 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7258 (set (match_operand:SWIM248 3 "register_operand" "")
7259 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7260 (clobber (reg:CC FLAGS_REG))])])
7262 ;; Split with 8bit unsigned divide:
7263 ;; if (dividend an divisor are in [0-255])
7264 ;; use 8bit unsigned integer divide
7266 ;; use original integer divide
7268 [(set (match_operand:SWI48 0 "register_operand" "")
7269 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7270 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7271 (set (match_operand:SWI48 1 "register_operand" "")
7272 (umod:SWI48 (match_dup 2) (match_dup 3)))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "TARGET_USE_8BIT_IDIV
7275 && TARGET_QIMODE_MATH
7276 && can_create_pseudo_p ()
7277 && !optimize_insn_for_size_p ()"
7279 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7281 (define_insn_and_split "udivmod<mode>4_1"
7282 [(set (match_operand:SWI48 0 "register_operand" "=a")
7283 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7284 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7285 (set (match_operand:SWI48 1 "register_operand" "=&d")
7286 (umod:SWI48 (match_dup 2) (match_dup 3)))
7287 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7288 (clobber (reg:CC FLAGS_REG))]
7292 [(set (match_dup 1) (const_int 0))
7293 (parallel [(set (match_dup 0)
7294 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7296 (umod:SWI48 (match_dup 2) (match_dup 3)))
7298 (clobber (reg:CC FLAGS_REG))])]
7300 [(set_attr "type" "multi")
7301 (set_attr "mode" "<MODE>")])
7303 (define_insn_and_split "*udivmod<mode>4"
7304 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7305 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7306 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7307 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7308 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7309 (clobber (reg:CC FLAGS_REG))]
7313 [(set (match_dup 1) (const_int 0))
7314 (parallel [(set (match_dup 0)
7315 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7317 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7319 (clobber (reg:CC FLAGS_REG))])]
7321 [(set_attr "type" "multi")
7322 (set_attr "mode" "<MODE>")])
7324 (define_insn "*udivmod<mode>4_noext"
7325 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7326 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7327 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7328 (set (match_operand:SWIM248 1 "register_operand" "=d")
7329 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7330 (use (match_operand:SWIM248 4 "register_operand" "1"))
7331 (clobber (reg:CC FLAGS_REG))]
7333 "div{<imodesuffix>}\t%3"
7334 [(set_attr "type" "idiv")
7335 (set_attr "mode" "<MODE>")])
7337 (define_expand "udivmodqi4"
7338 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7340 (match_operand:QI 1 "register_operand" "")
7341 (match_operand:QI 2 "nonimmediate_operand" "")))
7342 (set (match_operand:QI 3 "register_operand" "")
7343 (umod:QI (match_dup 1) (match_dup 2)))
7344 (clobber (reg:CC FLAGS_REG))])]
7345 "TARGET_QIMODE_MATH"
7350 tmp0 = gen_reg_rtx (HImode);
7351 tmp1 = gen_reg_rtx (HImode);
7353 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7355 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7356 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7358 /* Extract remainder from AH. */
7359 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7360 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7361 insn = emit_move_insn (operands[3], tmp1);
7363 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7364 set_unique_reg_note (insn, REG_EQUAL, mod);
7366 /* Extract quotient from AL. */
7367 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7369 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7370 set_unique_reg_note (insn, REG_EQUAL, div);
7375 (define_insn "udivmodhiqi3"
7376 [(set (match_operand:HI 0 "register_operand" "=a")
7381 (mod:HI (match_operand:HI 1 "register_operand" "0")
7383 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7387 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7388 (clobber (reg:CC FLAGS_REG))]
7389 "TARGET_QIMODE_MATH"
7391 [(set_attr "type" "idiv")
7392 (set_attr "mode" "QI")])
7394 ;; We cannot use div/idiv for double division, because it causes
7395 ;; "division by zero" on the overflow and that's not what we expect
7396 ;; from truncate. Because true (non truncating) double division is
7397 ;; never generated, we can't create this insn anyway.
7400 ; [(set (match_operand:SI 0 "register_operand" "=a")
7402 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7404 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7405 ; (set (match_operand:SI 3 "register_operand" "=d")
7407 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7408 ; (clobber (reg:CC FLAGS_REG))]
7410 ; "div{l}\t{%2, %0|%0, %2}"
7411 ; [(set_attr "type" "idiv")])
7413 ;;- Logical AND instructions
7415 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7416 ;; Note that this excludes ah.
7418 (define_expand "testsi_ccno_1"
7419 [(set (reg:CCNO FLAGS_REG)
7421 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7422 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7425 (define_expand "testqi_ccz_1"
7426 [(set (reg:CCZ FLAGS_REG)
7427 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7428 (match_operand:QI 1 "nonmemory_operand" ""))
7431 (define_expand "testdi_ccno_1"
7432 [(set (reg:CCNO FLAGS_REG)
7434 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7435 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7437 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7439 (define_insn "*testdi_1"
7440 [(set (reg FLAGS_REG)
7443 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7444 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7446 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7449 test{l}\t{%k1, %k0|%k0, %k1}
7450 test{l}\t{%k1, %k0|%k0, %k1}
7451 test{q}\t{%1, %0|%0, %1}
7452 test{q}\t{%1, %0|%0, %1}
7453 test{q}\t{%1, %0|%0, %1}"
7454 [(set_attr "type" "test")
7455 (set_attr "modrm" "0,1,0,1,1")
7456 (set_attr "mode" "SI,SI,DI,DI,DI")])
7458 (define_insn "*testqi_1_maybe_si"
7459 [(set (reg FLAGS_REG)
7462 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7463 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7465 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7466 && ix86_match_ccmode (insn,
7467 CONST_INT_P (operands[1])
7468 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7470 if (which_alternative == 3)
7472 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7473 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7474 return "test{l}\t{%1, %k0|%k0, %1}";
7476 return "test{b}\t{%1, %0|%0, %1}";
7478 [(set_attr "type" "test")
7479 (set_attr "modrm" "0,1,1,1")
7480 (set_attr "mode" "QI,QI,QI,SI")
7481 (set_attr "pent_pair" "uv,np,uv,np")])
7483 (define_insn "*test<mode>_1"
7484 [(set (reg FLAGS_REG)
7487 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7488 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7490 "ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7493 [(set_attr "type" "test")
7494 (set_attr "modrm" "0,1,1")
7495 (set_attr "mode" "<MODE>")
7496 (set_attr "pent_pair" "uv,np,uv")])
7498 (define_expand "testqi_ext_ccno_0"
7499 [(set (reg:CCNO FLAGS_REG)
7503 (match_operand 0 "ext_register_operand" "")
7506 (match_operand 1 "const_int_operand" ""))
7509 (define_insn "*testqi_ext_0"
7510 [(set (reg FLAGS_REG)
7514 (match_operand 0 "ext_register_operand" "Q")
7517 (match_operand 1 "const_int_operand" "n"))
7519 "ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%1, %h0|%h0, %1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")
7523 (set_attr "length_immediate" "1")
7524 (set_attr "modrm" "1")
7525 (set_attr "pent_pair" "np")])
7527 (define_insn "*testqi_ext_1_rex64"
7528 [(set (reg FLAGS_REG)
7532 (match_operand 0 "ext_register_operand" "Q")
7536 (match_operand:QI 1 "register_operand" "Q")))
7538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7539 "test{b}\t{%1, %h0|%h0, %1}"
7540 [(set_attr "type" "test")
7541 (set_attr "mode" "QI")])
7543 (define_insn "*testqi_ext_1"
7544 [(set (reg FLAGS_REG)
7548 (match_operand 0 "ext_register_operand" "Q")
7552 (match_operand:QI 1 "general_operand" "Qm")))
7554 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7555 "test{b}\t{%1, %h0|%h0, %1}"
7556 [(set_attr "type" "test")
7557 (set_attr "mode" "QI")])
7559 (define_insn "*testqi_ext_2"
7560 [(set (reg FLAGS_REG)
7564 (match_operand 0 "ext_register_operand" "Q")
7568 (match_operand 1 "ext_register_operand" "Q")
7572 "ix86_match_ccmode (insn, CCNOmode)"
7573 "test{b}\t{%h1, %h0|%h0, %h1}"
7574 [(set_attr "type" "test")
7575 (set_attr "mode" "QI")])
7577 (define_insn "*testqi_ext_3_rex64"
7578 [(set (reg FLAGS_REG)
7579 (compare (zero_extract:DI
7580 (match_operand 0 "nonimmediate_operand" "rm")
7581 (match_operand:DI 1 "const_int_operand" "")
7582 (match_operand:DI 2 "const_int_operand" ""))
7585 && ix86_match_ccmode (insn, CCNOmode)
7586 && INTVAL (operands[1]) > 0
7587 && INTVAL (operands[2]) >= 0
7588 /* Ensure that resulting mask is zero or sign extended operand. */
7589 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7590 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7591 && INTVAL (operands[1]) > 32))
7592 && (GET_MODE (operands[0]) == SImode
7593 || GET_MODE (operands[0]) == DImode
7594 || GET_MODE (operands[0]) == HImode
7595 || GET_MODE (operands[0]) == QImode)"
7598 ;; Combine likes to form bit extractions for some tests. Humor it.
7599 (define_insn "*testqi_ext_3"
7600 [(set (reg FLAGS_REG)
7601 (compare (zero_extract:SI
7602 (match_operand 0 "nonimmediate_operand" "rm")
7603 (match_operand:SI 1 "const_int_operand" "")
7604 (match_operand:SI 2 "const_int_operand" ""))
7606 "ix86_match_ccmode (insn, CCNOmode)
7607 && INTVAL (operands[1]) > 0
7608 && INTVAL (operands[2]) >= 0
7609 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7610 && (GET_MODE (operands[0]) == SImode
7611 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7612 || GET_MODE (operands[0]) == HImode
7613 || GET_MODE (operands[0]) == QImode)"
7617 [(set (match_operand 0 "flags_reg_operand" "")
7618 (match_operator 1 "compare_operator"
7620 (match_operand 2 "nonimmediate_operand" "")
7621 (match_operand 3 "const_int_operand" "")
7622 (match_operand 4 "const_int_operand" ""))
7624 "ix86_match_ccmode (insn, CCNOmode)"
7625 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7627 rtx val = operands[2];
7628 HOST_WIDE_INT len = INTVAL (operands[3]);
7629 HOST_WIDE_INT pos = INTVAL (operands[4]);
7631 enum machine_mode mode, submode;
7633 mode = GET_MODE (val);
7636 /* ??? Combine likes to put non-volatile mem extractions in QImode
7637 no matter the size of the test. So find a mode that works. */
7638 if (! MEM_VOLATILE_P (val))
7640 mode = smallest_mode_for_size (pos + len, MODE_INT);
7641 val = adjust_address (val, mode, 0);
7644 else if (GET_CODE (val) == SUBREG
7645 && (submode = GET_MODE (SUBREG_REG (val)),
7646 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7647 && pos + len <= GET_MODE_BITSIZE (submode)
7648 && GET_MODE_CLASS (submode) == MODE_INT)
7650 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7652 val = SUBREG_REG (val);
7654 else if (mode == HImode && pos + len <= 8)
7656 /* Small HImode tests can be converted to QImode. */
7658 val = gen_lowpart (QImode, val);
7661 if (len == HOST_BITS_PER_WIDE_INT)
7664 mask = ((HOST_WIDE_INT)1 << len) - 1;
7667 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7670 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7671 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7672 ;; this is relatively important trick.
7673 ;; Do the conversion only post-reload to avoid limiting of the register class
7676 [(set (match_operand 0 "flags_reg_operand" "")
7677 (match_operator 1 "compare_operator"
7678 [(and (match_operand 2 "register_operand" "")
7679 (match_operand 3 "const_int_operand" ""))
7682 && QI_REG_P (operands[2])
7683 && GET_MODE (operands[2]) != QImode
7684 && ((ix86_match_ccmode (insn, CCZmode)
7685 && !(INTVAL (operands[3]) & ~(255 << 8)))
7686 || (ix86_match_ccmode (insn, CCNOmode)
7687 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7690 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7693 "operands[2] = gen_lowpart (SImode, operands[2]);
7694 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7697 [(set (match_operand 0 "flags_reg_operand" "")
7698 (match_operator 1 "compare_operator"
7699 [(and (match_operand 2 "nonimmediate_operand" "")
7700 (match_operand 3 "const_int_operand" ""))
7703 && GET_MODE (operands[2]) != QImode
7704 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7705 && ((ix86_match_ccmode (insn, CCZmode)
7706 && !(INTVAL (operands[3]) & ~255))
7707 || (ix86_match_ccmode (insn, CCNOmode)
7708 && !(INTVAL (operands[3]) & ~127)))"
7710 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7712 "operands[2] = gen_lowpart (QImode, operands[2]);
7713 operands[3] = gen_lowpart (QImode, operands[3]);")
7715 ;; %%% This used to optimize known byte-wide and operations to memory,
7716 ;; and sometimes to QImode registers. If this is considered useful,
7717 ;; it should be done with splitters.
7719 (define_expand "and<mode>3"
7720 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7721 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7722 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7724 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7726 (define_insn "*anddi_1"
7727 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7729 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7730 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7731 (clobber (reg:CC FLAGS_REG))]
7732 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7734 switch (get_attr_type (insn))
7738 enum machine_mode mode;
7740 gcc_assert (CONST_INT_P (operands[2]));
7741 if (INTVAL (operands[2]) == 0xff)
7745 gcc_assert (INTVAL (operands[2]) == 0xffff);
7749 operands[1] = gen_lowpart (mode, operands[1]);
7751 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7753 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758 if (get_attr_mode (insn) == MODE_SI)
7759 return "and{l}\t{%k2, %k0|%k0, %k2}";
7761 return "and{q}\t{%2, %0|%0, %2}";
7764 [(set_attr "type" "alu,alu,alu,imovx")
7765 (set_attr "length_immediate" "*,*,*,0")
7766 (set (attr "prefix_rex")
7768 (and (eq_attr "type" "imovx")
7769 (and (match_test "INTVAL (operands[2]) == 0xff")
7770 (match_operand 1 "ext_QIreg_operand" "")))
7772 (const_string "*")))
7773 (set_attr "mode" "SI,DI,DI,SI")])
7775 (define_insn "*andsi_1"
7776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "ix86_binary_operator_ok (AND, SImode, operands)"
7782 switch (get_attr_type (insn))
7786 enum machine_mode mode;
7788 gcc_assert (CONST_INT_P (operands[2]));
7789 if (INTVAL (operands[2]) == 0xff)
7793 gcc_assert (INTVAL (operands[2]) == 0xffff);
7797 operands[1] = gen_lowpart (mode, operands[1]);
7799 return "movz{bl|x}\t{%1, %0|%0, %1}";
7801 return "movz{wl|x}\t{%1, %0|%0, %1}";
7805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806 return "and{l}\t{%2, %0|%0, %2}";
7809 [(set_attr "type" "alu,alu,imovx")
7810 (set (attr "prefix_rex")
7812 (and (eq_attr "type" "imovx")
7813 (and (match_test "INTVAL (operands[2]) == 0xff")
7814 (match_operand 1 "ext_QIreg_operand" "")))
7816 (const_string "*")))
7817 (set_attr "length_immediate" "*,*,0")
7818 (set_attr "mode" "SI")])
7820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821 (define_insn "*andsi_1_zext"
7822 [(set (match_operand:DI 0 "register_operand" "=r")
7824 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828 "and{l}\t{%2, %k0|%k0, %2}"
7829 [(set_attr "type" "alu")
7830 (set_attr "mode" "SI")])
7832 (define_insn "*andhi_1"
7833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "ix86_binary_operator_ok (AND, HImode, operands)"
7839 switch (get_attr_type (insn))
7842 gcc_assert (CONST_INT_P (operands[2]));
7843 gcc_assert (INTVAL (operands[2]) == 0xff);
7844 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7849 return "and{w}\t{%2, %0|%0, %2}";
7852 [(set_attr "type" "alu,alu,imovx")
7853 (set_attr "length_immediate" "*,*,0")
7854 (set (attr "prefix_rex")
7856 (and (eq_attr "type" "imovx")
7857 (match_operand 1 "ext_QIreg_operand" ""))
7859 (const_string "*")))
7860 (set_attr "mode" "HI,HI,SI")])
7862 ;; %%% Potential partial reg stall on alternative 2. What to do?
7863 (define_insn "*andqi_1"
7864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "ix86_binary_operator_ok (AND, QImode, operands)"
7870 and{b}\t{%2, %0|%0, %2}
7871 and{b}\t{%2, %0|%0, %2}
7872 and{l}\t{%k2, %k0|%k0, %k2}"
7873 [(set_attr "type" "alu")
7874 (set_attr "mode" "QI,QI,SI")])
7876 (define_insn "*andqi_1_slp"
7877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878 (and:QI (match_dup 0)
7879 (match_operand:QI 1 "general_operand" "qn,qmn")))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883 "and{b}\t{%1, %0|%0, %1}"
7884 [(set_attr "type" "alu1")
7885 (set_attr "mode" "QI")])
7888 [(set (match_operand 0 "register_operand" "")
7890 (const_int -65536)))
7891 (clobber (reg:CC FLAGS_REG))]
7892 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893 || optimize_function_for_size_p (cfun)"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (HImode, operands[0]);")
7898 [(set (match_operand 0 "ext_register_operand" "")
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && reload_completed"
7904 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905 "operands[1] = gen_lowpart (QImode, operands[0]);")
7908 [(set (match_operand 0 "ext_register_operand" "")
7910 (const_int -65281)))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913 && reload_completed"
7914 [(parallel [(set (zero_extract:SI (match_dup 0)
7918 (zero_extract:SI (match_dup 0)
7921 (zero_extract:SI (match_dup 0)
7924 (clobber (reg:CC FLAGS_REG))])]
7925 "operands[0] = gen_lowpart (SImode, operands[0]);")
7927 (define_insn "*anddi_2"
7928 [(set (reg FLAGS_REG)
7931 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7934 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935 (and:DI (match_dup 1) (match_dup 2)))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937 && ix86_binary_operator_ok (AND, DImode, operands)"
7939 and{l}\t{%k2, %k0|%k0, %k2}
7940 and{q}\t{%2, %0|%0, %2}
7941 and{q}\t{%2, %0|%0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI,DI,DI")])
7945 (define_insn "*andqi_2_maybe_si"
7946 [(set (reg FLAGS_REG)
7948 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7951 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952 (and:QI (match_dup 1) (match_dup 2)))]
7953 "ix86_binary_operator_ok (AND, QImode, operands)
7954 && ix86_match_ccmode (insn,
7955 CONST_INT_P (operands[2])
7956 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7958 if (which_alternative == 2)
7960 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962 return "and{l}\t{%2, %k0|%k0, %2}";
7964 return "and{b}\t{%2, %0|%0, %2}";
7966 [(set_attr "type" "alu")
7967 (set_attr "mode" "QI,QI,SI")])
7969 (define_insn "*and<mode>_2"
7970 [(set (reg FLAGS_REG)
7971 (compare (and:SWI124
7972 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7975 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976 (and:SWI124 (match_dup 1) (match_dup 2)))]
7977 "ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "<MODE>")])
7983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984 (define_insn "*andsi_2_zext"
7985 [(set (reg FLAGS_REG)
7987 (match_operand:SI 1 "nonimmediate_operand" "%0")
7988 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7990 (set (match_operand:DI 0 "register_operand" "=r")
7991 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993 && ix86_binary_operator_ok (AND, SImode, operands)"
7994 "and{l}\t{%2, %k0|%k0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "SI")])
7998 (define_insn "*andqi_2_slp"
7999 [(set (reg FLAGS_REG)
8001 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8004 (set (strict_low_part (match_dup 0))
8005 (and:QI (match_dup 0) (match_dup 1)))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && ix86_match_ccmode (insn, CCNOmode)
8008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009 "and{b}\t{%1, %0|%0, %1}"
8010 [(set_attr "type" "alu1")
8011 (set_attr "mode" "QI")])
8013 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8014 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8015 ;; for a QImode operand, which of course failed.
8016 (define_insn "andqi_ext_0"
8017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8022 (match_operand 1 "ext_register_operand" "0")
8025 (match_operand 2 "const_int_operand" "n")))
8026 (clobber (reg:CC FLAGS_REG))]
8028 "and{b}\t{%2, %h0|%h0, %2}"
8029 [(set_attr "type" "alu")
8030 (set_attr "length_immediate" "1")
8031 (set_attr "modrm" "1")
8032 (set_attr "mode" "QI")])
8034 ;; Generated by peephole translating test to and. This shows up
8035 ;; often in fp comparisons.
8036 (define_insn "*andqi_ext_0_cc"
8037 [(set (reg FLAGS_REG)
8041 (match_operand 1 "ext_register_operand" "0")
8044 (match_operand 2 "const_int_operand" "n"))
8046 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055 "ix86_match_ccmode (insn, CCNOmode)"
8056 "and{b}\t{%2, %h0|%h0, %2}"
8057 [(set_attr "type" "alu")
8058 (set_attr "length_immediate" "1")
8059 (set_attr "modrm" "1")
8060 (set_attr "mode" "QI")])
8062 (define_insn "*andqi_ext_1_rex64"
8063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8068 (match_operand 1 "ext_register_operand" "0")
8072 (match_operand 2 "ext_register_operand" "Q"))))
8073 (clobber (reg:CC FLAGS_REG))]
8075 "and{b}\t{%2, %h0|%h0, %2}"
8076 [(set_attr "type" "alu")
8077 (set_attr "length_immediate" "0")
8078 (set_attr "mode" "QI")])
8080 (define_insn "*andqi_ext_1"
8081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8086 (match_operand 1 "ext_register_operand" "0")
8090 (match_operand:QI 2 "general_operand" "Qm"))))
8091 (clobber (reg:CC FLAGS_REG))]
8093 "and{b}\t{%2, %h0|%h0, %2}"
8094 [(set_attr "type" "alu")
8095 (set_attr "length_immediate" "0")
8096 (set_attr "mode" "QI")])
8098 (define_insn "*andqi_ext_2"
8099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8104 (match_operand 1 "ext_register_operand" "%0")
8108 (match_operand 2 "ext_register_operand" "Q")
8111 (clobber (reg:CC FLAGS_REG))]
8113 "and{b}\t{%h2, %h0|%h0, %h2}"
8114 [(set_attr "type" "alu")
8115 (set_attr "length_immediate" "0")
8116 (set_attr "mode" "QI")])
8118 ;; Convert wide AND instructions with immediate operand to shorter QImode
8119 ;; equivalents when possible.
8120 ;; Don't do the splitting with memory operands, since it introduces risk
8121 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8122 ;; for size, but that can (should?) be handled by generic code instead.
8124 [(set (match_operand 0 "register_operand" "")
8125 (and (match_operand 1 "register_operand" "")
8126 (match_operand 2 "const_int_operand" "")))
8127 (clobber (reg:CC FLAGS_REG))]
8129 && QI_REG_P (operands[0])
8130 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131 && !(~INTVAL (operands[2]) & ~(255 << 8))
8132 && GET_MODE (operands[0]) != QImode"
8133 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134 (and:SI (zero_extract:SI (match_dup 1)
8135 (const_int 8) (const_int 8))
8137 (clobber (reg:CC FLAGS_REG))])]
8138 "operands[0] = gen_lowpart (SImode, operands[0]);
8139 operands[1] = gen_lowpart (SImode, operands[1]);
8140 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8142 ;; Since AND can be encoded with sign extended immediate, this is only
8143 ;; profitable when 7th bit is not set.
8145 [(set (match_operand 0 "register_operand" "")
8146 (and (match_operand 1 "general_operand" "")
8147 (match_operand 2 "const_int_operand" "")))
8148 (clobber (reg:CC FLAGS_REG))]
8150 && ANY_QI_REG_P (operands[0])
8151 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8152 && !(~INTVAL (operands[2]) & ~255)
8153 && !(INTVAL (operands[2]) & 128)
8154 && GET_MODE (operands[0]) != QImode"
8155 [(parallel [(set (strict_low_part (match_dup 0))
8156 (and:QI (match_dup 1)
8158 (clobber (reg:CC FLAGS_REG))])]
8159 "operands[0] = gen_lowpart (QImode, operands[0]);
8160 operands[1] = gen_lowpart (QImode, operands[1]);
8161 operands[2] = gen_lowpart (QImode, operands[2]);")
8163 ;; Logical inclusive and exclusive OR instructions
8165 ;; %%% This used to optimize known byte-wide and operations to memory.
8166 ;; If this is considered useful, it should be done with splitters.
8168 (define_expand "<code><mode>3"
8169 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8170 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8171 (match_operand:SWIM 2 "<general_operand>" "")))]
8173 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8175 (define_insn "*<code><mode>_1"
8176 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8178 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8179 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8182 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8183 [(set_attr "type" "alu")
8184 (set_attr "mode" "<MODE>")])
8186 ;; %%% Potential partial reg stall on alternative 2. What to do?
8187 (define_insn "*<code>qi_1"
8188 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8189 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8190 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8194 <logic>{b}\t{%2, %0|%0, %2}
8195 <logic>{b}\t{%2, %0|%0, %2}
8196 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "QI,QI,SI")])
8200 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8201 (define_insn "*<code>si_1_zext"
8202 [(set (match_operand:DI 0 "register_operand" "=r")
8204 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8205 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8208 "<logic>{l}\t{%2, %k0|%k0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "SI")])
8212 (define_insn "*<code>si_1_zext_imm"
8213 [(set (match_operand:DI 0 "register_operand" "=r")
8215 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8216 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8217 (clobber (reg:CC FLAGS_REG))]
8218 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8219 "<logic>{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8223 (define_insn "*<code>qi_1_slp"
8224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8225 (any_or:QI (match_dup 0)
8226 (match_operand:QI 1 "general_operand" "qmn,qn")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8230 "<logic>{b}\t{%1, %0|%0, %1}"
8231 [(set_attr "type" "alu1")
8232 (set_attr "mode" "QI")])
8234 (define_insn "*<code><mode>_2"
8235 [(set (reg FLAGS_REG)
8236 (compare (any_or:SWI
8237 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8238 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8240 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8241 (any_or:SWI (match_dup 1) (match_dup 2)))]
8242 "ix86_match_ccmode (insn, CCNOmode)
8243 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8244 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8245 [(set_attr "type" "alu")
8246 (set_attr "mode" "<MODE>")])
8248 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8249 ;; ??? Special case for immediate operand is missing - it is tricky.
8250 (define_insn "*<code>si_2_zext"
8251 [(set (reg FLAGS_REG)
8252 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8253 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8255 (set (match_operand:DI 0 "register_operand" "=r")
8256 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8258 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8259 "<logic>{l}\t{%2, %k0|%k0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "mode" "SI")])
8263 (define_insn "*<code>si_2_zext_imm"
8264 [(set (reg FLAGS_REG)
8266 (match_operand:SI 1 "nonimmediate_operand" "%0")
8267 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8269 (set (match_operand:DI 0 "register_operand" "=r")
8270 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8271 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8272 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8273 "<logic>{l}\t{%2, %k0|%k0, %2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "mode" "SI")])
8277 (define_insn "*<code>qi_2_slp"
8278 [(set (reg FLAGS_REG)
8279 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8280 (match_operand:QI 1 "general_operand" "qmn,qn"))
8282 (set (strict_low_part (match_dup 0))
8283 (any_or:QI (match_dup 0) (match_dup 1)))]
8284 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8285 && ix86_match_ccmode (insn, CCNOmode)
8286 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8287 "<logic>{b}\t{%1, %0|%0, %1}"
8288 [(set_attr "type" "alu1")
8289 (set_attr "mode" "QI")])
8291 (define_insn "*<code><mode>_3"
8292 [(set (reg FLAGS_REG)
8293 (compare (any_or:SWI
8294 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8295 (match_operand:SWI 2 "<general_operand>" "<g>"))
8297 (clobber (match_scratch:SWI 0 "=<r>"))]
8298 "ix86_match_ccmode (insn, CCNOmode)
8299 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8300 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "<MODE>")])
8304 (define_insn "*<code>qi_ext_0"
8305 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310 (match_operand 1 "ext_register_operand" "0")
8313 (match_operand 2 "const_int_operand" "n")))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8316 "<logic>{b}\t{%2, %h0|%h0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "length_immediate" "1")
8319 (set_attr "modrm" "1")
8320 (set_attr "mode" "QI")])
8322 (define_insn "*<code>qi_ext_1_rex64"
8323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328 (match_operand 1 "ext_register_operand" "0")
8332 (match_operand 2 "ext_register_operand" "Q"))))
8333 (clobber (reg:CC FLAGS_REG))]
8335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8336 "<logic>{b}\t{%2, %h0|%h0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "length_immediate" "0")
8339 (set_attr "mode" "QI")])
8341 (define_insn "*<code>qi_ext_1"
8342 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8347 (match_operand 1 "ext_register_operand" "0")
8351 (match_operand:QI 2 "general_operand" "Qm"))))
8352 (clobber (reg:CC FLAGS_REG))]
8354 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8355 "<logic>{b}\t{%2, %h0|%h0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "length_immediate" "0")
8358 (set_attr "mode" "QI")])
8360 (define_insn "*<code>qi_ext_2"
8361 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8365 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8368 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8371 (clobber (reg:CC FLAGS_REG))]
8372 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8373 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8374 [(set_attr "type" "alu")
8375 (set_attr "length_immediate" "0")
8376 (set_attr "mode" "QI")])
8379 [(set (match_operand 0 "register_operand" "")
8380 (any_or (match_operand 1 "register_operand" "")
8381 (match_operand 2 "const_int_operand" "")))
8382 (clobber (reg:CC FLAGS_REG))]
8384 && QI_REG_P (operands[0])
8385 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386 && !(INTVAL (operands[2]) & ~(255 << 8))
8387 && GET_MODE (operands[0]) != QImode"
8388 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8389 (any_or:SI (zero_extract:SI (match_dup 1)
8390 (const_int 8) (const_int 8))
8392 (clobber (reg:CC FLAGS_REG))])]
8393 "operands[0] = gen_lowpart (SImode, operands[0]);
8394 operands[1] = gen_lowpart (SImode, operands[1]);
8395 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8397 ;; Since OR can be encoded with sign extended immediate, this is only
8398 ;; profitable when 7th bit is set.
8400 [(set (match_operand 0 "register_operand" "")
8401 (any_or (match_operand 1 "general_operand" "")
8402 (match_operand 2 "const_int_operand" "")))
8403 (clobber (reg:CC FLAGS_REG))]
8405 && ANY_QI_REG_P (operands[0])
8406 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8407 && !(INTVAL (operands[2]) & ~255)
8408 && (INTVAL (operands[2]) & 128)
8409 && GET_MODE (operands[0]) != QImode"
8410 [(parallel [(set (strict_low_part (match_dup 0))
8411 (any_or:QI (match_dup 1)
8413 (clobber (reg:CC FLAGS_REG))])]
8414 "operands[0] = gen_lowpart (QImode, operands[0]);
8415 operands[1] = gen_lowpart (QImode, operands[1]);
8416 operands[2] = gen_lowpart (QImode, operands[2]);")
8418 (define_expand "xorqi_cc_ext_1"
8420 (set (reg:CCNO FLAGS_REG)
8424 (match_operand 1 "ext_register_operand" "")
8427 (match_operand:QI 2 "general_operand" ""))
8429 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8439 (define_insn "*xorqi_cc_ext_1_rex64"
8440 [(set (reg FLAGS_REG)
8444 (match_operand 1 "ext_register_operand" "0")
8447 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8449 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8459 "xor{b}\t{%2, %h0|%h0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "modrm" "1")
8462 (set_attr "mode" "QI")])
8464 (define_insn "*xorqi_cc_ext_1"
8465 [(set (reg FLAGS_REG)
8469 (match_operand 1 "ext_register_operand" "0")
8472 (match_operand:QI 2 "general_operand" "qmn"))
8474 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8483 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8484 "xor{b}\t{%2, %h0|%h0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "modrm" "1")
8487 (set_attr "mode" "QI")])
8489 ;; Negation instructions
8491 (define_expand "neg<mode>2"
8492 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8493 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8495 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8497 (define_insn_and_split "*neg<dwi>2_doubleword"
8498 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8499 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8500 (clobber (reg:CC FLAGS_REG))]
8501 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8505 [(set (reg:CCZ FLAGS_REG)
8506 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8507 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8510 (plus:DWIH (match_dup 3)
8511 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8513 (clobber (reg:CC FLAGS_REG))])
8516 (neg:DWIH (match_dup 2)))
8517 (clobber (reg:CC FLAGS_REG))])]
8518 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8520 (define_insn "*neg<mode>2_1"
8521 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8522 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8525 "neg{<imodesuffix>}\t%0"
8526 [(set_attr "type" "negnot")
8527 (set_attr "mode" "<MODE>")])
8529 ;; Combine is quite creative about this pattern.
8530 (define_insn "*negsi2_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8533 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8539 [(set_attr "type" "negnot")
8540 (set_attr "mode" "SI")])
8542 ;; The problem with neg is that it does not perform (compare x 0),
8543 ;; it really performs (compare 0 x), which leaves us with the zero
8544 ;; flag being the only useful item.
8546 (define_insn "*neg<mode>2_cmpz"
8547 [(set (reg:CCZ FLAGS_REG)
8549 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8552 (neg:SWI (match_dup 1)))]
8553 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8554 "neg{<imodesuffix>}\t%0"
8555 [(set_attr "type" "negnot")
8556 (set_attr "mode" "<MODE>")])
8558 (define_insn "*negsi2_cmpz_zext"
8559 [(set (reg:CCZ FLAGS_REG)
8563 (match_operand:DI 1 "register_operand" "0")
8567 (set (match_operand:DI 0 "register_operand" "=r")
8568 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8571 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8573 [(set_attr "type" "negnot")
8574 (set_attr "mode" "SI")])
8576 ;; Changing of sign for FP values is doable using integer unit too.
8578 (define_expand "<code><mode>2"
8579 [(set (match_operand:X87MODEF 0 "register_operand" "")
8580 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8581 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8582 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8584 (define_insn "*absneg<mode>2_mixed"
8585 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8586 (match_operator:MODEF 3 "absneg_operator"
8587 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8588 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8589 (clobber (reg:CC FLAGS_REG))]
8590 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8593 (define_insn "*absneg<mode>2_sse"
8594 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8595 (match_operator:MODEF 3 "absneg_operator"
8596 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8597 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8602 (define_insn "*absneg<mode>2_i387"
8603 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8604 (match_operator:X87MODEF 3 "absneg_operator"
8605 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8606 (use (match_operand 2 "" ""))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8611 (define_expand "<code>tf2"
8612 [(set (match_operand:TF 0 "register_operand" "")
8613 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8615 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8617 (define_insn "*absnegtf2_sse"
8618 [(set (match_operand:TF 0 "register_operand" "=x,x")
8619 (match_operator:TF 3 "absneg_operator"
8620 [(match_operand:TF 1 "register_operand" "0,x")]))
8621 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8622 (clobber (reg:CC FLAGS_REG))]
8626 ;; Splitters for fp abs and neg.
8629 [(set (match_operand 0 "fp_register_operand" "")
8630 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8631 (use (match_operand 2 "" ""))
8632 (clobber (reg:CC FLAGS_REG))]
8634 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8637 [(set (match_operand 0 "register_operand" "")
8638 (match_operator 3 "absneg_operator"
8639 [(match_operand 1 "register_operand" "")]))
8640 (use (match_operand 2 "nonimmediate_operand" ""))
8641 (clobber (reg:CC FLAGS_REG))]
8642 "reload_completed && SSE_REG_P (operands[0])"
8643 [(set (match_dup 0) (match_dup 3))]
8645 enum machine_mode mode = GET_MODE (operands[0]);
8646 enum machine_mode vmode = GET_MODE (operands[2]);
8649 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8650 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8651 if (operands_match_p (operands[0], operands[2]))
8654 operands[1] = operands[2];
8657 if (GET_CODE (operands[3]) == ABS)
8658 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8660 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8665 [(set (match_operand:SF 0 "register_operand" "")
8666 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8667 (use (match_operand:V4SF 2 "" ""))
8668 (clobber (reg:CC FLAGS_REG))]
8670 [(parallel [(set (match_dup 0) (match_dup 1))
8671 (clobber (reg:CC FLAGS_REG))])]
8674 operands[0] = gen_lowpart (SImode, operands[0]);
8675 if (GET_CODE (operands[1]) == ABS)
8677 tmp = gen_int_mode (0x7fffffff, SImode);
8678 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8682 tmp = gen_int_mode (0x80000000, SImode);
8683 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8689 [(set (match_operand:DF 0 "register_operand" "")
8690 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8691 (use (match_operand 2 "" ""))
8692 (clobber (reg:CC FLAGS_REG))]
8694 [(parallel [(set (match_dup 0) (match_dup 1))
8695 (clobber (reg:CC FLAGS_REG))])]
8700 tmp = gen_lowpart (DImode, operands[0]);
8701 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8704 if (GET_CODE (operands[1]) == ABS)
8707 tmp = gen_rtx_NOT (DImode, tmp);
8711 operands[0] = gen_highpart (SImode, operands[0]);
8712 if (GET_CODE (operands[1]) == ABS)
8714 tmp = gen_int_mode (0x7fffffff, SImode);
8715 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8719 tmp = gen_int_mode (0x80000000, SImode);
8720 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8727 [(set (match_operand:XF 0 "register_operand" "")
8728 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8729 (use (match_operand 2 "" ""))
8730 (clobber (reg:CC FLAGS_REG))]
8732 [(parallel [(set (match_dup 0) (match_dup 1))
8733 (clobber (reg:CC FLAGS_REG))])]
8736 operands[0] = gen_rtx_REG (SImode,
8737 true_regnum (operands[0])
8738 + (TARGET_64BIT ? 1 : 2));
8739 if (GET_CODE (operands[1]) == ABS)
8741 tmp = GEN_INT (0x7fff);
8742 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8746 tmp = GEN_INT (0x8000);
8747 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8752 ;; Conditionalize these after reload. If they match before reload, we
8753 ;; lose the clobber and ability to use integer instructions.
8755 (define_insn "*<code><mode>2_1"
8756 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8757 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8759 && (reload_completed
8760 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8761 "f<absneg_mnemonic>"
8762 [(set_attr "type" "fsgn")
8763 (set_attr "mode" "<MODE>")])
8765 (define_insn "*<code>extendsfdf2"
8766 [(set (match_operand:DF 0 "register_operand" "=f")
8767 (absneg:DF (float_extend:DF
8768 (match_operand:SF 1 "register_operand" "0"))))]
8769 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8770 "f<absneg_mnemonic>"
8771 [(set_attr "type" "fsgn")
8772 (set_attr "mode" "DF")])
8774 (define_insn "*<code>extendsfxf2"
8775 [(set (match_operand:XF 0 "register_operand" "=f")
8776 (absneg:XF (float_extend:XF
8777 (match_operand:SF 1 "register_operand" "0"))))]
8779 "f<absneg_mnemonic>"
8780 [(set_attr "type" "fsgn")
8781 (set_attr "mode" "XF")])
8783 (define_insn "*<code>extenddfxf2"
8784 [(set (match_operand:XF 0 "register_operand" "=f")
8785 (absneg:XF (float_extend:XF
8786 (match_operand:DF 1 "register_operand" "0"))))]
8788 "f<absneg_mnemonic>"
8789 [(set_attr "type" "fsgn")
8790 (set_attr "mode" "XF")])
8792 ;; Copysign instructions
8794 (define_mode_iterator CSGNMODE [SF DF TF])
8795 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8797 (define_expand "copysign<mode>3"
8798 [(match_operand:CSGNMODE 0 "register_operand" "")
8799 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8800 (match_operand:CSGNMODE 2 "register_operand" "")]
8801 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8802 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8803 "ix86_expand_copysign (operands); DONE;")
8805 (define_insn_and_split "copysign<mode>3_const"
8806 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8808 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8809 (match_operand:CSGNMODE 2 "register_operand" "0")
8810 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8812 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8813 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8815 "&& reload_completed"
8817 "ix86_split_copysign_const (operands); DONE;")
8819 (define_insn "copysign<mode>3_var"
8820 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8822 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8823 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8824 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8825 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8827 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8828 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8829 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8833 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8835 [(match_operand:CSGNMODE 2 "register_operand" "")
8836 (match_operand:CSGNMODE 3 "register_operand" "")
8837 (match_operand:<CSGNVMODE> 4 "" "")
8838 (match_operand:<CSGNVMODE> 5 "" "")]
8840 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8841 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8842 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8843 && reload_completed"
8845 "ix86_split_copysign_var (operands); DONE;")
8847 ;; One complement instructions
8849 (define_expand "one_cmpl<mode>2"
8850 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8851 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8853 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8855 (define_insn "*one_cmpl<mode>2_1"
8856 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8857 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8858 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8859 "not{<imodesuffix>}\t%0"
8860 [(set_attr "type" "negnot")
8861 (set_attr "mode" "<MODE>")])
8863 ;; %%% Potential partial reg stall on alternative 1. What to do?
8864 (define_insn "*one_cmplqi2_1"
8865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8866 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8867 "ix86_unary_operator_ok (NOT, QImode, operands)"
8871 [(set_attr "type" "negnot")
8872 (set_attr "mode" "QI,SI")])
8874 ;; ??? Currently never generated - xor is used instead.
8875 (define_insn "*one_cmplsi2_1_zext"
8876 [(set (match_operand:DI 0 "register_operand" "=r")
8878 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8879 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8881 [(set_attr "type" "negnot")
8882 (set_attr "mode" "SI")])
8884 (define_insn "*one_cmpl<mode>2_2"
8885 [(set (reg FLAGS_REG)
8886 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8888 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8889 (not:SWI (match_dup 1)))]
8890 "ix86_match_ccmode (insn, CCNOmode)
8891 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8893 [(set_attr "type" "alu1")
8894 (set_attr "mode" "<MODE>")])
8897 [(set (match_operand 0 "flags_reg_operand" "")
8898 (match_operator 2 "compare_operator"
8899 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8901 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8902 (not:SWI (match_dup 3)))]
8903 "ix86_match_ccmode (insn, CCNOmode)"
8904 [(parallel [(set (match_dup 0)
8905 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8908 (xor:SWI (match_dup 3) (const_int -1)))])])
8910 ;; ??? Currently never generated - xor is used instead.
8911 (define_insn "*one_cmplsi2_2_zext"
8912 [(set (reg FLAGS_REG)
8913 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8915 (set (match_operand:DI 0 "register_operand" "=r")
8916 (zero_extend:DI (not:SI (match_dup 1))))]
8917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_unary_operator_ok (NOT, SImode, operands)"
8920 [(set_attr "type" "alu1")
8921 (set_attr "mode" "SI")])
8924 [(set (match_operand 0 "flags_reg_operand" "")
8925 (match_operator 2 "compare_operator"
8926 [(not:SI (match_operand:SI 3 "register_operand" ""))
8928 (set (match_operand:DI 1 "register_operand" "")
8929 (zero_extend:DI (not:SI (match_dup 3))))]
8930 "ix86_match_ccmode (insn, CCNOmode)"
8931 [(parallel [(set (match_dup 0)
8932 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8935 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8937 ;; Shift instructions
8939 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8940 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8941 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8942 ;; from the assembler input.
8944 ;; This instruction shifts the target reg/mem as usual, but instead of
8945 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8946 ;; is a left shift double, bits are taken from the high order bits of
8947 ;; reg, else if the insn is a shift right double, bits are taken from the
8948 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8949 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8951 ;; Since sh[lr]d does not change the `reg' operand, that is done
8952 ;; separately, making all shifts emit pairs of shift double and normal
8953 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8954 ;; support a 63 bit shift, each shift where the count is in a reg expands
8955 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8957 ;; If the shift count is a constant, we need never emit more than one
8958 ;; shift pair, instead using moves and sign extension for counts greater
8961 (define_expand "ashl<mode>3"
8962 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8963 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8964 (match_operand:QI 2 "nonmemory_operand" "")))]
8966 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8968 (define_insn "*ashl<mode>3_doubleword"
8969 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8970 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8971 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8972 (clobber (reg:CC FLAGS_REG))]
8975 [(set_attr "type" "multi")])
8978 [(set (match_operand:DWI 0 "register_operand" "")
8979 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8980 (match_operand:QI 2 "nonmemory_operand" "")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8984 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8986 ;; By default we don't ask for a scratch register, because when DWImode
8987 ;; values are manipulated, registers are already at a premium. But if
8988 ;; we have one handy, we won't turn it away.
8991 [(match_scratch:DWIH 3 "r")
8992 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8994 (match_operand:<DWI> 1 "nonmemory_operand" "")
8995 (match_operand:QI 2 "nonmemory_operand" "")))
8996 (clobber (reg:CC FLAGS_REG))])
9000 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9002 (define_insn "x86_64_shld"
9003 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9004 (ior:DI (ashift:DI (match_dup 0)
9005 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9006 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9007 (minus:QI (const_int 64) (match_dup 2)))))
9008 (clobber (reg:CC FLAGS_REG))]
9010 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9011 [(set_attr "type" "ishift")
9012 (set_attr "prefix_0f" "1")
9013 (set_attr "mode" "DI")
9014 (set_attr "athlon_decode" "vector")
9015 (set_attr "amdfam10_decode" "vector")
9016 (set_attr "bdver1_decode" "vector")])
9018 (define_insn "x86_shld"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9020 (ior:SI (ashift:SI (match_dup 0)
9021 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9023 (minus:QI (const_int 32) (match_dup 2)))))
9024 (clobber (reg:CC FLAGS_REG))]
9026 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9027 [(set_attr "type" "ishift")
9028 (set_attr "prefix_0f" "1")
9029 (set_attr "mode" "SI")
9030 (set_attr "pent_pair" "np")
9031 (set_attr "athlon_decode" "vector")
9032 (set_attr "amdfam10_decode" "vector")
9033 (set_attr "bdver1_decode" "vector")])
9035 (define_expand "x86_shift<mode>_adj_1"
9036 [(set (reg:CCZ FLAGS_REG)
9037 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9040 (set (match_operand:SWI48 0 "register_operand" "")
9041 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9042 (match_operand:SWI48 1 "register_operand" "")
9045 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9046 (match_operand:SWI48 3 "register_operand" "r")
9049 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9051 (define_expand "x86_shift<mode>_adj_2"
9052 [(use (match_operand:SWI48 0 "register_operand" ""))
9053 (use (match_operand:SWI48 1 "register_operand" ""))
9054 (use (match_operand:QI 2 "register_operand" ""))]
9057 rtx label = gen_label_rtx ();
9060 emit_insn (gen_testqi_ccz_1 (operands[2],
9061 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9063 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9064 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9065 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9066 gen_rtx_LABEL_REF (VOIDmode, label),
9068 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9069 JUMP_LABEL (tmp) = label;
9071 emit_move_insn (operands[0], operands[1]);
9072 ix86_expand_clear (operands[1]);
9075 LABEL_NUSES (label) = 1;
9080 ;; Avoid useless masking of count operand.
9081 (define_insn_and_split "*ashl<mode>3_mask"
9082 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9084 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9087 (match_operand:SI 2 "nonimmediate_operand" "c")
9088 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9089 (clobber (reg:CC FLAGS_REG))]
9090 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9091 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9092 == GET_MODE_BITSIZE (<MODE>mode)-1"
9095 [(parallel [(set (match_dup 0)
9096 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9097 (clobber (reg:CC FLAGS_REG))])]
9099 if (can_create_pseudo_p ())
9100 operands [2] = force_reg (SImode, operands[2]);
9102 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9104 [(set_attr "type" "ishift")
9105 (set_attr "mode" "<MODE>")])
9107 (define_insn "*bmi2_ashl<mode>3_1"
9108 [(set (match_operand:SWI48 0 "register_operand" "=r")
9109 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9110 (match_operand:SWI48 2 "register_operand" "r")))]
9112 "shlx\t{%2, %1, %0|%0, %1, %2}"
9113 [(set_attr "type" "ishiftx")
9114 (set_attr "mode" "<MODE>")])
9116 (define_insn "*ashl<mode>3_1"
9117 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9118 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9119 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9123 switch (get_attr_type (insn))
9130 gcc_assert (operands[2] == const1_rtx);
9131 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132 return "add{<imodesuffix>}\t%0, %0";
9135 if (operands[2] == const1_rtx
9136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137 return "sal{<imodesuffix>}\t%0";
9139 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9142 [(set_attr "isa" "*,*,bmi2")
9144 (cond [(eq_attr "alternative" "1")
9145 (const_string "lea")
9146 (eq_attr "alternative" "2")
9147 (const_string "ishiftx")
9148 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9149 (match_operand 0 "register_operand" ""))
9150 (match_operand 2 "const1_operand" ""))
9151 (const_string "alu")
9153 (const_string "ishift")))
9154 (set (attr "length_immediate")
9156 (ior (eq_attr "type" "alu")
9157 (and (eq_attr "type" "ishift")
9158 (and (match_operand 2 "const1_operand" "")
9159 (ior (match_test "TARGET_SHIFT1")
9160 (match_test "optimize_function_for_size_p (cfun)")))))
9162 (const_string "*")))
9163 (set_attr "mode" "<MODE>")])
9165 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9167 [(set (match_operand:SWI48 0 "register_operand" "")
9168 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9169 (match_operand:QI 2 "register_operand" "")))
9170 (clobber (reg:CC FLAGS_REG))]
9171 "TARGET_BMI2 && reload_completed"
9173 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9174 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9176 (define_insn "*bmi2_ashlsi3_1_zext"
9177 [(set (match_operand:DI 0 "register_operand" "=r")
9179 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9180 (match_operand:SI 2 "register_operand" "r"))))]
9181 "TARGET_64BIT && TARGET_BMI2"
9182 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9183 [(set_attr "type" "ishiftx")
9184 (set_attr "mode" "SI")])
9186 (define_insn "*ashlsi3_1_zext"
9187 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9189 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9190 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9194 switch (get_attr_type (insn))
9201 gcc_assert (operands[2] == const1_rtx);
9202 return "add{l}\t%k0, %k0";
9205 if (operands[2] == const1_rtx
9206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207 return "sal{l}\t%k0";
9209 return "sal{l}\t{%2, %k0|%k0, %2}";
9212 [(set_attr "isa" "*,*,bmi2")
9214 (cond [(eq_attr "alternative" "1")
9215 (const_string "lea")
9216 (eq_attr "alternative" "2")
9217 (const_string "ishiftx")
9218 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9219 (match_operand 2 "const1_operand" ""))
9220 (const_string "alu")
9222 (const_string "ishift")))
9223 (set (attr "length_immediate")
9225 (ior (eq_attr "type" "alu")
9226 (and (eq_attr "type" "ishift")
9227 (and (match_operand 2 "const1_operand" "")
9228 (ior (match_test "TARGET_SHIFT1")
9229 (match_test "optimize_function_for_size_p (cfun)")))))
9231 (const_string "*")))
9232 (set_attr "mode" "SI")])
9234 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9236 [(set (match_operand:DI 0 "register_operand" "")
9238 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9239 (match_operand:QI 2 "register_operand" ""))))
9240 (clobber (reg:CC FLAGS_REG))]
9241 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9243 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9244 "operands[2] = gen_lowpart (SImode, operands[2]);")
9246 (define_insn "*ashlhi3_1"
9247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9248 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9249 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9253 switch (get_attr_type (insn))
9259 gcc_assert (operands[2] == const1_rtx);
9260 return "add{w}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{w}\t%0";
9267 return "sal{w}\t{%2, %0|%0, %2}";
9271 (cond [(eq_attr "alternative" "1")
9272 (const_string "lea")
9273 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9274 (match_operand 0 "register_operand" ""))
9275 (match_operand 2 "const1_operand" ""))
9276 (const_string "alu")
9278 (const_string "ishift")))
9279 (set (attr "length_immediate")
9281 (ior (eq_attr "type" "alu")
9282 (and (eq_attr "type" "ishift")
9283 (and (match_operand 2 "const1_operand" "")
9284 (ior (match_test "TARGET_SHIFT1")
9285 (match_test "optimize_function_for_size_p (cfun)")))))
9287 (const_string "*")))
9288 (set_attr "mode" "HI,SI")])
9290 ;; %%% Potential partial reg stall on alternative 1. What to do?
9291 (define_insn "*ashlqi3_1"
9292 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9293 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9294 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9295 (clobber (reg:CC FLAGS_REG))]
9296 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9298 switch (get_attr_type (insn))
9304 gcc_assert (operands[2] == const1_rtx);
9305 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9306 return "add{l}\t%k0, %k0";
9308 return "add{b}\t%0, %0";
9311 if (operands[2] == const1_rtx
9312 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9314 if (get_attr_mode (insn) == MODE_SI)
9315 return "sal{l}\t%k0";
9317 return "sal{b}\t%0";
9321 if (get_attr_mode (insn) == MODE_SI)
9322 return "sal{l}\t{%2, %k0|%k0, %2}";
9324 return "sal{b}\t{%2, %0|%0, %2}";
9329 (cond [(eq_attr "alternative" "2")
9330 (const_string "lea")
9331 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 0 "register_operand" ""))
9333 (match_operand 2 "const1_operand" ""))
9334 (const_string "alu")
9336 (const_string "ishift")))
9337 (set (attr "length_immediate")
9339 (ior (eq_attr "type" "alu")
9340 (and (eq_attr "type" "ishift")
9341 (and (match_operand 2 "const1_operand" "")
9342 (ior (match_test "TARGET_SHIFT1")
9343 (match_test "optimize_function_for_size_p (cfun)")))))
9345 (const_string "*")))
9346 (set_attr "mode" "QI,SI,SI")])
9348 (define_insn "*ashlqi3_1_slp"
9349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9350 (ashift:QI (match_dup 0)
9351 (match_operand:QI 1 "nonmemory_operand" "cI")))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "(optimize_function_for_size_p (cfun)
9354 || !TARGET_PARTIAL_FLAG_REG_STALL
9355 || (operands[1] == const1_rtx
9357 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9359 switch (get_attr_type (insn))
9362 gcc_assert (operands[1] == const1_rtx);
9363 return "add{b}\t%0, %0";
9366 if (operands[1] == const1_rtx
9367 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368 return "sal{b}\t%0";
9370 return "sal{b}\t{%1, %0|%0, %1}";
9374 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9375 (match_operand 0 "register_operand" ""))
9376 (match_operand 1 "const1_operand" ""))
9377 (const_string "alu")
9379 (const_string "ishift1")))
9380 (set (attr "length_immediate")
9382 (ior (eq_attr "type" "alu")
9383 (and (eq_attr "type" "ishift1")
9384 (and (match_operand 1 "const1_operand" "")
9385 (ior (match_test "TARGET_SHIFT1")
9386 (match_test "optimize_function_for_size_p (cfun)")))))
9388 (const_string "*")))
9389 (set_attr "mode" "QI")])
9391 ;; Convert ashift to the lea pattern to avoid flags dependency.
9393 [(set (match_operand 0 "register_operand" "")
9394 (ashift (match_operand 1 "index_register_operand" "")
9395 (match_operand:QI 2 "const_int_operand" "")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9399 && true_regnum (operands[0]) != true_regnum (operands[1])"
9402 enum machine_mode mode = GET_MODE (operands[0]);
9405 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9408 operands[0] = gen_lowpart (mode, operands[0]);
9409 operands[1] = gen_lowpart (mode, operands[1]);
9412 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9414 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9420 ;; Convert ashift to the lea pattern to avoid flags dependency.
9422 [(set (match_operand:DI 0 "register_operand" "")
9424 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9425 (match_operand:QI 2 "const_int_operand" ""))))
9426 (clobber (reg:CC FLAGS_REG))]
9427 "TARGET_64BIT && reload_completed
9428 && true_regnum (operands[0]) != true_regnum (operands[1])"
9430 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9432 operands[1] = gen_lowpart (DImode, operands[1]);
9433 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9436 ;; This pattern can't accept a variable shift count, since shifts by
9437 ;; zero don't affect the flags. We assume that shifts by constant
9438 ;; zero are optimized away.
9439 (define_insn "*ashl<mode>3_cmp"
9440 [(set (reg FLAGS_REG)
9442 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9443 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9446 (ashift:SWI (match_dup 1) (match_dup 2)))]
9447 "(optimize_function_for_size_p (cfun)
9448 || !TARGET_PARTIAL_FLAG_REG_STALL
9449 || (operands[2] == const1_rtx
9451 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9452 && ix86_match_ccmode (insn, CCGOCmode)
9453 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9455 switch (get_attr_type (insn))
9458 gcc_assert (operands[2] == const1_rtx);
9459 return "add{<imodesuffix>}\t%0, %0";
9462 if (operands[2] == const1_rtx
9463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464 return "sal{<imodesuffix>}\t%0";
9466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ior (match_test "TARGET_SHIFT1")
9482 (match_test "optimize_function_for_size_p (cfun)")))))
9484 (const_string "*")))
9485 (set_attr "mode" "<MODE>")])
9487 (define_insn "*ashlsi3_cmp_zext"
9488 [(set (reg FLAGS_REG)
9490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496 && (optimize_function_for_size_p (cfun)
9497 || !TARGET_PARTIAL_FLAG_REG_STALL
9498 || (operands[2] == const1_rtx
9500 || TARGET_DOUBLE_WITH_ADD)))
9501 && ix86_match_ccmode (insn, CCGOCmode)
9502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504 switch (get_attr_type (insn))
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{l}\t%k0, %k0";
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{l}\t%k0";
9515 return "sal{l}\t{%2, %k0|%k0, %2}";
9519 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9520 (match_operand 2 "const1_operand" ""))
9521 (const_string "alu")
9523 (const_string "ishift")))
9524 (set (attr "length_immediate")
9526 (ior (eq_attr "type" "alu")
9527 (and (eq_attr "type" "ishift")
9528 (and (match_operand 2 "const1_operand" "")
9529 (ior (match_test "TARGET_SHIFT1")
9530 (match_test "optimize_function_for_size_p (cfun)")))))
9532 (const_string "*")))
9533 (set_attr "mode" "SI")])
9535 (define_insn "*ashl<mode>3_cconly"
9536 [(set (reg FLAGS_REG)
9538 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9539 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541 (clobber (match_scratch:SWI 0 "=<r>"))]
9542 "(optimize_function_for_size_p (cfun)
9543 || !TARGET_PARTIAL_FLAG_REG_STALL
9544 || (operands[2] == const1_rtx
9546 || TARGET_DOUBLE_WITH_ADD)))
9547 && ix86_match_ccmode (insn, CCGOCmode)"
9549 switch (get_attr_type (insn))
9552 gcc_assert (operands[2] == const1_rtx);
9553 return "add{<imodesuffix>}\t%0, %0";
9556 if (operands[2] == const1_rtx
9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558 return "sal{<imodesuffix>}\t%0";
9560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9564 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9565 (match_operand 0 "register_operand" ""))
9566 (match_operand 2 "const1_operand" ""))
9567 (const_string "alu")
9569 (const_string "ishift")))
9570 (set (attr "length_immediate")
9572 (ior (eq_attr "type" "alu")
9573 (and (eq_attr "type" "ishift")
9574 (and (match_operand 2 "const1_operand" "")
9575 (ior (match_test "TARGET_SHIFT1")
9576 (match_test "optimize_function_for_size_p (cfun)")))))
9578 (const_string "*")))
9579 (set_attr "mode" "<MODE>")])
9581 ;; See comment above `ashl<mode>3' about how this works.
9583 (define_expand "<shift_insn><mode>3"
9584 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9585 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9586 (match_operand:QI 2 "nonmemory_operand" "")))]
9588 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9590 ;; Avoid useless masking of count operand.
9591 (define_insn_and_split "*<shift_insn><mode>3_mask"
9592 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9594 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9597 (match_operand:SI 2 "nonimmediate_operand" "c")
9598 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9601 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9602 == GET_MODE_BITSIZE (<MODE>mode)-1"
9605 [(parallel [(set (match_dup 0)
9606 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9607 (clobber (reg:CC FLAGS_REG))])]
9609 if (can_create_pseudo_p ())
9610 operands [2] = force_reg (SImode, operands[2]);
9612 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9614 [(set_attr "type" "ishift")
9615 (set_attr "mode" "<MODE>")])
9617 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9618 [(set (match_operand:DWI 0 "register_operand" "=r")
9619 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9620 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9621 (clobber (reg:CC FLAGS_REG))]
9624 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9626 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9627 [(set_attr "type" "multi")])
9629 ;; By default we don't ask for a scratch register, because when DWImode
9630 ;; values are manipulated, registers are already at a premium. But if
9631 ;; we have one handy, we won't turn it away.
9634 [(match_scratch:DWIH 3 "r")
9635 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9637 (match_operand:<DWI> 1 "register_operand" "")
9638 (match_operand:QI 2 "nonmemory_operand" "")))
9639 (clobber (reg:CC FLAGS_REG))])
9643 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9645 (define_insn "x86_64_shrd"
9646 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9647 (ior:DI (ashiftrt:DI (match_dup 0)
9648 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9649 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9650 (minus:QI (const_int 64) (match_dup 2)))))
9651 (clobber (reg:CC FLAGS_REG))]
9653 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9654 [(set_attr "type" "ishift")
9655 (set_attr "prefix_0f" "1")
9656 (set_attr "mode" "DI")
9657 (set_attr "athlon_decode" "vector")
9658 (set_attr "amdfam10_decode" "vector")
9659 (set_attr "bdver1_decode" "vector")])
9661 (define_insn "x86_shrd"
9662 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9663 (ior:SI (ashiftrt:SI (match_dup 0)
9664 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9665 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9666 (minus:QI (const_int 32) (match_dup 2)))))
9667 (clobber (reg:CC FLAGS_REG))]
9669 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9670 [(set_attr "type" "ishift")
9671 (set_attr "prefix_0f" "1")
9672 (set_attr "mode" "SI")
9673 (set_attr "pent_pair" "np")
9674 (set_attr "athlon_decode" "vector")
9675 (set_attr "amdfam10_decode" "vector")
9676 (set_attr "bdver1_decode" "vector")])
9678 (define_insn "ashrdi3_cvt"
9679 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9680 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9681 (match_operand:QI 2 "const_int_operand" "")))
9682 (clobber (reg:CC FLAGS_REG))]
9683 "TARGET_64BIT && INTVAL (operands[2]) == 63
9684 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9685 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9688 sar{q}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "imovx,ishift")
9690 (set_attr "prefix_0f" "0,*")
9691 (set_attr "length_immediate" "0,*")
9692 (set_attr "modrm" "0,1")
9693 (set_attr "mode" "DI")])
9695 (define_insn "ashrsi3_cvt"
9696 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9698 (match_operand:QI 2 "const_int_operand" "")))
9699 (clobber (reg:CC FLAGS_REG))]
9700 "INTVAL (operands[2]) == 31
9701 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9702 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9705 sar{l}\t{%2, %0|%0, %2}"
9706 [(set_attr "type" "imovx,ishift")
9707 (set_attr "prefix_0f" "0,*")
9708 (set_attr "length_immediate" "0,*")
9709 (set_attr "modrm" "0,1")
9710 (set_attr "mode" "SI")])
9712 (define_insn "*ashrsi3_cvt_zext"
9713 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9715 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9716 (match_operand:QI 2 "const_int_operand" ""))))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "TARGET_64BIT && INTVAL (operands[2]) == 31
9719 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9720 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9723 sar{l}\t{%2, %k0|%k0, %2}"
9724 [(set_attr "type" "imovx,ishift")
9725 (set_attr "prefix_0f" "0,*")
9726 (set_attr "length_immediate" "0,*")
9727 (set_attr "modrm" "0,1")
9728 (set_attr "mode" "SI")])
9730 (define_expand "x86_shift<mode>_adj_3"
9731 [(use (match_operand:SWI48 0 "register_operand" ""))
9732 (use (match_operand:SWI48 1 "register_operand" ""))
9733 (use (match_operand:QI 2 "register_operand" ""))]
9736 rtx label = gen_label_rtx ();
9739 emit_insn (gen_testqi_ccz_1 (operands[2],
9740 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9742 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9743 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9744 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9745 gen_rtx_LABEL_REF (VOIDmode, label),
9747 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9748 JUMP_LABEL (tmp) = label;
9750 emit_move_insn (operands[0], operands[1]);
9751 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9752 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9754 LABEL_NUSES (label) = 1;
9759 (define_insn "*bmi2_<shift_insn><mode>3_1"
9760 [(set (match_operand:SWI48 0 "register_operand" "=r")
9761 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9762 (match_operand:SWI48 2 "register_operand" "r")))]
9764 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9765 [(set_attr "type" "ishiftx")
9766 (set_attr "mode" "<MODE>")])
9768 (define_insn "*<shift_insn><mode>3_1"
9769 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9771 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9772 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9776 switch (get_attr_type (insn))
9782 if (operands[2] == const1_rtx
9783 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9784 return "<shift>{<imodesuffix>}\t%0";
9786 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9789 [(set_attr "isa" "*,bmi2")
9790 (set_attr "type" "ishift,ishiftx")
9791 (set (attr "length_immediate")
9793 (and (match_operand 2 "const1_operand" "")
9794 (ior (match_test "TARGET_SHIFT1")
9795 (match_test "optimize_function_for_size_p (cfun)")))
9797 (const_string "*")))
9798 (set_attr "mode" "<MODE>")])
9800 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9802 [(set (match_operand:SWI48 0 "register_operand" "")
9803 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9804 (match_operand:QI 2 "register_operand" "")))
9805 (clobber (reg:CC FLAGS_REG))]
9806 "TARGET_BMI2 && reload_completed"
9808 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9809 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9811 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9812 [(set (match_operand:DI 0 "register_operand" "=r")
9814 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9815 (match_operand:SI 2 "register_operand" "r"))))]
9816 "TARGET_64BIT && TARGET_BMI2"
9817 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9818 [(set_attr "type" "ishiftx")
9819 (set_attr "mode" "SI")])
9821 (define_insn "*<shift_insn>si3_1_zext"
9822 [(set (match_operand:DI 0 "register_operand" "=r,r")
9824 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9825 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9829 switch (get_attr_type (insn))
9835 if (operands[2] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "<shift>{l}\t%k0";
9839 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9842 [(set_attr "isa" "*,bmi2")
9843 (set_attr "type" "ishift,ishiftx")
9844 (set (attr "length_immediate")
9846 (and (match_operand 2 "const1_operand" "")
9847 (ior (match_test "TARGET_SHIFT1")
9848 (match_test "optimize_function_for_size_p (cfun)")))
9850 (const_string "*")))
9851 (set_attr "mode" "SI")])
9853 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9855 [(set (match_operand:DI 0 "register_operand" "")
9857 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9858 (match_operand:QI 2 "register_operand" ""))))
9859 (clobber (reg:CC FLAGS_REG))]
9860 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9862 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9863 "operands[2] = gen_lowpart (SImode, operands[2]);")
9865 (define_insn "*<shift_insn><mode>3_1"
9866 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9868 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9869 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9873 if (operands[2] == const1_rtx
9874 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9875 return "<shift>{<imodesuffix>}\t%0";
9877 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9879 [(set_attr "type" "ishift")
9880 (set (attr "length_immediate")
9882 (and (match_operand 2 "const1_operand" "")
9883 (ior (match_test "TARGET_SHIFT1")
9884 (match_test "optimize_function_for_size_p (cfun)")))
9886 (const_string "*")))
9887 (set_attr "mode" "<MODE>")])
9889 (define_insn "*<shift_insn>qi3_1_slp"
9890 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9891 (any_shiftrt:QI (match_dup 0)
9892 (match_operand:QI 1 "nonmemory_operand" "cI")))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "(optimize_function_for_size_p (cfun)
9895 || !TARGET_PARTIAL_REG_STALL
9896 || (operands[1] == const1_rtx
9899 if (operands[1] == const1_rtx
9900 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9901 return "<shift>{b}\t%0";
9903 return "<shift>{b}\t{%1, %0|%0, %1}";
9905 [(set_attr "type" "ishift1")
9906 (set (attr "length_immediate")
9908 (and (match_operand 1 "const1_operand" "")
9909 (ior (match_test "TARGET_SHIFT1")
9910 (match_test "optimize_function_for_size_p (cfun)")))
9912 (const_string "*")))
9913 (set_attr "mode" "QI")])
9915 ;; This pattern can't accept a variable shift count, since shifts by
9916 ;; zero don't affect the flags. We assume that shifts by constant
9917 ;; zero are optimized away.
9918 (define_insn "*<shift_insn><mode>3_cmp"
9919 [(set (reg FLAGS_REG)
9922 (match_operand:SWI 1 "nonimmediate_operand" "0")
9923 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9925 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9926 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9927 "(optimize_function_for_size_p (cfun)
9928 || !TARGET_PARTIAL_FLAG_REG_STALL
9929 || (operands[2] == const1_rtx
9931 && ix86_match_ccmode (insn, CCGOCmode)
9932 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9934 if (operands[2] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936 return "<shift>{<imodesuffix>}\t%0";
9938 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9940 [(set_attr "type" "ishift")
9941 (set (attr "length_immediate")
9943 (and (match_operand 2 "const1_operand" "")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))
9947 (const_string "*")))
9948 (set_attr "mode" "<MODE>")])
9950 (define_insn "*<shift_insn>si3_cmp_zext"
9951 [(set (reg FLAGS_REG)
9953 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9954 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9956 (set (match_operand:DI 0 "register_operand" "=r")
9957 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9959 && (optimize_function_for_size_p (cfun)
9960 || !TARGET_PARTIAL_FLAG_REG_STALL
9961 || (operands[2] == const1_rtx
9963 && ix86_match_ccmode (insn, CCGOCmode)
9964 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9966 if (operands[2] == const1_rtx
9967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9968 return "<shift>{l}\t%k0";
9970 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9972 [(set_attr "type" "ishift")
9973 (set (attr "length_immediate")
9975 (and (match_operand 2 "const1_operand" "")
9976 (ior (match_test "TARGET_SHIFT1")
9977 (match_test "optimize_function_for_size_p (cfun)")))
9979 (const_string "*")))
9980 (set_attr "mode" "SI")])
9982 (define_insn "*<shift_insn><mode>3_cconly"
9983 [(set (reg FLAGS_REG)
9986 (match_operand:SWI 1 "register_operand" "0")
9987 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9989 (clobber (match_scratch:SWI 0 "=<r>"))]
9990 "(optimize_function_for_size_p (cfun)
9991 || !TARGET_PARTIAL_FLAG_REG_STALL
9992 || (operands[2] == const1_rtx
9994 && ix86_match_ccmode (insn, CCGOCmode)"
9996 if (operands[2] == const1_rtx
9997 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9998 return "<shift>{<imodesuffix>}\t%0";
10000 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10002 [(set_attr "type" "ishift")
10003 (set (attr "length_immediate")
10005 (and (match_operand 2 "const1_operand" "")
10006 (ior (match_test "TARGET_SHIFT1")
10007 (match_test "optimize_function_for_size_p (cfun)")))
10009 (const_string "*")))
10010 (set_attr "mode" "<MODE>")])
10012 ;; Rotate instructions
10014 (define_expand "<rotate_insn>ti3"
10015 [(set (match_operand:TI 0 "register_operand" "")
10016 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10017 (match_operand:QI 2 "nonmemory_operand" "")))]
10020 if (const_1_to_63_operand (operands[2], VOIDmode))
10021 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10022 (operands[0], operands[1], operands[2]));
10029 (define_expand "<rotate_insn>di3"
10030 [(set (match_operand:DI 0 "shiftdi_operand" "")
10031 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10032 (match_operand:QI 2 "nonmemory_operand" "")))]
10036 ix86_expand_binary_operator (<CODE>, DImode, operands);
10037 else if (const_1_to_31_operand (operands[2], VOIDmode))
10038 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10039 (operands[0], operands[1], operands[2]));
10046 (define_expand "<rotate_insn><mode>3"
10047 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10048 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10049 (match_operand:QI 2 "nonmemory_operand" "")))]
10051 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10053 ;; Avoid useless masking of count operand.
10054 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10057 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10060 (match_operand:SI 2 "nonimmediate_operand" "c")
10061 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10064 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10065 == GET_MODE_BITSIZE (<MODE>mode)-1"
10068 [(parallel [(set (match_dup 0)
10069 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10070 (clobber (reg:CC FLAGS_REG))])]
10072 if (can_create_pseudo_p ())
10073 operands [2] = force_reg (SImode, operands[2]);
10075 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10077 [(set_attr "type" "rotate")
10078 (set_attr "mode" "<MODE>")])
10080 ;; Implement rotation using two double-precision
10081 ;; shift instructions and a scratch register.
10083 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10084 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10085 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10086 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10087 (clobber (reg:CC FLAGS_REG))
10088 (clobber (match_scratch:DWIH 3 "=&r"))]
10092 [(set (match_dup 3) (match_dup 4))
10094 [(set (match_dup 4)
10095 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10096 (lshiftrt:DWIH (match_dup 5)
10097 (minus:QI (match_dup 6) (match_dup 2)))))
10098 (clobber (reg:CC FLAGS_REG))])
10100 [(set (match_dup 5)
10101 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10102 (lshiftrt:DWIH (match_dup 3)
10103 (minus:QI (match_dup 6) (match_dup 2)))))
10104 (clobber (reg:CC FLAGS_REG))])]
10106 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10108 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10111 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10112 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10113 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10114 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10115 (clobber (reg:CC FLAGS_REG))
10116 (clobber (match_scratch:DWIH 3 "=&r"))]
10120 [(set (match_dup 3) (match_dup 4))
10122 [(set (match_dup 4)
10123 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10124 (ashift:DWIH (match_dup 5)
10125 (minus:QI (match_dup 6) (match_dup 2)))))
10126 (clobber (reg:CC FLAGS_REG))])
10128 [(set (match_dup 5)
10129 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10130 (ashift:DWIH (match_dup 3)
10131 (minus:QI (match_dup 6) (match_dup 2)))))
10132 (clobber (reg:CC FLAGS_REG))])]
10134 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10136 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10139 (define_insn "*bmi2_rorx<mode>3_1"
10140 [(set (match_operand:SWI48 0 "register_operand" "=r")
10141 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10142 (match_operand:QI 2 "immediate_operand" "<S>")))]
10144 "rorx\t{%2, %1, %0|%0, %1, %2}"
10145 [(set_attr "type" "rotatex")
10146 (set_attr "mode" "<MODE>")])
10148 (define_insn "*<rotate_insn><mode>3_1"
10149 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10151 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10152 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10153 (clobber (reg:CC FLAGS_REG))]
10154 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10156 switch (get_attr_type (insn))
10162 if (operands[2] == const1_rtx
10163 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10164 return "<rotate>{<imodesuffix>}\t%0";
10166 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10169 [(set_attr "isa" "*,bmi2")
10170 (set_attr "type" "rotate,rotatex")
10171 (set (attr "length_immediate")
10173 (and (eq_attr "type" "rotate")
10174 (and (match_operand 2 "const1_operand" "")
10175 (ior (match_test "TARGET_SHIFT1")
10176 (match_test "optimize_function_for_size_p (cfun)"))))
10178 (const_string "*")))
10179 (set_attr "mode" "<MODE>")])
10181 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10183 [(set (match_operand:SWI48 0 "register_operand" "")
10184 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10185 (match_operand:QI 2 "immediate_operand" "")))
10186 (clobber (reg:CC FLAGS_REG))]
10187 "TARGET_BMI2 && reload_completed"
10188 [(set (match_dup 0)
10189 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10192 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10196 [(set (match_operand:SWI48 0 "register_operand" "")
10197 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10198 (match_operand:QI 2 "immediate_operand" "")))
10199 (clobber (reg:CC FLAGS_REG))]
10200 "TARGET_BMI2 && reload_completed"
10201 [(set (match_dup 0)
10202 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10204 (define_insn "*bmi2_rorxsi3_1_zext"
10205 [(set (match_operand:DI 0 "register_operand" "=r")
10207 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10208 (match_operand:QI 2 "immediate_operand" "I"))))]
10209 "TARGET_64BIT && TARGET_BMI2"
10210 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10211 [(set_attr "type" "rotatex")
10212 (set_attr "mode" "SI")])
10214 (define_insn "*<rotate_insn>si3_1_zext"
10215 [(set (match_operand:DI 0 "register_operand" "=r,r")
10217 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10218 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10219 (clobber (reg:CC FLAGS_REG))]
10220 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10222 switch (get_attr_type (insn))
10228 if (operands[2] == const1_rtx
10229 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10230 return "<rotate>{l}\t%k0";
10232 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10235 [(set_attr "isa" "*,bmi2")
10236 (set_attr "type" "rotate,rotatex")
10237 (set (attr "length_immediate")
10239 (and (eq_attr "type" "rotate")
10240 (and (match_operand 2 "const1_operand" "")
10241 (ior (match_test "TARGET_SHIFT1")
10242 (match_test "optimize_function_for_size_p (cfun)"))))
10244 (const_string "*")))
10245 (set_attr "mode" "SI")])
10247 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10249 [(set (match_operand:DI 0 "register_operand" "")
10251 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10252 (match_operand:QI 2 "immediate_operand" ""))))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10255 [(set (match_dup 0)
10256 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10259 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10263 [(set (match_operand:DI 0 "register_operand" "")
10265 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10266 (match_operand:QI 2 "immediate_operand" ""))))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10269 [(set (match_dup 0)
10270 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10272 (define_insn "*<rotate_insn><mode>3_1"
10273 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10274 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10275 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10279 if (operands[2] == const1_rtx
10280 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10281 return "<rotate>{<imodesuffix>}\t%0";
10283 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10285 [(set_attr "type" "rotate")
10286 (set (attr "length_immediate")
10288 (and (match_operand 2 "const1_operand" "")
10289 (ior (match_test "TARGET_SHIFT1")
10290 (match_test "optimize_function_for_size_p (cfun)")))
10292 (const_string "*")))
10293 (set_attr "mode" "<MODE>")])
10295 (define_insn "*<rotate_insn>qi3_1_slp"
10296 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10297 (any_rotate:QI (match_dup 0)
10298 (match_operand:QI 1 "nonmemory_operand" "cI")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "(optimize_function_for_size_p (cfun)
10301 || !TARGET_PARTIAL_REG_STALL
10302 || (operands[1] == const1_rtx
10303 && TARGET_SHIFT1))"
10305 if (operands[1] == const1_rtx
10306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10307 return "<rotate>{b}\t%0";
10309 return "<rotate>{b}\t{%1, %0|%0, %1}";
10311 [(set_attr "type" "rotate1")
10312 (set (attr "length_immediate")
10314 (and (match_operand 1 "const1_operand" "")
10315 (ior (match_test "TARGET_SHIFT1")
10316 (match_test "optimize_function_for_size_p (cfun)")))
10318 (const_string "*")))
10319 (set_attr "mode" "QI")])
10322 [(set (match_operand:HI 0 "register_operand" "")
10323 (any_rotate:HI (match_dup 0) (const_int 8)))
10324 (clobber (reg:CC FLAGS_REG))]
10326 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10327 [(parallel [(set (strict_low_part (match_dup 0))
10328 (bswap:HI (match_dup 0)))
10329 (clobber (reg:CC FLAGS_REG))])])
10331 ;; Bit set / bit test instructions
10333 (define_expand "extv"
10334 [(set (match_operand:SI 0 "register_operand" "")
10335 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10336 (match_operand:SI 2 "const8_operand" "")
10337 (match_operand:SI 3 "const8_operand" "")))]
10340 /* Handle extractions from %ah et al. */
10341 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10344 /* From mips.md: extract_bit_field doesn't verify that our source
10345 matches the predicate, so check it again here. */
10346 if (! ext_register_operand (operands[1], VOIDmode))
10350 (define_expand "extzv"
10351 [(set (match_operand:SI 0 "register_operand" "")
10352 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10353 (match_operand:SI 2 "const8_operand" "")
10354 (match_operand:SI 3 "const8_operand" "")))]
10357 /* Handle extractions from %ah et al. */
10358 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10361 /* From mips.md: extract_bit_field doesn't verify that our source
10362 matches the predicate, so check it again here. */
10363 if (! ext_register_operand (operands[1], VOIDmode))
10367 (define_expand "insv"
10368 [(set (zero_extract (match_operand 0 "register_operand" "")
10369 (match_operand 1 "const_int_operand" "")
10370 (match_operand 2 "const_int_operand" ""))
10371 (match_operand 3 "register_operand" ""))]
10374 rtx (*gen_mov_insv_1) (rtx, rtx);
10376 if (ix86_expand_pinsr (operands))
10379 /* Handle insertions to %ah et al. */
10380 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10383 /* From mips.md: insert_bit_field doesn't verify that our source
10384 matches the predicate, so check it again here. */
10385 if (! ext_register_operand (operands[0], VOIDmode))
10388 gen_mov_insv_1 = (TARGET_64BIT
10389 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10391 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10395 ;; %%% bts, btr, btc, bt.
10396 ;; In general these instructions are *slow* when applied to memory,
10397 ;; since they enforce atomic operation. When applied to registers,
10398 ;; it depends on the cpu implementation. They're never faster than
10399 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10400 ;; no point. But in 64-bit, we can't hold the relevant immediates
10401 ;; within the instruction itself, so operating on bits in the high
10402 ;; 32-bits of a register becomes easier.
10404 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10405 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10406 ;; negdf respectively, so they can never be disabled entirely.
10408 (define_insn "*btsq"
10409 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10411 (match_operand:DI 1 "const_0_to_63_operand" ""))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10415 "bts{q}\t{%1, %0|%0, %1}"
10416 [(set_attr "type" "alu1")
10417 (set_attr "prefix_0f" "1")
10418 (set_attr "mode" "DI")])
10420 (define_insn "*btrq"
10421 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10423 (match_operand:DI 1 "const_0_to_63_operand" ""))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10427 "btr{q}\t{%1, %0|%0, %1}"
10428 [(set_attr "type" "alu1")
10429 (set_attr "prefix_0f" "1")
10430 (set_attr "mode" "DI")])
10432 (define_insn "*btcq"
10433 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10435 (match_operand:DI 1 "const_0_to_63_operand" ""))
10436 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10439 "btc{q}\t{%1, %0|%0, %1}"
10440 [(set_attr "type" "alu1")
10441 (set_attr "prefix_0f" "1")
10442 (set_attr "mode" "DI")])
10444 ;; Allow Nocona to avoid these instructions if a register is available.
10447 [(match_scratch:DI 2 "r")
10448 (parallel [(set (zero_extract:DI
10449 (match_operand:DI 0 "register_operand" "")
10451 (match_operand:DI 1 "const_0_to_63_operand" ""))
10453 (clobber (reg:CC FLAGS_REG))])]
10454 "TARGET_64BIT && !TARGET_USE_BT"
10457 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10460 if (HOST_BITS_PER_WIDE_INT >= 64)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10462 else if (i < HOST_BITS_PER_WIDE_INT)
10463 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10465 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10467 op1 = immed_double_const (lo, hi, DImode);
10470 emit_move_insn (operands[2], op1);
10474 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10479 [(match_scratch:DI 2 "r")
10480 (parallel [(set (zero_extract:DI
10481 (match_operand:DI 0 "register_operand" "")
10483 (match_operand:DI 1 "const_0_to_63_operand" ""))
10485 (clobber (reg:CC FLAGS_REG))])]
10486 "TARGET_64BIT && !TARGET_USE_BT"
10489 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10492 if (HOST_BITS_PER_WIDE_INT >= 64)
10493 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 else if (i < HOST_BITS_PER_WIDE_INT)
10495 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10497 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10499 op1 = immed_double_const (~lo, ~hi, DImode);
10502 emit_move_insn (operands[2], op1);
10506 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10511 [(match_scratch:DI 2 "r")
10512 (parallel [(set (zero_extract:DI
10513 (match_operand:DI 0 "register_operand" "")
10515 (match_operand:DI 1 "const_0_to_63_operand" ""))
10516 (not:DI (zero_extract:DI
10517 (match_dup 0) (const_int 1) (match_dup 1))))
10518 (clobber (reg:CC FLAGS_REG))])]
10519 "TARGET_64BIT && !TARGET_USE_BT"
10522 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10525 if (HOST_BITS_PER_WIDE_INT >= 64)
10526 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10527 else if (i < HOST_BITS_PER_WIDE_INT)
10528 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10530 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10532 op1 = immed_double_const (lo, hi, DImode);
10535 emit_move_insn (operands[2], op1);
10539 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10543 (define_insn "*bt<mode>"
10544 [(set (reg:CCC FLAGS_REG)
10546 (zero_extract:SWI48
10547 (match_operand:SWI48 0 "register_operand" "r")
10549 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10551 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10552 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10553 [(set_attr "type" "alu1")
10554 (set_attr "prefix_0f" "1")
10555 (set_attr "mode" "<MODE>")])
10557 ;; Store-flag instructions.
10559 ;; For all sCOND expanders, also expand the compare or test insn that
10560 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10562 (define_insn_and_split "*setcc_di_1"
10563 [(set (match_operand:DI 0 "register_operand" "=q")
10564 (match_operator:DI 1 "ix86_comparison_operator"
10565 [(reg FLAGS_REG) (const_int 0)]))]
10566 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10568 "&& reload_completed"
10569 [(set (match_dup 2) (match_dup 1))
10570 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10572 PUT_MODE (operands[1], QImode);
10573 operands[2] = gen_lowpart (QImode, operands[0]);
10576 (define_insn_and_split "*setcc_si_1_and"
10577 [(set (match_operand:SI 0 "register_operand" "=q")
10578 (match_operator:SI 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)]))
10580 (clobber (reg:CC FLAGS_REG))]
10581 "!TARGET_PARTIAL_REG_STALL
10582 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10584 "&& reload_completed"
10585 [(set (match_dup 2) (match_dup 1))
10586 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10587 (clobber (reg:CC FLAGS_REG))])]
10589 PUT_MODE (operands[1], QImode);
10590 operands[2] = gen_lowpart (QImode, operands[0]);
10593 (define_insn_and_split "*setcc_si_1_movzbl"
10594 [(set (match_operand:SI 0 "register_operand" "=q")
10595 (match_operator:SI 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)]))]
10597 "!TARGET_PARTIAL_REG_STALL
10598 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10600 "&& reload_completed"
10601 [(set (match_dup 2) (match_dup 1))
10602 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10604 PUT_MODE (operands[1], QImode);
10605 operands[2] = gen_lowpart (QImode, operands[0]);
10608 (define_insn "*setcc_qi"
10609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10610 (match_operator:QI 1 "ix86_comparison_operator"
10611 [(reg FLAGS_REG) (const_int 0)]))]
10614 [(set_attr "type" "setcc")
10615 (set_attr "mode" "QI")])
10617 (define_insn "*setcc_qi_slp"
10618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10619 (match_operator:QI 1 "ix86_comparison_operator"
10620 [(reg FLAGS_REG) (const_int 0)]))]
10623 [(set_attr "type" "setcc")
10624 (set_attr "mode" "QI")])
10626 ;; In general it is not safe to assume too much about CCmode registers,
10627 ;; so simplify-rtx stops when it sees a second one. Under certain
10628 ;; conditions this is safe on x86, so help combine not create
10635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10636 (ne:QI (match_operator 1 "ix86_comparison_operator"
10637 [(reg FLAGS_REG) (const_int 0)])
10640 [(set (match_dup 0) (match_dup 1))]
10641 "PUT_MODE (operands[1], QImode);")
10644 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10645 (ne:QI (match_operator 1 "ix86_comparison_operator"
10646 [(reg FLAGS_REG) (const_int 0)])
10649 [(set (match_dup 0) (match_dup 1))]
10650 "PUT_MODE (operands[1], QImode);")
10653 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10654 (eq:QI (match_operator 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)])
10658 [(set (match_dup 0) (match_dup 1))]
10660 rtx new_op1 = copy_rtx (operands[1]);
10661 operands[1] = new_op1;
10662 PUT_MODE (new_op1, QImode);
10663 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10664 GET_MODE (XEXP (new_op1, 0))));
10666 /* Make sure that (a) the CCmode we have for the flags is strong
10667 enough for the reversed compare or (b) we have a valid FP compare. */
10668 if (! ix86_comparison_operator (new_op1, VOIDmode))
10673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10674 (eq:QI (match_operator 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)])
10678 [(set (match_dup 0) (match_dup 1))]
10680 rtx new_op1 = copy_rtx (operands[1]);
10681 operands[1] = new_op1;
10682 PUT_MODE (new_op1, QImode);
10683 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10684 GET_MODE (XEXP (new_op1, 0))));
10686 /* Make sure that (a) the CCmode we have for the flags is strong
10687 enough for the reversed compare or (b) we have a valid FP compare. */
10688 if (! ix86_comparison_operator (new_op1, VOIDmode))
10692 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10693 ;; subsequent logical operations are used to imitate conditional moves.
10694 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10697 (define_insn "setcc_<mode>_sse"
10698 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10699 (match_operator:MODEF 3 "sse_comparison_operator"
10700 [(match_operand:MODEF 1 "register_operand" "0,x")
10701 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10702 "SSE_FLOAT_MODE_P (<MODE>mode)"
10704 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10705 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10706 [(set_attr "isa" "noavx,avx")
10707 (set_attr "type" "ssecmp")
10708 (set_attr "length_immediate" "1")
10709 (set_attr "prefix" "orig,vex")
10710 (set_attr "mode" "<MODE>")])
10712 ;; Basic conditional jump instructions.
10713 ;; We ignore the overflow flag for signed branch instructions.
10715 (define_insn "*jcc_1"
10717 (if_then_else (match_operator 1 "ix86_comparison_operator"
10718 [(reg FLAGS_REG) (const_int 0)])
10719 (label_ref (match_operand 0 "" ""))
10723 [(set_attr "type" "ibr")
10724 (set_attr "modrm" "0")
10725 (set (attr "length")
10726 (if_then_else (and (ge (minus (match_dup 0) (pc))
10728 (lt (minus (match_dup 0) (pc))
10733 (define_insn "*jcc_2"
10735 (if_then_else (match_operator 1 "ix86_comparison_operator"
10736 [(reg FLAGS_REG) (const_int 0)])
10738 (label_ref (match_operand 0 "" ""))))]
10741 [(set_attr "type" "ibr")
10742 (set_attr "modrm" "0")
10743 (set (attr "length")
10744 (if_then_else (and (ge (minus (match_dup 0) (pc))
10746 (lt (minus (match_dup 0) (pc))
10751 ;; In general it is not safe to assume too much about CCmode registers,
10752 ;; so simplify-rtx stops when it sees a second one. Under certain
10753 ;; conditions this is safe on x86, so help combine not create
10761 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10762 [(reg FLAGS_REG) (const_int 0)])
10764 (label_ref (match_operand 1 "" ""))
10768 (if_then_else (match_dup 0)
10769 (label_ref (match_dup 1))
10771 "PUT_MODE (operands[0], VOIDmode);")
10775 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10776 [(reg FLAGS_REG) (const_int 0)])
10778 (label_ref (match_operand 1 "" ""))
10782 (if_then_else (match_dup 0)
10783 (label_ref (match_dup 1))
10786 rtx new_op0 = copy_rtx (operands[0]);
10787 operands[0] = new_op0;
10788 PUT_MODE (new_op0, VOIDmode);
10789 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10790 GET_MODE (XEXP (new_op0, 0))));
10792 /* Make sure that (a) the CCmode we have for the flags is strong
10793 enough for the reversed compare or (b) we have a valid FP compare. */
10794 if (! ix86_comparison_operator (new_op0, VOIDmode))
10798 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10799 ;; pass generates from shift insn with QImode operand. Actually, the mode
10800 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10801 ;; appropriate modulo of the bit offset value.
10803 (define_insn_and_split "*jcc_bt<mode>"
10805 (if_then_else (match_operator 0 "bt_comparison_operator"
10806 [(zero_extract:SWI48
10807 (match_operand:SWI48 1 "register_operand" "r")
10810 (match_operand:QI 2 "register_operand" "r")))
10812 (label_ref (match_operand 3 "" ""))
10814 (clobber (reg:CC FLAGS_REG))]
10815 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10818 [(set (reg:CCC FLAGS_REG)
10820 (zero_extract:SWI48
10826 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10827 (label_ref (match_dup 3))
10830 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10832 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10835 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10836 ;; also for DImode, this is what combine produces.
10837 (define_insn_and_split "*jcc_bt<mode>_mask"
10839 (if_then_else (match_operator 0 "bt_comparison_operator"
10840 [(zero_extract:SWI48
10841 (match_operand:SWI48 1 "register_operand" "r")
10844 (match_operand:SI 2 "register_operand" "r")
10845 (match_operand:SI 3 "const_int_operand" "n")))])
10846 (label_ref (match_operand 4 "" ""))
10848 (clobber (reg:CC FLAGS_REG))]
10849 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10850 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10851 == GET_MODE_BITSIZE (<MODE>mode)-1"
10854 [(set (reg:CCC FLAGS_REG)
10856 (zero_extract:SWI48
10862 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10863 (label_ref (match_dup 4))
10866 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10868 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10871 (define_insn_and_split "*jcc_btsi_1"
10873 (if_then_else (match_operator 0 "bt_comparison_operator"
10876 (match_operand:SI 1 "register_operand" "r")
10877 (match_operand:QI 2 "register_operand" "r"))
10880 (label_ref (match_operand 3 "" ""))
10882 (clobber (reg:CC FLAGS_REG))]
10883 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10886 [(set (reg:CCC FLAGS_REG)
10894 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10895 (label_ref (match_dup 3))
10898 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10900 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10903 ;; avoid useless masking of bit offset operand
10904 (define_insn_and_split "*jcc_btsi_mask_1"
10907 (match_operator 0 "bt_comparison_operator"
10910 (match_operand:SI 1 "register_operand" "r")
10913 (match_operand:SI 2 "register_operand" "r")
10914 (match_operand:SI 3 "const_int_operand" "n")) 0))
10917 (label_ref (match_operand 4 "" ""))
10919 (clobber (reg:CC FLAGS_REG))]
10920 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10921 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10924 [(set (reg:CCC FLAGS_REG)
10932 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10933 (label_ref (match_dup 4))
10935 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10937 ;; Define combination compare-and-branch fp compare instructions to help
10940 (define_insn "*fp_jcc_1_387"
10942 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10943 [(match_operand 1 "register_operand" "f")
10944 (match_operand 2 "nonimmediate_operand" "fm")])
10945 (label_ref (match_operand 3 "" ""))
10947 (clobber (reg:CCFP FPSR_REG))
10948 (clobber (reg:CCFP FLAGS_REG))
10949 (clobber (match_scratch:HI 4 "=a"))]
10951 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10952 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10953 && SELECT_CC_MODE (GET_CODE (operands[0]),
10954 operands[1], operands[2]) == CCFPmode
10958 (define_insn "*fp_jcc_1r_387"
10960 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10961 [(match_operand 1 "register_operand" "f")
10962 (match_operand 2 "nonimmediate_operand" "fm")])
10964 (label_ref (match_operand 3 "" ""))))
10965 (clobber (reg:CCFP FPSR_REG))
10966 (clobber (reg:CCFP FLAGS_REG))
10967 (clobber (match_scratch:HI 4 "=a"))]
10969 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10970 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10971 && SELECT_CC_MODE (GET_CODE (operands[0]),
10972 operands[1], operands[2]) == CCFPmode
10976 (define_insn "*fp_jcc_2_387"
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "register_operand" "f")])
10981 (label_ref (match_operand 3 "" ""))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10991 (define_insn "*fp_jcc_2r_387"
10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994 [(match_operand 1 "register_operand" "f")
10995 (match_operand 2 "register_operand" "f")])
10997 (label_ref (match_operand 3 "" ""))))
10998 (clobber (reg:CCFP FPSR_REG))
10999 (clobber (reg:CCFP FLAGS_REG))
11000 (clobber (match_scratch:HI 4 "=a"))]
11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11006 (define_insn "*fp_jcc_3_387"
11008 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11009 [(match_operand 1 "register_operand" "f")
11010 (match_operand 2 "const0_operand" "")])
11011 (label_ref (match_operand 3 "" ""))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))
11015 (clobber (match_scratch:HI 4 "=a"))]
11016 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11017 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11018 && SELECT_CC_MODE (GET_CODE (operands[0]),
11019 operands[1], operands[2]) == CCFPmode
11025 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11026 [(match_operand 1 "register_operand" "")
11027 (match_operand 2 "nonimmediate_operand" "")])
11028 (match_operand 3 "" "")
11029 (match_operand 4 "" "")))
11030 (clobber (reg:CCFP FPSR_REG))
11031 (clobber (reg:CCFP FLAGS_REG))]
11035 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11036 operands[3], operands[4], NULL_RTX, NULL_RTX);
11042 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11043 [(match_operand 1 "register_operand" "")
11044 (match_operand 2 "general_operand" "")])
11045 (match_operand 3 "" "")
11046 (match_operand 4 "" "")))
11047 (clobber (reg:CCFP FPSR_REG))
11048 (clobber (reg:CCFP FLAGS_REG))
11049 (clobber (match_scratch:HI 5 "=a"))]
11053 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11054 operands[3], operands[4], operands[5], NULL_RTX);
11058 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11059 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11060 ;; with a precedence over other operators and is always put in the first
11061 ;; place. Swap condition and operands to match ficom instruction.
11063 (define_insn "*fp_jcc_4_<mode>_387"
11066 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11067 [(match_operator 1 "float_operator"
11068 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11069 (match_operand 3 "register_operand" "f,f")])
11070 (label_ref (match_operand 4 "" ""))
11072 (clobber (reg:CCFP FPSR_REG))
11073 (clobber (reg:CCFP FLAGS_REG))
11074 (clobber (match_scratch:HI 5 "=a,a"))]
11075 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11076 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11077 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11078 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11085 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11086 [(match_operator 1 "float_operator"
11087 [(match_operand:SWI24 2 "memory_operand" "")])
11088 (match_operand 3 "register_operand" "")])
11089 (match_operand 4 "" "")
11090 (match_operand 5 "" "")))
11091 (clobber (reg:CCFP FPSR_REG))
11092 (clobber (reg:CCFP FLAGS_REG))
11093 (clobber (match_scratch:HI 6 "=a"))]
11097 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11099 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11100 operands[3], operands[7],
11101 operands[4], operands[5], operands[6], NULL_RTX);
11105 ;; %%% Kill this when reload knows how to do it.
11109 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11110 [(match_operator 1 "float_operator"
11111 [(match_operand:SWI24 2 "register_operand" "")])
11112 (match_operand 3 "register_operand" "")])
11113 (match_operand 4 "" "")
11114 (match_operand 5 "" "")))
11115 (clobber (reg:CCFP FPSR_REG))
11116 (clobber (reg:CCFP FLAGS_REG))
11117 (clobber (match_scratch:HI 6 "=a"))]
11121 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11122 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11124 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11125 operands[3], operands[7],
11126 operands[4], operands[5], operands[6], operands[2]);
11130 ;; Unconditional and other jump instructions
11132 (define_insn "jump"
11134 (label_ref (match_operand 0 "" "")))]
11137 [(set_attr "type" "ibr")
11138 (set (attr "length")
11139 (if_then_else (and (ge (minus (match_dup 0) (pc))
11141 (lt (minus (match_dup 0) (pc))
11145 (set_attr "modrm" "0")])
11147 (define_expand "indirect_jump"
11148 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11150 (define_insn "*indirect_jump"
11151 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11154 [(set_attr "type" "ibr")
11155 (set_attr "length_immediate" "0")])
11157 (define_expand "tablejump"
11158 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11159 (use (label_ref (match_operand 1 "" "")))])]
11162 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11163 relative. Convert the relative address to an absolute address. */
11167 enum rtx_code code;
11169 /* We can't use @GOTOFF for text labels on VxWorks;
11170 see gotoff_operand. */
11171 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11175 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11177 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11181 op1 = pic_offset_table_rtx;
11186 op0 = pic_offset_table_rtx;
11190 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11193 else if (TARGET_X32)
11194 operands[0] = convert_memory_address (Pmode, operands[0]);
11197 (define_insn "*tablejump_1"
11198 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11199 (use (label_ref (match_operand 1 "" "")))]
11202 [(set_attr "type" "ibr")
11203 (set_attr "length_immediate" "0")])
11205 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11208 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11209 (set (match_operand:QI 1 "register_operand" "")
11210 (match_operator:QI 2 "ix86_comparison_operator"
11211 [(reg FLAGS_REG) (const_int 0)]))
11212 (set (match_operand 3 "q_regs_operand" "")
11213 (zero_extend (match_dup 1)))]
11214 "(peep2_reg_dead_p (3, operands[1])
11215 || operands_match_p (operands[1], operands[3]))
11216 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11217 [(set (match_dup 4) (match_dup 0))
11218 (set (strict_low_part (match_dup 5))
11221 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11222 operands[5] = gen_lowpart (QImode, operands[3]);
11223 ix86_expand_clear (operands[3]);
11226 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11229 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11230 (set (match_operand:QI 1 "register_operand" "")
11231 (match_operator:QI 2 "ix86_comparison_operator"
11232 [(reg FLAGS_REG) (const_int 0)]))
11233 (parallel [(set (match_operand 3 "q_regs_operand" "")
11234 (zero_extend (match_dup 1)))
11235 (clobber (reg:CC FLAGS_REG))])]
11236 "(peep2_reg_dead_p (3, operands[1])
11237 || operands_match_p (operands[1], operands[3]))
11238 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11239 [(set (match_dup 4) (match_dup 0))
11240 (set (strict_low_part (match_dup 5))
11243 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11244 operands[5] = gen_lowpart (QImode, operands[3]);
11245 ix86_expand_clear (operands[3]);
11248 ;; Call instructions.
11250 ;; The predicates normally associated with named expanders are not properly
11251 ;; checked for calls. This is a bug in the generic code, but it isn't that
11252 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11254 ;; P6 processors will jump to the address after the decrement when %esp
11255 ;; is used as a call operand, so they will execute return address as a code.
11256 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11258 ;; Register constraint for call instruction.
11259 (define_mode_attr c [(SI "l") (DI "r")])
11261 ;; Call subroutine returning no value.
11263 (define_expand "call"
11264 [(call (match_operand:QI 0 "" "")
11265 (match_operand 1 "" ""))
11266 (use (match_operand 2 "" ""))]
11269 ix86_expand_call (NULL, operands[0], operands[1],
11270 operands[2], NULL, false);
11274 (define_expand "sibcall"
11275 [(call (match_operand:QI 0 "" "")
11276 (match_operand 1 "" ""))
11277 (use (match_operand 2 "" ""))]
11280 ix86_expand_call (NULL, operands[0], operands[1],
11281 operands[2], NULL, true);
11285 (define_insn_and_split "*call_vzeroupper"
11286 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11287 (match_operand 1 "" ""))
11288 (unspec [(match_operand 2 "const_int_operand" "")]
11289 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11290 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11292 "&& reload_completed"
11294 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11295 [(set_attr "type" "call")])
11297 (define_insn "*call"
11298 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11299 (match_operand 1 "" ""))]
11300 "!SIBLING_CALL_P (insn)"
11301 "* return ix86_output_call_insn (insn, operands[0]);"
11302 [(set_attr "type" "call")])
11304 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11305 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11306 (match_operand 1 "" ""))
11307 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11308 (clobber (reg:TI XMM6_REG))
11309 (clobber (reg:TI XMM7_REG))
11310 (clobber (reg:TI XMM8_REG))
11311 (clobber (reg:TI XMM9_REG))
11312 (clobber (reg:TI XMM10_REG))
11313 (clobber (reg:TI XMM11_REG))
11314 (clobber (reg:TI XMM12_REG))
11315 (clobber (reg:TI XMM13_REG))
11316 (clobber (reg:TI XMM14_REG))
11317 (clobber (reg:TI XMM15_REG))
11318 (clobber (reg:DI SI_REG))
11319 (clobber (reg:DI DI_REG))
11320 (unspec [(match_operand 2 "const_int_operand" "")]
11321 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11322 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11324 "&& reload_completed"
11326 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11327 [(set_attr "type" "call")])
11329 (define_insn "*call_rex64_ms_sysv"
11330 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11331 (match_operand 1 "" ""))
11332 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11333 (clobber (reg:TI XMM6_REG))
11334 (clobber (reg:TI XMM7_REG))
11335 (clobber (reg:TI XMM8_REG))
11336 (clobber (reg:TI XMM9_REG))
11337 (clobber (reg:TI XMM10_REG))
11338 (clobber (reg:TI XMM11_REG))
11339 (clobber (reg:TI XMM12_REG))
11340 (clobber (reg:TI XMM13_REG))
11341 (clobber (reg:TI XMM14_REG))
11342 (clobber (reg:TI XMM15_REG))
11343 (clobber (reg:DI SI_REG))
11344 (clobber (reg:DI DI_REG))]
11345 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[0]);"
11347 [(set_attr "type" "call")])
11349 (define_insn_and_split "*sibcall_vzeroupper"
11350 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11351 (match_operand 1 "" ""))
11352 (unspec [(match_operand 2 "const_int_operand" "")]
11353 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11354 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11356 "&& reload_completed"
11358 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11359 [(set_attr "type" "call")])
11361 (define_insn "*sibcall"
11362 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11363 (match_operand 1 "" ""))]
11364 "SIBLING_CALL_P (insn)"
11365 "* return ix86_output_call_insn (insn, operands[0]);"
11366 [(set_attr "type" "call")])
11368 (define_expand "call_pop"
11369 [(parallel [(call (match_operand:QI 0 "" "")
11370 (match_operand:SI 1 "" ""))
11371 (set (reg:SI SP_REG)
11372 (plus:SI (reg:SI SP_REG)
11373 (match_operand:SI 3 "" "")))])]
11376 ix86_expand_call (NULL, operands[0], operands[1],
11377 operands[2], operands[3], false);
11381 (define_insn_and_split "*call_pop_vzeroupper"
11382 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383 (match_operand:SI 1 "" ""))
11384 (set (reg:SI SP_REG)
11385 (plus:SI (reg:SI SP_REG)
11386 (match_operand:SI 2 "immediate_operand" "i")))
11387 (unspec [(match_operand 3 "const_int_operand" "")]
11388 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11389 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11391 "&& reload_completed"
11393 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11394 [(set_attr "type" "call")])
11396 (define_insn "*call_pop"
11397 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11398 (match_operand 1 "" ""))
11399 (set (reg:SI SP_REG)
11400 (plus:SI (reg:SI SP_REG)
11401 (match_operand:SI 2 "immediate_operand" "i")))]
11402 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11403 "* return ix86_output_call_insn (insn, operands[0]);"
11404 [(set_attr "type" "call")])
11406 (define_insn_and_split "*sibcall_pop_vzeroupper"
11407 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408 (match_operand 1 "" ""))
11409 (set (reg:SI SP_REG)
11410 (plus:SI (reg:SI SP_REG)
11411 (match_operand:SI 2 "immediate_operand" "i")))
11412 (unspec [(match_operand 3 "const_int_operand" "")]
11413 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11414 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11416 "&& reload_completed"
11418 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11419 [(set_attr "type" "call")])
11421 (define_insn "*sibcall_pop"
11422 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11423 (match_operand 1 "" ""))
11424 (set (reg:SI SP_REG)
11425 (plus:SI (reg:SI SP_REG)
11426 (match_operand:SI 2 "immediate_operand" "i")))]
11427 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11428 "* return ix86_output_call_insn (insn, operands[0]);"
11429 [(set_attr "type" "call")])
11431 ;; Call subroutine, returning value in operand 0
11433 (define_expand "call_value"
11434 [(set (match_operand 0 "" "")
11435 (call (match_operand:QI 1 "" "")
11436 (match_operand 2 "" "")))
11437 (use (match_operand 3 "" ""))]
11440 ix86_expand_call (operands[0], operands[1], operands[2],
11441 operands[3], NULL, false);
11445 (define_expand "sibcall_value"
11446 [(set (match_operand 0 "" "")
11447 (call (match_operand:QI 1 "" "")
11448 (match_operand 2 "" "")))
11449 (use (match_operand 3 "" ""))]
11452 ix86_expand_call (operands[0], operands[1], operands[2],
11453 operands[3], NULL, true);
11457 (define_insn_and_split "*call_value_vzeroupper"
11458 [(set (match_operand 0 "" "")
11459 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11460 (match_operand 2 "" "")))
11461 (unspec [(match_operand 3 "const_int_operand" "")]
11462 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11463 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11465 "&& reload_completed"
11467 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11468 [(set_attr "type" "callv")])
11470 (define_insn "*call_value"
11471 [(set (match_operand 0 "" "")
11472 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11473 (match_operand 2 "" "")))]
11474 "!SIBLING_CALL_P (insn)"
11475 "* return ix86_output_call_insn (insn, operands[1]);"
11476 [(set_attr "type" "callv")])
11478 (define_insn_and_split "*sibcall_value_vzeroupper"
11479 [(set (match_operand 0 "" "")
11480 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11481 (match_operand 2 "" "")))
11482 (unspec [(match_operand 3 "const_int_operand" "")]
11483 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11484 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11486 "&& reload_completed"
11488 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11489 [(set_attr "type" "callv")])
11491 (define_insn "*sibcall_value"
11492 [(set (match_operand 0 "" "")
11493 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11494 (match_operand 2 "" "")))]
11495 "SIBLING_CALL_P (insn)"
11496 "* return ix86_output_call_insn (insn, operands[1]);"
11497 [(set_attr "type" "callv")])
11499 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11500 [(set (match_operand 0 "" "")
11501 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11502 (match_operand 2 "" "")))
11503 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11504 (clobber (reg:TI XMM6_REG))
11505 (clobber (reg:TI XMM7_REG))
11506 (clobber (reg:TI XMM8_REG))
11507 (clobber (reg:TI XMM9_REG))
11508 (clobber (reg:TI XMM10_REG))
11509 (clobber (reg:TI XMM11_REG))
11510 (clobber (reg:TI XMM12_REG))
11511 (clobber (reg:TI XMM13_REG))
11512 (clobber (reg:TI XMM14_REG))
11513 (clobber (reg:TI XMM15_REG))
11514 (clobber (reg:DI SI_REG))
11515 (clobber (reg:DI DI_REG))
11516 (unspec [(match_operand 3 "const_int_operand" "")]
11517 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11518 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11520 "&& reload_completed"
11522 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11523 [(set_attr "type" "callv")])
11525 (define_insn "*call_value_rex64_ms_sysv"
11526 [(set (match_operand 0 "" "")
11527 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11528 (match_operand 2 "" "")))
11529 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11530 (clobber (reg:TI XMM6_REG))
11531 (clobber (reg:TI XMM7_REG))
11532 (clobber (reg:TI XMM8_REG))
11533 (clobber (reg:TI XMM9_REG))
11534 (clobber (reg:TI XMM10_REG))
11535 (clobber (reg:TI XMM11_REG))
11536 (clobber (reg:TI XMM12_REG))
11537 (clobber (reg:TI XMM13_REG))
11538 (clobber (reg:TI XMM14_REG))
11539 (clobber (reg:TI XMM15_REG))
11540 (clobber (reg:DI SI_REG))
11541 (clobber (reg:DI DI_REG))]
11542 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543 "* return ix86_output_call_insn (insn, operands[1]);"
11544 [(set_attr "type" "callv")])
11546 (define_expand "call_value_pop"
11547 [(parallel [(set (match_operand 0 "" "")
11548 (call (match_operand:QI 1 "" "")
11549 (match_operand:SI 2 "" "")))
11550 (set (reg:SI SP_REG)
11551 (plus:SI (reg:SI SP_REG)
11552 (match_operand:SI 4 "" "")))])]
11555 ix86_expand_call (operands[0], operands[1], operands[2],
11556 operands[3], operands[4], false);
11560 (define_insn_and_split "*call_value_pop_vzeroupper"
11561 [(set (match_operand 0 "" "")
11562 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11563 (match_operand 2 "" "")))
11564 (set (reg:SI SP_REG)
11565 (plus:SI (reg:SI SP_REG)
11566 (match_operand:SI 3 "immediate_operand" "i")))
11567 (unspec [(match_operand 4 "const_int_operand" "")]
11568 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11569 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11571 "&& reload_completed"
11573 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11574 [(set_attr "type" "callv")])
11576 (define_insn "*call_value_pop"
11577 [(set (match_operand 0 "" "")
11578 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11579 (match_operand 2 "" "")))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 3 "immediate_operand" "i")))]
11583 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11584 "* return ix86_output_call_insn (insn, operands[1]);"
11585 [(set_attr "type" "callv")])
11587 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11588 [(set (match_operand 0 "" "")
11589 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11590 (match_operand 2 "" "")))
11591 (set (reg:SI SP_REG)
11592 (plus:SI (reg:SI SP_REG)
11593 (match_operand:SI 3 "immediate_operand" "i")))
11594 (unspec [(match_operand 4 "const_int_operand" "")]
11595 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11596 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11598 "&& reload_completed"
11600 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11601 [(set_attr "type" "callv")])
11603 (define_insn "*sibcall_value_pop"
11604 [(set (match_operand 0 "" "")
11605 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11606 (match_operand 2 "" "")))
11607 (set (reg:SI SP_REG)
11608 (plus:SI (reg:SI SP_REG)
11609 (match_operand:SI 3 "immediate_operand" "i")))]
11610 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11611 "* return ix86_output_call_insn (insn, operands[1]);"
11612 [(set_attr "type" "callv")])
11614 ;; Call subroutine returning any type.
11616 (define_expand "untyped_call"
11617 [(parallel [(call (match_operand 0 "" "")
11619 (match_operand 1 "" "")
11620 (match_operand 2 "" "")])]
11625 /* In order to give reg-stack an easier job in validating two
11626 coprocessor registers as containing a possible return value,
11627 simply pretend the untyped call returns a complex long double
11630 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11631 and should have the default ABI. */
11633 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11634 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11635 operands[0], const0_rtx,
11636 GEN_INT ((TARGET_64BIT
11637 ? (ix86_abi == SYSV_ABI
11638 ? X86_64_SSE_REGPARM_MAX
11639 : X86_64_MS_SSE_REGPARM_MAX)
11640 : X86_32_SSE_REGPARM_MAX)
11644 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11646 rtx set = XVECEXP (operands[2], 0, i);
11647 emit_move_insn (SET_DEST (set), SET_SRC (set));
11650 /* The optimizer does not know that the call sets the function value
11651 registers we stored in the result block. We avoid problems by
11652 claiming that all hard registers are used and clobbered at this
11654 emit_insn (gen_blockage ());
11659 ;; Prologue and epilogue instructions
11661 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11662 ;; all of memory. This blocks insns from being moved across this point.
11664 (define_insn "blockage"
11665 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11668 [(set_attr "length" "0")])
11670 ;; Do not schedule instructions accessing memory across this point.
11672 (define_expand "memory_blockage"
11673 [(set (match_dup 0)
11674 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11677 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11678 MEM_VOLATILE_P (operands[0]) = 1;
11681 (define_insn "*memory_blockage"
11682 [(set (match_operand:BLK 0 "" "")
11683 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11686 [(set_attr "length" "0")])
11688 ;; As USE insns aren't meaningful after reload, this is used instead
11689 ;; to prevent deleting instructions setting registers for PIC code
11690 (define_insn "prologue_use"
11691 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11694 [(set_attr "length" "0")])
11696 ;; Insn emitted into the body of a function to return from a function.
11697 ;; This is only done if the function's epilogue is known to be simple.
11698 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11700 (define_expand "return"
11702 "ix86_can_use_return_insn_p ()"
11704 if (crtl->args.pops_args)
11706 rtx popc = GEN_INT (crtl->args.pops_args);
11707 emit_jump_insn (gen_simple_return_pop_internal (popc));
11712 ;; We need to disable this for TARGET_SEH, as otherwise
11713 ;; shrink-wrapped prologue gets enabled too. This might exceed
11714 ;; the maximum size of prologue in unwind information.
11716 (define_expand "simple_return"
11720 if (crtl->args.pops_args)
11722 rtx popc = GEN_INT (crtl->args.pops_args);
11723 emit_jump_insn (gen_simple_return_pop_internal (popc));
11728 (define_insn "simple_return_internal"
11732 [(set_attr "length" "1")
11733 (set_attr "atom_unit" "jeu")
11734 (set_attr "length_immediate" "0")
11735 (set_attr "modrm" "0")])
11737 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11738 ;; instruction Athlon and K8 have.
11740 (define_insn "simple_return_internal_long"
11742 (unspec [(const_int 0)] UNSPEC_REP)]
11745 [(set_attr "length" "2")
11746 (set_attr "atom_unit" "jeu")
11747 (set_attr "length_immediate" "0")
11748 (set_attr "prefix_rep" "1")
11749 (set_attr "modrm" "0")])
11751 (define_insn "simple_return_pop_internal"
11753 (use (match_operand:SI 0 "const_int_operand" ""))]
11756 [(set_attr "length" "3")
11757 (set_attr "atom_unit" "jeu")
11758 (set_attr "length_immediate" "2")
11759 (set_attr "modrm" "0")])
11761 (define_insn "simple_return_indirect_internal"
11763 (use (match_operand:SI 0 "register_operand" "r"))]
11766 [(set_attr "type" "ibr")
11767 (set_attr "length_immediate" "0")])
11773 [(set_attr "length" "1")
11774 (set_attr "length_immediate" "0")
11775 (set_attr "modrm" "0")])
11777 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11778 (define_insn "nops"
11779 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11783 int num = INTVAL (operands[0]);
11785 gcc_assert (num >= 1 && num <= 8);
11788 fputs ("\tnop\n", asm_out_file);
11792 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11793 (set_attr "length_immediate" "0")
11794 (set_attr "modrm" "0")])
11796 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11797 ;; branch prediction penalty for the third jump in a 16-byte
11801 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11804 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11805 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11807 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11808 The align insn is used to avoid 3 jump instructions in the row to improve
11809 branch prediction and the benefits hardly outweigh the cost of extra 8
11810 nops on the average inserted by full alignment pseudo operation. */
11814 [(set_attr "length" "16")])
11816 (define_expand "prologue"
11819 "ix86_expand_prologue (); DONE;")
11821 (define_insn "set_got"
11822 [(set (match_operand:SI 0 "register_operand" "=r")
11823 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11824 (clobber (reg:CC FLAGS_REG))]
11826 "* return output_set_got (operands[0], NULL_RTX);"
11827 [(set_attr "type" "multi")
11828 (set_attr "length" "12")])
11830 (define_insn "set_got_labelled"
11831 [(set (match_operand:SI 0 "register_operand" "=r")
11832 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11834 (clobber (reg:CC FLAGS_REG))]
11836 "* return output_set_got (operands[0], operands[1]);"
11837 [(set_attr "type" "multi")
11838 (set_attr "length" "12")])
11840 (define_insn "set_got_rex64"
11841 [(set (match_operand:DI 0 "register_operand" "=r")
11842 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11844 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11845 [(set_attr "type" "lea")
11846 (set_attr "length_address" "4")
11847 (set_attr "mode" "DI")])
11849 (define_insn "set_rip_rex64"
11850 [(set (match_operand:DI 0 "register_operand" "=r")
11851 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11853 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11854 [(set_attr "type" "lea")
11855 (set_attr "length_address" "4")
11856 (set_attr "mode" "DI")])
11858 (define_insn "set_got_offset_rex64"
11859 [(set (match_operand:DI 0 "register_operand" "=r")
11861 [(label_ref (match_operand 1 "" ""))]
11862 UNSPEC_SET_GOT_OFFSET))]
11864 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11865 [(set_attr "type" "imov")
11866 (set_attr "length_immediate" "0")
11867 (set_attr "length_address" "8")
11868 (set_attr "mode" "DI")])
11870 (define_expand "epilogue"
11873 "ix86_expand_epilogue (1); DONE;")
11875 (define_expand "sibcall_epilogue"
11878 "ix86_expand_epilogue (0); DONE;")
11880 (define_expand "eh_return"
11881 [(use (match_operand 0 "register_operand" ""))]
11884 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11886 /* Tricky bit: we write the address of the handler to which we will
11887 be returning into someone else's stack frame, one word below the
11888 stack address we wish to restore. */
11889 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11890 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11891 tmp = gen_rtx_MEM (Pmode, tmp);
11892 emit_move_insn (tmp, ra);
11894 emit_jump_insn (gen_eh_return_internal ());
11899 (define_insn_and_split "eh_return_internal"
11903 "epilogue_completed"
11905 "ix86_expand_epilogue (2); DONE;")
11907 (define_insn "leave"
11908 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11909 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11910 (clobber (mem:BLK (scratch)))]
11913 [(set_attr "type" "leave")])
11915 (define_insn "leave_rex64"
11916 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11917 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11918 (clobber (mem:BLK (scratch)))]
11921 [(set_attr "type" "leave")])
11923 ;; Handle -fsplit-stack.
11925 (define_expand "split_stack_prologue"
11929 ix86_expand_split_stack_prologue ();
11933 ;; In order to support the call/return predictor, we use a return
11934 ;; instruction which the middle-end doesn't see.
11935 (define_insn "split_stack_return"
11936 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11937 UNSPECV_SPLIT_STACK_RETURN)]
11940 if (operands[0] == const0_rtx)
11945 [(set_attr "atom_unit" "jeu")
11946 (set_attr "modrm" "0")
11947 (set (attr "length")
11948 (if_then_else (match_operand:SI 0 "const0_operand" "")
11951 (set (attr "length_immediate")
11952 (if_then_else (match_operand:SI 0 "const0_operand" "")
11956 ;; If there are operand 0 bytes available on the stack, jump to
11959 (define_expand "split_stack_space_check"
11960 [(set (pc) (if_then_else
11961 (ltu (minus (reg SP_REG)
11962 (match_operand 0 "register_operand" ""))
11963 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11964 (label_ref (match_operand 1 "" ""))
11968 rtx reg, size, limit;
11970 reg = gen_reg_rtx (Pmode);
11971 size = force_reg (Pmode, operands[0]);
11972 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11973 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11974 UNSPEC_STACK_CHECK);
11975 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11976 ix86_expand_branch (GEU, reg, limit, operands[1]);
11981 ;; Bit manipulation instructions.
11983 (define_expand "ffs<mode>2"
11984 [(set (match_dup 2) (const_int -1))
11985 (parallel [(set (reg:CCZ FLAGS_REG)
11987 (match_operand:SWI48 1 "nonimmediate_operand" "")
11989 (set (match_operand:SWI48 0 "register_operand" "")
11990 (ctz:SWI48 (match_dup 1)))])
11991 (set (match_dup 0) (if_then_else:SWI48
11992 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11995 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11996 (clobber (reg:CC FLAGS_REG))])]
11999 if (<MODE>mode == SImode && !TARGET_CMOVE)
12001 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12004 operands[2] = gen_reg_rtx (<MODE>mode);
12007 (define_insn_and_split "ffssi2_no_cmove"
12008 [(set (match_operand:SI 0 "register_operand" "=r")
12009 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12010 (clobber (match_scratch:SI 2 "=&q"))
12011 (clobber (reg:CC FLAGS_REG))]
12014 "&& reload_completed"
12015 [(parallel [(set (reg:CCZ FLAGS_REG)
12016 (compare:CCZ (match_dup 1) (const_int 0)))
12017 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12018 (set (strict_low_part (match_dup 3))
12019 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12020 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12021 (clobber (reg:CC FLAGS_REG))])
12022 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12023 (clobber (reg:CC FLAGS_REG))])
12024 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12025 (clobber (reg:CC FLAGS_REG))])]
12027 operands[3] = gen_lowpart (QImode, operands[2]);
12028 ix86_expand_clear (operands[2]);
12031 (define_insn "*ffs<mode>_1"
12032 [(set (reg:CCZ FLAGS_REG)
12033 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12035 (set (match_operand:SWI48 0 "register_operand" "=r")
12036 (ctz:SWI48 (match_dup 1)))]
12038 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12039 [(set_attr "type" "alu1")
12040 (set_attr "prefix_0f" "1")
12041 (set_attr "mode" "<MODE>")])
12043 (define_insn "ctz<mode>2"
12044 [(set (match_operand:SWI248 0 "register_operand" "=r")
12045 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12046 (clobber (reg:CC FLAGS_REG))]
12050 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12052 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12054 [(set_attr "type" "alu1")
12055 (set_attr "prefix_0f" "1")
12056 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12057 (set_attr "mode" "<MODE>")])
12059 (define_expand "clz<mode>2"
12061 [(set (match_operand:SWI248 0 "register_operand" "")
12064 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12065 (clobber (reg:CC FLAGS_REG))])
12067 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12068 (clobber (reg:CC FLAGS_REG))])]
12073 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12076 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12079 (define_insn "clz<mode>2_lzcnt"
12080 [(set (match_operand:SWI248 0 "register_operand" "=r")
12081 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12082 (clobber (reg:CC FLAGS_REG))]
12084 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12085 [(set_attr "prefix_rep" "1")
12086 (set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12089 ;; BMI instructions.
12090 (define_insn "*bmi_andn_<mode>"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12094 (match_operand:SWI48 1 "register_operand" "r"))
12095 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12096 (clobber (reg:CC FLAGS_REG))]
12098 "andn\t{%2, %1, %0|%0, %1, %2}"
12099 [(set_attr "type" "bitmanip")
12100 (set_attr "mode" "<MODE>")])
12102 (define_insn "bmi_bextr_<mode>"
12103 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12105 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12107 (clobber (reg:CC FLAGS_REG))]
12109 "bextr\t{%2, %1, %0|%0, %1, %2}"
12110 [(set_attr "type" "bitmanip")
12111 (set_attr "mode" "<MODE>")])
12113 (define_insn "*bmi_blsi_<mode>"
12114 [(set (match_operand:SWI48 0 "register_operand" "=r")
12117 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "blsi\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "*bmi_blsmsk_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12132 (clobber (reg:CC FLAGS_REG))]
12134 "blsmsk\t{%1, %0|%0, %1}"
12135 [(set_attr "type" "bitmanip")
12136 (set_attr "mode" "<MODE>")])
12138 (define_insn "*bmi_blsr_<mode>"
12139 [(set (match_operand:SWI48 0 "register_operand" "=r")
12142 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12145 (clobber (reg:CC FLAGS_REG))]
12147 "blsr\t{%1, %0|%0, %1}"
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "mode" "<MODE>")])
12151 ;; BMI2 instructions.
12152 (define_insn "bmi2_bzhi_<mode>3"
12153 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12155 (lshiftrt:SWI48 (const_int -1)
12156 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12157 (clobber (reg:CC FLAGS_REG))]
12159 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "prefix" "vex")
12162 (set_attr "mode" "<MODE>")])
12164 (define_insn "bmi2_pdep_<mode>3"
12165 [(set (match_operand:SWI48 0 "register_operand" "=r")
12166 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12167 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12170 "pdep\t{%2, %1, %0|%0, %1, %2}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "prefix" "vex")
12173 (set_attr "mode" "<MODE>")])
12175 (define_insn "bmi2_pext_<mode>3"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12178 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12181 "pext\t{%2, %1, %0|%0, %1, %2}"
12182 [(set_attr "type" "bitmanip")
12183 (set_attr "prefix" "vex")
12184 (set_attr "mode" "<MODE>")])
12186 ;; TBM instructions.
12187 (define_insn "tbm_bextri_<mode>"
12188 [(set (match_operand:SWI48 0 "register_operand" "=r")
12189 (zero_extract:SWI48
12190 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12191 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12192 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12193 (clobber (reg:CC FLAGS_REG))]
12196 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12197 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12199 [(set_attr "type" "bitmanip")
12200 (set_attr "mode" "<MODE>")])
12202 (define_insn "*tbm_blcfill_<mode>"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12206 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209 (clobber (reg:CC FLAGS_REG))]
12211 "blcfill\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "bitmanip")
12213 (set_attr "mode" "<MODE>")])
12215 (define_insn "*tbm_blci_<mode>"
12216 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12223 (clobber (reg:CC FLAGS_REG))]
12225 "blci\t{%1, %0|%0, %1}"
12226 [(set_attr "type" "bitmanip")
12227 (set_attr "mode" "<MODE>")])
12229 (define_insn "*tbm_blcic_<mode>"
12230 [(set (match_operand:SWI48 0 "register_operand" "=r")
12233 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12237 (clobber (reg:CC FLAGS_REG))]
12239 "blcic\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "bitmanip")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "*tbm_blcmsk_<mode>"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12250 (clobber (reg:CC FLAGS_REG))]
12252 "blcmsk\t{%1, %0|%0, %1}"
12253 [(set_attr "type" "bitmanip")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*tbm_blcs_<mode>"
12257 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263 (clobber (reg:CC FLAGS_REG))]
12265 "blcs\t{%1, %0|%0, %1}"
12266 [(set_attr "type" "bitmanip")
12267 (set_attr "mode" "<MODE>")])
12269 (define_insn "*tbm_blsfill_<mode>"
12270 [(set (match_operand:SWI48 0 "register_operand" "=r")
12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12276 (clobber (reg:CC FLAGS_REG))]
12278 "blsfill\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "bitmanip")
12280 (set_attr "mode" "<MODE>")])
12282 (define_insn "*tbm_blsic_<mode>"
12283 [(set (match_operand:SWI48 0 "register_operand" "=r")
12286 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12290 (clobber (reg:CC FLAGS_REG))]
12292 "blsic\t{%1, %0|%0, %1}"
12293 [(set_attr "type" "bitmanip")
12294 (set_attr "mode" "<MODE>")])
12296 (define_insn "*tbm_t1mskc_<mode>"
12297 [(set (match_operand:SWI48 0 "register_operand" "=r")
12300 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12304 (clobber (reg:CC FLAGS_REG))]
12306 "t1mskc\t{%1, %0|%0, %1}"
12307 [(set_attr "type" "bitmanip")
12308 (set_attr "mode" "<MODE>")])
12310 (define_insn "*tbm_tzmsk_<mode>"
12311 [(set (match_operand:SWI48 0 "register_operand" "=r")
12314 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12318 (clobber (reg:CC FLAGS_REG))]
12320 "tzmsk\t{%1, %0|%0, %1}"
12321 [(set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12324 (define_insn "bsr_rex64"
12325 [(set (match_operand:DI 0 "register_operand" "=r")
12326 (minus:DI (const_int 63)
12327 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12328 (clobber (reg:CC FLAGS_REG))]
12330 "bsr{q}\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "alu1")
12332 (set_attr "prefix_0f" "1")
12333 (set_attr "mode" "DI")])
12336 [(set (match_operand:SI 0 "register_operand" "=r")
12337 (minus:SI (const_int 31)
12338 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12339 (clobber (reg:CC FLAGS_REG))]
12341 "bsr{l}\t{%1, %0|%0, %1}"
12342 [(set_attr "type" "alu1")
12343 (set_attr "prefix_0f" "1")
12344 (set_attr "mode" "SI")])
12346 (define_insn "*bsrhi"
12347 [(set (match_operand:HI 0 "register_operand" "=r")
12348 (minus:HI (const_int 15)
12349 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12350 (clobber (reg:CC FLAGS_REG))]
12352 "bsr{w}\t{%1, %0|%0, %1}"
12353 [(set_attr "type" "alu1")
12354 (set_attr "prefix_0f" "1")
12355 (set_attr "mode" "HI")])
12357 (define_insn "popcount<mode>2"
12358 [(set (match_operand:SWI248 0 "register_operand" "=r")
12360 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12361 (clobber (reg:CC FLAGS_REG))]
12365 return "popcnt\t{%1, %0|%0, %1}";
12367 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12370 [(set_attr "prefix_rep" "1")
12371 (set_attr "type" "bitmanip")
12372 (set_attr "mode" "<MODE>")])
12374 (define_insn "*popcount<mode>2_cmp"
12375 [(set (reg FLAGS_REG)
12378 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12380 (set (match_operand:SWI248 0 "register_operand" "=r")
12381 (popcount:SWI248 (match_dup 1)))]
12382 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12385 return "popcnt\t{%1, %0|%0, %1}";
12387 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12390 [(set_attr "prefix_rep" "1")
12391 (set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*popcountsi2_cmp_zext"
12395 [(set (reg FLAGS_REG)
12397 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12399 (set (match_operand:DI 0 "register_operand" "=r")
12400 (zero_extend:DI(popcount:SI (match_dup 1))))]
12401 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12404 return "popcnt\t{%1, %0|%0, %1}";
12406 return "popcnt{l}\t{%1, %0|%0, %1}";
12409 [(set_attr "prefix_rep" "1")
12410 (set_attr "type" "bitmanip")
12411 (set_attr "mode" "SI")])
12413 (define_expand "bswap<mode>2"
12414 [(set (match_operand:SWI48 0 "register_operand" "")
12415 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12418 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12420 rtx x = operands[0];
12422 emit_move_insn (x, operands[1]);
12423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12425 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12430 (define_insn "*bswap<mode>2_movbe"
12431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12432 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12437 movbe\t{%1, %0|%0, %1}
12438 movbe\t{%1, %0|%0, %1}"
12439 [(set_attr "type" "bitmanip,imov,imov")
12440 (set_attr "modrm" "0,1,1")
12441 (set_attr "prefix_0f" "*,1,1")
12442 (set_attr "prefix_extra" "*,1,1")
12443 (set_attr "mode" "<MODE>")])
12445 (define_insn "*bswap<mode>2_1"
12446 [(set (match_operand:SWI48 0 "register_operand" "=r")
12447 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12450 [(set_attr "type" "bitmanip")
12451 (set_attr "modrm" "0")
12452 (set_attr "mode" "<MODE>")])
12454 (define_insn "*bswaphi_lowpart_1"
12455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12456 (bswap:HI (match_dup 0)))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12460 xchg{b}\t{%h0, %b0|%b0, %h0}
12461 rol{w}\t{$8, %0|%0, 8}"
12462 [(set_attr "length" "2,4")
12463 (set_attr "mode" "QI,HI")])
12465 (define_insn "bswaphi_lowpart"
12466 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12467 (bswap:HI (match_dup 0)))
12468 (clobber (reg:CC FLAGS_REG))]
12470 "rol{w}\t{$8, %0|%0, 8}"
12471 [(set_attr "length" "4")
12472 (set_attr "mode" "HI")])
12474 (define_expand "paritydi2"
12475 [(set (match_operand:DI 0 "register_operand" "")
12476 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12479 rtx scratch = gen_reg_rtx (QImode);
12482 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12483 NULL_RTX, operands[1]));
12485 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12486 gen_rtx_REG (CCmode, FLAGS_REG),
12488 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12491 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12494 rtx tmp = gen_reg_rtx (SImode);
12496 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12497 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12502 (define_expand "paritysi2"
12503 [(set (match_operand:SI 0 "register_operand" "")
12504 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12507 rtx scratch = gen_reg_rtx (QImode);
12510 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12512 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12513 gen_rtx_REG (CCmode, FLAGS_REG),
12515 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12517 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12521 (define_insn_and_split "paritydi2_cmp"
12522 [(set (reg:CC FLAGS_REG)
12523 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12525 (clobber (match_scratch:DI 0 "=r"))
12526 (clobber (match_scratch:SI 1 "=&r"))
12527 (clobber (match_scratch:HI 2 "=Q"))]
12530 "&& reload_completed"
12532 [(set (match_dup 1)
12533 (xor:SI (match_dup 1) (match_dup 4)))
12534 (clobber (reg:CC FLAGS_REG))])
12536 [(set (reg:CC FLAGS_REG)
12537 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12538 (clobber (match_dup 1))
12539 (clobber (match_dup 2))])]
12541 operands[4] = gen_lowpart (SImode, operands[3]);
12545 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12546 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12549 operands[1] = gen_highpart (SImode, operands[3]);
12552 (define_insn_and_split "paritysi2_cmp"
12553 [(set (reg:CC FLAGS_REG)
12554 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12556 (clobber (match_scratch:SI 0 "=r"))
12557 (clobber (match_scratch:HI 1 "=&Q"))]
12560 "&& reload_completed"
12562 [(set (match_dup 1)
12563 (xor:HI (match_dup 1) (match_dup 3)))
12564 (clobber (reg:CC FLAGS_REG))])
12566 [(set (reg:CC FLAGS_REG)
12567 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12568 (clobber (match_dup 1))])]
12570 operands[3] = gen_lowpart (HImode, operands[2]);
12572 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12573 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12576 (define_insn "*parityhi2_cmp"
12577 [(set (reg:CC FLAGS_REG)
12578 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12580 (clobber (match_scratch:HI 0 "=Q"))]
12582 "xor{b}\t{%h0, %b0|%b0, %h0}"
12583 [(set_attr "length" "2")
12584 (set_attr "mode" "HI")])
12587 ;; Thread-local storage patterns for ELF.
12589 ;; Note that these code sequences must appear exactly as shown
12590 ;; in order to allow linker relaxation.
12592 (define_insn "*tls_global_dynamic_32_gnu"
12593 [(set (match_operand:SI 0 "register_operand" "=a")
12595 [(match_operand:SI 1 "register_operand" "b")
12596 (match_operand:SI 2 "tls_symbolic_operand" "")
12597 (match_operand:SI 3 "constant_call_address_operand" "z")]
12599 (clobber (match_scratch:SI 4 "=d"))
12600 (clobber (match_scratch:SI 5 "=c"))
12601 (clobber (reg:CC FLAGS_REG))]
12602 "!TARGET_64BIT && TARGET_GNU_TLS"
12605 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12606 if (TARGET_SUN_TLS)
12607 #ifdef HAVE_AS_IX86_TLSGDPLT
12608 return "call\t%a2@tlsgdplt";
12610 return "call\t%p3@plt";
12612 return "call\t%P3";
12614 [(set_attr "type" "multi")
12615 (set_attr "length" "12")])
12617 (define_expand "tls_global_dynamic_32"
12619 [(set (match_operand:SI 0 "register_operand" "")
12620 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12621 (match_operand:SI 1 "tls_symbolic_operand" "")
12622 (match_operand:SI 3 "constant_call_address_operand" "")]
12624 (clobber (match_scratch:SI 4 ""))
12625 (clobber (match_scratch:SI 5 ""))
12626 (clobber (reg:CC FLAGS_REG))])])
12628 (define_insn "*tls_global_dynamic_64"
12629 [(set (match_operand:DI 0 "register_operand" "=a")
12631 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12632 (match_operand:DI 3 "" "")))
12633 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12638 fputs (ASM_BYTE "0x66\n", asm_out_file);
12640 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12641 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12642 fputs ("\trex64\n", asm_out_file);
12643 if (TARGET_SUN_TLS)
12644 return "call\t%p2@plt";
12645 return "call\t%P2";
12647 [(set_attr "type" "multi")
12648 (set (attr "length")
12649 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12651 (define_expand "tls_global_dynamic_64"
12653 [(set (match_operand:DI 0 "register_operand" "")
12655 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12657 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12660 (define_insn "*tls_local_dynamic_base_32_gnu"
12661 [(set (match_operand:SI 0 "register_operand" "=a")
12663 [(match_operand:SI 1 "register_operand" "b")
12664 (match_operand:SI 2 "constant_call_address_operand" "z")]
12665 UNSPEC_TLS_LD_BASE))
12666 (clobber (match_scratch:SI 3 "=d"))
12667 (clobber (match_scratch:SI 4 "=c"))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "!TARGET_64BIT && TARGET_GNU_TLS"
12672 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12673 if (TARGET_SUN_TLS)
12674 #ifdef HAVE_AS_IX86_TLSLDMPLT
12675 return "call\t%&@tlsldmplt";
12677 return "call\t%p2@plt";
12679 return "call\t%P2";
12681 [(set_attr "type" "multi")
12682 (set_attr "length" "11")])
12684 (define_expand "tls_local_dynamic_base_32"
12686 [(set (match_operand:SI 0 "register_operand" "")
12688 [(match_operand:SI 1 "register_operand" "")
12689 (match_operand:SI 2 "constant_call_address_operand" "")]
12690 UNSPEC_TLS_LD_BASE))
12691 (clobber (match_scratch:SI 3 ""))
12692 (clobber (match_scratch:SI 4 ""))
12693 (clobber (reg:CC FLAGS_REG))])])
12695 (define_insn "*tls_local_dynamic_base_64"
12696 [(set (match_operand:DI 0 "register_operand" "=a")
12698 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12699 (match_operand:DI 2 "" "")))
12700 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12704 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12705 if (TARGET_SUN_TLS)
12706 return "call\t%p1@plt";
12707 return "call\t%P1";
12709 [(set_attr "type" "multi")
12710 (set_attr "length" "12")])
12712 (define_expand "tls_local_dynamic_base_64"
12714 [(set (match_operand:DI 0 "register_operand" "")
12716 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12718 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12720 ;; Local dynamic of a single variable is a lose. Show combine how
12721 ;; to convert that back to global dynamic.
12723 (define_insn_and_split "*tls_local_dynamic_32_once"
12724 [(set (match_operand:SI 0 "register_operand" "=a")
12726 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12727 (match_operand:SI 2 "constant_call_address_operand" "z")]
12728 UNSPEC_TLS_LD_BASE)
12729 (const:SI (unspec:SI
12730 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12732 (clobber (match_scratch:SI 4 "=d"))
12733 (clobber (match_scratch:SI 5 "=c"))
12734 (clobber (reg:CC FLAGS_REG))]
12739 [(set (match_dup 0)
12740 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12742 (clobber (match_dup 4))
12743 (clobber (match_dup 5))
12744 (clobber (reg:CC FLAGS_REG))])])
12746 ;; Segment register for the thread base ptr load
12747 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12749 ;; Load and add the thread base pointer from %<tp_seg>:0.
12750 (define_insn "*load_tp_x32"
12751 [(set (match_operand:SI 0 "register_operand" "=r")
12752 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12754 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12755 [(set_attr "type" "imov")
12756 (set_attr "modrm" "0")
12757 (set_attr "length" "7")
12758 (set_attr "memory" "load")
12759 (set_attr "imm_disp" "false")])
12761 (define_insn "*load_tp_x32_zext"
12762 [(set (match_operand:DI 0 "register_operand" "=r")
12763 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12765 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12766 [(set_attr "type" "imov")
12767 (set_attr "modrm" "0")
12768 (set_attr "length" "7")
12769 (set_attr "memory" "load")
12770 (set_attr "imm_disp" "false")])
12772 (define_insn "*load_tp_<mode>"
12773 [(set (match_operand:P 0 "register_operand" "=r")
12774 (unspec:P [(const_int 0)] UNSPEC_TP))]
12776 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12777 [(set_attr "type" "imov")
12778 (set_attr "modrm" "0")
12779 (set_attr "length" "7")
12780 (set_attr "memory" "load")
12781 (set_attr "imm_disp" "false")])
12783 (define_insn "*add_tp_x32"
12784 [(set (match_operand:SI 0 "register_operand" "=r")
12785 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12786 (match_operand:SI 1 "register_operand" "0")))
12787 (clobber (reg:CC FLAGS_REG))]
12789 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12790 [(set_attr "type" "alu")
12791 (set_attr "modrm" "0")
12792 (set_attr "length" "7")
12793 (set_attr "memory" "load")
12794 (set_attr "imm_disp" "false")])
12796 (define_insn "*add_tp_x32_zext"
12797 [(set (match_operand:DI 0 "register_operand" "=r")
12799 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12800 (match_operand:SI 1 "register_operand" "0"))))
12801 (clobber (reg:CC FLAGS_REG))]
12803 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12804 [(set_attr "type" "alu")
12805 (set_attr "modrm" "0")
12806 (set_attr "length" "7")
12807 (set_attr "memory" "load")
12808 (set_attr "imm_disp" "false")])
12810 (define_insn "*add_tp_<mode>"
12811 [(set (match_operand:P 0 "register_operand" "=r")
12812 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12813 (match_operand:P 1 "register_operand" "0")))
12814 (clobber (reg:CC FLAGS_REG))]
12816 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12817 [(set_attr "type" "alu")
12818 (set_attr "modrm" "0")
12819 (set_attr "length" "7")
12820 (set_attr "memory" "load")
12821 (set_attr "imm_disp" "false")])
12823 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12824 ;; %rax as destination of the initial executable code sequence.
12825 (define_insn "tls_initial_exec_64_sun"
12826 [(set (match_operand:DI 0 "register_operand" "=a")
12828 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12829 UNSPEC_TLS_IE_SUN))
12830 (clobber (reg:CC FLAGS_REG))]
12831 "TARGET_64BIT && TARGET_SUN_TLS"
12834 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12835 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12837 [(set_attr "type" "multi")])
12839 ;; GNU2 TLS patterns can be split.
12841 (define_expand "tls_dynamic_gnu2_32"
12842 [(set (match_dup 3)
12843 (plus:SI (match_operand:SI 2 "register_operand" "")
12845 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12848 [(set (match_operand:SI 0 "register_operand" "")
12849 (unspec:SI [(match_dup 1) (match_dup 3)
12850 (match_dup 2) (reg:SI SP_REG)]
12852 (clobber (reg:CC FLAGS_REG))])]
12853 "!TARGET_64BIT && TARGET_GNU2_TLS"
12855 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12856 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12859 (define_insn "*tls_dynamic_gnu2_lea_32"
12860 [(set (match_operand:SI 0 "register_operand" "=r")
12861 (plus:SI (match_operand:SI 1 "register_operand" "b")
12863 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12864 UNSPEC_TLSDESC))))]
12865 "!TARGET_64BIT && TARGET_GNU2_TLS"
12866 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12867 [(set_attr "type" "lea")
12868 (set_attr "mode" "SI")
12869 (set_attr "length" "6")
12870 (set_attr "length_address" "4")])
12872 (define_insn "*tls_dynamic_gnu2_call_32"
12873 [(set (match_operand:SI 0 "register_operand" "=a")
12874 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12875 (match_operand:SI 2 "register_operand" "0")
12876 ;; we have to make sure %ebx still points to the GOT
12877 (match_operand:SI 3 "register_operand" "b")
12880 (clobber (reg:CC FLAGS_REG))]
12881 "!TARGET_64BIT && TARGET_GNU2_TLS"
12882 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12883 [(set_attr "type" "call")
12884 (set_attr "length" "2")
12885 (set_attr "length_address" "0")])
12887 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12888 [(set (match_operand:SI 0 "register_operand" "=&a")
12890 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12891 (match_operand:SI 4 "" "")
12892 (match_operand:SI 2 "register_operand" "b")
12895 (const:SI (unspec:SI
12896 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12898 (clobber (reg:CC FLAGS_REG))]
12899 "!TARGET_64BIT && TARGET_GNU2_TLS"
12902 [(set (match_dup 0) (match_dup 5))]
12904 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12905 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12908 (define_expand "tls_dynamic_gnu2_64"
12909 [(set (match_dup 2)
12910 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12913 [(set (match_operand:DI 0 "register_operand" "")
12914 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12916 (clobber (reg:CC FLAGS_REG))])]
12917 "TARGET_64BIT && TARGET_GNU2_TLS"
12919 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12920 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12923 (define_insn "*tls_dynamic_gnu2_lea_64"
12924 [(set (match_operand:DI 0 "register_operand" "=r")
12925 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12927 "TARGET_64BIT && TARGET_GNU2_TLS"
12928 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12929 [(set_attr "type" "lea")
12930 (set_attr "mode" "DI")
12931 (set_attr "length" "7")
12932 (set_attr "length_address" "4")])
12934 (define_insn "*tls_dynamic_gnu2_call_64"
12935 [(set (match_operand:DI 0 "register_operand" "=a")
12936 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12937 (match_operand:DI 2 "register_operand" "0")
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_64BIT && TARGET_GNU2_TLS"
12942 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12943 [(set_attr "type" "call")
12944 (set_attr "length" "2")
12945 (set_attr "length_address" "0")])
12947 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12948 [(set (match_operand:DI 0 "register_operand" "=&a")
12950 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12951 (match_operand:DI 3 "" "")
12954 (const:DI (unspec:DI
12955 [(match_operand 1 "tls_symbolic_operand" "")]
12957 (clobber (reg:CC FLAGS_REG))]
12958 "TARGET_64BIT && TARGET_GNU2_TLS"
12961 [(set (match_dup 0) (match_dup 4))]
12963 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12964 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12967 ;; These patterns match the binary 387 instructions for addM3, subM3,
12968 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12969 ;; SFmode. The first is the normal insn, the second the same insn but
12970 ;; with one operand a conversion, and the third the same insn but with
12971 ;; the other operand a conversion. The conversion may be SFmode or
12972 ;; SImode if the target mode DFmode, but only SImode if the target mode
12975 ;; Gcc is slightly more smart about handling normal two address instructions
12976 ;; so use special patterns for add and mull.
12978 (define_insn "*fop_<mode>_comm_mixed"
12979 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12980 (match_operator:MODEF 3 "binary_fp_operator"
12981 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12982 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12983 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12984 && COMMUTATIVE_ARITH_P (operands[3])
12985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12986 "* return output_387_binary_op (insn, operands);"
12987 [(set (attr "type")
12988 (if_then_else (eq_attr "alternative" "1,2")
12989 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12990 (const_string "ssemul")
12991 (const_string "sseadd"))
12992 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12993 (const_string "fmul")
12994 (const_string "fop"))))
12995 (set_attr "isa" "*,noavx,avx")
12996 (set_attr "prefix" "orig,orig,vex")
12997 (set_attr "mode" "<MODE>")])
12999 (define_insn "*fop_<mode>_comm_sse"
13000 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13001 (match_operator:MODEF 3 "binary_fp_operator"
13002 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13003 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13004 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13005 && COMMUTATIVE_ARITH_P (operands[3])
13006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010 (const_string "ssemul")
13011 (const_string "sseadd")))
13012 (set_attr "isa" "noavx,avx")
13013 (set_attr "prefix" "orig,vex")
13014 (set_attr "mode" "<MODE>")])
13016 (define_insn "*fop_<mode>_comm_i387"
13017 [(set (match_operand:MODEF 0 "register_operand" "=f")
13018 (match_operator:MODEF 3 "binary_fp_operator"
13019 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13020 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13021 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13022 && COMMUTATIVE_ARITH_P (operands[3])
13023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024 "* return output_387_binary_op (insn, operands);"
13025 [(set (attr "type")
13026 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13027 (const_string "fmul")
13028 (const_string "fop")))
13029 (set_attr "mode" "<MODE>")])
13031 (define_insn "*fop_<mode>_1_mixed"
13032 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13033 (match_operator:MODEF 3 "binary_fp_operator"
13034 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13035 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13036 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13037 && !COMMUTATIVE_ARITH_P (operands[3])
13038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13039 "* return output_387_binary_op (insn, operands);"
13040 [(set (attr "type")
13041 (cond [(and (eq_attr "alternative" "2,3")
13042 (match_operand:MODEF 3 "mult_operator" ""))
13043 (const_string "ssemul")
13044 (and (eq_attr "alternative" "2,3")
13045 (match_operand:MODEF 3 "div_operator" ""))
13046 (const_string "ssediv")
13047 (eq_attr "alternative" "2,3")
13048 (const_string "sseadd")
13049 (match_operand:MODEF 3 "mult_operator" "")
13050 (const_string "fmul")
13051 (match_operand:MODEF 3 "div_operator" "")
13052 (const_string "fdiv")
13054 (const_string "fop")))
13055 (set_attr "isa" "*,*,noavx,avx")
13056 (set_attr "prefix" "orig,orig,orig,vex")
13057 (set_attr "mode" "<MODE>")])
13059 (define_insn "*rcpsf2_sse"
13060 [(set (match_operand:SF 0 "register_operand" "=x")
13061 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13064 "%vrcpss\t{%1, %d0|%d0, %1}"
13065 [(set_attr "type" "sse")
13066 (set_attr "atom_sse_attr" "rcp")
13067 (set_attr "prefix" "maybe_vex")
13068 (set_attr "mode" "SF")])
13070 (define_insn "*fop_<mode>_1_sse"
13071 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13072 (match_operator:MODEF 3 "binary_fp_operator"
13073 [(match_operand:MODEF 1 "register_operand" "0,x")
13074 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13075 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13076 && !COMMUTATIVE_ARITH_P (operands[3])"
13077 "* return output_387_binary_op (insn, operands);"
13078 [(set (attr "type")
13079 (cond [(match_operand:MODEF 3 "mult_operator" "")
13080 (const_string "ssemul")
13081 (match_operand:MODEF 3 "div_operator" "")
13082 (const_string "ssediv")
13084 (const_string "sseadd")))
13085 (set_attr "isa" "noavx,avx")
13086 (set_attr "prefix" "orig,vex")
13087 (set_attr "mode" "<MODE>")])
13089 ;; This pattern is not fully shadowed by the pattern above.
13090 (define_insn "*fop_<mode>_1_i387"
13091 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13092 (match_operator:MODEF 3 "binary_fp_operator"
13093 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13094 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13095 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13096 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13097 && !COMMUTATIVE_ARITH_P (operands[3])
13098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13099 "* return output_387_binary_op (insn, operands);"
13100 [(set (attr "type")
13101 (cond [(match_operand:MODEF 3 "mult_operator" "")
13102 (const_string "fmul")
13103 (match_operand:MODEF 3 "div_operator" "")
13104 (const_string "fdiv")
13106 (const_string "fop")))
13107 (set_attr "mode" "<MODE>")])
13109 ;; ??? Add SSE splitters for these!
13110 (define_insn "*fop_<MODEF:mode>_2_i387"
13111 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13112 (match_operator:MODEF 3 "binary_fp_operator"
13114 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13115 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13116 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13117 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13118 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13119 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13120 [(set (attr "type")
13121 (cond [(match_operand:MODEF 3 "mult_operator" "")
13122 (const_string "fmul")
13123 (match_operand:MODEF 3 "div_operator" "")
13124 (const_string "fdiv")
13126 (const_string "fop")))
13127 (set_attr "fp_int_src" "true")
13128 (set_attr "mode" "<SWI24:MODE>")])
13130 (define_insn "*fop_<MODEF:mode>_3_i387"
13131 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13132 (match_operator:MODEF 3 "binary_fp_operator"
13133 [(match_operand:MODEF 1 "register_operand" "0,0")
13135 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13136 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13137 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13138 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13139 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13140 [(set (attr "type")
13141 (cond [(match_operand:MODEF 3 "mult_operator" "")
13142 (const_string "fmul")
13143 (match_operand:MODEF 3 "div_operator" "")
13144 (const_string "fdiv")
13146 (const_string "fop")))
13147 (set_attr "fp_int_src" "true")
13148 (set_attr "mode" "<MODE>")])
13150 (define_insn "*fop_df_4_i387"
13151 [(set (match_operand:DF 0 "register_operand" "=f,f")
13152 (match_operator:DF 3 "binary_fp_operator"
13154 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13155 (match_operand:DF 2 "register_operand" "0,f")]))]
13156 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13157 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13159 "* return output_387_binary_op (insn, operands);"
13160 [(set (attr "type")
13161 (cond [(match_operand:DF 3 "mult_operator" "")
13162 (const_string "fmul")
13163 (match_operand:DF 3 "div_operator" "")
13164 (const_string "fdiv")
13166 (const_string "fop")))
13167 (set_attr "mode" "SF")])
13169 (define_insn "*fop_df_5_i387"
13170 [(set (match_operand:DF 0 "register_operand" "=f,f")
13171 (match_operator:DF 3 "binary_fp_operator"
13172 [(match_operand:DF 1 "register_operand" "0,f")
13174 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13175 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13176 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13177 "* return output_387_binary_op (insn, operands);"
13178 [(set (attr "type")
13179 (cond [(match_operand:DF 3 "mult_operator" "")
13180 (const_string "fmul")
13181 (match_operand:DF 3 "div_operator" "")
13182 (const_string "fdiv")
13184 (const_string "fop")))
13185 (set_attr "mode" "SF")])
13187 (define_insn "*fop_df_6_i387"
13188 [(set (match_operand:DF 0 "register_operand" "=f,f")
13189 (match_operator:DF 3 "binary_fp_operator"
13191 (match_operand:SF 1 "register_operand" "0,f"))
13193 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13194 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13195 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13196 "* return output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:DF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (match_operand:DF 3 "div_operator" "")
13201 (const_string "fdiv")
13203 (const_string "fop")))
13204 (set_attr "mode" "SF")])
13206 (define_insn "*fop_xf_comm_i387"
13207 [(set (match_operand:XF 0 "register_operand" "=f")
13208 (match_operator:XF 3 "binary_fp_operator"
13209 [(match_operand:XF 1 "register_operand" "%0")
13210 (match_operand:XF 2 "register_operand" "f")]))]
13212 && COMMUTATIVE_ARITH_P (operands[3])"
13213 "* return output_387_binary_op (insn, operands);"
13214 [(set (attr "type")
13215 (if_then_else (match_operand:XF 3 "mult_operator" "")
13216 (const_string "fmul")
13217 (const_string "fop")))
13218 (set_attr "mode" "XF")])
13220 (define_insn "*fop_xf_1_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f,f")
13222 (match_operator:XF 3 "binary_fp_operator"
13223 [(match_operand:XF 1 "register_operand" "0,f")
13224 (match_operand:XF 2 "register_operand" "f,0")]))]
13226 && !COMMUTATIVE_ARITH_P (operands[3])"
13227 "* return output_387_binary_op (insn, operands);"
13228 [(set (attr "type")
13229 (cond [(match_operand:XF 3 "mult_operator" "")
13230 (const_string "fmul")
13231 (match_operand:XF 3 "div_operator" "")
13232 (const_string "fdiv")
13234 (const_string "fop")))
13235 (set_attr "mode" "XF")])
13237 (define_insn "*fop_xf_2_i387"
13238 [(set (match_operand:XF 0 "register_operand" "=f,f")
13239 (match_operator:XF 3 "binary_fp_operator"
13241 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13242 (match_operand:XF 2 "register_operand" "0,0")]))]
13243 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13244 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13245 [(set (attr "type")
13246 (cond [(match_operand:XF 3 "mult_operator" "")
13247 (const_string "fmul")
13248 (match_operand:XF 3 "div_operator" "")
13249 (const_string "fdiv")
13251 (const_string "fop")))
13252 (set_attr "fp_int_src" "true")
13253 (set_attr "mode" "<MODE>")])
13255 (define_insn "*fop_xf_3_i387"
13256 [(set (match_operand:XF 0 "register_operand" "=f,f")
13257 (match_operator:XF 3 "binary_fp_operator"
13258 [(match_operand:XF 1 "register_operand" "0,0")
13260 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13261 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13262 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (cond [(match_operand:XF 3 "mult_operator" "")
13265 (const_string "fmul")
13266 (match_operand:XF 3 "div_operator" "")
13267 (const_string "fdiv")
13269 (const_string "fop")))
13270 (set_attr "fp_int_src" "true")
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "*fop_xf_4_i387"
13274 [(set (match_operand:XF 0 "register_operand" "=f,f")
13275 (match_operator:XF 3 "binary_fp_operator"
13277 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13278 (match_operand:XF 2 "register_operand" "0,f")]))]
13280 "* return output_387_binary_op (insn, operands);"
13281 [(set (attr "type")
13282 (cond [(match_operand:XF 3 "mult_operator" "")
13283 (const_string "fmul")
13284 (match_operand:XF 3 "div_operator" "")
13285 (const_string "fdiv")
13287 (const_string "fop")))
13288 (set_attr "mode" "<MODE>")])
13290 (define_insn "*fop_xf_5_i387"
13291 [(set (match_operand:XF 0 "register_operand" "=f,f")
13292 (match_operator:XF 3 "binary_fp_operator"
13293 [(match_operand:XF 1 "register_operand" "0,f")
13295 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13297 "* return output_387_binary_op (insn, operands);"
13298 [(set (attr "type")
13299 (cond [(match_operand:XF 3 "mult_operator" "")
13300 (const_string "fmul")
13301 (match_operand:XF 3 "div_operator" "")
13302 (const_string "fdiv")
13304 (const_string "fop")))
13305 (set_attr "mode" "<MODE>")])
13307 (define_insn "*fop_xf_6_i387"
13308 [(set (match_operand:XF 0 "register_operand" "=f,f")
13309 (match_operator:XF 3 "binary_fp_operator"
13311 (match_operand:MODEF 1 "register_operand" "0,f"))
13313 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13315 "* return output_387_binary_op (insn, operands);"
13316 [(set (attr "type")
13317 (cond [(match_operand:XF 3 "mult_operator" "")
13318 (const_string "fmul")
13319 (match_operand:XF 3 "div_operator" "")
13320 (const_string "fdiv")
13322 (const_string "fop")))
13323 (set_attr "mode" "<MODE>")])
13326 [(set (match_operand 0 "register_operand" "")
13327 (match_operator 3 "binary_fp_operator"
13328 [(float (match_operand:SWI24 1 "register_operand" ""))
13329 (match_operand 2 "register_operand" "")]))]
13331 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13332 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13335 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13336 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13337 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13338 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13339 GET_MODE (operands[3]),
13342 ix86_free_from_memory (GET_MODE (operands[1]));
13347 [(set (match_operand 0 "register_operand" "")
13348 (match_operator 3 "binary_fp_operator"
13349 [(match_operand 1 "register_operand" "")
13350 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13352 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13353 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13356 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13357 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13358 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13359 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13360 GET_MODE (operands[3]),
13363 ix86_free_from_memory (GET_MODE (operands[2]));
13367 ;; FPU special functions.
13369 ;; This pattern implements a no-op XFmode truncation for
13370 ;; all fancy i386 XFmode math functions.
13372 (define_insn "truncxf<mode>2_i387_noop_unspec"
13373 [(set (match_operand:MODEF 0 "register_operand" "=f")
13374 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13375 UNSPEC_TRUNC_NOOP))]
13376 "TARGET_USE_FANCY_MATH_387"
13377 "* return output_387_reg_move (insn, operands);"
13378 [(set_attr "type" "fmov")
13379 (set_attr "mode" "<MODE>")])
13381 (define_insn "sqrtxf2"
13382 [(set (match_operand:XF 0 "register_operand" "=f")
13383 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13384 "TARGET_USE_FANCY_MATH_387"
13386 [(set_attr "type" "fpspc")
13387 (set_attr "mode" "XF")
13388 (set_attr "athlon_decode" "direct")
13389 (set_attr "amdfam10_decode" "direct")
13390 (set_attr "bdver1_decode" "direct")])
13392 (define_insn "sqrt_extend<mode>xf2_i387"
13393 [(set (match_operand:XF 0 "register_operand" "=f")
13396 (match_operand:MODEF 1 "register_operand" "0"))))]
13397 "TARGET_USE_FANCY_MATH_387"
13399 [(set_attr "type" "fpspc")
13400 (set_attr "mode" "XF")
13401 (set_attr "athlon_decode" "direct")
13402 (set_attr "amdfam10_decode" "direct")
13403 (set_attr "bdver1_decode" "direct")])
13405 (define_insn "*rsqrtsf2_sse"
13406 [(set (match_operand:SF 0 "register_operand" "=x")
13407 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13410 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13411 [(set_attr "type" "sse")
13412 (set_attr "atom_sse_attr" "rcp")
13413 (set_attr "prefix" "maybe_vex")
13414 (set_attr "mode" "SF")])
13416 (define_expand "rsqrtsf2"
13417 [(set (match_operand:SF 0 "register_operand" "")
13418 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13422 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13426 (define_insn "*sqrt<mode>2_sse"
13427 [(set (match_operand:MODEF 0 "register_operand" "=x")
13429 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13430 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13431 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13432 [(set_attr "type" "sse")
13433 (set_attr "atom_sse_attr" "sqrt")
13434 (set_attr "prefix" "maybe_vex")
13435 (set_attr "mode" "<MODE>")
13436 (set_attr "athlon_decode" "*")
13437 (set_attr "amdfam10_decode" "*")
13438 (set_attr "bdver1_decode" "*")])
13440 (define_expand "sqrt<mode>2"
13441 [(set (match_operand:MODEF 0 "register_operand" "")
13443 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13444 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13445 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13447 if (<MODE>mode == SFmode
13449 && TARGET_RECIP_SQRT
13450 && !optimize_function_for_size_p (cfun)
13451 && flag_finite_math_only && !flag_trapping_math
13452 && flag_unsafe_math_optimizations)
13454 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13458 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13460 rtx op0 = gen_reg_rtx (XFmode);
13461 rtx op1 = force_reg (<MODE>mode, operands[1]);
13463 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13464 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13469 (define_insn "fpremxf4_i387"
13470 [(set (match_operand:XF 0 "register_operand" "=f")
13471 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13472 (match_operand:XF 3 "register_operand" "1")]
13474 (set (match_operand:XF 1 "register_operand" "=u")
13475 (unspec:XF [(match_dup 2) (match_dup 3)]
13477 (set (reg:CCFP FPSR_REG)
13478 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13480 "TARGET_USE_FANCY_MATH_387"
13482 [(set_attr "type" "fpspc")
13483 (set_attr "mode" "XF")])
13485 (define_expand "fmodxf3"
13486 [(use (match_operand:XF 0 "register_operand" ""))
13487 (use (match_operand:XF 1 "general_operand" ""))
13488 (use (match_operand:XF 2 "general_operand" ""))]
13489 "TARGET_USE_FANCY_MATH_387"
13491 rtx label = gen_label_rtx ();
13493 rtx op1 = gen_reg_rtx (XFmode);
13494 rtx op2 = gen_reg_rtx (XFmode);
13496 emit_move_insn (op2, operands[2]);
13497 emit_move_insn (op1, operands[1]);
13499 emit_label (label);
13500 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13501 ix86_emit_fp_unordered_jump (label);
13502 LABEL_NUSES (label) = 1;
13504 emit_move_insn (operands[0], op1);
13508 (define_expand "fmod<mode>3"
13509 [(use (match_operand:MODEF 0 "register_operand" ""))
13510 (use (match_operand:MODEF 1 "general_operand" ""))
13511 (use (match_operand:MODEF 2 "general_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387"
13514 rtx (*gen_truncxf) (rtx, rtx);
13516 rtx label = gen_label_rtx ();
13518 rtx op1 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13521 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13522 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13524 emit_label (label);
13525 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13526 ix86_emit_fp_unordered_jump (label);
13527 LABEL_NUSES (label) = 1;
13529 /* Truncate the result properly for strict SSE math. */
13530 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13531 && !TARGET_MIX_SSE_I387)
13532 gen_truncxf = gen_truncxf<mode>2;
13534 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13536 emit_insn (gen_truncxf (operands[0], op1));
13540 (define_insn "fprem1xf4_i387"
13541 [(set (match_operand:XF 0 "register_operand" "=f")
13542 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13543 (match_operand:XF 3 "register_operand" "1")]
13545 (set (match_operand:XF 1 "register_operand" "=u")
13546 (unspec:XF [(match_dup 2) (match_dup 3)]
13548 (set (reg:CCFP FPSR_REG)
13549 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13551 "TARGET_USE_FANCY_MATH_387"
13553 [(set_attr "type" "fpspc")
13554 (set_attr "mode" "XF")])
13556 (define_expand "remainderxf3"
13557 [(use (match_operand:XF 0 "register_operand" ""))
13558 (use (match_operand:XF 1 "general_operand" ""))
13559 (use (match_operand:XF 2 "general_operand" ""))]
13560 "TARGET_USE_FANCY_MATH_387"
13562 rtx label = gen_label_rtx ();
13564 rtx op1 = gen_reg_rtx (XFmode);
13565 rtx op2 = gen_reg_rtx (XFmode);
13567 emit_move_insn (op2, operands[2]);
13568 emit_move_insn (op1, operands[1]);
13570 emit_label (label);
13571 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13572 ix86_emit_fp_unordered_jump (label);
13573 LABEL_NUSES (label) = 1;
13575 emit_move_insn (operands[0], op1);
13579 (define_expand "remainder<mode>3"
13580 [(use (match_operand:MODEF 0 "register_operand" ""))
13581 (use (match_operand:MODEF 1 "general_operand" ""))
13582 (use (match_operand:MODEF 2 "general_operand" ""))]
13583 "TARGET_USE_FANCY_MATH_387"
13585 rtx (*gen_truncxf) (rtx, rtx);
13587 rtx label = gen_label_rtx ();
13589 rtx op1 = gen_reg_rtx (XFmode);
13590 rtx op2 = gen_reg_rtx (XFmode);
13592 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13593 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13595 emit_label (label);
13597 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13598 ix86_emit_fp_unordered_jump (label);
13599 LABEL_NUSES (label) = 1;
13601 /* Truncate the result properly for strict SSE math. */
13602 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13603 && !TARGET_MIX_SSE_I387)
13604 gen_truncxf = gen_truncxf<mode>2;
13606 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13608 emit_insn (gen_truncxf (operands[0], op1));
13612 (define_insn "*sinxf2_i387"
13613 [(set (match_operand:XF 0 "register_operand" "=f")
13614 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13615 "TARGET_USE_FANCY_MATH_387
13616 && flag_unsafe_math_optimizations"
13618 [(set_attr "type" "fpspc")
13619 (set_attr "mode" "XF")])
13621 (define_insn "*sin_extend<mode>xf2_i387"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(float_extend:XF
13624 (match_operand:MODEF 1 "register_operand" "0"))]
13626 "TARGET_USE_FANCY_MATH_387
13627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13628 || TARGET_MIX_SSE_I387)
13629 && flag_unsafe_math_optimizations"
13631 [(set_attr "type" "fpspc")
13632 (set_attr "mode" "XF")])
13634 (define_insn "*cosxf2_i387"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13637 "TARGET_USE_FANCY_MATH_387
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13643 (define_insn "*cos_extend<mode>xf2_i387"
13644 [(set (match_operand:XF 0 "register_operand" "=f")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 1 "register_operand" "0"))]
13648 "TARGET_USE_FANCY_MATH_387
13649 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13650 || TARGET_MIX_SSE_I387)
13651 && flag_unsafe_math_optimizations"
13653 [(set_attr "type" "fpspc")
13654 (set_attr "mode" "XF")])
13656 ;; When sincos pattern is defined, sin and cos builtin functions will be
13657 ;; expanded to sincos pattern with one of its outputs left unused.
13658 ;; CSE pass will figure out if two sincos patterns can be combined,
13659 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13660 ;; depending on the unused output.
13662 (define_insn "sincosxf3"
13663 [(set (match_operand:XF 0 "register_operand" "=f")
13664 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13665 UNSPEC_SINCOS_COS))
13666 (set (match_operand:XF 1 "register_operand" "=u")
13667 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13668 "TARGET_USE_FANCY_MATH_387
13669 && flag_unsafe_math_optimizations"
13671 [(set_attr "type" "fpspc")
13672 (set_attr "mode" "XF")])
13675 [(set (match_operand:XF 0 "register_operand" "")
13676 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13677 UNSPEC_SINCOS_COS))
13678 (set (match_operand:XF 1 "register_operand" "")
13679 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13680 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13681 && can_create_pseudo_p ()"
13682 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13685 [(set (match_operand:XF 0 "register_operand" "")
13686 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13687 UNSPEC_SINCOS_COS))
13688 (set (match_operand:XF 1 "register_operand" "")
13689 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13690 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13691 && can_create_pseudo_p ()"
13692 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13694 (define_insn "sincos_extend<mode>xf3_i387"
13695 [(set (match_operand:XF 0 "register_operand" "=f")
13696 (unspec:XF [(float_extend:XF
13697 (match_operand:MODEF 2 "register_operand" "0"))]
13698 UNSPEC_SINCOS_COS))
13699 (set (match_operand:XF 1 "register_operand" "=u")
13700 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13701 "TARGET_USE_FANCY_MATH_387
13702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13703 || TARGET_MIX_SSE_I387)
13704 && flag_unsafe_math_optimizations"
13706 [(set_attr "type" "fpspc")
13707 (set_attr "mode" "XF")])
13710 [(set (match_operand:XF 0 "register_operand" "")
13711 (unspec:XF [(float_extend:XF
13712 (match_operand:MODEF 2 "register_operand" ""))]
13713 UNSPEC_SINCOS_COS))
13714 (set (match_operand:XF 1 "register_operand" "")
13715 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13716 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13717 && can_create_pseudo_p ()"
13718 [(set (match_dup 1)
13719 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13722 [(set (match_operand:XF 0 "register_operand" "")
13723 (unspec:XF [(float_extend:XF
13724 (match_operand:MODEF 2 "register_operand" ""))]
13725 UNSPEC_SINCOS_COS))
13726 (set (match_operand:XF 1 "register_operand" "")
13727 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13728 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13729 && can_create_pseudo_p ()"
13730 [(set (match_dup 0)
13731 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13733 (define_expand "sincos<mode>3"
13734 [(use (match_operand:MODEF 0 "register_operand" ""))
13735 (use (match_operand:MODEF 1 "register_operand" ""))
13736 (use (match_operand:MODEF 2 "register_operand" ""))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739 || TARGET_MIX_SSE_I387)
13740 && flag_unsafe_math_optimizations"
13742 rtx op0 = gen_reg_rtx (XFmode);
13743 rtx op1 = gen_reg_rtx (XFmode);
13745 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13751 (define_insn "fptanxf4_i387"
13752 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (match_operand:XF 3 "const_double_operand" "F"))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations
13759 && standard_80387_constant_p (operands[3]) == 2"
13761 [(set_attr "type" "fpspc")
13762 (set_attr "mode" "XF")])
13764 (define_insn "fptan_extend<mode>xf4_i387"
13765 [(set (match_operand:MODEF 0 "register_operand" "=f")
13766 (match_operand:MODEF 3 "const_double_operand" "F"))
13767 (set (match_operand:XF 1 "register_operand" "=u")
13768 (unspec:XF [(float_extend:XF
13769 (match_operand:MODEF 2 "register_operand" "0"))]
13771 "TARGET_USE_FANCY_MATH_387
13772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13773 || TARGET_MIX_SSE_I387)
13774 && flag_unsafe_math_optimizations
13775 && standard_80387_constant_p (operands[3]) == 2"
13777 [(set_attr "type" "fpspc")
13778 (set_attr "mode" "XF")])
13780 (define_expand "tanxf2"
13781 [(use (match_operand:XF 0 "register_operand" ""))
13782 (use (match_operand:XF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && flag_unsafe_math_optimizations"
13786 rtx one = gen_reg_rtx (XFmode);
13787 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13789 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13793 (define_expand "tan<mode>2"
13794 [(use (match_operand:MODEF 0 "register_operand" ""))
13795 (use (match_operand:MODEF 1 "register_operand" ""))]
13796 "TARGET_USE_FANCY_MATH_387
13797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13798 || TARGET_MIX_SSE_I387)
13799 && flag_unsafe_math_optimizations"
13801 rtx op0 = gen_reg_rtx (XFmode);
13803 rtx one = gen_reg_rtx (<MODE>mode);
13804 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13806 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13807 operands[1], op2));
13808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13812 (define_insn "*fpatanxf3_i387"
13813 [(set (match_operand:XF 0 "register_operand" "=f")
13814 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13815 (match_operand:XF 2 "register_operand" "u")]
13817 (clobber (match_scratch:XF 3 "=2"))]
13818 "TARGET_USE_FANCY_MATH_387
13819 && flag_unsafe_math_optimizations"
13821 [(set_attr "type" "fpspc")
13822 (set_attr "mode" "XF")])
13824 (define_insn "fpatan_extend<mode>xf3_i387"
13825 [(set (match_operand:XF 0 "register_operand" "=f")
13826 (unspec:XF [(float_extend:XF
13827 (match_operand:MODEF 1 "register_operand" "0"))
13829 (match_operand:MODEF 2 "register_operand" "u"))]
13831 (clobber (match_scratch:XF 3 "=2"))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13834 || TARGET_MIX_SSE_I387)
13835 && flag_unsafe_math_optimizations"
13837 [(set_attr "type" "fpspc")
13838 (set_attr "mode" "XF")])
13840 (define_expand "atan2xf3"
13841 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13842 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13843 (match_operand:XF 1 "register_operand" "")]
13845 (clobber (match_scratch:XF 3 ""))])]
13846 "TARGET_USE_FANCY_MATH_387
13847 && flag_unsafe_math_optimizations")
13849 (define_expand "atan2<mode>3"
13850 [(use (match_operand:MODEF 0 "register_operand" ""))
13851 (use (match_operand:MODEF 1 "register_operand" ""))
13852 (use (match_operand:MODEF 2 "register_operand" ""))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13855 || TARGET_MIX_SSE_I387)
13856 && flag_unsafe_math_optimizations"
13858 rtx op0 = gen_reg_rtx (XFmode);
13860 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13865 (define_expand "atanxf2"
13866 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13867 (unspec:XF [(match_dup 2)
13868 (match_operand:XF 1 "register_operand" "")]
13870 (clobber (match_scratch:XF 3 ""))])]
13871 "TARGET_USE_FANCY_MATH_387
13872 && flag_unsafe_math_optimizations"
13874 operands[2] = gen_reg_rtx (XFmode);
13875 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13878 (define_expand "atan<mode>2"
13879 [(use (match_operand:MODEF 0 "register_operand" ""))
13880 (use (match_operand:MODEF 1 "register_operand" ""))]
13881 "TARGET_USE_FANCY_MATH_387
13882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13883 || TARGET_MIX_SSE_I387)
13884 && flag_unsafe_math_optimizations"
13886 rtx op0 = gen_reg_rtx (XFmode);
13888 rtx op2 = gen_reg_rtx (<MODE>mode);
13889 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13891 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13892 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13896 (define_expand "asinxf2"
13897 [(set (match_dup 2)
13898 (mult:XF (match_operand:XF 1 "register_operand" "")
13900 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13901 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13902 (parallel [(set (match_operand:XF 0 "register_operand" "")
13903 (unspec:XF [(match_dup 5) (match_dup 1)]
13905 (clobber (match_scratch:XF 6 ""))])]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13911 if (optimize_insn_for_size_p ())
13914 for (i = 2; i < 6; i++)
13915 operands[i] = gen_reg_rtx (XFmode);
13917 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13920 (define_expand "asin<mode>2"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13928 rtx op0 = gen_reg_rtx (XFmode);
13929 rtx op1 = gen_reg_rtx (XFmode);
13931 if (optimize_insn_for_size_p ())
13934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13935 emit_insn (gen_asinxf2 (op0, op1));
13936 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13940 (define_expand "acosxf2"
13941 [(set (match_dup 2)
13942 (mult:XF (match_operand:XF 1 "register_operand" "")
13944 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13945 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13946 (parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_dup 1) (match_dup 5)]
13949 (clobber (match_scratch:XF 6 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13955 if (optimize_insn_for_size_p ())
13958 for (i = 2; i < 6; i++)
13959 operands[i] = gen_reg_rtx (XFmode);
13961 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13964 (define_expand "acos<mode>2"
13965 [(use (match_operand:MODEF 0 "register_operand" ""))
13966 (use (match_operand:MODEF 1 "general_operand" ""))]
13967 "TARGET_USE_FANCY_MATH_387
13968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13969 || TARGET_MIX_SSE_I387)
13970 && flag_unsafe_math_optimizations"
13972 rtx op0 = gen_reg_rtx (XFmode);
13973 rtx op1 = gen_reg_rtx (XFmode);
13975 if (optimize_insn_for_size_p ())
13978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13979 emit_insn (gen_acosxf2 (op0, op1));
13980 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13984 (define_insn "fyl2xxf3_i387"
13985 [(set (match_operand:XF 0 "register_operand" "=f")
13986 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13987 (match_operand:XF 2 "register_operand" "u")]
13989 (clobber (match_scratch:XF 3 "=2"))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && flag_unsafe_math_optimizations"
13993 [(set_attr "type" "fpspc")
13994 (set_attr "mode" "XF")])
13996 (define_insn "fyl2x_extend<mode>xf3_i387"
13997 [(set (match_operand:XF 0 "register_operand" "=f")
13998 (unspec:XF [(float_extend:XF
13999 (match_operand:MODEF 1 "register_operand" "0"))
14000 (match_operand:XF 2 "register_operand" "u")]
14002 (clobber (match_scratch:XF 3 "=2"))]
14003 "TARGET_USE_FANCY_MATH_387
14004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14005 || TARGET_MIX_SSE_I387)
14006 && flag_unsafe_math_optimizations"
14008 [(set_attr "type" "fpspc")
14009 (set_attr "mode" "XF")])
14011 (define_expand "logxf2"
14012 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14013 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14014 (match_dup 2)] UNSPEC_FYL2X))
14015 (clobber (match_scratch:XF 3 ""))])]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14019 operands[2] = gen_reg_rtx (XFmode);
14020 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14023 (define_expand "log<mode>2"
14024 [(use (match_operand:MODEF 0 "register_operand" ""))
14025 (use (match_operand:MODEF 1 "register_operand" ""))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028 || TARGET_MIX_SSE_I387)
14029 && flag_unsafe_math_optimizations"
14031 rtx op0 = gen_reg_rtx (XFmode);
14033 rtx op2 = gen_reg_rtx (XFmode);
14034 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14036 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14041 (define_expand "log10xf2"
14042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14044 (match_dup 2)] UNSPEC_FYL2X))
14045 (clobber (match_scratch:XF 3 ""))])]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14049 operands[2] = gen_reg_rtx (XFmode);
14050 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14053 (define_expand "log10<mode>2"
14054 [(use (match_operand:MODEF 0 "register_operand" ""))
14055 (use (match_operand:MODEF 1 "register_operand" ""))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14058 || TARGET_MIX_SSE_I387)
14059 && flag_unsafe_math_optimizations"
14061 rtx op0 = gen_reg_rtx (XFmode);
14063 rtx op2 = gen_reg_rtx (XFmode);
14064 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14066 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14071 (define_expand "log2xf2"
14072 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14073 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14074 (match_dup 2)] UNSPEC_FYL2X))
14075 (clobber (match_scratch:XF 3 ""))])]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14079 operands[2] = gen_reg_rtx (XFmode);
14080 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14083 (define_expand "log2<mode>2"
14084 [(use (match_operand:MODEF 0 "register_operand" ""))
14085 (use (match_operand:MODEF 1 "register_operand" ""))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14088 || TARGET_MIX_SSE_I387)
14089 && flag_unsafe_math_optimizations"
14091 rtx op0 = gen_reg_rtx (XFmode);
14093 rtx op2 = gen_reg_rtx (XFmode);
14094 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14096 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14097 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14101 (define_insn "fyl2xp1xf3_i387"
14102 [(set (match_operand:XF 0 "register_operand" "=f")
14103 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14104 (match_operand:XF 2 "register_operand" "u")]
14106 (clobber (match_scratch:XF 3 "=2"))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14113 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14114 [(set (match_operand:XF 0 "register_operand" "=f")
14115 (unspec:XF [(float_extend:XF
14116 (match_operand:MODEF 1 "register_operand" "0"))
14117 (match_operand:XF 2 "register_operand" "u")]
14119 (clobber (match_scratch:XF 3 "=2"))]
14120 "TARGET_USE_FANCY_MATH_387
14121 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14122 || TARGET_MIX_SSE_I387)
14123 && flag_unsafe_math_optimizations"
14125 [(set_attr "type" "fpspc")
14126 (set_attr "mode" "XF")])
14128 (define_expand "log1pxf2"
14129 [(use (match_operand:XF 0 "register_operand" ""))
14130 (use (match_operand:XF 1 "register_operand" ""))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_unsafe_math_optimizations"
14134 if (optimize_insn_for_size_p ())
14137 ix86_emit_i387_log1p (operands[0], operands[1]);
14141 (define_expand "log1p<mode>2"
14142 [(use (match_operand:MODEF 0 "register_operand" ""))
14143 (use (match_operand:MODEF 1 "register_operand" ""))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14146 || TARGET_MIX_SSE_I387)
14147 && flag_unsafe_math_optimizations"
14151 if (optimize_insn_for_size_p ())
14154 op0 = gen_reg_rtx (XFmode);
14156 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14158 ix86_emit_i387_log1p (op0, operands[1]);
14159 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14163 (define_insn "fxtractxf3_i387"
14164 [(set (match_operand:XF 0 "register_operand" "=f")
14165 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14166 UNSPEC_XTRACT_FRACT))
14167 (set (match_operand:XF 1 "register_operand" "=u")
14168 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && flag_unsafe_math_optimizations"
14172 [(set_attr "type" "fpspc")
14173 (set_attr "mode" "XF")])
14175 (define_insn "fxtract_extend<mode>xf3_i387"
14176 [(set (match_operand:XF 0 "register_operand" "=f")
14177 (unspec:XF [(float_extend:XF
14178 (match_operand:MODEF 2 "register_operand" "0"))]
14179 UNSPEC_XTRACT_FRACT))
14180 (set (match_operand:XF 1 "register_operand" "=u")
14181 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations"
14187 [(set_attr "type" "fpspc")
14188 (set_attr "mode" "XF")])
14190 (define_expand "logbxf2"
14191 [(parallel [(set (match_dup 2)
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14193 UNSPEC_XTRACT_FRACT))
14194 (set (match_operand:XF 0 "register_operand" "")
14195 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14196 "TARGET_USE_FANCY_MATH_387
14197 && flag_unsafe_math_optimizations"
14198 "operands[2] = gen_reg_rtx (XFmode);")
14200 (define_expand "logb<mode>2"
14201 [(use (match_operand:MODEF 0 "register_operand" ""))
14202 (use (match_operand:MODEF 1 "register_operand" ""))]
14203 "TARGET_USE_FANCY_MATH_387
14204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14205 || TARGET_MIX_SSE_I387)
14206 && flag_unsafe_math_optimizations"
14208 rtx op0 = gen_reg_rtx (XFmode);
14209 rtx op1 = gen_reg_rtx (XFmode);
14211 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14212 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14216 (define_expand "ilogbxf2"
14217 [(use (match_operand:SI 0 "register_operand" ""))
14218 (use (match_operand:XF 1 "register_operand" ""))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14224 if (optimize_insn_for_size_p ())
14227 op0 = gen_reg_rtx (XFmode);
14228 op1 = gen_reg_rtx (XFmode);
14230 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14235 (define_expand "ilogb<mode>2"
14236 [(use (match_operand:SI 0 "register_operand" ""))
14237 (use (match_operand:MODEF 1 "register_operand" ""))]
14238 "TARGET_USE_FANCY_MATH_387
14239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14240 || TARGET_MIX_SSE_I387)
14241 && flag_unsafe_math_optimizations"
14245 if (optimize_insn_for_size_p ())
14248 op0 = gen_reg_rtx (XFmode);
14249 op1 = gen_reg_rtx (XFmode);
14251 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14252 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14256 (define_insn "*f2xm1xf2_i387"
14257 [(set (match_operand:XF 0 "register_operand" "=f")
14258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "XF")])
14266 (define_insn "*fscalexf4_i387"
14267 [(set (match_operand:XF 0 "register_operand" "=f")
14268 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14269 (match_operand:XF 3 "register_operand" "1")]
14270 UNSPEC_FSCALE_FRACT))
14271 (set (match_operand:XF 1 "register_operand" "=u")
14272 (unspec:XF [(match_dup 2) (match_dup 3)]
14273 UNSPEC_FSCALE_EXP))]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14277 [(set_attr "type" "fpspc")
14278 (set_attr "mode" "XF")])
14280 (define_expand "expNcorexf3"
14281 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14282 (match_operand:XF 2 "register_operand" "")))
14283 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14284 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14285 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14286 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14287 (parallel [(set (match_operand:XF 0 "register_operand" "")
14288 (unspec:XF [(match_dup 8) (match_dup 4)]
14289 UNSPEC_FSCALE_FRACT))
14291 (unspec:XF [(match_dup 8) (match_dup 4)]
14292 UNSPEC_FSCALE_EXP))])]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14298 if (optimize_insn_for_size_p ())
14301 for (i = 3; i < 10; i++)
14302 operands[i] = gen_reg_rtx (XFmode);
14304 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14307 (define_expand "expxf2"
14308 [(use (match_operand:XF 0 "register_operand" ""))
14309 (use (match_operand:XF 1 "register_operand" ""))]
14310 "TARGET_USE_FANCY_MATH_387
14311 && flag_unsafe_math_optimizations"
14315 if (optimize_insn_for_size_p ())
14318 op2 = gen_reg_rtx (XFmode);
14319 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14321 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14325 (define_expand "exp<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand" ""))
14327 (use (match_operand:MODEF 1 "general_operand" ""))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14335 if (optimize_insn_for_size_p ())
14338 op0 = gen_reg_rtx (XFmode);
14339 op1 = gen_reg_rtx (XFmode);
14341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14342 emit_insn (gen_expxf2 (op0, op1));
14343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14347 (define_expand "exp10xf2"
14348 [(use (match_operand:XF 0 "register_operand" ""))
14349 (use (match_operand:XF 1 "register_operand" ""))]
14350 "TARGET_USE_FANCY_MATH_387
14351 && flag_unsafe_math_optimizations"
14355 if (optimize_insn_for_size_p ())
14358 op2 = gen_reg_rtx (XFmode);
14359 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14361 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14365 (define_expand "exp10<mode>2"
14366 [(use (match_operand:MODEF 0 "register_operand" ""))
14367 (use (match_operand:MODEF 1 "general_operand" ""))]
14368 "TARGET_USE_FANCY_MATH_387
14369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14370 || TARGET_MIX_SSE_I387)
14371 && flag_unsafe_math_optimizations"
14375 if (optimize_insn_for_size_p ())
14378 op0 = gen_reg_rtx (XFmode);
14379 op1 = gen_reg_rtx (XFmode);
14381 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14382 emit_insn (gen_exp10xf2 (op0, op1));
14383 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14387 (define_expand "exp2xf2"
14388 [(use (match_operand:XF 0 "register_operand" ""))
14389 (use (match_operand:XF 1 "register_operand" ""))]
14390 "TARGET_USE_FANCY_MATH_387
14391 && flag_unsafe_math_optimizations"
14395 if (optimize_insn_for_size_p ())
14398 op2 = gen_reg_rtx (XFmode);
14399 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14401 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14405 (define_expand "exp2<mode>2"
14406 [(use (match_operand:MODEF 0 "register_operand" ""))
14407 (use (match_operand:MODEF 1 "general_operand" ""))]
14408 "TARGET_USE_FANCY_MATH_387
14409 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410 || TARGET_MIX_SSE_I387)
14411 && flag_unsafe_math_optimizations"
14415 if (optimize_insn_for_size_p ())
14418 op0 = gen_reg_rtx (XFmode);
14419 op1 = gen_reg_rtx (XFmode);
14421 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14422 emit_insn (gen_exp2xf2 (op0, op1));
14423 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14427 (define_expand "expm1xf2"
14428 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14430 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14431 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14432 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14433 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14434 (parallel [(set (match_dup 7)
14435 (unspec:XF [(match_dup 6) (match_dup 4)]
14436 UNSPEC_FSCALE_FRACT))
14438 (unspec:XF [(match_dup 6) (match_dup 4)]
14439 UNSPEC_FSCALE_EXP))])
14440 (parallel [(set (match_dup 10)
14441 (unspec:XF [(match_dup 9) (match_dup 8)]
14442 UNSPEC_FSCALE_FRACT))
14443 (set (match_dup 11)
14444 (unspec:XF [(match_dup 9) (match_dup 8)]
14445 UNSPEC_FSCALE_EXP))])
14446 (set (match_dup 12) (minus:XF (match_dup 10)
14447 (float_extend:XF (match_dup 13))))
14448 (set (match_operand:XF 0 "register_operand" "")
14449 (plus:XF (match_dup 12) (match_dup 7)))]
14450 "TARGET_USE_FANCY_MATH_387
14451 && flag_unsafe_math_optimizations"
14455 if (optimize_insn_for_size_p ())
14458 for (i = 2; i < 13; i++)
14459 operands[i] = gen_reg_rtx (XFmode);
14462 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14464 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14467 (define_expand "expm1<mode>2"
14468 [(use (match_operand:MODEF 0 "register_operand" ""))
14469 (use (match_operand:MODEF 1 "general_operand" ""))]
14470 "TARGET_USE_FANCY_MATH_387
14471 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14472 || TARGET_MIX_SSE_I387)
14473 && flag_unsafe_math_optimizations"
14477 if (optimize_insn_for_size_p ())
14480 op0 = gen_reg_rtx (XFmode);
14481 op1 = gen_reg_rtx (XFmode);
14483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14484 emit_insn (gen_expm1xf2 (op0, op1));
14485 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14489 (define_expand "ldexpxf3"
14490 [(set (match_dup 3)
14491 (float:XF (match_operand:SI 2 "register_operand" "")))
14492 (parallel [(set (match_operand:XF 0 " register_operand" "")
14493 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14495 UNSPEC_FSCALE_FRACT))
14497 (unspec:XF [(match_dup 1) (match_dup 3)]
14498 UNSPEC_FSCALE_EXP))])]
14499 "TARGET_USE_FANCY_MATH_387
14500 && flag_unsafe_math_optimizations"
14502 if (optimize_insn_for_size_p ())
14505 operands[3] = gen_reg_rtx (XFmode);
14506 operands[4] = gen_reg_rtx (XFmode);
14509 (define_expand "ldexp<mode>3"
14510 [(use (match_operand:MODEF 0 "register_operand" ""))
14511 (use (match_operand:MODEF 1 "general_operand" ""))
14512 (use (match_operand:SI 2 "register_operand" ""))]
14513 "TARGET_USE_FANCY_MATH_387
14514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14515 || TARGET_MIX_SSE_I387)
14516 && flag_unsafe_math_optimizations"
14520 if (optimize_insn_for_size_p ())
14523 op0 = gen_reg_rtx (XFmode);
14524 op1 = gen_reg_rtx (XFmode);
14526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14527 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14528 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14532 (define_expand "scalbxf3"
14533 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14534 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14535 (match_operand:XF 2 "register_operand" "")]
14536 UNSPEC_FSCALE_FRACT))
14538 (unspec:XF [(match_dup 1) (match_dup 2)]
14539 UNSPEC_FSCALE_EXP))])]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14543 if (optimize_insn_for_size_p ())
14546 operands[3] = gen_reg_rtx (XFmode);
14549 (define_expand "scalb<mode>3"
14550 [(use (match_operand:MODEF 0 "register_operand" ""))
14551 (use (match_operand:MODEF 1 "general_operand" ""))
14552 (use (match_operand:MODEF 2 "general_operand" ""))]
14553 "TARGET_USE_FANCY_MATH_387
14554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14555 || TARGET_MIX_SSE_I387)
14556 && flag_unsafe_math_optimizations"
14560 if (optimize_insn_for_size_p ())
14563 op0 = gen_reg_rtx (XFmode);
14564 op1 = gen_reg_rtx (XFmode);
14565 op2 = gen_reg_rtx (XFmode);
14567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14568 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14569 emit_insn (gen_scalbxf3 (op0, op1, op2));
14570 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14574 (define_expand "significandxf2"
14575 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14576 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14577 UNSPEC_XTRACT_FRACT))
14579 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14580 "TARGET_USE_FANCY_MATH_387
14581 && flag_unsafe_math_optimizations"
14582 "operands[2] = gen_reg_rtx (XFmode);")
14584 (define_expand "significand<mode>2"
14585 [(use (match_operand:MODEF 0 "register_operand" ""))
14586 (use (match_operand:MODEF 1 "register_operand" ""))]
14587 "TARGET_USE_FANCY_MATH_387
14588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14589 || TARGET_MIX_SSE_I387)
14590 && flag_unsafe_math_optimizations"
14592 rtx op0 = gen_reg_rtx (XFmode);
14593 rtx op1 = gen_reg_rtx (XFmode);
14595 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14596 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14601 (define_insn "sse4_1_round<mode>2"
14602 [(set (match_operand:MODEF 0 "register_operand" "=x")
14603 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14604 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14607 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14608 [(set_attr "type" "ssecvt")
14609 (set_attr "prefix_extra" "1")
14610 (set_attr "prefix" "maybe_vex")
14611 (set_attr "mode" "<MODE>")])
14613 (define_insn "rintxf2"
14614 [(set (match_operand:XF 0 "register_operand" "=f")
14615 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations"
14620 [(set_attr "type" "fpspc")
14621 (set_attr "mode" "XF")])
14623 (define_expand "rint<mode>2"
14624 [(use (match_operand:MODEF 0 "register_operand" ""))
14625 (use (match_operand:MODEF 1 "register_operand" ""))]
14626 "(TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations)
14630 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14631 && !flag_trapping_math)"
14633 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14634 && !flag_trapping_math)
14637 emit_insn (gen_sse4_1_round<mode>2
14638 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14639 else if (optimize_insn_for_size_p ())
14642 ix86_expand_rint (operand0, operand1);
14646 rtx op0 = gen_reg_rtx (XFmode);
14647 rtx op1 = gen_reg_rtx (XFmode);
14649 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14650 emit_insn (gen_rintxf2 (op0, op1));
14652 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14657 (define_expand "round<mode>2"
14658 [(match_operand:X87MODEF 0 "register_operand" "")
14659 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14660 "(TARGET_USE_FANCY_MATH_387
14661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14662 || TARGET_MIX_SSE_I387)
14663 && flag_unsafe_math_optimizations)
14664 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665 && !flag_trapping_math && !flag_rounding_math)"
14667 if (optimize_insn_for_size_p ())
14670 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14671 && !flag_trapping_math && !flag_rounding_math)
14675 operands[1] = force_reg (<MODE>mode, operands[1]);
14676 ix86_expand_round_sse4 (operands[0], operands[1]);
14678 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14679 ix86_expand_round (operands[0], operands[1]);
14681 ix86_expand_rounddf_32 (operands[0], operands[1]);
14685 operands[1] = force_reg (<MODE>mode, operands[1]);
14686 ix86_emit_i387_round (operands[0], operands[1]);
14691 (define_insn_and_split "*fistdi2_1"
14692 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14693 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14695 "TARGET_USE_FANCY_MATH_387
14696 && can_create_pseudo_p ()"
14701 if (memory_operand (operands[0], VOIDmode))
14702 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14705 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14706 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "DI")])
14714 (define_insn "fistdi2"
14715 [(set (match_operand:DI 0 "memory_operand" "=m")
14716 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14718 (clobber (match_scratch:XF 2 "=&1f"))]
14719 "TARGET_USE_FANCY_MATH_387"
14720 "* return output_fix_trunc (insn, operands, false);"
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "DI")])
14724 (define_insn "fistdi2_with_temp"
14725 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14726 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14728 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14729 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14730 "TARGET_USE_FANCY_MATH_387"
14732 [(set_attr "type" "fpspc")
14733 (set_attr "mode" "DI")])
14736 [(set (match_operand:DI 0 "register_operand" "")
14737 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14739 (clobber (match_operand:DI 2 "memory_operand" ""))
14740 (clobber (match_scratch 3 ""))]
14742 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14743 (clobber (match_dup 3))])
14744 (set (match_dup 0) (match_dup 2))])
14747 [(set (match_operand:DI 0 "memory_operand" "")
14748 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14750 (clobber (match_operand:DI 2 "memory_operand" ""))
14751 (clobber (match_scratch 3 ""))]
14753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14754 (clobber (match_dup 3))])])
14756 (define_insn_and_split "*fist<mode>2_1"
14757 [(set (match_operand:SWI24 0 "register_operand" "")
14758 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14760 "TARGET_USE_FANCY_MATH_387
14761 && can_create_pseudo_p ()"
14766 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14767 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14771 [(set_attr "type" "fpspc")
14772 (set_attr "mode" "<MODE>")])
14774 (define_insn "fist<mode>2"
14775 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14776 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14778 "TARGET_USE_FANCY_MATH_387"
14779 "* return output_fix_trunc (insn, operands, false);"
14780 [(set_attr "type" "fpspc")
14781 (set_attr "mode" "<MODE>")])
14783 (define_insn "fist<mode>2_with_temp"
14784 [(set (match_operand:SWI24 0 "register_operand" "=r")
14785 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14787 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14788 "TARGET_USE_FANCY_MATH_387"
14790 [(set_attr "type" "fpspc")
14791 (set_attr "mode" "<MODE>")])
14794 [(set (match_operand:SWI24 0 "register_operand" "")
14795 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14797 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14799 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14800 (set (match_dup 0) (match_dup 2))])
14803 [(set (match_operand:SWI24 0 "memory_operand" "")
14804 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14806 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14808 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14810 (define_expand "lrintxf<mode>2"
14811 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14812 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14814 "TARGET_USE_FANCY_MATH_387")
14816 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14817 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14818 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14819 UNSPEC_FIX_NOTRUNC))]
14820 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14821 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14823 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14824 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14825 (match_operand:X87MODEF 1 "register_operand" "")]
14826 "(TARGET_USE_FANCY_MATH_387
14827 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14828 || TARGET_MIX_SSE_I387)
14829 && flag_unsafe_math_optimizations)
14830 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14831 && <SWI248x:MODE>mode != HImode
14832 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14833 && !flag_trapping_math && !flag_rounding_math)"
14835 if (optimize_insn_for_size_p ())
14838 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14839 && <SWI248x:MODE>mode != HImode
14840 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14841 && !flag_trapping_math && !flag_rounding_math)
14842 ix86_expand_lround (operand0, operand1);
14844 ix86_emit_i387_round (operands[0], operands[1]);
14848 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14849 (define_insn_and_split "frndintxf2_floor"
14850 [(set (match_operand:XF 0 "register_operand" "")
14851 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14852 UNSPEC_FRNDINT_FLOOR))
14853 (clobber (reg:CC FLAGS_REG))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations
14856 && can_create_pseudo_p ()"
14861 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14866 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14867 operands[2], operands[3]));
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "floor")
14872 (set_attr "mode" "XF")])
14874 (define_insn "frndintxf2_floor_i387"
14875 [(set (match_operand:XF 0 "register_operand" "=f")
14876 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14877 UNSPEC_FRNDINT_FLOOR))
14878 (use (match_operand:HI 2 "memory_operand" "m"))
14879 (use (match_operand:HI 3 "memory_operand" "m"))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && flag_unsafe_math_optimizations"
14882 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14883 [(set_attr "type" "frndint")
14884 (set_attr "i387_cw" "floor")
14885 (set_attr "mode" "XF")])
14887 (define_expand "floorxf2"
14888 [(use (match_operand:XF 0 "register_operand" ""))
14889 (use (match_operand:XF 1 "register_operand" ""))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && flag_unsafe_math_optimizations"
14893 if (optimize_insn_for_size_p ())
14895 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14899 (define_expand "floor<mode>2"
14900 [(use (match_operand:MODEF 0 "register_operand" ""))
14901 (use (match_operand:MODEF 1 "register_operand" ""))]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math)"
14909 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14910 && !flag_trapping_math)
14913 emit_insn (gen_sse4_1_round<mode>2
14914 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14915 else if (optimize_insn_for_size_p ())
14917 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14918 ix86_expand_floorceil (operand0, operand1, true);
14920 ix86_expand_floorceildf_32 (operand0, operand1, true);
14926 if (optimize_insn_for_size_p ())
14929 op0 = gen_reg_rtx (XFmode);
14930 op1 = gen_reg_rtx (XFmode);
14931 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14932 emit_insn (gen_frndintxf2_floor (op0, op1));
14934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14939 (define_insn_and_split "*fist<mode>2_floor_1"
14940 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14941 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14942 UNSPEC_FIST_FLOOR))
14943 (clobber (reg:CC FLAGS_REG))]
14944 "TARGET_USE_FANCY_MATH_387
14945 && flag_unsafe_math_optimizations
14946 && can_create_pseudo_p ()"
14951 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14953 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14954 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14955 if (memory_operand (operands[0], VOIDmode))
14956 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14957 operands[2], operands[3]));
14960 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14961 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14962 operands[2], operands[3],
14967 [(set_attr "type" "fistp")
14968 (set_attr "i387_cw" "floor")
14969 (set_attr "mode" "<MODE>")])
14971 (define_insn "fistdi2_floor"
14972 [(set (match_operand:DI 0 "memory_operand" "=m")
14973 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14974 UNSPEC_FIST_FLOOR))
14975 (use (match_operand:HI 2 "memory_operand" "m"))
14976 (use (match_operand:HI 3 "memory_operand" "m"))
14977 (clobber (match_scratch:XF 4 "=&1f"))]
14978 "TARGET_USE_FANCY_MATH_387
14979 && flag_unsafe_math_optimizations"
14980 "* return output_fix_trunc (insn, operands, false);"
14981 [(set_attr "type" "fistp")
14982 (set_attr "i387_cw" "floor")
14983 (set_attr "mode" "DI")])
14985 (define_insn "fistdi2_floor_with_temp"
14986 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14987 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" "m,m"))
14990 (use (match_operand:HI 3 "memory_operand" "m,m"))
14991 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14992 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14993 "TARGET_USE_FANCY_MATH_387
14994 && flag_unsafe_math_optimizations"
14996 [(set_attr "type" "fistp")
14997 (set_attr "i387_cw" "floor")
14998 (set_attr "mode" "DI")])
15001 [(set (match_operand:DI 0 "register_operand" "")
15002 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15003 UNSPEC_FIST_FLOOR))
15004 (use (match_operand:HI 2 "memory_operand" ""))
15005 (use (match_operand:HI 3 "memory_operand" ""))
15006 (clobber (match_operand:DI 4 "memory_operand" ""))
15007 (clobber (match_scratch 5 ""))]
15009 [(parallel [(set (match_dup 4)
15010 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15011 (use (match_dup 2))
15012 (use (match_dup 3))
15013 (clobber (match_dup 5))])
15014 (set (match_dup 0) (match_dup 4))])
15017 [(set (match_operand:DI 0 "memory_operand" "")
15018 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15019 UNSPEC_FIST_FLOOR))
15020 (use (match_operand:HI 2 "memory_operand" ""))
15021 (use (match_operand:HI 3 "memory_operand" ""))
15022 (clobber (match_operand:DI 4 "memory_operand" ""))
15023 (clobber (match_scratch 5 ""))]
15025 [(parallel [(set (match_dup 0)
15026 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15027 (use (match_dup 2))
15028 (use (match_dup 3))
15029 (clobber (match_dup 5))])])
15031 (define_insn "fist<mode>2_floor"
15032 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15034 UNSPEC_FIST_FLOOR))
15035 (use (match_operand:HI 2 "memory_operand" "m"))
15036 (use (match_operand:HI 3 "memory_operand" "m"))]
15037 "TARGET_USE_FANCY_MATH_387
15038 && flag_unsafe_math_optimizations"
15039 "* return output_fix_trunc (insn, operands, false);"
15040 [(set_attr "type" "fistp")
15041 (set_attr "i387_cw" "floor")
15042 (set_attr "mode" "<MODE>")])
15044 (define_insn "fist<mode>2_floor_with_temp"
15045 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15047 UNSPEC_FIST_FLOOR))
15048 (use (match_operand:HI 2 "memory_operand" "m,m"))
15049 (use (match_operand:HI 3 "memory_operand" "m,m"))
15050 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations"
15054 [(set_attr "type" "fistp")
15055 (set_attr "i387_cw" "floor")
15056 (set_attr "mode" "<MODE>")])
15059 [(set (match_operand:SWI24 0 "register_operand" "")
15060 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15061 UNSPEC_FIST_FLOOR))
15062 (use (match_operand:HI 2 "memory_operand" ""))
15063 (use (match_operand:HI 3 "memory_operand" ""))
15064 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15066 [(parallel [(set (match_dup 4)
15067 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15068 (use (match_dup 2))
15069 (use (match_dup 3))])
15070 (set (match_dup 0) (match_dup 4))])
15073 [(set (match_operand:SWI24 0 "memory_operand" "")
15074 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15075 UNSPEC_FIST_FLOOR))
15076 (use (match_operand:HI 2 "memory_operand" ""))
15077 (use (match_operand:HI 3 "memory_operand" ""))
15078 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15080 [(parallel [(set (match_dup 0)
15081 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15082 (use (match_dup 2))
15083 (use (match_dup 3))])])
15085 (define_expand "lfloorxf<mode>2"
15086 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15087 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15088 UNSPEC_FIST_FLOOR))
15089 (clobber (reg:CC FLAGS_REG))])]
15090 "TARGET_USE_FANCY_MATH_387
15091 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15092 && flag_unsafe_math_optimizations")
15094 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15095 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15096 (match_operand:MODEF 1 "register_operand" "")]
15097 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15098 && !flag_trapping_math"
15100 if (TARGET_64BIT && optimize_insn_for_size_p ())
15102 ix86_expand_lfloorceil (operand0, operand1, true);
15106 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15107 (define_insn_and_split "frndintxf2_ceil"
15108 [(set (match_operand:XF 0 "register_operand" "")
15109 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15110 UNSPEC_FRNDINT_CEIL))
15111 (clobber (reg:CC FLAGS_REG))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations
15114 && can_create_pseudo_p ()"
15119 ix86_optimize_mode_switching[I387_CEIL] = 1;
15121 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15122 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15124 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15125 operands[2], operands[3]));
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "XF")])
15132 (define_insn "frndintxf2_ceil_i387"
15133 [(set (match_operand:XF 0 "register_operand" "=f")
15134 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15135 UNSPEC_FRNDINT_CEIL))
15136 (use (match_operand:HI 2 "memory_operand" "m"))
15137 (use (match_operand:HI 3 "memory_operand" "m"))]
15138 "TARGET_USE_FANCY_MATH_387
15139 && flag_unsafe_math_optimizations"
15140 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15141 [(set_attr "type" "frndint")
15142 (set_attr "i387_cw" "ceil")
15143 (set_attr "mode" "XF")])
15145 (define_expand "ceilxf2"
15146 [(use (match_operand:XF 0 "register_operand" ""))
15147 (use (match_operand:XF 1 "register_operand" ""))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15151 if (optimize_insn_for_size_p ())
15153 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15157 (define_expand "ceil<mode>2"
15158 [(use (match_operand:MODEF 0 "register_operand" ""))
15159 (use (match_operand:MODEF 1 "register_operand" ""))]
15160 "(TARGET_USE_FANCY_MATH_387
15161 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15162 || TARGET_MIX_SSE_I387)
15163 && flag_unsafe_math_optimizations)
15164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15165 && !flag_trapping_math)"
15167 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15168 && !flag_trapping_math)
15171 emit_insn (gen_sse4_1_round<mode>2
15172 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15173 else if (optimize_insn_for_size_p ())
15175 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15176 ix86_expand_floorceil (operand0, operand1, false);
15178 ix86_expand_floorceildf_32 (operand0, operand1, false);
15184 if (optimize_insn_for_size_p ())
15187 op0 = gen_reg_rtx (XFmode);
15188 op1 = gen_reg_rtx (XFmode);
15189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15190 emit_insn (gen_frndintxf2_ceil (op0, op1));
15192 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15197 (define_insn_and_split "*fist<mode>2_ceil_1"
15198 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15199 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15201 (clobber (reg:CC FLAGS_REG))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && flag_unsafe_math_optimizations
15204 && can_create_pseudo_p ()"
15209 ix86_optimize_mode_switching[I387_CEIL] = 1;
15211 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15212 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15213 if (memory_operand (operands[0], VOIDmode))
15214 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15215 operands[2], operands[3]));
15218 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15219 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15220 operands[2], operands[3],
15225 [(set_attr "type" "fistp")
15226 (set_attr "i387_cw" "ceil")
15227 (set_attr "mode" "<MODE>")])
15229 (define_insn "fistdi2_ceil"
15230 [(set (match_operand:DI 0 "memory_operand" "=m")
15231 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15233 (use (match_operand:HI 2 "memory_operand" "m"))
15234 (use (match_operand:HI 3 "memory_operand" "m"))
15235 (clobber (match_scratch:XF 4 "=&1f"))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15238 "* return output_fix_trunc (insn, operands, false);"
15239 [(set_attr "type" "fistp")
15240 (set_attr "i387_cw" "ceil")
15241 (set_attr "mode" "DI")])
15243 (define_insn "fistdi2_ceil_with_temp"
15244 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15245 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15247 (use (match_operand:HI 2 "memory_operand" "m,m"))
15248 (use (match_operand:HI 3 "memory_operand" "m,m"))
15249 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15250 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && flag_unsafe_math_optimizations"
15254 [(set_attr "type" "fistp")
15255 (set_attr "i387_cw" "ceil")
15256 (set_attr "mode" "DI")])
15259 [(set (match_operand:DI 0 "register_operand" "")
15260 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15262 (use (match_operand:HI 2 "memory_operand" ""))
15263 (use (match_operand:HI 3 "memory_operand" ""))
15264 (clobber (match_operand:DI 4 "memory_operand" ""))
15265 (clobber (match_scratch 5 ""))]
15267 [(parallel [(set (match_dup 4)
15268 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15269 (use (match_dup 2))
15270 (use (match_dup 3))
15271 (clobber (match_dup 5))])
15272 (set (match_dup 0) (match_dup 4))])
15275 [(set (match_operand:DI 0 "memory_operand" "")
15276 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15278 (use (match_operand:HI 2 "memory_operand" ""))
15279 (use (match_operand:HI 3 "memory_operand" ""))
15280 (clobber (match_operand:DI 4 "memory_operand" ""))
15281 (clobber (match_scratch 5 ""))]
15283 [(parallel [(set (match_dup 0)
15284 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15285 (use (match_dup 2))
15286 (use (match_dup 3))
15287 (clobber (match_dup 5))])])
15289 (define_insn "fist<mode>2_ceil"
15290 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15293 (use (match_operand:HI 2 "memory_operand" "m"))
15294 (use (match_operand:HI 3 "memory_operand" "m"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations"
15297 "* return output_fix_trunc (insn, operands, false);"
15298 [(set_attr "type" "fistp")
15299 (set_attr "i387_cw" "ceil")
15300 (set_attr "mode" "<MODE>")])
15302 (define_insn "fist<mode>2_ceil_with_temp"
15303 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15304 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15306 (use (match_operand:HI 2 "memory_operand" "m,m"))
15307 (use (match_operand:HI 3 "memory_operand" "m,m"))
15308 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15309 "TARGET_USE_FANCY_MATH_387
15310 && flag_unsafe_math_optimizations"
15312 [(set_attr "type" "fistp")
15313 (set_attr "i387_cw" "ceil")
15314 (set_attr "mode" "<MODE>")])
15317 [(set (match_operand:SWI24 0 "register_operand" "")
15318 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15320 (use (match_operand:HI 2 "memory_operand" ""))
15321 (use (match_operand:HI 3 "memory_operand" ""))
15322 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15324 [(parallel [(set (match_dup 4)
15325 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15326 (use (match_dup 2))
15327 (use (match_dup 3))])
15328 (set (match_dup 0) (match_dup 4))])
15331 [(set (match_operand:SWI24 0 "memory_operand" "")
15332 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15334 (use (match_operand:HI 2 "memory_operand" ""))
15335 (use (match_operand:HI 3 "memory_operand" ""))
15336 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15338 [(parallel [(set (match_dup 0)
15339 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15340 (use (match_dup 2))
15341 (use (match_dup 3))])])
15343 (define_expand "lceilxf<mode>2"
15344 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15345 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15347 (clobber (reg:CC FLAGS_REG))])]
15348 "TARGET_USE_FANCY_MATH_387
15349 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15350 && flag_unsafe_math_optimizations")
15352 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15353 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15354 (match_operand:MODEF 1 "register_operand" "")]
15355 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15356 && !flag_trapping_math"
15358 ix86_expand_lfloorceil (operand0, operand1, false);
15362 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15363 (define_insn_and_split "frndintxf2_trunc"
15364 [(set (match_operand:XF 0 "register_operand" "")
15365 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15366 UNSPEC_FRNDINT_TRUNC))
15367 (clobber (reg:CC FLAGS_REG))]
15368 "TARGET_USE_FANCY_MATH_387
15369 && flag_unsafe_math_optimizations
15370 && can_create_pseudo_p ()"
15375 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15377 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15378 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15380 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15381 operands[2], operands[3]));
15384 [(set_attr "type" "frndint")
15385 (set_attr "i387_cw" "trunc")
15386 (set_attr "mode" "XF")])
15388 (define_insn "frndintxf2_trunc_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15391 UNSPEC_FRNDINT_TRUNC))
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && flag_unsafe_math_optimizations"
15396 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15397 [(set_attr "type" "frndint")
15398 (set_attr "i387_cw" "trunc")
15399 (set_attr "mode" "XF")])
15401 (define_expand "btruncxf2"
15402 [(use (match_operand:XF 0 "register_operand" ""))
15403 (use (match_operand:XF 1 "register_operand" ""))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15407 if (optimize_insn_for_size_p ())
15409 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15413 (define_expand "btrunc<mode>2"
15414 [(use (match_operand:MODEF 0 "register_operand" ""))
15415 (use (match_operand:MODEF 1 "register_operand" ""))]
15416 "(TARGET_USE_FANCY_MATH_387
15417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15418 || TARGET_MIX_SSE_I387)
15419 && flag_unsafe_math_optimizations)
15420 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15421 && !flag_trapping_math)"
15423 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15424 && !flag_trapping_math)
15427 emit_insn (gen_sse4_1_round<mode>2
15428 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15429 else if (optimize_insn_for_size_p ())
15431 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15432 ix86_expand_trunc (operand0, operand1);
15434 ix86_expand_truncdf_32 (operand0, operand1);
15440 if (optimize_insn_for_size_p ())
15443 op0 = gen_reg_rtx (XFmode);
15444 op1 = gen_reg_rtx (XFmode);
15445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15446 emit_insn (gen_frndintxf2_trunc (op0, op1));
15448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15453 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15454 (define_insn_and_split "frndintxf2_mask_pm"
15455 [(set (match_operand:XF 0 "register_operand" "")
15456 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15457 UNSPEC_FRNDINT_MASK_PM))
15458 (clobber (reg:CC FLAGS_REG))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && flag_unsafe_math_optimizations
15461 && can_create_pseudo_p ()"
15466 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15468 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15469 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15471 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15472 operands[2], operands[3]));
15475 [(set_attr "type" "frndint")
15476 (set_attr "i387_cw" "mask_pm")
15477 (set_attr "mode" "XF")])
15479 (define_insn "frndintxf2_mask_pm_i387"
15480 [(set (match_operand:XF 0 "register_operand" "=f")
15481 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15482 UNSPEC_FRNDINT_MASK_PM))
15483 (use (match_operand:HI 2 "memory_operand" "m"))
15484 (use (match_operand:HI 3 "memory_operand" "m"))]
15485 "TARGET_USE_FANCY_MATH_387
15486 && flag_unsafe_math_optimizations"
15487 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15488 [(set_attr "type" "frndint")
15489 (set_attr "i387_cw" "mask_pm")
15490 (set_attr "mode" "XF")])
15492 (define_expand "nearbyintxf2"
15493 [(use (match_operand:XF 0 "register_operand" ""))
15494 (use (match_operand:XF 1 "register_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15498 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15502 (define_expand "nearbyint<mode>2"
15503 [(use (match_operand:MODEF 0 "register_operand" ""))
15504 (use (match_operand:MODEF 1 "register_operand" ""))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15507 || TARGET_MIX_SSE_I387)
15508 && flag_unsafe_math_optimizations"
15510 rtx op0 = gen_reg_rtx (XFmode);
15511 rtx op1 = gen_reg_rtx (XFmode);
15513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15514 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15516 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15520 (define_insn "fxam<mode>2_i387"
15521 [(set (match_operand:HI 0 "register_operand" "=a")
15523 [(match_operand:X87MODEF 1 "register_operand" "f")]
15525 "TARGET_USE_FANCY_MATH_387"
15526 "fxam\n\tfnstsw\t%0"
15527 [(set_attr "type" "multi")
15528 (set_attr "length" "4")
15529 (set_attr "unit" "i387")
15530 (set_attr "mode" "<MODE>")])
15532 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15533 [(set (match_operand:HI 0 "register_operand" "")
15535 [(match_operand:MODEF 1 "memory_operand" "")]
15537 "TARGET_USE_FANCY_MATH_387
15538 && can_create_pseudo_p ()"
15541 [(set (match_dup 2)(match_dup 1))
15543 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15545 operands[2] = gen_reg_rtx (<MODE>mode);
15547 MEM_VOLATILE_P (operands[1]) = 1;
15549 [(set_attr "type" "multi")
15550 (set_attr "unit" "i387")
15551 (set_attr "mode" "<MODE>")])
15553 (define_expand "isinfxf2"
15554 [(use (match_operand:SI 0 "register_operand" ""))
15555 (use (match_operand:XF 1 "register_operand" ""))]
15556 "TARGET_USE_FANCY_MATH_387
15557 && TARGET_C99_FUNCTIONS"
15559 rtx mask = GEN_INT (0x45);
15560 rtx val = GEN_INT (0x05);
15564 rtx scratch = gen_reg_rtx (HImode);
15565 rtx res = gen_reg_rtx (QImode);
15567 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15569 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15570 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15571 cond = gen_rtx_fmt_ee (EQ, QImode,
15572 gen_rtx_REG (CCmode, FLAGS_REG),
15574 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15575 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15579 (define_expand "isinf<mode>2"
15580 [(use (match_operand:SI 0 "register_operand" ""))
15581 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && TARGET_C99_FUNCTIONS
15584 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15586 rtx mask = GEN_INT (0x45);
15587 rtx val = GEN_INT (0x05);
15591 rtx scratch = gen_reg_rtx (HImode);
15592 rtx res = gen_reg_rtx (QImode);
15594 /* Remove excess precision by forcing value through memory. */
15595 if (memory_operand (operands[1], VOIDmode))
15596 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15599 enum ix86_stack_slot slot = (virtuals_instantiated
15602 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15604 emit_move_insn (temp, operands[1]);
15605 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15608 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15609 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15610 cond = gen_rtx_fmt_ee (EQ, QImode,
15611 gen_rtx_REG (CCmode, FLAGS_REG),
15613 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15614 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15618 (define_expand "signbitxf2"
15619 [(use (match_operand:SI 0 "register_operand" ""))
15620 (use (match_operand:XF 1 "register_operand" ""))]
15621 "TARGET_USE_FANCY_MATH_387"
15623 rtx scratch = gen_reg_rtx (HImode);
15625 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631 (define_insn "movmsk_df"
15632 [(set (match_operand:SI 0 "register_operand" "=r")
15634 [(match_operand:DF 1 "register_operand" "x")]
15636 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15637 "%vmovmskpd\t{%1, %0|%0, %1}"
15638 [(set_attr "type" "ssemov")
15639 (set_attr "prefix" "maybe_vex")
15640 (set_attr "mode" "DF")])
15642 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15643 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15644 (define_expand "signbitdf2"
15645 [(use (match_operand:SI 0 "register_operand" ""))
15646 (use (match_operand:DF 1 "register_operand" ""))]
15647 "TARGET_USE_FANCY_MATH_387
15648 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15650 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15652 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15653 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15657 rtx scratch = gen_reg_rtx (HImode);
15659 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15660 emit_insn (gen_andsi3 (operands[0],
15661 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15666 (define_expand "signbitsf2"
15667 [(use (match_operand:SI 0 "register_operand" ""))
15668 (use (match_operand:SF 1 "register_operand" ""))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15672 rtx scratch = gen_reg_rtx (HImode);
15674 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15675 emit_insn (gen_andsi3 (operands[0],
15676 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15680 ;; Block operation instructions
15683 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15686 [(set_attr "length" "1")
15687 (set_attr "length_immediate" "0")
15688 (set_attr "modrm" "0")])
15690 (define_expand "movmem<mode>"
15691 [(use (match_operand:BLK 0 "memory_operand" ""))
15692 (use (match_operand:BLK 1 "memory_operand" ""))
15693 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15694 (use (match_operand:SWI48 3 "const_int_operand" ""))
15695 (use (match_operand:SI 4 "const_int_operand" ""))
15696 (use (match_operand:SI 5 "const_int_operand" ""))]
15699 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15700 operands[4], operands[5]))
15706 ;; Most CPUs don't like single string operations
15707 ;; Handle this case here to simplify previous expander.
15709 (define_expand "strmov"
15710 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15711 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15712 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15713 (clobber (reg:CC FLAGS_REG))])
15714 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15715 (clobber (reg:CC FLAGS_REG))])]
15718 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15720 /* If .md ever supports :P for Pmode, these can be directly
15721 in the pattern above. */
15722 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15723 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15725 /* Can't use this if the user has appropriated esi or edi. */
15726 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15727 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15729 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15730 operands[2], operands[3],
15731 operands[5], operands[6]));
15735 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15738 (define_expand "strmov_singleop"
15739 [(parallel [(set (match_operand 1 "memory_operand" "")
15740 (match_operand 3 "memory_operand" ""))
15741 (set (match_operand 0 "register_operand" "")
15742 (match_operand 4 "" ""))
15743 (set (match_operand 2 "register_operand" "")
15744 (match_operand 5 "" ""))])]
15746 "ix86_current_function_needs_cld = 1;")
15748 (define_insn "*strmovdi_rex_1"
15749 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15750 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15751 (set (match_operand:DI 0 "register_operand" "=D")
15752 (plus:DI (match_dup 2)
15754 (set (match_operand:DI 1 "register_operand" "=S")
15755 (plus:DI (match_dup 3)
15758 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "DI")])
15764 (define_insn "*strmovsi_1"
15765 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15766 (mem:SI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set_attr "mode" "SI")])
15779 (define_insn "*strmovhi_1"
15780 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15781 (mem:HI (match_operand:P 3 "register_operand" "1")))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (match_dup 2)
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (match_dup 3)
15788 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "both")
15792 (set_attr "mode" "HI")])
15794 (define_insn "*strmovqi_1"
15795 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15796 (mem:QI (match_operand:P 3 "register_operand" "1")))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (match_dup 2)
15800 (set (match_operand:P 1 "register_operand" "=S")
15801 (plus:P (match_dup 3)
15803 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15805 [(set_attr "type" "str")
15806 (set_attr "memory" "both")
15807 (set (attr "prefix_rex")
15809 (match_test "<P:MODE>mode == DImode")
15811 (const_string "*")))
15812 (set_attr "mode" "QI")])
15814 (define_expand "rep_mov"
15815 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15816 (set (match_operand 0 "register_operand" "")
15817 (match_operand 5 "" ""))
15818 (set (match_operand 2 "register_operand" "")
15819 (match_operand 6 "" ""))
15820 (set (match_operand 1 "memory_operand" "")
15821 (match_operand 3 "memory_operand" ""))
15822 (use (match_dup 4))])]
15824 "ix86_current_function_needs_cld = 1;")
15826 (define_insn "*rep_movdi_rex64"
15827 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15828 (set (match_operand:DI 0 "register_operand" "=D")
15829 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15831 (match_operand:DI 3 "register_operand" "0")))
15832 (set (match_operand:DI 1 "register_operand" "=S")
15833 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15834 (match_operand:DI 4 "register_operand" "1")))
15835 (set (mem:BLK (match_dup 3))
15836 (mem:BLK (match_dup 4)))
15837 (use (match_dup 5))]
15839 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841 [(set_attr "type" "str")
15842 (set_attr "prefix_rep" "1")
15843 (set_attr "memory" "both")
15844 (set_attr "mode" "DI")])
15846 (define_insn "*rep_movsi"
15847 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15848 (set (match_operand:P 0 "register_operand" "=D")
15849 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15851 (match_operand:P 3 "register_operand" "0")))
15852 (set (match_operand:P 1 "register_operand" "=S")
15853 (plus:P (ashift:P (match_dup 5) (const_int 2))
15854 (match_operand:P 4 "register_operand" "1")))
15855 (set (mem:BLK (match_dup 3))
15856 (mem:BLK (match_dup 4)))
15857 (use (match_dup 5))]
15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859 "rep{%;} movs{l|d}"
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "both")
15863 (set_attr "mode" "SI")])
15865 (define_insn "*rep_movqi"
15866 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15867 (set (match_operand:P 0 "register_operand" "=D")
15868 (plus:P (match_operand:P 3 "register_operand" "0")
15869 (match_operand:P 5 "register_operand" "2")))
15870 (set (match_operand:P 1 "register_operand" "=S")
15871 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15872 (set (mem:BLK (match_dup 3))
15873 (mem:BLK (match_dup 4)))
15874 (use (match_dup 5))]
15875 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15877 [(set_attr "type" "str")
15878 (set_attr "prefix_rep" "1")
15879 (set_attr "memory" "both")
15880 (set_attr "mode" "QI")])
15882 (define_expand "setmem<mode>"
15883 [(use (match_operand:BLK 0 "memory_operand" ""))
15884 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15885 (use (match_operand:QI 2 "nonmemory_operand" ""))
15886 (use (match_operand 3 "const_int_operand" ""))
15887 (use (match_operand:SI 4 "const_int_operand" ""))
15888 (use (match_operand:SI 5 "const_int_operand" ""))]
15891 if (ix86_expand_setmem (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[4], operands[5]))
15899 ;; Most CPUs don't like single string operations
15900 ;; Handle this case here to simplify previous expander.
15902 (define_expand "strset"
15903 [(set (match_operand 1 "memory_operand" "")
15904 (match_operand 2 "register_operand" ""))
15905 (parallel [(set (match_operand 0 "register_operand" "")
15907 (clobber (reg:CC FLAGS_REG))])]
15910 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15911 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15913 /* If .md ever supports :P for Pmode, this can be directly
15914 in the pattern above. */
15915 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15916 GEN_INT (GET_MODE_SIZE (GET_MODE
15918 /* Can't use this if the user has appropriated eax or edi. */
15919 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15920 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15922 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15928 (define_expand "strset_singleop"
15929 [(parallel [(set (match_operand 1 "memory_operand" "")
15930 (match_operand 2 "register_operand" ""))
15931 (set (match_operand 0 "register_operand" "")
15932 (match_operand 3 "" ""))])]
15934 "ix86_current_function_needs_cld = 1;")
15936 (define_insn "*strsetdi_rex_1"
15937 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15938 (match_operand:DI 2 "register_operand" "a"))
15939 (set (match_operand:DI 0 "register_operand" "=D")
15940 (plus:DI (match_dup 1)
15943 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15945 [(set_attr "type" "str")
15946 (set_attr "memory" "store")
15947 (set_attr "mode" "DI")])
15949 (define_insn "*strsetsi_1"
15950 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15951 (match_operand:SI 2 "register_operand" "a"))
15952 (set (match_operand:P 0 "register_operand" "=D")
15953 (plus:P (match_dup 1)
15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "SI")])
15961 (define_insn "*strsethi_1"
15962 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:HI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "HI")])
15973 (define_insn "*strsetqi_1"
15974 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:QI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set (attr "prefix_rex")
15985 (match_test "<P:MODE>mode == DImode")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15990 (define_expand "rep_stos"
15991 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15992 (set (match_operand 0 "register_operand" "")
15993 (match_operand 4 "" ""))
15994 (set (match_operand 2 "memory_operand" "") (const_int 0))
15995 (use (match_operand 3 "register_operand" ""))
15996 (use (match_dup 1))])]
15998 "ix86_current_function_needs_cld = 1;")
16000 (define_insn "*rep_stosdi_rex64"
16001 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16002 (set (match_operand:DI 0 "register_operand" "=D")
16003 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16005 (match_operand:DI 3 "register_operand" "0")))
16006 (set (mem:BLK (match_dup 3))
16008 (use (match_operand:DI 2 "register_operand" "a"))
16009 (use (match_dup 4))]
16011 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set_attr "mode" "DI")])
16018 (define_insn "*rep_stossi"
16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16023 (match_operand:P 3 "register_operand" "0")))
16024 (set (mem:BLK (match_dup 3))
16026 (use (match_operand:SI 2 "register_operand" "a"))
16027 (use (match_dup 4))]
16028 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16029 "rep{%;} stos{l|d}"
16030 [(set_attr "type" "str")
16031 (set_attr "prefix_rep" "1")
16032 (set_attr "memory" "store")
16033 (set_attr "mode" "SI")])
16035 (define_insn "*rep_stosqi"
16036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16037 (set (match_operand:P 0 "register_operand" "=D")
16038 (plus:P (match_operand:P 3 "register_operand" "0")
16039 (match_operand:P 4 "register_operand" "1")))
16040 (set (mem:BLK (match_dup 3))
16042 (use (match_operand:QI 2 "register_operand" "a"))
16043 (use (match_dup 4))]
16044 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16046 [(set_attr "type" "str")
16047 (set_attr "prefix_rep" "1")
16048 (set_attr "memory" "store")
16049 (set (attr "prefix_rex")
16051 (match_test "<P:MODE>mode == DImode")
16053 (const_string "*")))
16054 (set_attr "mode" "QI")])
16056 (define_expand "cmpstrnsi"
16057 [(set (match_operand:SI 0 "register_operand" "")
16058 (compare:SI (match_operand:BLK 1 "general_operand" "")
16059 (match_operand:BLK 2 "general_operand" "")))
16060 (use (match_operand 3 "general_operand" ""))
16061 (use (match_operand 4 "immediate_operand" ""))]
16064 rtx addr1, addr2, out, outlow, count, countreg, align;
16066 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16069 /* Can't use this if the user has appropriated ecx, esi or edi. */
16070 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16075 out = gen_reg_rtx (SImode);
16077 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16078 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16079 if (addr1 != XEXP (operands[1], 0))
16080 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16081 if (addr2 != XEXP (operands[2], 0))
16082 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16084 count = operands[3];
16085 countreg = ix86_zero_extend_to_Pmode (count);
16087 /* %%% Iff we are testing strict equality, we can use known alignment
16088 to good advantage. This may be possible with combine, particularly
16089 once cc0 is dead. */
16090 align = operands[4];
16092 if (CONST_INT_P (count))
16094 if (INTVAL (count) == 0)
16096 emit_move_insn (operands[0], const0_rtx);
16099 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16104 rtx (*gen_cmp) (rtx, rtx);
16106 gen_cmp = (TARGET_64BIT
16107 ? gen_cmpdi_1 : gen_cmpsi_1);
16109 emit_insn (gen_cmp (countreg, countreg));
16110 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16111 operands[1], operands[2]));
16114 outlow = gen_lowpart (QImode, out);
16115 emit_insn (gen_cmpintqi (outlow));
16116 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16118 if (operands[0] != out)
16119 emit_move_insn (operands[0], out);
16124 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16126 (define_expand "cmpintqi"
16127 [(set (match_dup 1)
16128 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16131 (parallel [(set (match_operand:QI 0 "register_operand" "")
16132 (minus:QI (match_dup 1)
16134 (clobber (reg:CC FLAGS_REG))])]
16137 operands[1] = gen_reg_rtx (QImode);
16138 operands[2] = gen_reg_rtx (QImode);
16141 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16142 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16144 (define_expand "cmpstrnqi_nz_1"
16145 [(parallel [(set (reg:CC FLAGS_REG)
16146 (compare:CC (match_operand 4 "memory_operand" "")
16147 (match_operand 5 "memory_operand" "")))
16148 (use (match_operand 2 "register_operand" ""))
16149 (use (match_operand:SI 3 "immediate_operand" ""))
16150 (clobber (match_operand 0 "register_operand" ""))
16151 (clobber (match_operand 1 "register_operand" ""))
16152 (clobber (match_dup 2))])]
16154 "ix86_current_function_needs_cld = 1;")
16156 (define_insn "*cmpstrnqi_nz_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16159 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16160 (use (match_operand:P 6 "register_operand" "2"))
16161 (use (match_operand:SI 3 "immediate_operand" "i"))
16162 (clobber (match_operand:P 0 "register_operand" "=S"))
16163 (clobber (match_operand:P 1 "register_operand" "=D"))
16164 (clobber (match_operand:P 2 "register_operand" "=c"))]
16165 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16167 [(set_attr "type" "str")
16168 (set_attr "mode" "QI")
16169 (set (attr "prefix_rex")
16171 (match_test "<P:MODE>mode == DImode")
16173 (const_string "*")))
16174 (set_attr "prefix_rep" "1")])
16176 ;; The same, but the count is not known to not be zero.
16178 (define_expand "cmpstrnqi_1"
16179 [(parallel [(set (reg:CC FLAGS_REG)
16180 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16182 (compare:CC (match_operand 4 "memory_operand" "")
16183 (match_operand 5 "memory_operand" ""))
16185 (use (match_operand:SI 3 "immediate_operand" ""))
16186 (use (reg:CC FLAGS_REG))
16187 (clobber (match_operand 0 "register_operand" ""))
16188 (clobber (match_operand 1 "register_operand" ""))
16189 (clobber (match_dup 2))])]
16191 "ix86_current_function_needs_cld = 1;")
16193 (define_insn "*cmpstrnqi_1"
16194 [(set (reg:CC FLAGS_REG)
16195 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16197 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16198 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16200 (use (match_operand:SI 3 "immediate_operand" "i"))
16201 (use (reg:CC FLAGS_REG))
16202 (clobber (match_operand:P 0 "register_operand" "=S"))
16203 (clobber (match_operand:P 1 "register_operand" "=D"))
16204 (clobber (match_operand:P 2 "register_operand" "=c"))]
16205 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set (attr "prefix_rex")
16211 (match_test "<P:MODE>mode == DImode")
16213 (const_string "*")))
16214 (set_attr "prefix_rep" "1")])
16216 (define_expand "strlen<mode>"
16217 [(set (match_operand:P 0 "register_operand" "")
16218 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16219 (match_operand:QI 2 "immediate_operand" "")
16220 (match_operand 3 "immediate_operand" "")]
16224 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16230 (define_expand "strlenqi_1"
16231 [(parallel [(set (match_operand 0 "register_operand" "")
16232 (match_operand 2 "" ""))
16233 (clobber (match_operand 1 "register_operand" ""))
16234 (clobber (reg:CC FLAGS_REG))])]
16236 "ix86_current_function_needs_cld = 1;")
16238 (define_insn "*strlenqi_1"
16239 [(set (match_operand:P 0 "register_operand" "=&c")
16240 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16241 (match_operand:QI 2 "register_operand" "a")
16242 (match_operand:P 3 "immediate_operand" "i")
16243 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16244 (clobber (match_operand:P 1 "register_operand" "=D"))
16245 (clobber (reg:CC FLAGS_REG))]
16246 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16248 [(set_attr "type" "str")
16249 (set_attr "mode" "QI")
16250 (set (attr "prefix_rex")
16252 (match_test "<P:MODE>mode == DImode")
16254 (const_string "*")))
16255 (set_attr "prefix_rep" "1")])
16257 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16258 ;; handled in combine, but it is not currently up to the task.
16259 ;; When used for their truth value, the cmpstrn* expanders generate
16268 ;; The intermediate three instructions are unnecessary.
16270 ;; This one handles cmpstrn*_nz_1...
16273 (set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16275 (mem:BLK (match_operand 5 "register_operand" ""))))
16276 (use (match_operand 6 "register_operand" ""))
16277 (use (match_operand:SI 3 "immediate_operand" ""))
16278 (clobber (match_operand 0 "register_operand" ""))
16279 (clobber (match_operand 1 "register_operand" ""))
16280 (clobber (match_operand 2 "register_operand" ""))])
16281 (set (match_operand:QI 7 "register_operand" "")
16282 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (match_operand:QI 8 "register_operand" "")
16284 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (reg FLAGS_REG)
16286 (compare (match_dup 7) (match_dup 8)))
16288 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16290 (set (reg:CC FLAGS_REG)
16291 (compare:CC (mem:BLK (match_dup 4))
16292 (mem:BLK (match_dup 5))))
16293 (use (match_dup 6))
16294 (use (match_dup 3))
16295 (clobber (match_dup 0))
16296 (clobber (match_dup 1))
16297 (clobber (match_dup 2))])])
16299 ;; ...and this one handles cmpstrn*_1.
16302 (set (reg:CC FLAGS_REG)
16303 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16305 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16306 (mem:BLK (match_operand 5 "register_operand" "")))
16308 (use (match_operand:SI 3 "immediate_operand" ""))
16309 (use (reg:CC FLAGS_REG))
16310 (clobber (match_operand 0 "register_operand" ""))
16311 (clobber (match_operand 1 "register_operand" ""))
16312 (clobber (match_operand 2 "register_operand" ""))])
16313 (set (match_operand:QI 7 "register_operand" "")
16314 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (match_operand:QI 8 "register_operand" "")
16316 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16317 (set (reg FLAGS_REG)
16318 (compare (match_dup 7) (match_dup 8)))
16320 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16322 (set (reg:CC FLAGS_REG)
16323 (if_then_else:CC (ne (match_dup 6)
16325 (compare:CC (mem:BLK (match_dup 4))
16326 (mem:BLK (match_dup 5)))
16328 (use (match_dup 3))
16329 (use (reg:CC FLAGS_REG))
16330 (clobber (match_dup 0))
16331 (clobber (match_dup 1))
16332 (clobber (match_dup 2))])])
16334 ;; Conditional move instructions.
16336 (define_expand "mov<mode>cc"
16337 [(set (match_operand:SWIM 0 "register_operand" "")
16338 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16339 (match_operand:SWIM 2 "<general_operand>" "")
16340 (match_operand:SWIM 3 "<general_operand>" "")))]
16342 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16344 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16345 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16346 ;; So just document what we're doing explicitly.
16348 (define_expand "x86_mov<mode>cc_0_m1"
16350 [(set (match_operand:SWI48 0 "register_operand" "")
16351 (if_then_else:SWI48
16352 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16353 [(match_operand 1 "flags_reg_operand" "")
16357 (clobber (reg:CC FLAGS_REG))])])
16359 (define_insn "*x86_mov<mode>cc_0_m1"
16360 [(set (match_operand:SWI48 0 "register_operand" "=r")
16361 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16365 (clobber (reg:CC FLAGS_REG))]
16367 "sbb{<imodesuffix>}\t%0, %0"
16368 ; Since we don't have the proper number of operands for an alu insn,
16369 ; fill in all the blanks.
16370 [(set_attr "type" "alu")
16371 (set_attr "use_carry" "1")
16372 (set_attr "pent_pair" "pu")
16373 (set_attr "memory" "none")
16374 (set_attr "imm_disp" "false")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "length_immediate" "0")])
16378 (define_insn "*x86_mov<mode>cc_0_m1_se"
16379 [(set (match_operand:SWI48 0 "register_operand" "=r")
16380 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16384 (clobber (reg:CC FLAGS_REG))]
16386 "sbb{<imodesuffix>}\t%0, %0"
16387 [(set_attr "type" "alu")
16388 (set_attr "use_carry" "1")
16389 (set_attr "pent_pair" "pu")
16390 (set_attr "memory" "none")
16391 (set_attr "imm_disp" "false")
16392 (set_attr "mode" "<MODE>")
16393 (set_attr "length_immediate" "0")])
16395 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16396 [(set (match_operand:SWI48 0 "register_operand" "=r")
16397 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16398 [(reg FLAGS_REG) (const_int 0)])))]
16400 "sbb{<imodesuffix>}\t%0, %0"
16401 [(set_attr "type" "alu")
16402 (set_attr "use_carry" "1")
16403 (set_attr "pent_pair" "pu")
16404 (set_attr "memory" "none")
16405 (set_attr "imm_disp" "false")
16406 (set_attr "mode" "<MODE>")
16407 (set_attr "length_immediate" "0")])
16409 (define_insn "*mov<mode>cc_noc"
16410 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16411 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16412 [(reg FLAGS_REG) (const_int 0)])
16413 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16414 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16415 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16417 cmov%O2%C1\t{%2, %0|%0, %2}
16418 cmov%O2%c1\t{%3, %0|%0, %3}"
16419 [(set_attr "type" "icmov")
16420 (set_attr "mode" "<MODE>")])
16422 (define_insn_and_split "*movqicc_noc"
16423 [(set (match_operand:QI 0 "register_operand" "=r,r")
16424 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16425 [(match_operand 4 "flags_reg_operand" "")
16427 (match_operand:QI 2 "register_operand" "r,0")
16428 (match_operand:QI 3 "register_operand" "0,r")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16431 "&& reload_completed"
16432 [(set (match_dup 0)
16433 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16436 "operands[0] = gen_lowpart (SImode, operands[0]);
16437 operands[2] = gen_lowpart (SImode, operands[2]);
16438 operands[3] = gen_lowpart (SImode, operands[3]);"
16439 [(set_attr "type" "icmov")
16440 (set_attr "mode" "SI")])
16442 (define_expand "mov<mode>cc"
16443 [(set (match_operand:X87MODEF 0 "register_operand" "")
16444 (if_then_else:X87MODEF
16445 (match_operand 1 "ix86_fp_comparison_operator" "")
16446 (match_operand:X87MODEF 2 "register_operand" "")
16447 (match_operand:X87MODEF 3 "register_operand" "")))]
16448 "(TARGET_80387 && TARGET_CMOVE)
16449 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16450 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16452 (define_insn "*movxfcc_1"
16453 [(set (match_operand:XF 0 "register_operand" "=f,f")
16454 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16455 [(reg FLAGS_REG) (const_int 0)])
16456 (match_operand:XF 2 "register_operand" "f,0")
16457 (match_operand:XF 3 "register_operand" "0,f")))]
16458 "TARGET_80387 && TARGET_CMOVE"
16460 fcmov%F1\t{%2, %0|%0, %2}
16461 fcmov%f1\t{%3, %0|%0, %3}"
16462 [(set_attr "type" "fcmov")
16463 (set_attr "mode" "XF")])
16465 (define_insn "*movdfcc_1_rex64"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16467 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16468 [(reg FLAGS_REG) (const_int 0)])
16469 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16470 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16471 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16472 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16474 fcmov%F1\t{%2, %0|%0, %2}
16475 fcmov%f1\t{%3, %0|%0, %3}
16476 cmov%O2%C1\t{%2, %0|%0, %2}
16477 cmov%O2%c1\t{%3, %0|%0, %3}"
16478 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16479 (set_attr "mode" "DF,DF,DI,DI")])
16481 (define_insn "*movdfcc_1"
16482 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16483 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16484 [(reg FLAGS_REG) (const_int 0)])
16485 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16486 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16487 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16488 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16490 fcmov%F1\t{%2, %0|%0, %2}
16491 fcmov%f1\t{%3, %0|%0, %3}
16494 [(set_attr "type" "fcmov,fcmov,multi,multi")
16495 (set_attr "mode" "DF,DF,DI,DI")])
16498 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16499 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16500 [(match_operand 4 "flags_reg_operand" "")
16502 (match_operand:DF 2 "nonimmediate_operand" "")
16503 (match_operand:DF 3 "nonimmediate_operand" "")))]
16504 "!TARGET_64BIT && reload_completed"
16505 [(set (match_dup 2)
16506 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16510 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16514 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16515 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16518 (define_insn "*movsfcc_1_387"
16519 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16520 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16523 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524 "TARGET_80387 && TARGET_CMOVE
16525 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16527 fcmov%F1\t{%2, %0|%0, %2}
16528 fcmov%f1\t{%3, %0|%0, %3}
16529 cmov%O2%C1\t{%2, %0|%0, %2}
16530 cmov%O2%c1\t{%3, %0|%0, %3}"
16531 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16532 (set_attr "mode" "SF,SF,SI,SI")])
16534 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16535 ;; the scalar versions to have only XMM registers as operands.
16537 ;; XOP conditional move
16538 (define_insn "*xop_pcmov_<mode>"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x")
16540 (if_then_else:MODEF
16541 (match_operand:MODEF 1 "register_operand" "x")
16542 (match_operand:MODEF 2 "register_operand" "x")
16543 (match_operand:MODEF 3 "register_operand" "x")))]
16545 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16546 [(set_attr "type" "sse4arg")])
16548 ;; These versions of the min/max patterns are intentionally ignorant of
16549 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16550 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16551 ;; are undefined in this condition, we're certain this is correct.
16553 (define_insn "<code><mode>3"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16556 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16557 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16560 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16561 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562 [(set_attr "isa" "noavx,avx")
16563 (set_attr "prefix" "orig,vex")
16564 (set_attr "type" "sseadd")
16565 (set_attr "mode" "<MODE>")])
16567 ;; These versions of the min/max patterns implement exactly the operations
16568 ;; min = (op1 < op2 ? op1 : op2)
16569 ;; max = (!(op1 < op2) ? op1 : op2)
16570 ;; Their operands are not commutative, and thus they may be used in the
16571 ;; presence of -0.0 and NaN.
16573 (define_insn "*ieee_smin<mode>3"
16574 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16576 [(match_operand:MODEF 1 "register_operand" "0,x")
16577 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16579 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16581 min<ssemodesuffix>\t{%2, %0|%0, %2}
16582 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16583 [(set_attr "isa" "noavx,avx")
16584 (set_attr "prefix" "orig,vex")
16585 (set_attr "type" "sseadd")
16586 (set_attr "mode" "<MODE>")])
16588 (define_insn "*ieee_smax<mode>3"
16589 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16591 [(match_operand:MODEF 1 "register_operand" "0,x")
16592 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16596 max<ssemodesuffix>\t{%2, %0|%0, %2}
16597 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16598 [(set_attr "isa" "noavx,avx")
16599 (set_attr "prefix" "orig,vex")
16600 (set_attr "type" "sseadd")
16601 (set_attr "mode" "<MODE>")])
16603 ;; Make two stack loads independent:
16605 ;; fld %st(0) -> fld bb
16606 ;; fmul bb fmul %st(1), %st
16608 ;; Actually we only match the last two instructions for simplicity.
16610 [(set (match_operand 0 "fp_register_operand" "")
16611 (match_operand 1 "fp_register_operand" ""))
16613 (match_operator 2 "binary_fp_operator"
16615 (match_operand 3 "memory_operand" "")]))]
16616 "REGNO (operands[0]) != REGNO (operands[1])"
16617 [(set (match_dup 0) (match_dup 3))
16618 (set (match_dup 0) (match_dup 4))]
16620 ;; The % modifier is not operational anymore in peephole2's, so we have to
16621 ;; swap the operands manually in the case of addition and multiplication.
16622 "if (COMMUTATIVE_ARITH_P (operands[2]))
16623 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16624 GET_MODE (operands[2]),
16625 operands[0], operands[1]);
16627 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16628 GET_MODE (operands[2]),
16629 operands[1], operands[0]);")
16631 ;; Conditional addition patterns
16632 (define_expand "add<mode>cc"
16633 [(match_operand:SWI 0 "register_operand" "")
16634 (match_operand 1 "ordered_comparison_operator" "")
16635 (match_operand:SWI 2 "register_operand" "")
16636 (match_operand:SWI 3 "const_int_operand" "")]
16638 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16640 ;; Misc patterns (?)
16642 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16643 ;; Otherwise there will be nothing to keep
16645 ;; [(set (reg ebp) (reg esp))]
16646 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16647 ;; (clobber (eflags)]
16648 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16650 ;; in proper program order.
16652 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16653 [(set (match_operand:P 0 "register_operand" "=r,r")
16654 (plus:P (match_operand:P 1 "register_operand" "0,r")
16655 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16656 (clobber (reg:CC FLAGS_REG))
16657 (clobber (mem:BLK (scratch)))]
16660 switch (get_attr_type (insn))
16663 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16667 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16668 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16670 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16674 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16677 [(set (attr "type")
16678 (cond [(and (eq_attr "alternative" "0")
16679 (not (match_test "TARGET_OPT_AGU")))
16680 (const_string "alu")
16681 (match_operand:<MODE> 2 "const0_operand" "")
16682 (const_string "imov")
16684 (const_string "lea")))
16685 (set (attr "length_immediate")
16686 (cond [(eq_attr "type" "imov")
16688 (and (eq_attr "type" "alu")
16689 (match_operand 2 "const128_operand" ""))
16692 (const_string "*")))
16693 (set_attr "mode" "<MODE>")])
16695 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16696 [(set (match_operand:P 0 "register_operand" "=r")
16697 (minus:P (match_operand:P 1 "register_operand" "0")
16698 (match_operand:P 2 "register_operand" "r")))
16699 (clobber (reg:CC FLAGS_REG))
16700 (clobber (mem:BLK (scratch)))]
16702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16703 [(set_attr "type" "alu")
16704 (set_attr "mode" "<MODE>")])
16706 (define_insn "allocate_stack_worker_probe_<mode>"
16707 [(set (match_operand:P 0 "register_operand" "=a")
16708 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16709 UNSPECV_STACK_PROBE))
16710 (clobber (reg:CC FLAGS_REG))]
16711 "ix86_target_stack_probe ()"
16712 "call\t___chkstk_ms"
16713 [(set_attr "type" "multi")
16714 (set_attr "length" "5")])
16716 (define_expand "allocate_stack"
16717 [(match_operand 0 "register_operand" "")
16718 (match_operand 1 "general_operand" "")]
16719 "ix86_target_stack_probe ()"
16723 #ifndef CHECK_STACK_LIMIT
16724 #define CHECK_STACK_LIMIT 0
16727 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16728 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16730 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16731 stack_pointer_rtx, 0, OPTAB_DIRECT);
16732 if (x != stack_pointer_rtx)
16733 emit_move_insn (stack_pointer_rtx, x);
16737 x = copy_to_mode_reg (Pmode, operands[1]);
16739 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16741 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16742 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16743 stack_pointer_rtx, 0, OPTAB_DIRECT);
16744 if (x != stack_pointer_rtx)
16745 emit_move_insn (stack_pointer_rtx, x);
16748 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16752 ;; Use IOR for stack probes, this is shorter.
16753 (define_expand "probe_stack"
16754 [(match_operand 0 "memory_operand" "")]
16757 rtx (*gen_ior3) (rtx, rtx, rtx);
16759 gen_ior3 = (GET_MODE (operands[0]) == DImode
16760 ? gen_iordi3 : gen_iorsi3);
16762 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16766 (define_insn "adjust_stack_and_probe<mode>"
16767 [(set (match_operand:P 0 "register_operand" "=r")
16768 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16769 UNSPECV_PROBE_STACK_RANGE))
16770 (set (reg:P SP_REG)
16771 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16772 (clobber (reg:CC FLAGS_REG))
16773 (clobber (mem:BLK (scratch)))]
16775 "* return output_adjust_stack_and_probe (operands[0]);"
16776 [(set_attr "type" "multi")])
16778 (define_insn "probe_stack_range<mode>"
16779 [(set (match_operand:P 0 "register_operand" "=r")
16780 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16781 (match_operand:P 2 "const_int_operand" "n")]
16782 UNSPECV_PROBE_STACK_RANGE))
16783 (clobber (reg:CC FLAGS_REG))]
16785 "* return output_probe_stack_range (operands[0], operands[2]);"
16786 [(set_attr "type" "multi")])
16788 (define_expand "builtin_setjmp_receiver"
16789 [(label_ref (match_operand 0 "" ""))]
16790 "!TARGET_64BIT && flag_pic"
16796 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16797 rtx label_rtx = gen_label_rtx ();
16798 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16799 xops[0] = xops[1] = picreg;
16800 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16801 ix86_expand_binary_operator (MINUS, SImode, xops);
16805 emit_insn (gen_set_got (pic_offset_table_rtx));
16809 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16812 [(set (match_operand 0 "register_operand" "")
16813 (match_operator 3 "promotable_binary_operator"
16814 [(match_operand 1 "register_operand" "")
16815 (match_operand 2 "aligned_operand" "")]))
16816 (clobber (reg:CC FLAGS_REG))]
16817 "! TARGET_PARTIAL_REG_STALL && reload_completed
16818 && ((GET_MODE (operands[0]) == HImode
16819 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16820 /* ??? next two lines just !satisfies_constraint_K (...) */
16821 || !CONST_INT_P (operands[2])
16822 || satisfies_constraint_K (operands[2])))
16823 || (GET_MODE (operands[0]) == QImode
16824 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16825 [(parallel [(set (match_dup 0)
16826 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "operands[0] = gen_lowpart (SImode, operands[0]);
16829 operands[1] = gen_lowpart (SImode, operands[1]);
16830 if (GET_CODE (operands[3]) != ASHIFT)
16831 operands[2] = gen_lowpart (SImode, operands[2]);
16832 PUT_MODE (operands[3], SImode);")
16834 ; Promote the QImode tests, as i386 has encoding of the AND
16835 ; instruction with 32-bit sign-extended immediate and thus the
16836 ; instruction size is unchanged, except in the %eax case for
16837 ; which it is increased by one byte, hence the ! optimize_size.
16839 [(set (match_operand 0 "flags_reg_operand" "")
16840 (match_operator 2 "compare_operator"
16841 [(and (match_operand 3 "aligned_operand" "")
16842 (match_operand 4 "const_int_operand" ""))
16844 (set (match_operand 1 "register_operand" "")
16845 (and (match_dup 3) (match_dup 4)))]
16846 "! TARGET_PARTIAL_REG_STALL && reload_completed
16847 && optimize_insn_for_speed_p ()
16848 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16849 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16850 /* Ensure that the operand will remain sign-extended immediate. */
16851 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16852 [(parallel [(set (match_dup 0)
16853 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16856 (and:SI (match_dup 3) (match_dup 4)))])]
16859 = gen_int_mode (INTVAL (operands[4])
16860 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16861 operands[1] = gen_lowpart (SImode, operands[1]);
16862 operands[3] = gen_lowpart (SImode, operands[3]);
16865 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16866 ; the TEST instruction with 32-bit sign-extended immediate and thus
16867 ; the instruction size would at least double, which is not what we
16868 ; want even with ! optimize_size.
16870 [(set (match_operand 0 "flags_reg_operand" "")
16871 (match_operator 1 "compare_operator"
16872 [(and (match_operand:HI 2 "aligned_operand" "")
16873 (match_operand:HI 3 "const_int_operand" ""))
16875 "! TARGET_PARTIAL_REG_STALL && reload_completed
16876 && ! TARGET_FAST_PREFIX
16877 && optimize_insn_for_speed_p ()
16878 /* Ensure that the operand will remain sign-extended immediate. */
16879 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16880 [(set (match_dup 0)
16881 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16885 = gen_int_mode (INTVAL (operands[3])
16886 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16887 operands[2] = gen_lowpart (SImode, operands[2]);
16891 [(set (match_operand 0 "register_operand" "")
16892 (neg (match_operand 1 "register_operand" "")))
16893 (clobber (reg:CC FLAGS_REG))]
16894 "! TARGET_PARTIAL_REG_STALL && reload_completed
16895 && (GET_MODE (operands[0]) == HImode
16896 || (GET_MODE (operands[0]) == QImode
16897 && (TARGET_PROMOTE_QImode
16898 || optimize_insn_for_size_p ())))"
16899 [(parallel [(set (match_dup 0)
16900 (neg:SI (match_dup 1)))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "operands[0] = gen_lowpart (SImode, operands[0]);
16903 operands[1] = gen_lowpart (SImode, operands[1]);")
16906 [(set (match_operand 0 "register_operand" "")
16907 (not (match_operand 1 "register_operand" "")))]
16908 "! TARGET_PARTIAL_REG_STALL && reload_completed
16909 && (GET_MODE (operands[0]) == HImode
16910 || (GET_MODE (operands[0]) == QImode
16911 && (TARGET_PROMOTE_QImode
16912 || optimize_insn_for_size_p ())))"
16913 [(set (match_dup 0)
16914 (not:SI (match_dup 1)))]
16915 "operands[0] = gen_lowpart (SImode, operands[0]);
16916 operands[1] = gen_lowpart (SImode, operands[1]);")
16919 [(set (match_operand 0 "register_operand" "")
16920 (if_then_else (match_operator 1 "ordered_comparison_operator"
16921 [(reg FLAGS_REG) (const_int 0)])
16922 (match_operand 2 "register_operand" "")
16923 (match_operand 3 "register_operand" "")))]
16924 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16925 && (GET_MODE (operands[0]) == HImode
16926 || (GET_MODE (operands[0]) == QImode
16927 && (TARGET_PROMOTE_QImode
16928 || optimize_insn_for_size_p ())))"
16929 [(set (match_dup 0)
16930 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16931 "operands[0] = gen_lowpart (SImode, operands[0]);
16932 operands[2] = gen_lowpart (SImode, operands[2]);
16933 operands[3] = gen_lowpart (SImode, operands[3]);")
16935 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16936 ;; transform a complex memory operation into two memory to register operations.
16938 ;; Don't push memory operands
16940 [(set (match_operand:SWI 0 "push_operand" "")
16941 (match_operand:SWI 1 "memory_operand" ""))
16942 (match_scratch:SWI 2 "<r>")]
16943 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16944 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16945 [(set (match_dup 2) (match_dup 1))
16946 (set (match_dup 0) (match_dup 2))])
16948 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16951 [(set (match_operand:SF 0 "push_operand" "")
16952 (match_operand:SF 1 "memory_operand" ""))
16953 (match_scratch:SF 2 "r")]
16954 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16955 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16956 [(set (match_dup 2) (match_dup 1))
16957 (set (match_dup 0) (match_dup 2))])
16959 ;; Don't move an immediate directly to memory when the instruction
16962 [(match_scratch:SWI124 1 "<r>")
16963 (set (match_operand:SWI124 0 "memory_operand" "")
16965 "optimize_insn_for_speed_p ()
16966 && !TARGET_USE_MOV0
16967 && TARGET_SPLIT_LONG_MOVES
16968 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16969 && peep2_regno_dead_p (0, FLAGS_REG)"
16970 [(parallel [(set (match_dup 2) (const_int 0))
16971 (clobber (reg:CC FLAGS_REG))])
16972 (set (match_dup 0) (match_dup 1))]
16973 "operands[2] = gen_lowpart (SImode, operands[1]);")
16976 [(match_scratch:SWI124 2 "<r>")
16977 (set (match_operand:SWI124 0 "memory_operand" "")
16978 (match_operand:SWI124 1 "immediate_operand" ""))]
16979 "optimize_insn_for_speed_p ()
16980 && TARGET_SPLIT_LONG_MOVES
16981 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16982 [(set (match_dup 2) (match_dup 1))
16983 (set (match_dup 0) (match_dup 2))])
16985 ;; Don't compare memory with zero, load and use a test instead.
16987 [(set (match_operand 0 "flags_reg_operand" "")
16988 (match_operator 1 "compare_operator"
16989 [(match_operand:SI 2 "memory_operand" "")
16991 (match_scratch:SI 3 "r")]
16992 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16993 [(set (match_dup 3) (match_dup 2))
16994 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16996 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16997 ;; Don't split NOTs with a displacement operand, because resulting XOR
16998 ;; will not be pairable anyway.
17000 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17001 ;; represented using a modRM byte. The XOR replacement is long decoded,
17002 ;; so this split helps here as well.
17004 ;; Note: Can't do this as a regular split because we can't get proper
17005 ;; lifetime information then.
17008 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17009 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17010 "optimize_insn_for_speed_p ()
17011 && ((TARGET_NOT_UNPAIRABLE
17012 && (!MEM_P (operands[0])
17013 || !memory_displacement_operand (operands[0], <MODE>mode)))
17014 || (TARGET_NOT_VECTORMODE
17015 && long_memory_operand (operands[0], <MODE>mode)))
17016 && peep2_regno_dead_p (0, FLAGS_REG)"
17017 [(parallel [(set (match_dup 0)
17018 (xor:SWI124 (match_dup 1) (const_int -1)))
17019 (clobber (reg:CC FLAGS_REG))])])
17021 ;; Non pairable "test imm, reg" instructions can be translated to
17022 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17023 ;; byte opcode instead of two, have a short form for byte operands),
17024 ;; so do it for other CPUs as well. Given that the value was dead,
17025 ;; this should not create any new dependencies. Pass on the sub-word
17026 ;; versions if we're concerned about partial register stalls.
17029 [(set (match_operand 0 "flags_reg_operand" "")
17030 (match_operator 1 "compare_operator"
17031 [(and:SI (match_operand:SI 2 "register_operand" "")
17032 (match_operand:SI 3 "immediate_operand" ""))
17034 "ix86_match_ccmode (insn, CCNOmode)
17035 && (true_regnum (operands[2]) != AX_REG
17036 || satisfies_constraint_K (operands[3]))
17037 && peep2_reg_dead_p (1, operands[2])"
17039 [(set (match_dup 0)
17040 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17043 (and:SI (match_dup 2) (match_dup 3)))])])
17045 ;; We don't need to handle HImode case, because it will be promoted to SImode
17046 ;; on ! TARGET_PARTIAL_REG_STALL
17049 [(set (match_operand 0 "flags_reg_operand" "")
17050 (match_operator 1 "compare_operator"
17051 [(and:QI (match_operand:QI 2 "register_operand" "")
17052 (match_operand:QI 3 "immediate_operand" ""))
17054 "! TARGET_PARTIAL_REG_STALL
17055 && ix86_match_ccmode (insn, CCNOmode)
17056 && true_regnum (operands[2]) != AX_REG
17057 && peep2_reg_dead_p (1, operands[2])"
17059 [(set (match_dup 0)
17060 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17063 (and:QI (match_dup 2) (match_dup 3)))])])
17066 [(set (match_operand 0 "flags_reg_operand" "")
17067 (match_operator 1 "compare_operator"
17070 (match_operand 2 "ext_register_operand" "")
17073 (match_operand 3 "const_int_operand" ""))
17075 "! TARGET_PARTIAL_REG_STALL
17076 && ix86_match_ccmode (insn, CCNOmode)
17077 && true_regnum (operands[2]) != AX_REG
17078 && peep2_reg_dead_p (1, operands[2])"
17079 [(parallel [(set (match_dup 0)
17088 (set (zero_extract:SI (match_dup 2)
17096 (match_dup 3)))])])
17098 ;; Don't do logical operations with memory inputs.
17100 [(match_scratch:SI 2 "r")
17101 (parallel [(set (match_operand:SI 0 "register_operand" "")
17102 (match_operator:SI 3 "arith_or_logical_operator"
17104 (match_operand:SI 1 "memory_operand" "")]))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17107 [(set (match_dup 2) (match_dup 1))
17108 (parallel [(set (match_dup 0)
17109 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17110 (clobber (reg:CC FLAGS_REG))])])
17113 [(match_scratch:SI 2 "r")
17114 (parallel [(set (match_operand:SI 0 "register_operand" "")
17115 (match_operator:SI 3 "arith_or_logical_operator"
17116 [(match_operand:SI 1 "memory_operand" "")
17118 (clobber (reg:CC FLAGS_REG))])]
17119 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17120 [(set (match_dup 2) (match_dup 1))
17121 (parallel [(set (match_dup 0)
17122 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17123 (clobber (reg:CC FLAGS_REG))])])
17125 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17126 ;; refers to the destination of the load!
17129 [(set (match_operand:SI 0 "register_operand" "")
17130 (match_operand:SI 1 "register_operand" ""))
17131 (parallel [(set (match_dup 0)
17132 (match_operator:SI 3 "commutative_operator"
17134 (match_operand:SI 2 "memory_operand" "")]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "REGNO (operands[0]) != REGNO (operands[1])
17137 && GENERAL_REGNO_P (REGNO (operands[0]))
17138 && GENERAL_REGNO_P (REGNO (operands[1]))"
17139 [(set (match_dup 0) (match_dup 4))
17140 (parallel [(set (match_dup 0)
17141 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17142 (clobber (reg:CC FLAGS_REG))])]
17143 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17146 [(set (match_operand 0 "register_operand" "")
17147 (match_operand 1 "register_operand" ""))
17149 (match_operator 3 "commutative_operator"
17151 (match_operand 2 "memory_operand" "")]))]
17152 "REGNO (operands[0]) != REGNO (operands[1])
17153 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17154 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17155 [(set (match_dup 0) (match_dup 2))
17157 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17159 ; Don't do logical operations with memory outputs
17161 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17162 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17163 ; the same decoder scheduling characteristics as the original.
17166 [(match_scratch:SI 2 "r")
17167 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17168 (match_operator:SI 3 "arith_or_logical_operator"
17170 (match_operand:SI 1 "nonmemory_operand" "")]))
17171 (clobber (reg:CC FLAGS_REG))])]
17172 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17173 /* Do not split stack checking probes. */
17174 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17175 [(set (match_dup 2) (match_dup 0))
17176 (parallel [(set (match_dup 2)
17177 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17178 (clobber (reg:CC FLAGS_REG))])
17179 (set (match_dup 0) (match_dup 2))])
17182 [(match_scratch:SI 2 "r")
17183 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17184 (match_operator:SI 3 "arith_or_logical_operator"
17185 [(match_operand:SI 1 "nonmemory_operand" "")
17187 (clobber (reg:CC FLAGS_REG))])]
17188 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17189 /* Do not split stack checking probes. */
17190 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17191 [(set (match_dup 2) (match_dup 0))
17192 (parallel [(set (match_dup 2)
17193 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17194 (clobber (reg:CC FLAGS_REG))])
17195 (set (match_dup 0) (match_dup 2))])
17197 ;; Attempt to use arith or logical operations with memory outputs with
17198 ;; setting of flags.
17200 [(set (match_operand:SWI 0 "register_operand" "")
17201 (match_operand:SWI 1 "memory_operand" ""))
17202 (parallel [(set (match_dup 0)
17203 (match_operator:SWI 3 "plusminuslogic_operator"
17205 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17206 (clobber (reg:CC FLAGS_REG))])
17207 (set (match_dup 1) (match_dup 0))
17208 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17209 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17210 && peep2_reg_dead_p (4, operands[0])
17211 && !reg_overlap_mentioned_p (operands[0], operands[1])
17212 && ix86_match_ccmode (peep2_next_insn (3),
17213 (GET_CODE (operands[3]) == PLUS
17214 || GET_CODE (operands[3]) == MINUS)
17215 ? CCGOCmode : CCNOmode)"
17216 [(parallel [(set (match_dup 4) (match_dup 5))
17217 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17218 (match_dup 2)]))])]
17219 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17220 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17221 copy_rtx (operands[1]),
17222 copy_rtx (operands[2]));
17223 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17224 operands[5], const0_rtx);")
17227 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17228 (match_operator:SWI 2 "plusminuslogic_operator"
17230 (match_operand:SWI 1 "memory_operand" "")]))
17231 (clobber (reg:CC FLAGS_REG))])
17232 (set (match_dup 1) (match_dup 0))
17233 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17234 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17235 && GET_CODE (operands[2]) != MINUS
17236 && peep2_reg_dead_p (3, operands[0])
17237 && !reg_overlap_mentioned_p (operands[0], operands[1])
17238 && ix86_match_ccmode (peep2_next_insn (2),
17239 GET_CODE (operands[2]) == PLUS
17240 ? CCGOCmode : CCNOmode)"
17241 [(parallel [(set (match_dup 3) (match_dup 4))
17242 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17243 (match_dup 0)]))])]
17244 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17245 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17246 copy_rtx (operands[1]),
17247 copy_rtx (operands[0]));
17248 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17249 operands[4], const0_rtx);")
17252 [(set (match_operand:SWI12 0 "register_operand" "")
17253 (match_operand:SWI12 1 "memory_operand" ""))
17254 (parallel [(set (match_operand:SI 4 "register_operand" "")
17255 (match_operator:SI 3 "plusminuslogic_operator"
17257 (match_operand:SI 2 "nonmemory_operand" "")]))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (set (match_dup 1) (match_dup 0))
17260 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17262 && REG_P (operands[0]) && REG_P (operands[4])
17263 && REGNO (operands[0]) == REGNO (operands[4])
17264 && peep2_reg_dead_p (4, operands[0])
17265 && !reg_overlap_mentioned_p (operands[0], operands[1])
17266 && ix86_match_ccmode (peep2_next_insn (3),
17267 (GET_CODE (operands[3]) == PLUS
17268 || GET_CODE (operands[3]) == MINUS)
17269 ? CCGOCmode : CCNOmode)"
17270 [(parallel [(set (match_dup 4) (match_dup 5))
17271 (set (match_dup 1) (match_dup 6))])]
17272 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17273 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17274 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17275 copy_rtx (operands[1]), operands[2]);
17276 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17277 operands[5], const0_rtx);
17278 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17279 copy_rtx (operands[1]),
17280 copy_rtx (operands[2]));")
17282 ;; Attempt to always use XOR for zeroing registers.
17284 [(set (match_operand 0 "register_operand" "")
17285 (match_operand 1 "const0_operand" ""))]
17286 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17287 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17288 && GENERAL_REG_P (operands[0])
17289 && peep2_regno_dead_p (0, FLAGS_REG)"
17290 [(parallel [(set (match_dup 0) (const_int 0))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17295 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17297 "(GET_MODE (operands[0]) == QImode
17298 || GET_MODE (operands[0]) == HImode)
17299 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17302 (clobber (reg:CC FLAGS_REG))])])
17304 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17306 [(set (match_operand:SWI248 0 "register_operand" "")
17308 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17309 && peep2_regno_dead_p (0, FLAGS_REG)"
17310 [(parallel [(set (match_dup 0) (const_int -1))
17311 (clobber (reg:CC FLAGS_REG))])]
17313 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17314 operands[0] = gen_lowpart (SImode, operands[0]);
17317 ;; Attempt to convert simple lea to add/shift.
17318 ;; These can be created by move expanders.
17321 [(set (match_operand:SWI48 0 "register_operand" "")
17322 (plus:SWI48 (match_dup 0)
17323 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17324 "peep2_regno_dead_p (0, FLAGS_REG)"
17325 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17326 (clobber (reg:CC FLAGS_REG))])])
17329 [(set (match_operand:SI 0 "register_operand" "")
17330 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17331 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17333 && peep2_regno_dead_p (0, FLAGS_REG)
17334 && REGNO (operands[0]) == REGNO (operands[1])"
17335 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17336 (clobber (reg:CC FLAGS_REG))])]
17337 "operands[2] = gen_lowpart (SImode, operands[2]);")
17340 [(set (match_operand:SWI48 0 "register_operand" "")
17341 (mult:SWI48 (match_dup 0)
17342 (match_operand:SWI48 1 "const_int_operand" "")))]
17343 "exact_log2 (INTVAL (operands[1])) >= 0
17344 && peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17346 (clobber (reg:CC FLAGS_REG))])]
17347 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17350 [(set (match_operand:SI 0 "register_operand" "")
17351 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17352 (match_operand:DI 2 "const_int_operand" "")) 0))]
17354 && exact_log2 (INTVAL (operands[2])) >= 0
17355 && REGNO (operands[0]) == REGNO (operands[1])
17356 && peep2_regno_dead_p (0, FLAGS_REG)"
17357 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17358 (clobber (reg:CC FLAGS_REG))])]
17359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17361 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17362 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17363 ;; On many CPUs it is also faster, since special hardware to avoid esp
17364 ;; dependencies is present.
17366 ;; While some of these conversions may be done using splitters, we use
17367 ;; peepholes in order to allow combine_stack_adjustments pass to see
17368 ;; nonobfuscated RTL.
17370 ;; Convert prologue esp subtractions to push.
17371 ;; We need register to push. In order to keep verify_flow_info happy we have
17373 ;; - use scratch and clobber it in order to avoid dependencies
17374 ;; - use already live register
17375 ;; We can't use the second way right now, since there is no reliable way how to
17376 ;; verify that given register is live. First choice will also most likely in
17377 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17378 ;; call clobbered registers are dead. We may want to use base pointer as an
17379 ;; alternative when no register is available later.
17382 [(match_scratch:P 1 "r")
17383 (parallel [(set (reg:P SP_REG)
17384 (plus:P (reg:P SP_REG)
17385 (match_operand:P 0 "const_int_operand" "")))
17386 (clobber (reg:CC FLAGS_REG))
17387 (clobber (mem:BLK (scratch)))])]
17388 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17389 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17390 [(clobber (match_dup 1))
17391 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17392 (clobber (mem:BLK (scratch)))])])
17395 [(match_scratch:P 1 "r")
17396 (parallel [(set (reg:P SP_REG)
17397 (plus:P (reg:P SP_REG)
17398 (match_operand:P 0 "const_int_operand" "")))
17399 (clobber (reg:CC FLAGS_REG))
17400 (clobber (mem:BLK (scratch)))])]
17401 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17402 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17403 [(clobber (match_dup 1))
17404 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17406 (clobber (mem:BLK (scratch)))])])
17408 ;; Convert esp subtractions to push.
17410 [(match_scratch:P 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand" "")))
17414 (clobber (reg:CC FLAGS_REG))])]
17415 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17416 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17417 [(clobber (match_dup 1))
17418 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17421 [(match_scratch:P 1 "r")
17422 (parallel [(set (reg:P SP_REG)
17423 (plus:P (reg:P SP_REG)
17424 (match_operand:P 0 "const_int_operand" "")))
17425 (clobber (reg:CC FLAGS_REG))])]
17426 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17427 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17428 [(clobber (match_dup 1))
17429 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17430 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17432 ;; Convert epilogue deallocator to pop.
17434 [(match_scratch:P 1 "r")
17435 (parallel [(set (reg:P SP_REG)
17436 (plus:P (reg:P SP_REG)
17437 (match_operand:P 0 "const_int_operand" "")))
17438 (clobber (reg:CC FLAGS_REG))
17439 (clobber (mem:BLK (scratch)))])]
17440 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17441 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17442 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17443 (clobber (mem:BLK (scratch)))])])
17445 ;; Two pops case is tricky, since pop causes dependency
17446 ;; on destination register. We use two registers if available.
17448 [(match_scratch:P 1 "r")
17449 (match_scratch:P 2 "r")
17450 (parallel [(set (reg:P SP_REG)
17451 (plus:P (reg:P SP_REG)
17452 (match_operand:P 0 "const_int_operand" "")))
17453 (clobber (reg:CC FLAGS_REG))
17454 (clobber (mem:BLK (scratch)))])]
17455 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17456 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17457 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17458 (clobber (mem:BLK (scratch)))])
17459 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17462 [(match_scratch:P 1 "r")
17463 (parallel [(set (reg:P SP_REG)
17464 (plus:P (reg:P SP_REG)
17465 (match_operand:P 0 "const_int_operand" "")))
17466 (clobber (reg:CC FLAGS_REG))
17467 (clobber (mem:BLK (scratch)))])]
17468 "optimize_insn_for_size_p ()
17469 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17470 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17471 (clobber (mem:BLK (scratch)))])
17472 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17474 ;; Convert esp additions to pop.
17476 [(match_scratch:P 1 "r")
17477 (parallel [(set (reg:P SP_REG)
17478 (plus:P (reg:P SP_REG)
17479 (match_operand:P 0 "const_int_operand" "")))
17480 (clobber (reg:CC FLAGS_REG))])]
17481 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17482 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17484 ;; Two pops case is tricky, since pop causes dependency
17485 ;; on destination register. We use two registers if available.
17487 [(match_scratch:P 1 "r")
17488 (match_scratch:P 2 "r")
17489 (parallel [(set (reg:P SP_REG)
17490 (plus:P (reg:P SP_REG)
17491 (match_operand:P 0 "const_int_operand" "")))
17492 (clobber (reg:CC FLAGS_REG))])]
17493 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17494 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17495 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17498 [(match_scratch:P 1 "r")
17499 (parallel [(set (reg:P SP_REG)
17500 (plus:P (reg:P SP_REG)
17501 (match_operand:P 0 "const_int_operand" "")))
17502 (clobber (reg:CC FLAGS_REG))])]
17503 "optimize_insn_for_size_p ()
17504 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17505 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17506 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17508 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17509 ;; required and register dies. Similarly for 128 to -128.
17511 [(set (match_operand 0 "flags_reg_operand" "")
17512 (match_operator 1 "compare_operator"
17513 [(match_operand 2 "register_operand" "")
17514 (match_operand 3 "const_int_operand" "")]))]
17515 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17516 && incdec_operand (operands[3], GET_MODE (operands[3])))
17517 || (!TARGET_FUSE_CMP_AND_BRANCH
17518 && INTVAL (operands[3]) == 128))
17519 && ix86_match_ccmode (insn, CCGCmode)
17520 && peep2_reg_dead_p (1, operands[2])"
17521 [(parallel [(set (match_dup 0)
17522 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17523 (clobber (match_dup 2))])])
17525 ;; Convert imul by three, five and nine into lea
17528 [(set (match_operand:SWI48 0 "register_operand" "")
17529 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17530 (match_operand:SWI48 2 "const359_operand" "")))
17531 (clobber (reg:CC FLAGS_REG))])]
17532 "!TARGET_PARTIAL_REG_STALL
17533 || <MODE>mode == SImode
17534 || optimize_function_for_size_p (cfun)"
17535 [(set (match_dup 0)
17536 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17538 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17542 [(set (match_operand:SWI48 0 "register_operand" "")
17543 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17544 (match_operand:SWI48 2 "const359_operand" "")))
17545 (clobber (reg:CC FLAGS_REG))])]
17546 "optimize_insn_for_speed_p ()
17547 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17548 [(set (match_dup 0) (match_dup 1))
17550 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17552 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17554 ;; imul $32bit_imm, mem, reg is vector decoded, while
17555 ;; imul $32bit_imm, reg, reg is direct decoded.
17557 [(match_scratch:SWI48 3 "r")
17558 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17559 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17560 (match_operand:SWI48 2 "immediate_operand" "")))
17561 (clobber (reg:CC FLAGS_REG))])]
17562 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17563 && !satisfies_constraint_K (operands[2])"
17564 [(set (match_dup 3) (match_dup 1))
17565 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17566 (clobber (reg:CC FLAGS_REG))])])
17569 [(match_scratch:SI 3 "r")
17570 (parallel [(set (match_operand:DI 0 "register_operand" "")
17572 (mult:SI (match_operand:SI 1 "memory_operand" "")
17573 (match_operand:SI 2 "immediate_operand" ""))))
17574 (clobber (reg:CC FLAGS_REG))])]
17576 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17577 && !satisfies_constraint_K (operands[2])"
17578 [(set (match_dup 3) (match_dup 1))
17579 (parallel [(set (match_dup 0)
17580 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17581 (clobber (reg:CC FLAGS_REG))])])
17583 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17584 ;; Convert it into imul reg, reg
17585 ;; It would be better to force assembler to encode instruction using long
17586 ;; immediate, but there is apparently no way to do so.
17588 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17590 (match_operand:SWI248 1 "nonimmediate_operand" "")
17591 (match_operand:SWI248 2 "const_int_operand" "")))
17592 (clobber (reg:CC FLAGS_REG))])
17593 (match_scratch:SWI248 3 "r")]
17594 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17595 && satisfies_constraint_K (operands[2])"
17596 [(set (match_dup 3) (match_dup 2))
17597 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17598 (clobber (reg:CC FLAGS_REG))])]
17600 if (!rtx_equal_p (operands[0], operands[1]))
17601 emit_move_insn (operands[0], operands[1]);
17604 ;; After splitting up read-modify operations, array accesses with memory
17605 ;; operands might end up in form:
17607 ;; movl 4(%esp), %edx
17609 ;; instead of pre-splitting:
17611 ;; addl 4(%esp), %eax
17613 ;; movl 4(%esp), %edx
17614 ;; leal (%edx,%eax,4), %eax
17617 [(match_scratch:P 5 "r")
17618 (parallel [(set (match_operand 0 "register_operand" "")
17619 (ashift (match_operand 1 "register_operand" "")
17620 (match_operand 2 "const_int_operand" "")))
17621 (clobber (reg:CC FLAGS_REG))])
17622 (parallel [(set (match_operand 3 "register_operand" "")
17623 (plus (match_dup 0)
17624 (match_operand 4 "x86_64_general_operand" "")))
17625 (clobber (reg:CC FLAGS_REG))])]
17626 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17627 /* Validate MODE for lea. */
17628 && ((!TARGET_PARTIAL_REG_STALL
17629 && (GET_MODE (operands[0]) == QImode
17630 || GET_MODE (operands[0]) == HImode))
17631 || GET_MODE (operands[0]) == SImode
17632 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17633 && (rtx_equal_p (operands[0], operands[3])
17634 || peep2_reg_dead_p (2, operands[0]))
17635 /* We reorder load and the shift. */
17636 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17637 [(set (match_dup 5) (match_dup 4))
17638 (set (match_dup 0) (match_dup 1))]
17640 enum machine_mode op1mode = GET_MODE (operands[1]);
17641 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17642 int scale = 1 << INTVAL (operands[2]);
17643 rtx index = gen_lowpart (Pmode, operands[1]);
17644 rtx base = gen_lowpart (Pmode, operands[5]);
17645 rtx dest = gen_lowpart (mode, operands[3]);
17647 operands[1] = gen_rtx_PLUS (Pmode, base,
17648 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17649 operands[5] = base;
17651 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17652 if (op1mode != Pmode)
17653 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17654 operands[0] = dest;
17657 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17658 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17659 ;; caught for use by garbage collectors and the like. Using an insn that
17660 ;; maps to SIGILL makes it more likely the program will rightfully die.
17661 ;; Keeping with tradition, "6" is in honor of #UD.
17662 (define_insn "trap"
17663 [(trap_if (const_int 1) (const_int 6))]
17665 { return ASM_SHORT "0x0b0f"; }
17666 [(set_attr "length" "2")])
17668 (define_expand "prefetch"
17669 [(prefetch (match_operand 0 "address_operand" "")
17670 (match_operand:SI 1 "const_int_operand" "")
17671 (match_operand:SI 2 "const_int_operand" ""))]
17672 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17674 int rw = INTVAL (operands[1]);
17675 int locality = INTVAL (operands[2]);
17677 gcc_assert (rw == 0 || rw == 1);
17678 gcc_assert (locality >= 0 && locality <= 3);
17679 gcc_assert (GET_MODE (operands[0]) == Pmode
17680 || GET_MODE (operands[0]) == VOIDmode);
17682 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17683 supported by SSE counterpart or the SSE prefetch is not available
17684 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17686 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17687 operands[2] = GEN_INT (3);
17689 operands[1] = const0_rtx;
17692 (define_insn "*prefetch_sse_<mode>"
17693 [(prefetch (match_operand:P 0 "address_operand" "p")
17695 (match_operand:SI 1 "const_int_operand" ""))]
17696 "TARGET_PREFETCH_SSE"
17698 static const char * const patterns[4] = {
17699 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17702 int locality = INTVAL (operands[1]);
17703 gcc_assert (locality >= 0 && locality <= 3);
17705 return patterns[locality];
17707 [(set_attr "type" "sse")
17708 (set_attr "atom_sse_attr" "prefetch")
17709 (set (attr "length_address")
17710 (symbol_ref "memory_address_length (operands[0])"))
17711 (set_attr "memory" "none")])
17713 (define_insn "*prefetch_3dnow_<mode>"
17714 [(prefetch (match_operand:P 0 "address_operand" "p")
17715 (match_operand:SI 1 "const_int_operand" "n")
17719 if (INTVAL (operands[1]) == 0)
17720 return "prefetch\t%a0";
17722 return "prefetchw\t%a0";
17724 [(set_attr "type" "mmx")
17725 (set (attr "length_address")
17726 (symbol_ref "memory_address_length (operands[0])"))
17727 (set_attr "memory" "none")])
17729 (define_expand "stack_protect_set"
17730 [(match_operand 0 "memory_operand" "")
17731 (match_operand 1 "memory_operand" "")]
17734 rtx (*insn)(rtx, rtx);
17736 #ifdef TARGET_THREAD_SSP_OFFSET
17737 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17738 insn = (TARGET_LP64
17739 ? gen_stack_tls_protect_set_di
17740 : gen_stack_tls_protect_set_si);
17742 insn = (TARGET_LP64
17743 ? gen_stack_protect_set_di
17744 : gen_stack_protect_set_si);
17747 emit_insn (insn (operands[0], operands[1]));
17751 (define_insn "stack_protect_set_<mode>"
17752 [(set (match_operand:PTR 0 "memory_operand" "=m")
17753 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17755 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17756 (clobber (reg:CC FLAGS_REG))]
17758 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17759 [(set_attr "type" "multi")])
17761 (define_insn "stack_tls_protect_set_<mode>"
17762 [(set (match_operand:PTR 0 "memory_operand" "=m")
17763 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17764 UNSPEC_SP_TLS_SET))
17765 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17766 (clobber (reg:CC FLAGS_REG))]
17768 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17769 [(set_attr "type" "multi")])
17771 (define_expand "stack_protect_test"
17772 [(match_operand 0 "memory_operand" "")
17773 (match_operand 1 "memory_operand" "")
17774 (match_operand 2 "" "")]
17777 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17779 rtx (*insn)(rtx, rtx, rtx);
17781 #ifdef TARGET_THREAD_SSP_OFFSET
17782 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17783 insn = (TARGET_LP64
17784 ? gen_stack_tls_protect_test_di
17785 : gen_stack_tls_protect_test_si);
17787 insn = (TARGET_LP64
17788 ? gen_stack_protect_test_di
17789 : gen_stack_protect_test_si);
17792 emit_insn (insn (flags, operands[0], operands[1]));
17794 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17795 flags, const0_rtx, operands[2]));
17799 (define_insn "stack_protect_test_<mode>"
17800 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17801 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17802 (match_operand:PTR 2 "memory_operand" "m")]
17804 (clobber (match_scratch:PTR 3 "=&r"))]
17806 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17807 [(set_attr "type" "multi")])
17809 (define_insn "stack_tls_protect_test_<mode>"
17810 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17811 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17812 (match_operand:PTR 2 "const_int_operand" "i")]
17813 UNSPEC_SP_TLS_TEST))
17814 (clobber (match_scratch:PTR 3 "=r"))]
17816 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17817 [(set_attr "type" "multi")])
17819 (define_insn "sse4_2_crc32<mode>"
17820 [(set (match_operand:SI 0 "register_operand" "=r")
17822 [(match_operand:SI 1 "register_operand" "0")
17823 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17825 "TARGET_SSE4_2 || TARGET_CRC32"
17826 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17827 [(set_attr "type" "sselog1")
17828 (set_attr "prefix_rep" "1")
17829 (set_attr "prefix_extra" "1")
17830 (set (attr "prefix_data16")
17831 (if_then_else (match_operand:HI 2 "" "")
17833 (const_string "*")))
17834 (set (attr "prefix_rex")
17835 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17837 (const_string "*")))
17838 (set_attr "mode" "SI")])
17840 (define_insn "sse4_2_crc32di"
17841 [(set (match_operand:DI 0 "register_operand" "=r")
17843 [(match_operand:DI 1 "register_operand" "0")
17844 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17846 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17847 "crc32{q}\t{%2, %0|%0, %2}"
17848 [(set_attr "type" "sselog1")
17849 (set_attr "prefix_rep" "1")
17850 (set_attr "prefix_extra" "1")
17851 (set_attr "mode" "DI")])
17853 (define_expand "rdpmc"
17854 [(match_operand:DI 0 "register_operand" "")
17855 (match_operand:SI 1 "register_operand" "")]
17858 rtx reg = gen_reg_rtx (DImode);
17861 /* Force operand 1 into ECX. */
17862 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17863 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17864 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17869 rtvec vec = rtvec_alloc (2);
17870 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17871 rtx upper = gen_reg_rtx (DImode);
17872 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17873 gen_rtvec (1, const0_rtx),
17875 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17876 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17878 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17879 NULL, 1, OPTAB_DIRECT);
17880 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17884 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17885 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17889 (define_insn "*rdpmc"
17890 [(set (match_operand:DI 0 "register_operand" "=A")
17891 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17895 [(set_attr "type" "other")
17896 (set_attr "length" "2")])
17898 (define_insn "*rdpmc_rex64"
17899 [(set (match_operand:DI 0 "register_operand" "=a")
17900 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17902 (set (match_operand:DI 1 "register_operand" "=d")
17903 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17906 [(set_attr "type" "other")
17907 (set_attr "length" "2")])
17909 (define_expand "rdtsc"
17910 [(set (match_operand:DI 0 "register_operand" "")
17911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17916 rtvec vec = rtvec_alloc (2);
17917 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17918 rtx upper = gen_reg_rtx (DImode);
17919 rtx lower = gen_reg_rtx (DImode);
17920 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17921 gen_rtvec (1, const0_rtx),
17923 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17924 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17926 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17927 NULL, 1, OPTAB_DIRECT);
17928 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17930 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17935 (define_insn "*rdtsc"
17936 [(set (match_operand:DI 0 "register_operand" "=A")
17937 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17940 [(set_attr "type" "other")
17941 (set_attr "length" "2")])
17943 (define_insn "*rdtsc_rex64"
17944 [(set (match_operand:DI 0 "register_operand" "=a")
17945 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17946 (set (match_operand:DI 1 "register_operand" "=d")
17947 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17950 [(set_attr "type" "other")
17951 (set_attr "length" "2")])
17953 (define_expand "rdtscp"
17954 [(match_operand:DI 0 "register_operand" "")
17955 (match_operand:SI 1 "memory_operand" "")]
17958 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17959 gen_rtvec (1, const0_rtx),
17961 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17962 gen_rtvec (1, const0_rtx),
17964 rtx reg = gen_reg_rtx (DImode);
17965 rtx tmp = gen_reg_rtx (SImode);
17969 rtvec vec = rtvec_alloc (3);
17970 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17971 rtx upper = gen_reg_rtx (DImode);
17972 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17973 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17974 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17976 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17977 NULL, 1, OPTAB_DIRECT);
17978 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17983 rtvec vec = rtvec_alloc (2);
17984 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17985 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17986 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17989 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17990 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17994 (define_insn "*rdtscp"
17995 [(set (match_operand:DI 0 "register_operand" "=A")
17996 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17997 (set (match_operand:SI 1 "register_operand" "=c")
17998 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18001 [(set_attr "type" "other")
18002 (set_attr "length" "3")])
18004 (define_insn "*rdtscp_rex64"
18005 [(set (match_operand:DI 0 "register_operand" "=a")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18007 (set (match_operand:DI 1 "register_operand" "=d")
18008 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18009 (set (match_operand:SI 2 "register_operand" "=c")
18010 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18013 [(set_attr "type" "other")
18014 (set_attr "length" "3")])
18016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18018 ;; LWP instructions
18020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18022 (define_expand "lwp_llwpcb"
18023 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18024 UNSPECV_LLWP_INTRINSIC)]
18027 (define_insn "*lwp_llwpcb<mode>1"
18028 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18029 UNSPECV_LLWP_INTRINSIC)]
18032 [(set_attr "type" "lwp")
18033 (set_attr "mode" "<MODE>")
18034 (set_attr "length" "5")])
18036 (define_expand "lwp_slwpcb"
18037 [(set (match_operand 0 "register_operand" "=r")
18038 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18043 insn = (TARGET_64BIT
18045 : gen_lwp_slwpcbsi);
18047 emit_insn (insn (operands[0]));
18051 (define_insn "lwp_slwpcb<mode>"
18052 [(set (match_operand:P 0 "register_operand" "=r")
18053 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18056 [(set_attr "type" "lwp")
18057 (set_attr "mode" "<MODE>")
18058 (set_attr "length" "5")])
18060 (define_expand "lwp_lwpval<mode>3"
18061 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18062 (match_operand:SI 2 "nonimmediate_operand" "rm")
18063 (match_operand:SI 3 "const_int_operand" "i")]
18064 UNSPECV_LWPVAL_INTRINSIC)]
18066 "/* Avoid unused variable warning. */
18069 (define_insn "*lwp_lwpval<mode>3_1"
18070 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18071 (match_operand:SI 1 "nonimmediate_operand" "rm")
18072 (match_operand:SI 2 "const_int_operand" "i")]
18073 UNSPECV_LWPVAL_INTRINSIC)]
18075 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18076 [(set_attr "type" "lwp")
18077 (set_attr "mode" "<MODE>")
18078 (set (attr "length")
18079 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18081 (define_expand "lwp_lwpins<mode>3"
18082 [(set (reg:CCC FLAGS_REG)
18083 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18084 (match_operand:SI 2 "nonimmediate_operand" "rm")
18085 (match_operand:SI 3 "const_int_operand" "i")]
18086 UNSPECV_LWPINS_INTRINSIC))
18087 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18088 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18091 (define_insn "*lwp_lwpins<mode>3_1"
18092 [(set (reg:CCC FLAGS_REG)
18093 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18094 (match_operand:SI 1 "nonimmediate_operand" "rm")
18095 (match_operand:SI 2 "const_int_operand" "i")]
18096 UNSPECV_LWPINS_INTRINSIC))]
18098 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18099 [(set_attr "type" "lwp")
18100 (set_attr "mode" "<MODE>")
18101 (set (attr "length")
18102 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18104 (define_insn "rdfsbase<mode>"
18105 [(set (match_operand:SWI48 0 "register_operand" "=r")
18106 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18107 "TARGET_64BIT && TARGET_FSGSBASE"
18109 [(set_attr "type" "other")
18110 (set_attr "prefix_extra" "2")])
18112 (define_insn "rdgsbase<mode>"
18113 [(set (match_operand:SWI48 0 "register_operand" "=r")
18114 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18115 "TARGET_64BIT && TARGET_FSGSBASE"
18117 [(set_attr "type" "other")
18118 (set_attr "prefix_extra" "2")])
18120 (define_insn "wrfsbase<mode>"
18121 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18123 "TARGET_64BIT && TARGET_FSGSBASE"
18125 [(set_attr "type" "other")
18126 (set_attr "prefix_extra" "2")])
18128 (define_insn "wrgsbase<mode>"
18129 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18131 "TARGET_64BIT && TARGET_FSGSBASE"
18133 [(set_attr "type" "other")
18134 (set_attr "prefix_extra" "2")])
18136 (define_insn "rdrand<mode>_1"
18137 [(set (match_operand:SWI248 0 "register_operand" "=r")
18138 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18139 (set (reg:CCC FLAGS_REG)
18140 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18143 [(set_attr "type" "other")
18144 (set_attr "prefix_extra" "1")])
18146 (define_expand "pause"
18147 [(set (match_dup 0)
18148 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18151 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18152 MEM_VOLATILE_P (operands[0]) = 1;
18155 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18156 ;; They have the same encoding.
18157 (define_insn "*pause"
18158 [(set (match_operand:BLK 0 "" "")
18159 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18162 [(set_attr "length" "2")
18163 (set_attr "memory" "unknown")])
18167 (include "sync.md")