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
237 ;; For RDRAND support
241 (define_c_enum "unspecv" [
244 UNSPECV_PROBE_STACK_RANGE
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
272 UNSPECV_SPLIT_STACK_RETURN
275 ;; Constants to represent rounding modes in the ROUND instruction
284 ;; Constants to represent pcomtrue/pcomfalse variants
294 ;; Constants used in the XOP pperm instruction
296 [(PPERM_SRC 0x00) /* copy source */
297 (PPERM_INVERT 0x20) /* invert source */
298 (PPERM_REVERSE 0x40) /* bit reverse source */
299 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
300 (PPERM_ZERO 0x80) /* all 0's */
301 (PPERM_ONES 0xa0) /* all 1's */
302 (PPERM_SIGN 0xc0) /* propagate sign bit */
303 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
304 (PPERM_SRC1 0x00) /* use first source byte */
305 (PPERM_SRC2 0x10) /* use second source byte */
308 ;; Registers by name.
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first. This allows for better optimization. For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372 atom,generic64,amdfam10,bdver1,bdver2,btver1"
373 (const (symbol_ref "ix86_schedule")))
375 ;; A basic instruction type. Refinements due to arguments to be
376 ;; provided in other attributes.
379 alu,alu1,negnot,imov,imovx,lea,
380 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381 icmp,test,ibr,setcc,icmov,
382 push,pop,call,callv,leave,
384 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387 ssemuladd,sse4arg,lwp,
388 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389 (const_string "other"))
391 ;; Main data type used by the insn
393 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394 (const_string "unknown"))
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399 (const_string "i387")
400 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
404 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
406 (eq_attr "type" "other")
407 (const_string "unknown")]
408 (const_string "integer")))
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
415 (eq_attr "unit" "i387,sse,mmx")
417 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
419 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420 (eq_attr "type" "imov,test")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422 (eq_attr "type" "call")
423 (if_then_else (match_operand 0 "constant_call_address_operand" "")
426 (eq_attr "type" "callv")
427 (if_then_else (match_operand 1 "constant_call_address_operand" "")
430 ;; We don't know the size before shorten_branches. Expect
431 ;; the instruction to fit for better scheduling.
432 (eq_attr "type" "ibr")
435 (symbol_ref "/* Update immediate_length and other attributes! */
436 gcc_unreachable (),1")))
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440 (cond [(eq_attr "type" "str,other,multi,fxch")
442 (and (eq_attr "type" "call")
443 (match_operand 0 "constant_call_address_operand" ""))
445 (and (eq_attr "type" "callv")
446 (match_operand 1 "constant_call_address_operand" ""))
449 (symbol_ref "ix86_attr_length_address_default (insn)")))
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
455 (eq_attr "mode" "HI")
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
474 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475 (eq_attr "unit" "sse,mmx"))
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
483 (and (eq_attr "mode" "DI")
484 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485 (eq_attr "unit" "!mmx")))
487 (and (eq_attr "mode" "QI")
488 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
491 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand" ""))
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
507 (eq_attr "type" "sseiadd1,ssecvt1")
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
516 (const_string "orig")))
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526 (if_then_else (and (eq_attr "prefix_0f" "1")
527 (eq_attr "prefix_extra" "0"))
528 (if_then_else (eq_attr "prefix_vex_w" "1")
529 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537 (cond [(eq_attr "type" "str,leave")
539 (eq_attr "unit" "i387")
541 (and (eq_attr "type" "incdec")
542 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543 (ior (match_operand:SI 1 "register_operand" "")
544 (match_operand:HI 1 "register_operand" ""))))
546 (and (eq_attr "type" "push")
547 (not (match_operand 1 "memory_operand" "")))
549 (and (eq_attr "type" "pop")
550 (not (match_operand 0 "memory_operand" "")))
552 (and (eq_attr "type" "imov")
553 (and (not (eq_attr "mode" "DI"))
554 (ior (and (match_operand 0 "register_operand" "")
555 (match_operand 1 "immediate_operand" ""))
556 (ior (and (match_operand 0 "ax_reg_operand" "")
557 (match_operand 1 "memory_displacement_only_operand" ""))
558 (and (match_operand 0 "memory_displacement_only_operand" "")
559 (match_operand 1 "ax_reg_operand" ""))))))
561 (and (eq_attr "type" "call")
562 (match_operand 0 "constant_call_address_operand" ""))
564 (and (eq_attr "type" "callv")
565 (match_operand 1 "constant_call_address_operand" ""))
567 (and (eq_attr "type" "alu,alu1,icmp,test")
568 (match_operand 0 "ax_reg_operand" ""))
569 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
577 (define_attr "length" ""
578 (cond [(eq_attr "type" "other,multi,fistp,frndint")
580 (eq_attr "type" "fcmp")
582 (eq_attr "unit" "i387")
584 (plus (attr "prefix_data16")
585 (attr "length_address")))
586 (ior (eq_attr "prefix" "vex")
587 (and (eq_attr "prefix" "maybe_vex")
588 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589 (plus (attr "length_vex")
590 (plus (attr "length_immediate")
592 (attr "length_address"))))]
593 (plus (plus (attr "modrm")
594 (plus (attr "prefix_0f")
595 (plus (attr "prefix_rex")
596 (plus (attr "prefix_extra")
598 (plus (attr "prefix_rep")
599 (plus (attr "prefix_data16")
600 (plus (attr "length_immediate")
601 (attr "length_address")))))))
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
607 (define_attr "memory" "none,load,store,both,unknown"
608 (cond [(eq_attr "type" "other,multi,str,lwp")
609 (const_string "unknown")
610 (eq_attr "type" "lea,fcmov,fpspc")
611 (const_string "none")
612 (eq_attr "type" "fistp,leave")
613 (const_string "both")
614 (eq_attr "type" "frndint")
615 (const_string "load")
616 (eq_attr "type" "push")
617 (if_then_else (match_operand 1 "memory_operand" "")
618 (const_string "both")
619 (const_string "store"))
620 (eq_attr "type" "pop")
621 (if_then_else (match_operand 0 "memory_operand" "")
622 (const_string "both")
623 (const_string "load"))
624 (eq_attr "type" "setcc")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "store")
627 (const_string "none"))
628 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629 (if_then_else (ior (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "load")
632 (const_string "none"))
633 (eq_attr "type" "ibr")
634 (if_then_else (match_operand 0 "memory_operand" "")
635 (const_string "load")
636 (const_string "none"))
637 (eq_attr "type" "call")
638 (if_then_else (match_operand 0 "constant_call_address_operand" "")
639 (const_string "none")
640 (const_string "load"))
641 (eq_attr "type" "callv")
642 (if_then_else (match_operand 1 "constant_call_address_operand" "")
643 (const_string "none")
644 (const_string "load"))
645 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646 (match_operand 1 "memory_operand" ""))
647 (const_string "both")
648 (and (match_operand 0 "memory_operand" "")
649 (match_operand 1 "memory_operand" ""))
650 (const_string "both")
651 (match_operand 0 "memory_operand" "")
652 (const_string "store")
653 (match_operand 1 "memory_operand" "")
654 (const_string "load")
656 "!alu1,negnot,ishift1,
657 imov,imovx,icmp,test,bitmanip,
659 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661 (match_operand 2 "memory_operand" ""))
662 (const_string "load")
663 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664 (match_operand 3 "memory_operand" ""))
665 (const_string "load")
667 (const_string "none")))
669 ;; Indicates if an instruction has both an immediate and a displacement.
671 (define_attr "imm_disp" "false,true,unknown"
672 (cond [(eq_attr "type" "other,multi")
673 (const_string "unknown")
674 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675 (and (match_operand 0 "memory_displacement_operand" "")
676 (match_operand 1 "immediate_operand" "")))
677 (const_string "true")
678 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679 (and (match_operand 0 "memory_displacement_operand" "")
680 (match_operand 2 "immediate_operand" "")))
681 (const_string "true")
683 (const_string "false")))
685 ;; Indicates if an FP operation has an integer source.
687 (define_attr "fp_int_src" "false,true"
688 (const_string "false"))
690 ;; Defines rounding mode of an FP operation.
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693 (const_string "any"))
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703 (const_string "base"))
705 (define_attr "enabled" ""
706 (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713 [(set_attr "length" "128")
714 (set_attr "type" "multi")])
716 (define_code_iterator plusminus [plus minus])
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727 [(plus "add") (ss_plus "adds") (us_plus "addus")
728 (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730 [(plus "adc") (minus "sbb")])
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734 (minus "") (ss_minus "") (us_minus "")])
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744 (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783 (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791 (div "i") (udiv "")])
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822 (HI "TARGET_HIMODE_MATH")
823 SI DI (TI "TARGET_64BIT")])
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827 (HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832 (HI "TARGET_HIMODE_MATH")
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837 SI (DI "TARGET_64BIT")])
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841 (TI "TARGET_64BIT")])
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849 (DI "TARGET_64BIT")])
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877 [(QI "general_operand")
878 (HI "general_operand")
879 (SI "x86_64_general_operand")
880 (DI "x86_64_general_operand")
881 (TI "x86_64_general_operand")])
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885 [(QI "general_operand")
886 (HI "general_operand")
887 (SI "x86_64_szext_general_operand")
888 (DI "x86_64_szext_general_operand")])
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892 [(QI "immediate_operand")
893 (HI "immediate_operand")
894 (SI "x86_64_immediate_operand")
895 (DI "x86_64_immediate_operand")])
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899 [(QI "nonmemory_operand")
900 (HI "nonmemory_operand")
901 (SI "x86_64_nonmemory_operand")
902 (DI "x86_64_nonmemory_operand")])
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906 [(QI "nonimmediate_operand")
907 (HI "nonimmediate_operand")
908 (SI "nonimmediate_operand")
909 (DI "shiftdi_operand")
910 (TI "register_operand")])
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914 [(QI "const_1_to_31_operand")
915 (HI "const_1_to_31_operand")
916 (SI "const_1_to_31_operand")
917 (DI "const_1_to_63_operand")])
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921 [(QI "nonimmediate_operand")
922 (HI "nonimmediate_operand")
923 (SI "nonimmediate_operand")
924 (DI "ashldi_input_operand")
925 (TI "reg_or_pm1_operand")])
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
936 (V8SF "ps") (V4DF "pd")
937 (V4SF "ps") (V2DF "pd")
938 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
955 ;; This mode iterator allows :PTR to be used for patterns that operate on
956 ;; ptr_mode sized quantities.
957 (define_mode_iterator PTR
958 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
960 ;; Scheduling descriptions
962 (include "pentium.md")
965 (include "athlon.md")
966 (include "bdver1.md")
972 ;; Operand and operator predicates and constraints
974 (include "predicates.md")
975 (include "constraints.md")
978 ;; Compare and branch/compare and store instructions.
980 (define_expand "cbranch<mode>4"
981 [(set (reg:CC FLAGS_REG)
982 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
983 (match_operand:SDWIM 2 "<general_operand>" "")))
984 (set (pc) (if_then_else
985 (match_operator 0 "ordered_comparison_operator"
986 [(reg:CC FLAGS_REG) (const_int 0)])
987 (label_ref (match_operand 3 "" ""))
991 if (MEM_P (operands[1]) && MEM_P (operands[2]))
992 operands[1] = force_reg (<MODE>mode, operands[1]);
993 ix86_expand_branch (GET_CODE (operands[0]),
994 operands[1], operands[2], operands[3]);
998 (define_expand "cstore<mode>4"
999 [(set (reg:CC FLAGS_REG)
1000 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1001 (match_operand:SWIM 3 "<general_operand>" "")))
1002 (set (match_operand:QI 0 "register_operand" "")
1003 (match_operator 1 "ordered_comparison_operator"
1004 [(reg:CC FLAGS_REG) (const_int 0)]))]
1007 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1008 operands[2] = force_reg (<MODE>mode, operands[2]);
1009 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1010 operands[2], operands[3]);
1014 (define_expand "cmp<mode>_1"
1015 [(set (reg:CC FLAGS_REG)
1016 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1017 (match_operand:SWI48 1 "<general_operand>" "")))])
1019 (define_insn "*cmp<mode>_ccno_1"
1020 [(set (reg FLAGS_REG)
1021 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1022 (match_operand:SWI 1 "const0_operand" "")))]
1023 "ix86_match_ccmode (insn, CCNOmode)"
1025 test{<imodesuffix>}\t%0, %0
1026 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1027 [(set_attr "type" "test,icmp")
1028 (set_attr "length_immediate" "0,1")
1029 (set_attr "mode" "<MODE>")])
1031 (define_insn "*cmp<mode>_1"
1032 [(set (reg FLAGS_REG)
1033 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1034 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1035 "ix86_match_ccmode (insn, CCmode)"
1036 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1037 [(set_attr "type" "icmp")
1038 (set_attr "mode" "<MODE>")])
1040 (define_insn "*cmp<mode>_minus_1"
1041 [(set (reg FLAGS_REG)
1043 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1044 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1046 "ix86_match_ccmode (insn, CCGOCmode)"
1047 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1048 [(set_attr "type" "icmp")
1049 (set_attr "mode" "<MODE>")])
1051 (define_insn "*cmpqi_ext_1"
1052 [(set (reg FLAGS_REG)
1054 (match_operand:QI 0 "general_operand" "Qm")
1057 (match_operand 1 "ext_register_operand" "Q")
1059 (const_int 8)) 0)))]
1060 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061 "cmp{b}\t{%h1, %0|%0, %h1}"
1062 [(set_attr "type" "icmp")
1063 (set_attr "mode" "QI")])
1065 (define_insn "*cmpqi_ext_1_rex64"
1066 [(set (reg FLAGS_REG)
1068 (match_operand:QI 0 "register_operand" "Q")
1071 (match_operand 1 "ext_register_operand" "Q")
1073 (const_int 8)) 0)))]
1074 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075 "cmp{b}\t{%h1, %0|%0, %h1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "mode" "QI")])
1079 (define_insn "*cmpqi_ext_2"
1080 [(set (reg FLAGS_REG)
1084 (match_operand 0 "ext_register_operand" "Q")
1087 (match_operand:QI 1 "const0_operand" "")))]
1088 "ix86_match_ccmode (insn, CCNOmode)"
1090 [(set_attr "type" "test")
1091 (set_attr "length_immediate" "0")
1092 (set_attr "mode" "QI")])
1094 (define_expand "cmpqi_ext_3"
1095 [(set (reg:CC FLAGS_REG)
1099 (match_operand 0 "ext_register_operand" "")
1102 (match_operand:QI 1 "immediate_operand" "")))])
1104 (define_insn "*cmpqi_ext_3_insn"
1105 [(set (reg FLAGS_REG)
1109 (match_operand 0 "ext_register_operand" "Q")
1112 (match_operand:QI 1 "general_operand" "Qmn")))]
1113 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1114 "cmp{b}\t{%1, %h0|%h0, %1}"
1115 [(set_attr "type" "icmp")
1116 (set_attr "modrm" "1")
1117 (set_attr "mode" "QI")])
1119 (define_insn "*cmpqi_ext_3_insn_rex64"
1120 [(set (reg FLAGS_REG)
1124 (match_operand 0 "ext_register_operand" "Q")
1127 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1128 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1129 "cmp{b}\t{%1, %h0|%h0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "modrm" "1")
1132 (set_attr "mode" "QI")])
1134 (define_insn "*cmpqi_ext_4"
1135 [(set (reg FLAGS_REG)
1139 (match_operand 0 "ext_register_operand" "Q")
1144 (match_operand 1 "ext_register_operand" "Q")
1146 (const_int 8)) 0)))]
1147 "ix86_match_ccmode (insn, CCmode)"
1148 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1149 [(set_attr "type" "icmp")
1150 (set_attr "mode" "QI")])
1152 ;; These implement float point compares.
1153 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1154 ;; which would allow mix and match FP modes on the compares. Which is what
1155 ;; the old patterns did, but with many more of them.
1157 (define_expand "cbranchxf4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1160 (match_operand:XF 2 "nonmemory_operand" "")))
1161 (set (pc) (if_then_else
1162 (match_operator 0 "ix86_fp_comparison_operator"
1165 (label_ref (match_operand 3 "" ""))
1169 ix86_expand_branch (GET_CODE (operands[0]),
1170 operands[1], operands[2], operands[3]);
1174 (define_expand "cstorexf4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1177 (match_operand:XF 3 "nonmemory_operand" "")))
1178 (set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "ix86_fp_comparison_operator"
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
1189 (define_expand "cbranch<mode>4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1192 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1193 (set (pc) (if_then_else
1194 (match_operator 0 "ix86_fp_comparison_operator"
1197 (label_ref (match_operand 3 "" ""))
1199 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1201 ix86_expand_branch (GET_CODE (operands[0]),
1202 operands[1], operands[2], operands[3]);
1206 (define_expand "cstore<mode>4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1209 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1210 (set (match_operand:QI 0 "register_operand" "")
1211 (match_operator 1 "ix86_fp_comparison_operator"
1214 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1216 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1217 operands[2], operands[3]);
1221 (define_expand "cbranchcc4"
1222 [(set (pc) (if_then_else
1223 (match_operator 0 "comparison_operator"
1224 [(match_operand 1 "flags_reg_operand" "")
1225 (match_operand 2 "const0_operand" "")])
1226 (label_ref (match_operand 3 "" ""))
1230 ix86_expand_branch (GET_CODE (operands[0]),
1231 operands[1], operands[2], operands[3]);
1235 (define_expand "cstorecc4"
1236 [(set (match_operand:QI 0 "register_operand" "")
1237 (match_operator 1 "comparison_operator"
1238 [(match_operand 2 "flags_reg_operand" "")
1239 (match_operand 3 "const0_operand" "")]))]
1242 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1243 operands[2], operands[3]);
1248 ;; FP compares, step 1:
1249 ;; Set the FP condition codes.
1251 ;; CCFPmode compare with exceptions
1252 ;; CCFPUmode compare with no exceptions
1254 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1255 ;; used to manage the reg stack popping would not be preserved.
1257 (define_insn "*cmpfp_0"
1258 [(set (match_operand:HI 0 "register_operand" "=a")
1261 (match_operand 1 "register_operand" "f")
1262 (match_operand 2 "const0_operand" ""))]
1264 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1265 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1266 "* return output_fp_compare (insn, operands, false, false);"
1267 [(set_attr "type" "multi")
1268 (set_attr "unit" "i387")
1270 (cond [(match_operand:SF 1 "" "")
1272 (match_operand:DF 1 "" "")
1275 (const_string "XF")))])
1277 (define_insn_and_split "*cmpfp_0_cc"
1278 [(set (reg:CCFP FLAGS_REG)
1280 (match_operand 1 "register_operand" "f")
1281 (match_operand 2 "const0_operand" "")))
1282 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1284 && TARGET_SAHF && !TARGET_CMOVE
1285 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1287 "&& reload_completed"
1290 [(compare:CCFP (match_dup 1)(match_dup 2))]
1292 (set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1298 (cond [(match_operand:SF 1 "" "")
1300 (match_operand:DF 1 "" "")
1303 (const_string "XF")))])
1305 (define_insn "*cmpfp_xf"
1306 [(set (match_operand:HI 0 "register_operand" "=a")
1309 (match_operand:XF 1 "register_operand" "f")
1310 (match_operand:XF 2 "register_operand" "f"))]
1313 "* return output_fp_compare (insn, operands, false, false);"
1314 [(set_attr "type" "multi")
1315 (set_attr "unit" "i387")
1316 (set_attr "mode" "XF")])
1318 (define_insn_and_split "*cmpfp_xf_cc"
1319 [(set (reg:CCFP FLAGS_REG)
1321 (match_operand:XF 1 "register_operand" "f")
1322 (match_operand:XF 2 "register_operand" "f")))
1323 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 && TARGET_SAHF && !TARGET_CMOVE"
1327 "&& reload_completed"
1330 [(compare:CCFP (match_dup 1)(match_dup 2))]
1332 (set (reg:CC FLAGS_REG)
1333 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "XF")])
1339 (define_insn "*cmpfp_<mode>"
1340 [(set (match_operand:HI 0 "register_operand" "=a")
1343 (match_operand:MODEF 1 "register_operand" "f")
1344 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1347 "* return output_fp_compare (insn, operands, false, false);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1350 (set_attr "mode" "<MODE>")])
1352 (define_insn_and_split "*cmpfp_<mode>_cc"
1353 [(set (reg:CCFP FLAGS_REG)
1355 (match_operand:MODEF 1 "register_operand" "f")
1356 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1357 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 && TARGET_SAHF && !TARGET_CMOVE"
1361 "&& reload_completed"
1364 [(compare:CCFP (match_dup 1)(match_dup 2))]
1366 (set (reg:CC FLAGS_REG)
1367 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1371 (set_attr "mode" "<MODE>")])
1373 (define_insn "*cmpfp_u"
1374 [(set (match_operand:HI 0 "register_operand" "=a")
1377 (match_operand 1 "register_operand" "f")
1378 (match_operand 2 "register_operand" "f"))]
1380 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1381 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1382 "* return output_fp_compare (insn, operands, false, true);"
1383 [(set_attr "type" "multi")
1384 (set_attr "unit" "i387")
1386 (cond [(match_operand:SF 1 "" "")
1388 (match_operand:DF 1 "" "")
1391 (const_string "XF")))])
1393 (define_insn_and_split "*cmpfp_u_cc"
1394 [(set (reg:CCFPU FLAGS_REG)
1396 (match_operand 1 "register_operand" "f")
1397 (match_operand 2 "register_operand" "f")))
1398 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1399 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1400 && TARGET_SAHF && !TARGET_CMOVE
1401 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1403 "&& reload_completed"
1406 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1408 (set (reg:CC FLAGS_REG)
1409 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1411 [(set_attr "type" "multi")
1412 (set_attr "unit" "i387")
1414 (cond [(match_operand:SF 1 "" "")
1416 (match_operand:DF 1 "" "")
1419 (const_string "XF")))])
1421 (define_insn "*cmpfp_<mode>"
1422 [(set (match_operand:HI 0 "register_operand" "=a")
1425 (match_operand 1 "register_operand" "f")
1426 (match_operator 3 "float_operator"
1427 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1429 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1430 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1432 "* return output_fp_compare (insn, operands, false, false);"
1433 [(set_attr "type" "multi")
1434 (set_attr "unit" "i387")
1435 (set_attr "fp_int_src" "true")
1436 (set_attr "mode" "<MODE>")])
1438 (define_insn_and_split "*cmpfp_<mode>_cc"
1439 [(set (reg:CCFP FLAGS_REG)
1441 (match_operand 1 "register_operand" "f")
1442 (match_operator 3 "float_operator"
1443 [(match_operand:SWI24 2 "memory_operand" "m")])))
1444 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1446 && TARGET_SAHF && !TARGET_CMOVE
1447 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1448 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1450 "&& reload_completed"
1455 (match_op_dup 3 [(match_dup 2)]))]
1457 (set (reg:CC FLAGS_REG)
1458 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1460 [(set_attr "type" "multi")
1461 (set_attr "unit" "i387")
1462 (set_attr "fp_int_src" "true")
1463 (set_attr "mode" "<MODE>")])
1465 ;; FP compares, step 2
1466 ;; Move the fpsw to ax.
1468 (define_insn "x86_fnstsw_1"
1469 [(set (match_operand:HI 0 "register_operand" "=a")
1470 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1473 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1474 (set_attr "mode" "SI")
1475 (set_attr "unit" "i387")])
1477 ;; FP compares, step 3
1478 ;; Get ax into flags, general case.
1480 (define_insn "x86_sahf_1"
1481 [(set (reg:CC FLAGS_REG)
1482 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1486 #ifndef HAVE_AS_IX86_SAHF
1488 return ASM_BYTE "0x9e";
1493 [(set_attr "length" "1")
1494 (set_attr "athlon_decode" "vector")
1495 (set_attr "amdfam10_decode" "direct")
1496 (set_attr "bdver1_decode" "direct")
1497 (set_attr "mode" "SI")])
1499 ;; Pentium Pro can do steps 1 through 3 in one go.
1500 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1501 (define_insn "*cmpfp_i_mixed"
1502 [(set (reg:CCFP FLAGS_REG)
1503 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1504 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1505 "TARGET_MIX_SSE_I387
1506 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1507 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1508 "* return output_fp_compare (insn, operands, true, false);"
1509 [(set_attr "type" "fcmp,ssecomi")
1510 (set_attr "prefix" "orig,maybe_vex")
1512 (if_then_else (match_operand:SF 1 "" "")
1514 (const_string "DF")))
1515 (set (attr "prefix_rep")
1516 (if_then_else (eq_attr "type" "ssecomi")
1518 (const_string "*")))
1519 (set (attr "prefix_data16")
1520 (cond [(eq_attr "type" "fcmp")
1522 (eq_attr "mode" "DF")
1525 (const_string "0")))
1526 (set_attr "athlon_decode" "vector")
1527 (set_attr "amdfam10_decode" "direct")
1528 (set_attr "bdver1_decode" "double")])
1530 (define_insn "*cmpfp_i_sse"
1531 [(set (reg:CCFP FLAGS_REG)
1532 (compare:CCFP (match_operand 0 "register_operand" "x")
1533 (match_operand 1 "nonimmediate_operand" "xm")))]
1535 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537 "* return output_fp_compare (insn, operands, true, false);"
1538 [(set_attr "type" "ssecomi")
1539 (set_attr "prefix" "maybe_vex")
1541 (if_then_else (match_operand:SF 1 "" "")
1543 (const_string "DF")))
1544 (set_attr "prefix_rep" "0")
1545 (set (attr "prefix_data16")
1546 (if_then_else (eq_attr "mode" "DF")
1548 (const_string "0")))
1549 (set_attr "athlon_decode" "vector")
1550 (set_attr "amdfam10_decode" "direct")
1551 (set_attr "bdver1_decode" "double")])
1553 (define_insn "*cmpfp_i_i387"
1554 [(set (reg:CCFP FLAGS_REG)
1555 (compare:CCFP (match_operand 0 "register_operand" "f")
1556 (match_operand 1 "register_operand" "f")))]
1557 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1559 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1560 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1561 "* return output_fp_compare (insn, operands, true, false);"
1562 [(set_attr "type" "fcmp")
1564 (cond [(match_operand:SF 1 "" "")
1566 (match_operand:DF 1 "" "")
1569 (const_string "XF")))
1570 (set_attr "athlon_decode" "vector")
1571 (set_attr "amdfam10_decode" "direct")
1572 (set_attr "bdver1_decode" "double")])
1574 (define_insn "*cmpfp_iu_mixed"
1575 [(set (reg:CCFPU FLAGS_REG)
1576 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1577 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1578 "TARGET_MIX_SSE_I387
1579 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1580 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1581 "* return output_fp_compare (insn, operands, true, true);"
1582 [(set_attr "type" "fcmp,ssecomi")
1583 (set_attr "prefix" "orig,maybe_vex")
1585 (if_then_else (match_operand:SF 1 "" "")
1587 (const_string "DF")))
1588 (set (attr "prefix_rep")
1589 (if_then_else (eq_attr "type" "ssecomi")
1591 (const_string "*")))
1592 (set (attr "prefix_data16")
1593 (cond [(eq_attr "type" "fcmp")
1595 (eq_attr "mode" "DF")
1598 (const_string "0")))
1599 (set_attr "athlon_decode" "vector")
1600 (set_attr "amdfam10_decode" "direct")
1601 (set_attr "bdver1_decode" "double")])
1603 (define_insn "*cmpfp_iu_sse"
1604 [(set (reg:CCFPU FLAGS_REG)
1605 (compare:CCFPU (match_operand 0 "register_operand" "x")
1606 (match_operand 1 "nonimmediate_operand" "xm")))]
1608 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1609 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1610 "* return output_fp_compare (insn, operands, true, true);"
1611 [(set_attr "type" "ssecomi")
1612 (set_attr "prefix" "maybe_vex")
1614 (if_then_else (match_operand:SF 1 "" "")
1616 (const_string "DF")))
1617 (set_attr "prefix_rep" "0")
1618 (set (attr "prefix_data16")
1619 (if_then_else (eq_attr "mode" "DF")
1621 (const_string "0")))
1622 (set_attr "athlon_decode" "vector")
1623 (set_attr "amdfam10_decode" "direct")
1624 (set_attr "bdver1_decode" "double")])
1626 (define_insn "*cmpfp_iu_387"
1627 [(set (reg:CCFPU FLAGS_REG)
1628 (compare:CCFPU (match_operand 0 "register_operand" "f")
1629 (match_operand 1 "register_operand" "f")))]
1630 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1632 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1633 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1634 "* return output_fp_compare (insn, operands, true, true);"
1635 [(set_attr "type" "fcmp")
1637 (cond [(match_operand:SF 1 "" "")
1639 (match_operand:DF 1 "" "")
1642 (const_string "XF")))
1643 (set_attr "athlon_decode" "vector")
1644 (set_attr "amdfam10_decode" "direct")
1645 (set_attr "bdver1_decode" "direct")])
1647 ;; Push/pop instructions.
1649 (define_insn "*push<mode>2"
1650 [(set (match_operand:DWI 0 "push_operand" "=<")
1651 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1654 [(set_attr "type" "multi")
1655 (set_attr "mode" "<MODE>")])
1658 [(set (match_operand:TI 0 "push_operand" "")
1659 (match_operand:TI 1 "general_operand" ""))]
1660 "TARGET_64BIT && reload_completed
1661 && !SSE_REG_P (operands[1])"
1663 "ix86_split_long_move (operands); DONE;")
1665 (define_insn "*pushdi2_rex64"
1666 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1667 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1672 [(set_attr "type" "push,multi")
1673 (set_attr "mode" "DI")])
1675 ;; Convert impossible pushes of immediate to existing instructions.
1676 ;; First try to get scratch register and go through it. In case this
1677 ;; fails, push sign extended lower part first and then overwrite
1678 ;; upper part by 32bit move.
1680 [(match_scratch:DI 2 "r")
1681 (set (match_operand:DI 0 "push_operand" "")
1682 (match_operand:DI 1 "immediate_operand" ""))]
1683 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684 && !x86_64_immediate_operand (operands[1], DImode)"
1685 [(set (match_dup 2) (match_dup 1))
1686 (set (match_dup 0) (match_dup 2))])
1688 ;; We need to define this as both peepholer and splitter for case
1689 ;; peephole2 pass is not run.
1690 ;; "&& 1" is needed to keep it from matching the previous pattern.
1692 [(set (match_operand:DI 0 "push_operand" "")
1693 (match_operand:DI 1 "immediate_operand" ""))]
1694 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1695 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1696 [(set (match_dup 0) (match_dup 1))
1697 (set (match_dup 2) (match_dup 3))]
1699 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1701 operands[1] = gen_lowpart (DImode, operands[2]);
1702 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1707 [(set (match_operand:DI 0 "push_operand" "")
1708 (match_operand:DI 1 "immediate_operand" ""))]
1709 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1710 ? epilogue_completed : reload_completed)
1711 && !symbolic_operand (operands[1], DImode)
1712 && !x86_64_immediate_operand (operands[1], DImode)"
1713 [(set (match_dup 0) (match_dup 1))
1714 (set (match_dup 2) (match_dup 3))]
1716 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1718 operands[1] = gen_lowpart (DImode, operands[2]);
1719 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1724 [(set (match_operand:DI 0 "push_operand" "")
1725 (match_operand:DI 1 "general_operand" ""))]
1726 "!TARGET_64BIT && reload_completed
1727 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1729 "ix86_split_long_move (operands); DONE;")
1731 (define_insn "*pushsi2"
1732 [(set (match_operand:SI 0 "push_operand" "=<")
1733 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1736 [(set_attr "type" "push")
1737 (set_attr "mode" "SI")])
1739 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1740 ;; "push a byte/word". But actually we use pushl, which has the effect
1741 ;; of rounding the amount pushed up to a word.
1743 ;; For TARGET_64BIT we always round up to 8 bytes.
1744 (define_insn "*push<mode>2_rex64"
1745 [(set (match_operand:SWI124 0 "push_operand" "=X")
1746 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1749 [(set_attr "type" "push")
1750 (set_attr "mode" "DI")])
1752 (define_insn "*push<mode>2"
1753 [(set (match_operand:SWI12 0 "push_operand" "=X")
1754 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1757 [(set_attr "type" "push")
1758 (set_attr "mode" "SI")])
1760 (define_insn "*push<mode>2_prologue"
1761 [(set (match_operand:P 0 "push_operand" "=<")
1762 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1763 (clobber (mem:BLK (scratch)))]
1765 "push{<imodesuffix>}\t%1"
1766 [(set_attr "type" "push")
1767 (set_attr "mode" "<MODE>")])
1769 (define_insn "*pop<mode>1"
1770 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1771 (match_operand:P 1 "pop_operand" ">"))]
1773 "pop{<imodesuffix>}\t%0"
1774 [(set_attr "type" "pop")
1775 (set_attr "mode" "<MODE>")])
1777 (define_insn "*pop<mode>1_epilogue"
1778 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1779 (match_operand:P 1 "pop_operand" ">"))
1780 (clobber (mem:BLK (scratch)))]
1782 "pop{<imodesuffix>}\t%0"
1783 [(set_attr "type" "pop")
1784 (set_attr "mode" "<MODE>")])
1786 ;; Move instructions.
1788 (define_expand "movoi"
1789 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1790 (match_operand:OI 1 "general_operand" ""))]
1792 "ix86_expand_move (OImode, operands); DONE;")
1794 (define_expand "movti"
1795 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1796 (match_operand:TI 1 "nonimmediate_operand" ""))]
1797 "TARGET_64BIT || TARGET_SSE"
1800 ix86_expand_move (TImode, operands);
1801 else if (push_operand (operands[0], TImode))
1802 ix86_expand_push (TImode, operands[1]);
1804 ix86_expand_vector_move (TImode, operands);
1808 ;; This expands to what emit_move_complex would generate if we didn't
1809 ;; have a movti pattern. Having this avoids problems with reload on
1810 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1811 ;; to have around all the time.
1812 (define_expand "movcdi"
1813 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1814 (match_operand:CDI 1 "general_operand" ""))]
1817 if (push_operand (operands[0], CDImode))
1818 emit_move_complex_push (CDImode, operands[0], operands[1]);
1820 emit_move_complex_parts (operands[0], operands[1]);
1824 (define_expand "mov<mode>"
1825 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1826 (match_operand:SWI1248x 1 "general_operand" ""))]
1828 "ix86_expand_move (<MODE>mode, operands); DONE;")
1830 (define_insn "*mov<mode>_xor"
1831 [(set (match_operand:SWI48 0 "register_operand" "=r")
1832 (match_operand:SWI48 1 "const0_operand" ""))
1833 (clobber (reg:CC FLAGS_REG))]
1836 [(set_attr "type" "alu1")
1837 (set_attr "mode" "SI")
1838 (set_attr "length_immediate" "0")])
1840 (define_insn "*mov<mode>_or"
1841 [(set (match_operand:SWI48 0 "register_operand" "=r")
1842 (match_operand:SWI48 1 "const_int_operand" ""))
1843 (clobber (reg:CC FLAGS_REG))]
1845 && operands[1] == constm1_rtx"
1846 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1847 [(set_attr "type" "alu1")
1848 (set_attr "mode" "<MODE>")
1849 (set_attr "length_immediate" "1")])
1851 (define_insn "*movoi_internal_avx"
1852 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1853 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1854 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1856 switch (which_alternative)
1859 return standard_sse_constant_opcode (insn, operands[1]);
1862 if (misaligned_operand (operands[0], OImode)
1863 || misaligned_operand (operands[1], OImode))
1864 return "vmovdqu\t{%1, %0|%0, %1}";
1866 return "vmovdqa\t{%1, %0|%0, %1}";
1871 [(set_attr "type" "sselog1,ssemov,ssemov")
1872 (set_attr "prefix" "vex")
1873 (set_attr "mode" "OI")])
1875 (define_insn "*movti_internal_rex64"
1876 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1877 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1878 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1880 switch (which_alternative)
1886 return standard_sse_constant_opcode (insn, operands[1]);
1889 /* TDmode values are passed as TImode on the stack. Moving them
1890 to stack may result in unaligned memory access. */
1891 if (misaligned_operand (operands[0], TImode)
1892 || misaligned_operand (operands[1], TImode))
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovups\t{%1, %0|%0, %1}";
1897 return "%vmovdqu\t{%1, %0|%0, %1}";
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1904 return "%vmovdqa\t{%1, %0|%0, %1}";
1910 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1913 (cond [(eq_attr "alternative" "2,3")
1915 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917 (const_string "V4SF")
1918 (const_string "TI"))
1919 (eq_attr "alternative" "4")
1921 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1923 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1926 (const_string "TI"))]
1927 (const_string "DI")))])
1930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931 (match_operand:TI 1 "general_operand" ""))]
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1935 "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (which_alternative)
1946 return standard_sse_constant_opcode (insn, operands[1]);
1949 /* TDmode values are passed as TImode on the stack. Moving them
1950 to stack may result in unaligned memory access. */
1951 if (misaligned_operand (operands[0], TImode)
1952 || misaligned_operand (operands[1], TImode))
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovups\t{%1, %0|%0, %1}";
1957 return "%vmovdqu\t{%1, %0|%0, %1}";
1961 if (get_attr_mode (insn) == MODE_V4SF)
1962 return "%vmovaps\t{%1, %0|%0, %1}";
1964 return "%vmovdqa\t{%1, %0|%0, %1}";
1970 [(set_attr "type" "sselog1,ssemov,ssemov")
1971 (set_attr "prefix" "maybe_vex")
1973 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1974 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1976 (const_string "V4SF")
1977 (and (eq_attr "alternative" "2")
1978 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1980 (const_string "V4SF")]
1981 (const_string "TI")))])
1983 (define_insn "*movdi_internal_rex64"
1984 [(set (match_operand:DI 0 "nonimmediate_operand"
1985 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1986 (match_operand:DI 1 "general_operand"
1987 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1988 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990 switch (get_attr_type (insn))
1993 if (SSE_REG_P (operands[0]))
1994 return "movq2dq\t{%1, %0|%0, %1}";
1996 return "movdq2q\t{%1, %0|%0, %1}";
1999 if (get_attr_mode (insn) == MODE_TI)
2000 return "%vmovdqa\t{%1, %0|%0, %1}";
2001 /* Handle broken assemblers that require movd instead of movq. */
2002 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003 return "%vmovd\t{%1, %0|%0, %1}";
2005 return "%vmovq\t{%1, %0|%0, %1}";
2008 /* Handle broken assemblers that require movd instead of movq. */
2009 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2010 return "movd\t{%1, %0|%0, %1}";
2012 return "movq\t{%1, %0|%0, %1}";
2015 return standard_sse_constant_opcode (insn, operands[1]);
2018 return "pxor\t%0, %0";
2024 return "lea{q}\t{%a1, %0|%0, %a1}";
2027 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2028 if (get_attr_mode (insn) == MODE_SI)
2029 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2030 else if (which_alternative == 2)
2031 return "movabs{q}\t{%1, %0|%0, %1}";
2033 return "mov{q}\t{%1, %0|%0, %1}";
2037 (cond [(eq_attr "alternative" "4")
2038 (const_string "multi")
2039 (eq_attr "alternative" "5")
2040 (const_string "mmx")
2041 (eq_attr "alternative" "6,7,8,9")
2042 (const_string "mmxmov")
2043 (eq_attr "alternative" "10")
2044 (const_string "sselog1")
2045 (eq_attr "alternative" "11,12,13,14,15")
2046 (const_string "ssemov")
2047 (eq_attr "alternative" "16,17")
2048 (const_string "ssecvt")
2049 (match_operand 1 "pic_32bit_operand" "")
2050 (const_string "lea")
2052 (const_string "imov")))
2055 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2057 (const_string "*")))
2058 (set (attr "length_immediate")
2060 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2062 (const_string "*")))
2063 (set (attr "prefix_rex")
2064 (if_then_else (eq_attr "alternative" "8,9")
2066 (const_string "*")))
2067 (set (attr "prefix_data16")
2068 (if_then_else (eq_attr "alternative" "11")
2070 (const_string "*")))
2071 (set (attr "prefix")
2072 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2073 (const_string "maybe_vex")
2074 (const_string "orig")))
2075 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2077 ;; Convert impossible stores of immediate to existing instructions.
2078 ;; First try to get scratch register and go through it. In case this
2079 ;; fails, move by 32bit parts.
2081 [(match_scratch:DI 2 "r")
2082 (set (match_operand:DI 0 "memory_operand" "")
2083 (match_operand:DI 1 "immediate_operand" ""))]
2084 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085 && !x86_64_immediate_operand (operands[1], DImode)"
2086 [(set (match_dup 2) (match_dup 1))
2087 (set (match_dup 0) (match_dup 2))])
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 ;; "&& 1" is needed to keep it from matching the previous pattern.
2093 [(set (match_operand:DI 0 "memory_operand" "")
2094 (match_operand:DI 1 "immediate_operand" ""))]
2095 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2096 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2097 [(set (match_dup 2) (match_dup 3))
2098 (set (match_dup 4) (match_dup 5))]
2099 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2102 [(set (match_operand:DI 0 "memory_operand" "")
2103 (match_operand:DI 1 "immediate_operand" ""))]
2104 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2105 ? epilogue_completed : reload_completed)
2106 && !symbolic_operand (operands[1], DImode)
2107 && !x86_64_immediate_operand (operands[1], DImode)"
2108 [(set (match_dup 2) (match_dup 3))
2109 (set (match_dup 4) (match_dup 5))]
2110 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2112 (define_insn "*movdi_internal"
2113 [(set (match_operand:DI 0 "nonimmediate_operand"
2114 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2115 (match_operand:DI 1 "general_operand"
2116 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2117 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2119 switch (get_attr_type (insn))
2122 if (SSE_REG_P (operands[0]))
2123 return "movq2dq\t{%1, %0|%0, %1}";
2125 return "movdq2q\t{%1, %0|%0, %1}";
2128 switch (get_attr_mode (insn))
2131 return "%vmovdqa\t{%1, %0|%0, %1}";
2133 return "%vmovq\t{%1, %0|%0, %1}";
2135 return "movaps\t{%1, %0|%0, %1}";
2137 return "movlps\t{%1, %0|%0, %1}";
2143 return "movq\t{%1, %0|%0, %1}";
2146 return standard_sse_constant_opcode (insn, operands[1]);
2149 return "pxor\t%0, %0";
2159 (if_then_else (eq_attr "alternative" "9,10,11,12")
2160 (const_string "noavx")
2161 (const_string "*")))
2163 (cond [(eq_attr "alternative" "0,1")
2164 (const_string "multi")
2165 (eq_attr "alternative" "2")
2166 (const_string "mmx")
2167 (eq_attr "alternative" "3,4")
2168 (const_string "mmxmov")
2169 (eq_attr "alternative" "5,9")
2170 (const_string "sselog1")
2171 (eq_attr "alternative" "13,14")
2172 (const_string "ssecvt")
2174 (const_string "ssemov")))
2175 (set (attr "prefix")
2176 (if_then_else (eq_attr "alternative" "5,6,7,8")
2177 (const_string "maybe_vex")
2178 (const_string "orig")))
2179 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2182 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2183 (match_operand:DI 1 "general_operand" ""))]
2184 "!TARGET_64BIT && reload_completed
2185 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2186 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2188 "ix86_split_long_move (operands); DONE;")
2190 (define_insn "*movsi_internal"
2191 [(set (match_operand:SI 0 "nonimmediate_operand"
2192 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2193 (match_operand:SI 1 "general_operand"
2194 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2195 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2197 switch (get_attr_type (insn))
2200 return standard_sse_constant_opcode (insn, operands[1]);
2203 switch (get_attr_mode (insn))
2206 return "%vmovdqa\t{%1, %0|%0, %1}";
2208 return "%vmovaps\t{%1, %0|%0, %1}";
2210 return "%vmovd\t{%1, %0|%0, %1}";
2212 return "%vmovss\t{%1, %0|%0, %1}";
2218 return "pxor\t%0, %0";
2221 if (get_attr_mode (insn) == MODE_DI)
2222 return "movq\t{%1, %0|%0, %1}";
2223 return "movd\t{%1, %0|%0, %1}";
2226 return "lea{l}\t{%a1, %0|%0, %a1}";
2229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2230 return "mov{l}\t{%1, %0|%0, %1}";
2234 (cond [(eq_attr "alternative" "2")
2235 (const_string "mmx")
2236 (eq_attr "alternative" "3,4,5")
2237 (const_string "mmxmov")
2238 (eq_attr "alternative" "6")
2239 (const_string "sselog1")
2240 (eq_attr "alternative" "7,8,9,10,11")
2241 (const_string "ssemov")
2242 (match_operand 1 "pic_32bit_operand" "")
2243 (const_string "lea")
2245 (const_string "imov")))
2246 (set (attr "prefix")
2247 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2248 (const_string "orig")
2249 (const_string "maybe_vex")))
2250 (set (attr "prefix_data16")
2251 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2253 (const_string "*")))
2255 (cond [(eq_attr "alternative" "2,3")
2257 (eq_attr "alternative" "6,7")
2259 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2260 (const_string "V4SF")
2261 (const_string "TI"))
2262 (and (eq_attr "alternative" "8,9,10,11")
2263 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2266 (const_string "SI")))])
2268 (define_insn "*movhi_internal"
2269 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2270 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2271 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2273 switch (get_attr_type (insn))
2276 /* movzwl is faster than movw on p2 due to partial word stalls,
2277 though not as fast as an aligned movl. */
2278 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2280 if (get_attr_mode (insn) == MODE_SI)
2281 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2283 return "mov{w}\t{%1, %0|%0, %1}";
2287 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2289 (const_string "imov")
2290 (and (eq_attr "alternative" "0")
2291 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2293 (eq (symbol_ref "TARGET_HIMODE_MATH")
2295 (const_string "imov")
2296 (and (eq_attr "alternative" "1,2")
2297 (match_operand:HI 1 "aligned_operand" ""))
2298 (const_string "imov")
2299 (and (ne (symbol_ref "TARGET_MOVX")
2301 (eq_attr "alternative" "0,2"))
2302 (const_string "imovx")
2304 (const_string "imov")))
2306 (cond [(eq_attr "type" "imovx")
2308 (and (eq_attr "alternative" "1,2")
2309 (match_operand:HI 1 "aligned_operand" ""))
2311 (and (eq_attr "alternative" "0")
2312 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2314 (eq (symbol_ref "TARGET_HIMODE_MATH")
2318 (const_string "HI")))])
2320 ;; Situation is quite tricky about when to choose full sized (SImode) move
2321 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2322 ;; partial register dependency machines (such as AMD Athlon), where QImode
2323 ;; moves issue extra dependency and for partial register stalls machines
2324 ;; that don't use QImode patterns (and QImode move cause stall on the next
2327 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2328 ;; register stall machines with, where we use QImode instructions, since
2329 ;; partial register stall can be caused there. Then we use movzx.
2330 (define_insn "*movqi_internal"
2331 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2332 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2333 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2335 switch (get_attr_type (insn))
2338 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2339 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2341 if (get_attr_mode (insn) == MODE_SI)
2342 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2344 return "mov{b}\t{%1, %0|%0, %1}";
2348 (cond [(and (eq_attr "alternative" "5")
2349 (not (match_operand:QI 1 "aligned_operand" "")))
2350 (const_string "imovx")
2351 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2353 (const_string "imov")
2354 (and (eq_attr "alternative" "3")
2355 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2357 (eq (symbol_ref "TARGET_QIMODE_MATH")
2359 (const_string "imov")
2360 (eq_attr "alternative" "3,5")
2361 (const_string "imovx")
2362 (and (ne (symbol_ref "TARGET_MOVX")
2364 (eq_attr "alternative" "2"))
2365 (const_string "imovx")
2367 (const_string "imov")))
2369 (cond [(eq_attr "alternative" "3,4,5")
2371 (eq_attr "alternative" "6")
2373 (eq_attr "type" "imovx")
2375 (and (eq_attr "type" "imov")
2376 (and (eq_attr "alternative" "0,1")
2377 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2379 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2381 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2384 ;; Avoid partial register stalls when not using QImode arithmetic
2385 (and (eq_attr "type" "imov")
2386 (and (eq_attr "alternative" "0,1")
2387 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2389 (eq (symbol_ref "TARGET_QIMODE_MATH")
2393 (const_string "QI")))])
2395 ;; Stores and loads of ax to arbitrary constant address.
2396 ;; We fake an second form of instruction to force reload to load address
2397 ;; into register when rax is not available
2398 (define_insn "*movabs<mode>_1"
2399 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2400 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2401 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2403 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2404 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2405 [(set_attr "type" "imov")
2406 (set_attr "modrm" "0,*")
2407 (set_attr "length_address" "8,0")
2408 (set_attr "length_immediate" "0,*")
2409 (set_attr "memory" "store")
2410 (set_attr "mode" "<MODE>")])
2412 (define_insn "*movabs<mode>_2"
2413 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2414 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2415 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2417 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2418 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2419 [(set_attr "type" "imov")
2420 (set_attr "modrm" "0,*")
2421 (set_attr "length_address" "8,0")
2422 (set_attr "length_immediate" "0")
2423 (set_attr "memory" "load")
2424 (set_attr "mode" "<MODE>")])
2426 (define_insn "*swap<mode>"
2427 [(set (match_operand:SWI48 0 "register_operand" "+r")
2428 (match_operand:SWI48 1 "register_operand" "+r"))
2432 "xchg{<imodesuffix>}\t%1, %0"
2433 [(set_attr "type" "imov")
2434 (set_attr "mode" "<MODE>")
2435 (set_attr "pent_pair" "np")
2436 (set_attr "athlon_decode" "vector")
2437 (set_attr "amdfam10_decode" "double")
2438 (set_attr "bdver1_decode" "double")])
2440 (define_insn "*swap<mode>_1"
2441 [(set (match_operand:SWI12 0 "register_operand" "+r")
2442 (match_operand:SWI12 1 "register_operand" "+r"))
2445 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2447 [(set_attr "type" "imov")
2448 (set_attr "mode" "SI")
2449 (set_attr "pent_pair" "np")
2450 (set_attr "athlon_decode" "vector")
2451 (set_attr "amdfam10_decode" "double")
2452 (set_attr "bdver1_decode" "double")])
2454 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2455 ;; is disabled for AMDFAM10
2456 (define_insn "*swap<mode>_2"
2457 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2458 (match_operand:SWI12 1 "register_operand" "+<r>"))
2461 "TARGET_PARTIAL_REG_STALL"
2462 "xchg{<imodesuffix>}\t%1, %0"
2463 [(set_attr "type" "imov")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "pent_pair" "np")
2466 (set_attr "athlon_decode" "vector")])
2468 (define_expand "movstrict<mode>"
2469 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2470 (match_operand:SWI12 1 "general_operand" ""))]
2473 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2475 if (GET_CODE (operands[0]) == SUBREG
2476 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2478 /* Don't generate memory->memory moves, go through a register */
2479 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2480 operands[1] = force_reg (<MODE>mode, operands[1]);
2483 (define_insn "*movstrict<mode>_1"
2484 [(set (strict_low_part
2485 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2486 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2487 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2489 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2490 [(set_attr "type" "imov")
2491 (set_attr "mode" "<MODE>")])
2493 (define_insn "*movstrict<mode>_xor"
2494 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2495 (match_operand:SWI12 1 "const0_operand" ""))
2496 (clobber (reg:CC FLAGS_REG))]
2498 "xor{<imodesuffix>}\t%0, %0"
2499 [(set_attr "type" "alu1")
2500 (set_attr "mode" "<MODE>")
2501 (set_attr "length_immediate" "0")])
2503 (define_insn "*mov<mode>_extv_1"
2504 [(set (match_operand:SWI24 0 "register_operand" "=R")
2505 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2509 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2510 [(set_attr "type" "imovx")
2511 (set_attr "mode" "SI")])
2513 (define_insn "*movqi_extv_1_rex64"
2514 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2515 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2520 switch (get_attr_type (insn))
2523 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2525 return "mov{b}\t{%h1, %0|%0, %h1}";
2529 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2530 (ne (symbol_ref "TARGET_MOVX")
2532 (const_string "imovx")
2533 (const_string "imov")))
2535 (if_then_else (eq_attr "type" "imovx")
2537 (const_string "QI")))])
2539 (define_insn "*movqi_extv_1"
2540 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2541 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2556 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2557 (ne (symbol_ref "TARGET_MOVX")
2559 (const_string "imovx")
2560 (const_string "imov")))
2562 (if_then_else (eq_attr "type" "imovx")
2564 (const_string "QI")))])
2566 (define_insn "*mov<mode>_extzv_1"
2567 [(set (match_operand:SWI48 0 "register_operand" "=R")
2568 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2572 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2573 [(set_attr "type" "imovx")
2574 (set_attr "mode" "SI")])
2576 (define_insn "*movqi_extzv_2_rex64"
2577 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2579 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2584 switch (get_attr_type (insn))
2587 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2589 return "mov{b}\t{%h1, %0|%0, %h1}";
2593 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2594 (ne (symbol_ref "TARGET_MOVX")
2596 (const_string "imovx")
2597 (const_string "imov")))
2599 (if_then_else (eq_attr "type" "imovx")
2601 (const_string "QI")))])
2603 (define_insn "*movqi_extzv_2"
2604 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2606 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2611 switch (get_attr_type (insn))
2614 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2616 return "mov{b}\t{%h1, %0|%0, %h1}";
2620 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2621 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2622 (ne (symbol_ref "TARGET_MOVX")
2624 (const_string "imovx")
2625 (const_string "imov")))
2627 (if_then_else (eq_attr "type" "imovx")
2629 (const_string "QI")))])
2631 (define_expand "mov<mode>_insv_1"
2632 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2635 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2637 (define_insn "*mov<mode>_insv_1_rex64"
2638 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2641 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2643 "mov{b}\t{%b1, %h0|%h0, %b1}"
2644 [(set_attr "type" "imov")
2645 (set_attr "mode" "QI")])
2647 (define_insn "*movsi_insv_1"
2648 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2651 (match_operand:SI 1 "general_operand" "Qmn"))]
2653 "mov{b}\t{%b1, %h0|%h0, %b1}"
2654 [(set_attr "type" "imov")
2655 (set_attr "mode" "QI")])
2657 (define_insn "*movqi_insv_2"
2658 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2661 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2664 "mov{b}\t{%h1, %h0|%h0, %h1}"
2665 [(set_attr "type" "imov")
2666 (set_attr "mode" "QI")])
2668 ;; Floating point push instructions.
2670 (define_insn "*pushtf"
2671 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2672 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2675 /* This insn should be already split before reg-stack. */
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "sse,*,*")
2680 (set_attr "mode" "TF,SI,SI")])
2682 ;; %%% Kill this when call knows how to work this out.
2684 [(set (match_operand:TF 0 "push_operand" "")
2685 (match_operand:TF 1 "sse_reg_operand" ""))]
2686 "TARGET_SSE2 && reload_completed"
2687 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2688 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2690 (define_insn "*pushxf"
2691 [(set (match_operand:XF 0 "push_operand" "=<,<")
2692 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2693 "optimize_function_for_speed_p (cfun)"
2695 /* This insn should be already split before reg-stack. */
2698 [(set_attr "type" "multi")
2699 (set_attr "unit" "i387,*")
2700 (set_attr "mode" "XF,SI")])
2702 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2703 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2704 ;; Pushing using integer instructions is longer except for constants
2705 ;; and direct memory references (assuming that any given constant is pushed
2706 ;; only once, but this ought to be handled elsewhere).
2708 (define_insn "*pushxf_nointeger"
2709 [(set (match_operand:XF 0 "push_operand" "=<,<")
2710 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2711 "optimize_function_for_size_p (cfun)"
2713 /* This insn should be already split before reg-stack. */
2716 [(set_attr "type" "multi")
2717 (set_attr "unit" "i387,*")
2718 (set_attr "mode" "XF,SI")])
2720 ;; %%% Kill this when call knows how to work this out.
2722 [(set (match_operand:XF 0 "push_operand" "")
2723 (match_operand:XF 1 "fp_register_operand" ""))]
2725 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2726 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2727 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2729 (define_insn "*pushdf_rex64"
2730 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2731 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
2734 /* This insn should be already split before reg-stack. */
2737 [(set_attr "type" "multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "DF,DI,DF")])
2741 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2742 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2743 ;; On the average, pushdf using integers can be still shorter.
2745 (define_insn "*pushdf"
2746 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2747 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2750 /* This insn should be already split before reg-stack. */
2753 [(set_attr "type" "multi")
2754 (set_attr "unit" "i387,*,*")
2755 (set_attr "mode" "DF,DI,DF")])
2757 ;; %%% Kill this when call knows how to work this out.
2759 [(set (match_operand:DF 0 "push_operand" "")
2760 (match_operand:DF 1 "any_fp_register_operand" ""))]
2762 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2763 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2765 (define_insn "*pushsf_rex64"
2766 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2767 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2770 /* Anything else should be already split before reg-stack. */
2771 gcc_assert (which_alternative == 1);
2772 return "push{q}\t%q1";
2774 [(set_attr "type" "multi,push,multi")
2775 (set_attr "unit" "i387,*,*")
2776 (set_attr "mode" "SF,DI,SF")])
2778 (define_insn "*pushsf"
2779 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2780 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2783 /* Anything else should be already split before reg-stack. */
2784 gcc_assert (which_alternative == 1);
2785 return "push{l}\t%1";
2787 [(set_attr "type" "multi,push,multi")
2788 (set_attr "unit" "i387,*,*")
2789 (set_attr "mode" "SF,SI,SF")])
2791 ;; %%% Kill this when call knows how to work this out.
2793 [(set (match_operand:SF 0 "push_operand" "")
2794 (match_operand:SF 1 "any_fp_register_operand" ""))]
2796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2797 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2798 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2801 [(set (match_operand:SF 0 "push_operand" "")
2802 (match_operand:SF 1 "memory_operand" ""))]
2804 && (operands[2] = find_constant_src (insn))"
2805 [(set (match_dup 0) (match_dup 2))])
2808 [(set (match_operand 0 "push_operand" "")
2809 (match_operand 1 "general_operand" ""))]
2811 && (GET_MODE (operands[0]) == TFmode
2812 || GET_MODE (operands[0]) == XFmode
2813 || GET_MODE (operands[0]) == DFmode)
2814 && !ANY_FP_REG_P (operands[1])"
2816 "ix86_split_long_move (operands); DONE;")
2818 ;; Floating point move instructions.
2820 (define_expand "movtf"
2821 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822 (match_operand:TF 1 "nonimmediate_operand" ""))]
2825 ix86_expand_move (TFmode, operands);
2829 (define_expand "mov<mode>"
2830 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2831 (match_operand:X87MODEF 1 "general_operand" ""))]
2833 "ix86_expand_move (<MODE>mode, operands); DONE;")
2835 (define_insn "*movtf_internal"
2836 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2837 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2839 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2840 && (!can_create_pseudo_p ()
2841 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2842 || GET_CODE (operands[1]) != CONST_DOUBLE
2843 || (optimize_function_for_size_p (cfun)
2844 && standard_sse_constant_p (operands[1])
2845 && !memory_operand (operands[0], TFmode))
2846 || (!TARGET_MEMORY_MISMATCH_STALL
2847 && memory_operand (operands[0], TFmode)))"
2849 switch (which_alternative)
2853 /* Handle misaligned load/store since we
2854 don't have movmisaligntf pattern. */
2855 if (misaligned_operand (operands[0], TFmode)
2856 || misaligned_operand (operands[1], TFmode))
2858 if (get_attr_mode (insn) == MODE_V4SF)
2859 return "%vmovups\t{%1, %0|%0, %1}";
2861 return "%vmovdqu\t{%1, %0|%0, %1}";
2865 if (get_attr_mode (insn) == MODE_V4SF)
2866 return "%vmovaps\t{%1, %0|%0, %1}";
2868 return "%vmovdqa\t{%1, %0|%0, %1}";
2872 return standard_sse_constant_opcode (insn, operands[1]);
2882 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2883 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2885 (cond [(eq_attr "alternative" "0,2")
2887 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2889 (const_string "V4SF")
2890 (const_string "TI"))
2891 (eq_attr "alternative" "1")
2893 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2895 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2897 (const_string "V4SF")
2898 (const_string "TI"))]
2899 (const_string "DI")))])
2901 ;; Possible store forwarding (partial memory) stall in alternative 4.
2902 (define_insn "*movxf_internal"
2903 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2904 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2905 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2906 && (!can_create_pseudo_p ()
2907 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908 || GET_CODE (operands[1]) != CONST_DOUBLE
2909 || (optimize_function_for_size_p (cfun)
2910 && standard_80387_constant_p (operands[1]) > 0
2911 && !memory_operand (operands[0], XFmode))
2912 || (!TARGET_MEMORY_MISMATCH_STALL
2913 && memory_operand (operands[0], XFmode)))"
2915 switch (which_alternative)
2919 return output_387_reg_move (insn, operands);
2922 return standard_80387_constant_opcode (operands[1]);
2932 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2933 (set_attr "mode" "XF,XF,XF,SI,SI")])
2935 (define_insn "*movdf_internal_rex64"
2936 [(set (match_operand:DF 0 "nonimmediate_operand"
2937 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2938 (match_operand:DF 1 "general_operand"
2939 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2940 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2941 && (!can_create_pseudo_p ()
2942 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2943 || GET_CODE (operands[1]) != CONST_DOUBLE
2944 || (optimize_function_for_size_p (cfun)
2945 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2946 && standard_80387_constant_p (operands[1]) > 0)
2947 || (TARGET_SSE2 && TARGET_SSE_MATH
2948 && standard_sse_constant_p (operands[1]))))
2949 || memory_operand (operands[0], DFmode))"
2951 switch (which_alternative)
2955 return output_387_reg_move (insn, operands);
2958 return standard_80387_constant_opcode (operands[1]);
2962 return "mov{q}\t{%1, %0|%0, %1}";
2965 return "movabs{q}\t{%1, %0|%0, %1}";
2971 return standard_sse_constant_opcode (insn, operands[1]);
2976 switch (get_attr_mode (insn))
2979 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2980 return "%vmovapd\t{%1, %0|%0, %1}";
2982 return "%vmovaps\t{%1, %0|%0, %1}";
2985 return "%vmovq\t{%1, %0|%0, %1}";
2987 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2988 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2989 return "%vmovsd\t{%1, %0|%0, %1}";
2991 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2993 return "%vmovlps\t{%1, %d0|%d0, %1}";
3000 /* Handle broken assemblers that require movd instead of movq. */
3001 return "%vmovd\t{%1, %0|%0, %1}";
3007 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3010 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3012 (const_string "*")))
3013 (set (attr "length_immediate")
3015 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3017 (const_string "*")))
3018 (set (attr "prefix")
3019 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3020 (const_string "orig")
3021 (const_string "maybe_vex")))
3022 (set (attr "prefix_data16")
3023 (if_then_else (eq_attr "mode" "V1DF")
3025 (const_string "*")))
3027 (cond [(eq_attr "alternative" "0,1,2")
3029 (eq_attr "alternative" "3,4,5,6,11,12")
3032 /* xorps is one byte shorter. */
3033 (eq_attr "alternative" "7")
3034 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3036 (const_string "V4SF")
3037 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3041 (const_string "V2DF"))
3043 /* For architectures resolving dependencies on
3044 whole SSE registers use APD move to break dependency
3045 chains, otherwise use short move to avoid extra work.
3047 movaps encodes one byte shorter. */
3048 (eq_attr "alternative" "8")
3050 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3052 (const_string "V4SF")
3053 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3055 (const_string "V2DF")
3057 (const_string "DF"))
3058 /* For architectures resolving dependencies on register
3059 parts we may avoid extra work to zero out upper part
3061 (eq_attr "alternative" "9")
3063 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3065 (const_string "V1DF")
3066 (const_string "DF"))
3068 (const_string "DF")))])
3070 ;; Possible store forwarding (partial memory) stall in alternative 4.
3071 (define_insn "*movdf_internal"
3072 [(set (match_operand:DF 0 "nonimmediate_operand"
3073 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3074 (match_operand:DF 1 "general_operand"
3075 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3076 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3077 && (!can_create_pseudo_p ()
3078 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3079 || GET_CODE (operands[1]) != CONST_DOUBLE
3080 || (optimize_function_for_size_p (cfun)
3081 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3082 && standard_80387_constant_p (operands[1]) > 0)
3083 || (TARGET_SSE2 && TARGET_SSE_MATH
3084 && standard_sse_constant_p (operands[1])))
3085 && !memory_operand (operands[0], DFmode))
3086 || (!TARGET_MEMORY_MISMATCH_STALL
3087 && memory_operand (operands[0], DFmode)))"
3089 switch (which_alternative)
3093 return output_387_reg_move (insn, operands);
3096 return standard_80387_constant_opcode (operands[1]);
3103 return standard_sse_constant_opcode (insn, operands[1]);
3108 switch (get_attr_mode (insn))
3111 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3112 return "%vmovapd\t{%1, %0|%0, %1}";
3114 return "%vmovaps\t{%1, %0|%0, %1}";
3117 return "%vmovq\t{%1, %0|%0, %1}";
3119 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3120 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3121 return "%vmovsd\t{%1, %0|%0, %1}";
3123 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3125 return "%vmovlps\t{%1, %d0|%d0, %1}";
3134 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3135 (set (attr "prefix")
3136 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3137 (const_string "orig")
3138 (const_string "maybe_vex")))
3139 (set (attr "prefix_data16")
3140 (if_then_else (eq_attr "mode" "V1DF")
3142 (const_string "*")))
3144 (cond [(eq_attr "alternative" "0,1,2")
3146 (eq_attr "alternative" "3,4")
3149 /* For SSE1, we have many fewer alternatives. */
3150 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3152 (eq_attr "alternative" "5,6")
3153 (const_string "V4SF")
3154 (const_string "V2SF"))
3156 /* xorps is one byte shorter. */
3157 (eq_attr "alternative" "5")
3158 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3160 (const_string "V4SF")
3161 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3165 (const_string "V2DF"))
3167 /* For architectures resolving dependencies on
3168 whole SSE registers use APD move to break dependency
3169 chains, otherwise use short move to avoid extra work.
3171 movaps encodes one byte shorter. */
3172 (eq_attr "alternative" "6")
3174 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3176 (const_string "V4SF")
3177 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3179 (const_string "V2DF")
3181 (const_string "DF"))
3182 /* For architectures resolving dependencies on register
3183 parts we may avoid extra work to zero out upper part
3185 (eq_attr "alternative" "7")
3187 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3189 (const_string "V1DF")
3190 (const_string "DF"))
3192 (const_string "DF")))])
3194 (define_insn "*movsf_internal"
3195 [(set (match_operand:SF 0 "nonimmediate_operand"
3196 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3197 (match_operand:SF 1 "general_operand"
3198 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3199 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3200 && (!can_create_pseudo_p ()
3201 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3202 || GET_CODE (operands[1]) != CONST_DOUBLE
3203 || (optimize_function_for_size_p (cfun)
3204 && ((!TARGET_SSE_MATH
3205 && standard_80387_constant_p (operands[1]) > 0)
3207 && standard_sse_constant_p (operands[1]))))
3208 || memory_operand (operands[0], SFmode))"
3210 switch (which_alternative)
3214 return output_387_reg_move (insn, operands);
3217 return standard_80387_constant_opcode (operands[1]);
3221 return "mov{l}\t{%1, %0|%0, %1}";
3224 return standard_sse_constant_opcode (insn, operands[1]);
3227 if (get_attr_mode (insn) == MODE_V4SF)
3228 return "%vmovaps\t{%1, %0|%0, %1}";
3230 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3234 return "%vmovss\t{%1, %0|%0, %1}";
3240 return "movd\t{%1, %0|%0, %1}";
3243 return "movq\t{%1, %0|%0, %1}";
3247 return "%vmovd\t{%1, %0|%0, %1}";
3253 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256 (const_string "maybe_vex")
3257 (const_string "orig")))
3259 (cond [(eq_attr "alternative" "3,4,9,10")
3261 (eq_attr "alternative" "5")
3263 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3265 (ne (symbol_ref "TARGET_SSE2")
3267 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3270 (const_string "V4SF"))
3271 /* For architectures resolving dependencies on
3272 whole SSE registers use APS move to break dependency
3273 chains, otherwise use short move to avoid extra work.
3275 Do the same for architectures resolving dependencies on
3276 the parts. While in DF mode it is better to always handle
3277 just register parts, the SF mode is different due to lack
3278 of instructions to load just part of the register. It is
3279 better to maintain the whole registers in single format
3280 to avoid problems on using packed logical operations. */
3281 (eq_attr "alternative" "6")
3283 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3287 (const_string "V4SF")
3288 (const_string "SF"))
3289 (eq_attr "alternative" "11")
3290 (const_string "DI")]
3291 (const_string "SF")))])
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (match_operand 1 "memory_operand" ""))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode
3300 || GET_MODE (operands[0]) == SFmode)
3301 && (operands[2] = find_constant_src (insn))"
3302 [(set (match_dup 0) (match_dup 2))]
3304 rtx c = operands[2];
3305 int r = REGNO (operands[0]);
3307 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3308 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3313 [(set (match_operand 0 "any_fp_register_operand" "")
3314 (float_extend (match_operand 1 "memory_operand" "")))]
3316 && (GET_MODE (operands[0]) == TFmode
3317 || GET_MODE (operands[0]) == XFmode
3318 || GET_MODE (operands[0]) == DFmode)
3319 && (operands[2] = find_constant_src (insn))"
3320 [(set (match_dup 0) (match_dup 2))]
3322 rtx c = operands[2];
3323 int r = REGNO (operands[0]);
3325 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3326 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3330 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3332 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3333 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3335 && (standard_80387_constant_p (operands[1]) == 8
3336 || standard_80387_constant_p (operands[1]) == 9)"
3337 [(set (match_dup 0)(match_dup 1))
3339 (neg:X87MODEF (match_dup 0)))]
3343 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3344 if (real_isnegzero (&r))
3345 operands[1] = CONST0_RTX (<MODE>mode);
3347 operands[1] = CONST1_RTX (<MODE>mode);
3351 [(set (match_operand 0 "nonimmediate_operand" "")
3352 (match_operand 1 "general_operand" ""))]
3354 && (GET_MODE (operands[0]) == TFmode
3355 || GET_MODE (operands[0]) == XFmode
3356 || GET_MODE (operands[0]) == DFmode)
3357 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3359 "ix86_split_long_move (operands); DONE;")
3361 (define_insn "swapxf"
3362 [(set (match_operand:XF 0 "register_operand" "+f")
3363 (match_operand:XF 1 "register_operand" "+f"))
3368 if (STACK_TOP_P (operands[0]))
3373 [(set_attr "type" "fxch")
3374 (set_attr "mode" "XF")])
3376 (define_insn "*swap<mode>"
3377 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3378 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3381 "TARGET_80387 || reload_completed"
3383 if (STACK_TOP_P (operands[0]))
3388 [(set_attr "type" "fxch")
3389 (set_attr "mode" "<MODE>")])
3391 ;; Zero extension instructions
3393 (define_expand "zero_extendsidi2"
3394 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3395 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3400 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3405 (define_insn "*zero_extendsidi2_rex64"
3406 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3408 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3411 mov\t{%k1, %k0|%k0, %k1}
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 %vmovd\t{%1, %0|%0, %1}
3416 %vmovd\t{%1, %0|%0, %1}"
3417 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3418 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3419 (set_attr "prefix_0f" "0,*,*,*,*,*")
3420 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3423 [(set (match_operand:DI 0 "memory_operand" "")
3424 (zero_extend:DI (match_dup 0)))]
3426 [(set (match_dup 4) (const_int 0))]
3427 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3429 ;; %%% Kill me once multi-word ops are sane.
3430 (define_insn "zero_extendsidi2_1"
3431 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3433 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3434 (clobber (reg:CC FLAGS_REG))]
3440 movd\t{%1, %0|%0, %1}
3441 movd\t{%1, %0|%0, %1}
3442 %vmovd\t{%1, %0|%0, %1}
3443 %vmovd\t{%1, %0|%0, %1}"
3444 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3445 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3446 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3449 [(set (match_operand:DI 0 "register_operand" "")
3450 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3451 (clobber (reg:CC FLAGS_REG))]
3452 "!TARGET_64BIT && reload_completed
3453 && true_regnum (operands[0]) == true_regnum (operands[1])"
3454 [(set (match_dup 4) (const_int 0))]
3455 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3458 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3459 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3460 (clobber (reg:CC FLAGS_REG))]
3461 "!TARGET_64BIT && reload_completed
3462 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3463 [(set (match_dup 3) (match_dup 1))
3464 (set (match_dup 4) (const_int 0))]
3465 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3467 (define_insn "zero_extend<mode>di2"
3468 [(set (match_operand:DI 0 "register_operand" "=r")
3470 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3472 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3473 [(set_attr "type" "imovx")
3474 (set_attr "mode" "SI")])
3476 (define_expand "zero_extendhisi2"
3477 [(set (match_operand:SI 0 "register_operand" "")
3478 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3481 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3483 operands[1] = force_reg (HImode, operands[1]);
3484 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3489 (define_insn_and_split "zero_extendhisi2_and"
3490 [(set (match_operand:SI 0 "register_operand" "=r")
3491 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3492 (clobber (reg:CC FLAGS_REG))]
3493 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3495 "&& reload_completed"
3496 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3497 (clobber (reg:CC FLAGS_REG))])]
3499 [(set_attr "type" "alu1")
3500 (set_attr "mode" "SI")])
3502 (define_insn "*zero_extendhisi2_movzwl"
3503 [(set (match_operand:SI 0 "register_operand" "=r")
3504 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3505 "!TARGET_ZERO_EXTEND_WITH_AND
3506 || optimize_function_for_size_p (cfun)"
3507 "movz{wl|x}\t{%1, %0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "SI")])
3511 (define_expand "zero_extendqi<mode>2"
3513 [(set (match_operand:SWI24 0 "register_operand" "")
3514 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3515 (clobber (reg:CC FLAGS_REG))])])
3517 (define_insn "*zero_extendqi<mode>2_and"
3518 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3519 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3520 (clobber (reg:CC FLAGS_REG))]
3521 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3523 [(set_attr "type" "alu1")
3524 (set_attr "mode" "<MODE>")])
3526 ;; When source and destination does not overlap, clear destination
3527 ;; first and then do the movb
3529 [(set (match_operand:SWI24 0 "register_operand" "")
3530 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531 (clobber (reg:CC FLAGS_REG))]
3533 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3534 && ANY_QI_REG_P (operands[0])
3535 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3536 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3537 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3539 operands[2] = gen_lowpart (QImode, operands[0]);
3540 ix86_expand_clear (operands[0]);
3543 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3544 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3545 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3546 (clobber (reg:CC FLAGS_REG))]
3547 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3549 [(set_attr "type" "imovx,alu1")
3550 (set_attr "mode" "<MODE>")])
3552 ;; For the movzbl case strip only the clobber
3554 [(set (match_operand:SWI24 0 "register_operand" "")
3555 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3556 (clobber (reg:CC FLAGS_REG))]
3558 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3559 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3561 (zero_extend:SWI24 (match_dup 1)))])
3563 ; zero extend to SImode to avoid partial register stalls
3564 (define_insn "*zero_extendqi<mode>2_movzbl"
3565 [(set (match_operand:SWI24 0 "register_operand" "=r")
3566 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3568 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3569 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3573 ;; Rest is handled by single and.
3575 [(set (match_operand:SWI24 0 "register_operand" "")
3576 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3577 (clobber (reg:CC FLAGS_REG))]
3579 && true_regnum (operands[0]) == true_regnum (operands[1])"
3580 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3581 (clobber (reg:CC FLAGS_REG))])])
3583 ;; Sign extension instructions
3585 (define_expand "extendsidi2"
3586 [(set (match_operand:DI 0 "register_operand" "")
3587 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3592 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3597 (define_insn "*extendsidi2_rex64"
3598 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3599 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3603 movs{lq|x}\t{%1, %0|%0, %1}"
3604 [(set_attr "type" "imovx")
3605 (set_attr "mode" "DI")
3606 (set_attr "prefix_0f" "0")
3607 (set_attr "modrm" "0,1")])
3609 (define_insn "extendsidi2_1"
3610 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3611 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3612 (clobber (reg:CC FLAGS_REG))
3613 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3617 ;; Extend to memory case when source register does die.
3619 [(set (match_operand:DI 0 "memory_operand" "")
3620 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3621 (clobber (reg:CC FLAGS_REG))
3622 (clobber (match_operand:SI 2 "register_operand" ""))]
3624 && dead_or_set_p (insn, operands[1])
3625 && !reg_mentioned_p (operands[1], operands[0]))"
3626 [(set (match_dup 3) (match_dup 1))
3627 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3628 (clobber (reg:CC FLAGS_REG))])
3629 (set (match_dup 4) (match_dup 1))]
3630 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3632 ;; Extend to memory case when source register does not die.
3634 [(set (match_operand:DI 0 "memory_operand" "")
3635 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3636 (clobber (reg:CC FLAGS_REG))
3637 (clobber (match_operand:SI 2 "register_operand" ""))]
3641 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3643 emit_move_insn (operands[3], operands[1]);
3645 /* Generate a cltd if possible and doing so it profitable. */
3646 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3647 && true_regnum (operands[1]) == AX_REG
3648 && true_regnum (operands[2]) == DX_REG)
3650 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3654 emit_move_insn (operands[2], operands[1]);
3655 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3657 emit_move_insn (operands[4], operands[2]);
3661 ;; Extend to register case. Optimize case where source and destination
3662 ;; registers match and cases where we can use cltd.
3664 [(set (match_operand:DI 0 "register_operand" "")
3665 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3666 (clobber (reg:CC FLAGS_REG))
3667 (clobber (match_scratch:SI 2 ""))]
3671 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3673 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3674 emit_move_insn (operands[3], operands[1]);
3676 /* Generate a cltd if possible and doing so it profitable. */
3677 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3678 && true_regnum (operands[3]) == AX_REG
3679 && true_regnum (operands[4]) == DX_REG)
3681 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3685 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3686 emit_move_insn (operands[4], operands[1]);
3688 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3692 (define_insn "extend<mode>di2"
3693 [(set (match_operand:DI 0 "register_operand" "=r")
3695 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3697 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "imovx")
3699 (set_attr "mode" "DI")])
3701 (define_insn "extendhisi2"
3702 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3703 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3706 switch (get_attr_prefix_0f (insn))
3709 return "{cwtl|cwde}";
3711 return "movs{wl|x}\t{%1, %0|%0, %1}";
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")
3716 (set (attr "prefix_0f")
3717 ;; movsx is short decodable while cwtl is vector decoded.
3718 (if_then_else (and (eq_attr "cpu" "!k6")
3719 (eq_attr "alternative" "0"))
3721 (const_string "1")))
3723 (if_then_else (eq_attr "prefix_0f" "0")
3725 (const_string "1")))])
3727 (define_insn "*extendhisi2_zext"
3728 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3731 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3734 switch (get_attr_prefix_0f (insn))
3737 return "{cwtl|cwde}";
3739 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")
3744 (set (attr "prefix_0f")
3745 ;; movsx is short decodable while cwtl is vector decoded.
3746 (if_then_else (and (eq_attr "cpu" "!k6")
3747 (eq_attr "alternative" "0"))
3749 (const_string "1")))
3751 (if_then_else (eq_attr "prefix_0f" "0")
3753 (const_string "1")))])
3755 (define_insn "extendqisi2"
3756 [(set (match_operand:SI 0 "register_operand" "=r")
3757 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3759 "movs{bl|x}\t{%1, %0|%0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "SI")])
3763 (define_insn "*extendqisi2_zext"
3764 [(set (match_operand:DI 0 "register_operand" "=r")
3766 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3768 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3769 [(set_attr "type" "imovx")
3770 (set_attr "mode" "SI")])
3772 (define_insn "extendqihi2"
3773 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3774 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3777 switch (get_attr_prefix_0f (insn))
3780 return "{cbtw|cbw}";
3782 return "movs{bw|x}\t{%1, %0|%0, %1}";
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "HI")
3787 (set (attr "prefix_0f")
3788 ;; movsx is short decodable while cwtl is vector decoded.
3789 (if_then_else (and (eq_attr "cpu" "!k6")
3790 (eq_attr "alternative" "0"))
3792 (const_string "1")))
3794 (if_then_else (eq_attr "prefix_0f" "0")
3796 (const_string "1")))])
3798 ;; Conversions between float and double.
3800 ;; These are all no-ops in the model used for the 80387.
3801 ;; So just emit moves.
3803 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3805 [(set (match_operand:DF 0 "push_operand" "")
3806 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3808 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3809 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3812 [(set (match_operand:XF 0 "push_operand" "")
3813 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3815 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3816 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3817 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3819 (define_expand "extendsfdf2"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3821 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3822 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3824 /* ??? Needed for compress_float_constant since all fp constants
3825 are TARGET_LEGITIMATE_CONSTANT_P. */
3826 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3828 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3829 && standard_80387_constant_p (operands[1]) > 0)
3831 operands[1] = simplify_const_unary_operation
3832 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3833 emit_move_insn_1 (operands[0], operands[1]);
3836 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3840 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3842 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3844 We do the conversion post reload to avoid producing of 128bit spills
3845 that might lead to ICE on 32bit target. The sequence unlikely combine
3848 [(set (match_operand:DF 0 "register_operand" "")
3850 (match_operand:SF 1 "nonimmediate_operand" "")))]
3851 "TARGET_USE_VECTOR_FP_CONVERTS
3852 && optimize_insn_for_speed_p ()
3853 && reload_completed && SSE_REG_P (operands[0])"
3858 (parallel [(const_int 0) (const_int 1)]))))]
3860 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3861 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3862 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3863 Try to avoid move when unpacking can be done in source. */
3864 if (REG_P (operands[1]))
3866 /* If it is unsafe to overwrite upper half of source, we need
3867 to move to destination and unpack there. */
3868 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3869 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3870 && true_regnum (operands[0]) != true_regnum (operands[1]))
3872 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3873 emit_move_insn (tmp, operands[1]);
3876 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3877 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3881 emit_insn (gen_vec_setv4sf_0 (operands[3],
3882 CONST0_RTX (V4SFmode), operands[1]));
3885 (define_insn "*extendsfdf2_mixed"
3886 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3888 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3889 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3891 switch (which_alternative)
3895 return output_387_reg_move (insn, operands);
3898 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3904 [(set_attr "type" "fmov,fmov,ssecvt")
3905 (set_attr "prefix" "orig,orig,maybe_vex")
3906 (set_attr "mode" "SF,XF,DF")])
3908 (define_insn "*extendsfdf2_sse"
3909 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3910 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3911 "TARGET_SSE2 && TARGET_SSE_MATH"
3912 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3913 [(set_attr "type" "ssecvt")
3914 (set_attr "prefix" "maybe_vex")
3915 (set_attr "mode" "DF")])
3917 (define_insn "*extendsfdf2_i387"
3918 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3919 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3921 "* return output_387_reg_move (insn, operands);"
3922 [(set_attr "type" "fmov")
3923 (set_attr "mode" "SF,XF")])
3925 (define_expand "extend<mode>xf2"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3927 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3930 /* ??? Needed for compress_float_constant since all fp constants
3931 are TARGET_LEGITIMATE_CONSTANT_P. */
3932 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3934 if (standard_80387_constant_p (operands[1]) > 0)
3936 operands[1] = simplify_const_unary_operation
3937 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3938 emit_move_insn_1 (operands[0], operands[1]);
3941 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3945 (define_insn "*extend<mode>xf2_i387"
3946 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3948 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3950 "* return output_387_reg_move (insn, operands);"
3951 [(set_attr "type" "fmov")
3952 (set_attr "mode" "<MODE>,XF")])
3954 ;; %%% This seems bad bad news.
3955 ;; This cannot output into an f-reg because there is no way to be sure
3956 ;; of truncating in that case. Otherwise this is just like a simple move
3957 ;; insn. So we pretend we can output to a reg in order to get better
3958 ;; register preferencing, but we really use a stack slot.
3960 ;; Conversion from DFmode to SFmode.
3962 (define_expand "truncdfsf2"
3963 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3965 (match_operand:DF 1 "nonimmediate_operand" "")))]
3966 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3968 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3970 else if (flag_unsafe_math_optimizations)
3974 enum ix86_stack_slot slot = (virtuals_instantiated
3977 rtx temp = assign_386_stack_local (SFmode, slot);
3978 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3983 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3985 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3987 We do the conversion post reload to avoid producing of 128bit spills
3988 that might lead to ICE on 32bit target. The sequence unlikely combine
3991 [(set (match_operand:SF 0 "register_operand" "")
3993 (match_operand:DF 1 "nonimmediate_operand" "")))]
3994 "TARGET_USE_VECTOR_FP_CONVERTS
3995 && optimize_insn_for_speed_p ()
3996 && reload_completed && SSE_REG_P (operands[0])"
3999 (float_truncate:V2SF
4003 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4004 operands[3] = CONST0_RTX (V2SFmode);
4005 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4006 /* Use movsd for loading from memory, unpcklpd for registers.
4007 Try to avoid move when unpacking can be done in source, or SSE3
4008 movddup is available. */
4009 if (REG_P (operands[1]))
4012 && true_regnum (operands[0]) != true_regnum (operands[1])
4013 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4014 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4016 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4017 emit_move_insn (tmp, operands[1]);
4020 else if (!TARGET_SSE3)
4021 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4022 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4025 emit_insn (gen_sse2_loadlpd (operands[4],
4026 CONST0_RTX (V2DFmode), operands[1]));
4029 (define_expand "truncdfsf2_with_temp"
4030 [(parallel [(set (match_operand:SF 0 "" "")
4031 (float_truncate:SF (match_operand:DF 1 "" "")))
4032 (clobber (match_operand:SF 2 "" ""))])])
4034 (define_insn "*truncdfsf_fast_mixed"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4037 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4038 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4040 switch (which_alternative)
4043 return output_387_reg_move (insn, operands);
4045 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4050 [(set_attr "type" "fmov,ssecvt")
4051 (set_attr "prefix" "orig,maybe_vex")
4052 (set_attr "mode" "SF")])
4054 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4055 ;; because nothing we do here is unsafe.
4056 (define_insn "*truncdfsf_fast_sse"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4059 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4060 "TARGET_SSE2 && TARGET_SSE_MATH"
4061 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4062 [(set_attr "type" "ssecvt")
4063 (set_attr "prefix" "maybe_vex")
4064 (set_attr "mode" "SF")])
4066 (define_insn "*truncdfsf_fast_i387"
4067 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4069 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4070 "TARGET_80387 && flag_unsafe_math_optimizations"
4071 "* return output_387_reg_move (insn, operands);"
4072 [(set_attr "type" "fmov")
4073 (set_attr "mode" "SF")])
4075 (define_insn "*truncdfsf_mixed"
4076 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4078 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4079 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4080 "TARGET_MIX_SSE_I387"
4082 switch (which_alternative)
4085 return output_387_reg_move (insn, operands);
4087 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4093 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4094 (set_attr "unit" "*,*,i387,i387,i387")
4095 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4096 (set_attr "mode" "SF")])
4098 (define_insn "*truncdfsf_i387"
4099 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4101 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4102 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4105 switch (which_alternative)
4108 return output_387_reg_move (insn, operands);
4114 [(set_attr "type" "fmov,multi,multi,multi")
4115 (set_attr "unit" "*,i387,i387,i387")
4116 (set_attr "mode" "SF")])
4118 (define_insn "*truncdfsf2_i387_1"
4119 [(set (match_operand:SF 0 "memory_operand" "=m")
4121 (match_operand:DF 1 "register_operand" "f")))]
4123 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4124 && !TARGET_MIX_SSE_I387"
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "SF")])
4130 [(set (match_operand:SF 0 "register_operand" "")
4132 (match_operand:DF 1 "fp_register_operand" "")))
4133 (clobber (match_operand 2 "" ""))]
4135 [(set (match_dup 2) (match_dup 1))
4136 (set (match_dup 0) (match_dup 2))]
4137 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4139 ;; Conversion from XFmode to {SF,DF}mode
4141 (define_expand "truncxf<mode>2"
4142 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4143 (float_truncate:MODEF
4144 (match_operand:XF 1 "register_operand" "")))
4145 (clobber (match_dup 2))])]
4148 if (flag_unsafe_math_optimizations)
4150 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4151 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4152 if (reg != operands[0])
4153 emit_move_insn (operands[0], reg);
4158 enum ix86_stack_slot slot = (virtuals_instantiated
4161 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4165 (define_insn "*truncxfsf2_mixed"
4166 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4168 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4169 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4172 gcc_assert (!which_alternative);
4173 return output_387_reg_move (insn, operands);
4175 [(set_attr "type" "fmov,multi,multi,multi")
4176 (set_attr "unit" "*,i387,i387,i387")
4177 (set_attr "mode" "SF")])
4179 (define_insn "*truncxfdf2_mixed"
4180 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4182 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4183 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4186 gcc_assert (!which_alternative);
4187 return output_387_reg_move (insn, operands);
4189 [(set_attr "type" "fmov,multi,multi,multi")
4190 (set_attr "unit" "*,i387,i387,i387")
4191 (set_attr "mode" "DF")])
4193 (define_insn "truncxf<mode>2_i387_noop"
4194 [(set (match_operand:MODEF 0 "register_operand" "=f")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "f")))]
4197 "TARGET_80387 && flag_unsafe_math_optimizations"
4198 "* return output_387_reg_move (insn, operands);"
4199 [(set_attr "type" "fmov")
4200 (set_attr "mode" "<MODE>")])
4202 (define_insn "*truncxf<mode>2_i387"
4203 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "f")))]
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "<MODE>")])
4212 [(set (match_operand:MODEF 0 "register_operand" "")
4213 (float_truncate:MODEF
4214 (match_operand:XF 1 "register_operand" "")))
4215 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4216 "TARGET_80387 && reload_completed"
4217 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4218 (set (match_dup 0) (match_dup 2))])
4221 [(set (match_operand:MODEF 0 "memory_operand" "")
4222 (float_truncate:MODEF
4223 (match_operand:XF 1 "register_operand" "")))
4224 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4226 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4228 ;; Signed conversion to DImode.
4230 (define_expand "fix_truncxfdi2"
4231 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4232 (fix:DI (match_operand:XF 1 "register_operand" "")))
4233 (clobber (reg:CC FLAGS_REG))])]
4238 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4243 (define_expand "fix_trunc<mode>di2"
4244 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4245 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4246 (clobber (reg:CC FLAGS_REG))])]
4247 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4250 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4252 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4257 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4258 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4259 if (out != operands[0])
4260 emit_move_insn (operands[0], out);
4265 ;; Signed conversion to SImode.
4267 (define_expand "fix_truncxfsi2"
4268 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4269 (fix:SI (match_operand:XF 1 "register_operand" "")))
4270 (clobber (reg:CC FLAGS_REG))])]
4275 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4280 (define_expand "fix_trunc<mode>si2"
4281 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4282 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4283 (clobber (reg:CC FLAGS_REG))])]
4284 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4287 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4289 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292 if (SSE_FLOAT_MODE_P (<MODE>mode))
4294 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4295 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4296 if (out != operands[0])
4297 emit_move_insn (operands[0], out);
4302 ;; Signed conversion to HImode.
4304 (define_expand "fix_trunc<mode>hi2"
4305 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4306 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4307 (clobber (reg:CC FLAGS_REG))])]
4309 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4313 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4318 ;; Unsigned conversion to SImode.
4320 (define_expand "fixuns_trunc<mode>si2"
4322 [(set (match_operand:SI 0 "register_operand" "")
4324 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4326 (clobber (match_scratch:<ssevecmode> 3 ""))
4327 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4328 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4330 enum machine_mode mode = <MODE>mode;
4331 enum machine_mode vecmode = <ssevecmode>mode;
4332 REAL_VALUE_TYPE TWO31r;
4335 if (optimize_insn_for_size_p ())
4338 real_ldexp (&TWO31r, &dconst1, 31);
4339 two31 = const_double_from_real_value (TWO31r, mode);
4340 two31 = ix86_build_const_vector (vecmode, true, two31);
4341 operands[2] = force_reg (vecmode, two31);
4344 (define_insn_and_split "*fixuns_trunc<mode>_1"
4345 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4347 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4348 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4349 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4350 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4351 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4352 && optimize_function_for_speed_p (cfun)"
4354 "&& reload_completed"
4357 ix86_split_convert_uns_si_sse (operands);
4361 ;; Unsigned conversion to HImode.
4362 ;; Without these patterns, we'll try the unsigned SI conversion which
4363 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4365 (define_expand "fixuns_trunc<mode>hi2"
4367 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4368 (set (match_operand:HI 0 "nonimmediate_operand" "")
4369 (subreg:HI (match_dup 2) 0))]
4370 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4371 "operands[2] = gen_reg_rtx (SImode);")
4373 ;; When SSE is available, it is always faster to use it!
4374 (define_insn "fix_trunc<mode>di_sse"
4375 [(set (match_operand:DI 0 "register_operand" "=r,r")
4376 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4377 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4378 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4379 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4380 [(set_attr "type" "sseicvt")
4381 (set_attr "prefix" "maybe_vex")
4382 (set_attr "prefix_rex" "1")
4383 (set_attr "mode" "<MODE>")
4384 (set_attr "athlon_decode" "double,vector")
4385 (set_attr "amdfam10_decode" "double,double")
4386 (set_attr "bdver1_decode" "double,double")])
4388 (define_insn "fix_trunc<mode>si_sse"
4389 [(set (match_operand:SI 0 "register_operand" "=r,r")
4390 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4391 "SSE_FLOAT_MODE_P (<MODE>mode)
4392 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4393 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4394 [(set_attr "type" "sseicvt")
4395 (set_attr "prefix" "maybe_vex")
4396 (set_attr "mode" "<MODE>")
4397 (set_attr "athlon_decode" "double,vector")
4398 (set_attr "amdfam10_decode" "double,double")
4399 (set_attr "bdver1_decode" "double,double")])
4401 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4403 [(set (match_operand:MODEF 0 "register_operand" "")
4404 (match_operand:MODEF 1 "memory_operand" ""))
4405 (set (match_operand:SWI48x 2 "register_operand" "")
4406 (fix:SWI48x (match_dup 0)))]
4407 "TARGET_SHORTEN_X87_SSE
4408 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4409 && peep2_reg_dead_p (2, operands[0])"
4410 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4412 ;; Avoid vector decoded forms of the instruction.
4414 [(match_scratch:DF 2 "Y2")
4415 (set (match_operand:SWI48x 0 "register_operand" "")
4416 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4417 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4418 [(set (match_dup 2) (match_dup 1))
4419 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4422 [(match_scratch:SF 2 "x")
4423 (set (match_operand:SWI48x 0 "register_operand" "")
4424 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4425 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4426 [(set (match_dup 2) (match_dup 1))
4427 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4429 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4430 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4431 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4432 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4434 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && (TARGET_64BIT || <MODE>mode != DImode))
4437 && can_create_pseudo_p ()"
4442 if (memory_operand (operands[0], VOIDmode))
4443 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4446 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4447 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4453 [(set_attr "type" "fisttp")
4454 (set_attr "mode" "<MODE>")])
4456 (define_insn "fix_trunc<mode>_i387_fisttp"
4457 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4458 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4459 (clobber (match_scratch:XF 2 "=&1f"))]
4460 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4463 && (TARGET_64BIT || <MODE>mode != DImode))
4464 && TARGET_SSE_MATH)"
4465 "* return output_fix_trunc (insn, operands, true);"
4466 [(set_attr "type" "fisttp")
4467 (set_attr "mode" "<MODE>")])
4469 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4470 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4471 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4472 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4473 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4474 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4477 && (TARGET_64BIT || <MODE>mode != DImode))
4478 && TARGET_SSE_MATH)"
4480 [(set_attr "type" "fisttp")
4481 (set_attr "mode" "<MODE>")])
4484 [(set (match_operand:SWI248x 0 "register_operand" "")
4485 (fix:SWI248x (match_operand 1 "register_operand" "")))
4486 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4487 (clobber (match_scratch 3 ""))]
4489 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4490 (clobber (match_dup 3))])
4491 (set (match_dup 0) (match_dup 2))])
4494 [(set (match_operand:SWI248x 0 "memory_operand" "")
4495 (fix:SWI248x (match_operand 1 "register_operand" "")))
4496 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4497 (clobber (match_scratch 3 ""))]
4499 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4500 (clobber (match_dup 3))])])
4502 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4503 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4504 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4505 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4506 ;; function in i386.c.
4507 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4508 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4509 (fix:SWI248x (match_operand 1 "register_operand" "")))
4510 (clobber (reg:CC FLAGS_REG))]
4511 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && (TARGET_64BIT || <MODE>mode != DImode))
4515 && can_create_pseudo_p ()"
4520 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4522 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4523 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4524 if (memory_operand (operands[0], VOIDmode))
4525 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4526 operands[2], operands[3]));
4529 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4530 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4531 operands[2], operands[3],
4536 [(set_attr "type" "fistp")
4537 (set_attr "i387_cw" "trunc")
4538 (set_attr "mode" "<MODE>")])
4540 (define_insn "fix_truncdi_i387"
4541 [(set (match_operand:DI 0 "memory_operand" "=m")
4542 (fix:DI (match_operand 1 "register_operand" "f")))
4543 (use (match_operand:HI 2 "memory_operand" "m"))
4544 (use (match_operand:HI 3 "memory_operand" "m"))
4545 (clobber (match_scratch:XF 4 "=&1f"))]
4546 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4549 "* return output_fix_trunc (insn, operands, false);"
4550 [(set_attr "type" "fistp")
4551 (set_attr "i387_cw" "trunc")
4552 (set_attr "mode" "DI")])
4554 (define_insn "fix_truncdi_i387_with_temp"
4555 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4556 (fix:DI (match_operand 1 "register_operand" "f,f")))
4557 (use (match_operand:HI 2 "memory_operand" "m,m"))
4558 (use (match_operand:HI 3 "memory_operand" "m,m"))
4559 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4560 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565 [(set_attr "type" "fistp")
4566 (set_attr "i387_cw" "trunc")
4567 (set_attr "mode" "DI")])
4570 [(set (match_operand:DI 0 "register_operand" "")
4571 (fix:DI (match_operand 1 "register_operand" "")))
4572 (use (match_operand:HI 2 "memory_operand" ""))
4573 (use (match_operand:HI 3 "memory_operand" ""))
4574 (clobber (match_operand:DI 4 "memory_operand" ""))
4575 (clobber (match_scratch 5 ""))]
4577 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4580 (clobber (match_dup 5))])
4581 (set (match_dup 0) (match_dup 4))])
4584 [(set (match_operand:DI 0 "memory_operand" "")
4585 (fix:DI (match_operand 1 "register_operand" "")))
4586 (use (match_operand:HI 2 "memory_operand" ""))
4587 (use (match_operand:HI 3 "memory_operand" ""))
4588 (clobber (match_operand:DI 4 "memory_operand" ""))
4589 (clobber (match_scratch 5 ""))]
4591 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4594 (clobber (match_dup 5))])])
4596 (define_insn "fix_trunc<mode>_i387"
4597 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4598 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4599 (use (match_operand:HI 2 "memory_operand" "m"))
4600 (use (match_operand:HI 3 "memory_operand" "m"))]
4601 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4604 "* return output_fix_trunc (insn, operands, false);"
4605 [(set_attr "type" "fistp")
4606 (set_attr "i387_cw" "trunc")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_trunc<mode>_i387_with_temp"
4610 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4611 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4612 (use (match_operand:HI 2 "memory_operand" "m,m"))
4613 (use (match_operand:HI 3 "memory_operand" "m,m"))
4614 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4619 [(set_attr "type" "fistp")
4620 (set_attr "i387_cw" "trunc")
4621 (set_attr "mode" "<MODE>")])
4624 [(set (match_operand:SWI24 0 "register_operand" "")
4625 (fix:SWI24 (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:SWI24 4 "memory_operand" ""))]
4630 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4632 (use (match_dup 3))])
4633 (set (match_dup 0) (match_dup 4))])
4636 [(set (match_operand:SWI24 0 "memory_operand" "")
4637 (fix:SWI24 (match_operand 1 "register_operand" "")))
4638 (use (match_operand:HI 2 "memory_operand" ""))
4639 (use (match_operand:HI 3 "memory_operand" ""))
4640 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4642 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4644 (use (match_dup 3))])])
4646 (define_insn "x86_fnstcw_1"
4647 [(set (match_operand:HI 0 "memory_operand" "=m")
4648 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4651 [(set (attr "length")
4652 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4653 (set_attr "mode" "HI")
4654 (set_attr "unit" "i387")
4655 (set_attr "bdver1_decode" "vector")])
4657 (define_insn "x86_fldcw_1"
4658 [(set (reg:HI FPCR_REG)
4659 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4662 [(set (attr "length")
4663 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4664 (set_attr "mode" "HI")
4665 (set_attr "unit" "i387")
4666 (set_attr "athlon_decode" "vector")
4667 (set_attr "amdfam10_decode" "vector")
4668 (set_attr "bdver1_decode" "vector")])
4670 ;; Conversion between fixed point and floating point.
4672 ;; Even though we only accept memory inputs, the backend _really_
4673 ;; wants to be able to do this between registers.
4675 (define_expand "floathi<mode>2"
4676 [(set (match_operand:X87MODEF 0 "register_operand" "")
4677 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4680 || TARGET_MIX_SSE_I387)")
4682 ;; Pre-reload splitter to add memory clobber to the pattern.
4683 (define_insn_and_split "*floathi<mode>2_1"
4684 [(set (match_operand:X87MODEF 0 "register_operand" "")
4685 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4688 || TARGET_MIX_SSE_I387)
4689 && can_create_pseudo_p ()"
4692 [(parallel [(set (match_dup 0)
4693 (float:X87MODEF (match_dup 1)))
4694 (clobber (match_dup 2))])]
4695 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4697 (define_insn "*floathi<mode>2_i387_with_temp"
4698 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4699 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4700 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4703 || TARGET_MIX_SSE_I387)"
4705 [(set_attr "type" "fmov,multi")
4706 (set_attr "mode" "<MODE>")
4707 (set_attr "unit" "*,i387")
4708 (set_attr "fp_int_src" "true")])
4710 (define_insn "*floathi<mode>2_i387"
4711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4712 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4715 || TARGET_MIX_SSE_I387)"
4717 [(set_attr "type" "fmov")
4718 (set_attr "mode" "<MODE>")
4719 (set_attr "fp_int_src" "true")])
4722 [(set (match_operand:X87MODEF 0 "register_operand" "")
4723 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4724 (clobber (match_operand:HI 2 "memory_operand" ""))]
4726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4727 || TARGET_MIX_SSE_I387)
4728 && reload_completed"
4729 [(set (match_dup 2) (match_dup 1))
4730 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4733 [(set (match_operand:X87MODEF 0 "register_operand" "")
4734 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4735 (clobber (match_operand:HI 2 "memory_operand" ""))]
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)
4739 && reload_completed"
4740 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4742 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4743 [(set (match_operand:X87MODEF 0 "register_operand" "")
4745 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4747 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4748 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4750 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4751 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4752 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4754 rtx reg = gen_reg_rtx (XFmode);
4755 rtx (*insn)(rtx, rtx);
4757 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4759 if (<X87MODEF:MODE>mode == SFmode)
4760 insn = gen_truncxfsf2;
4761 else if (<X87MODEF:MODE>mode == DFmode)
4762 insn = gen_truncxfdf2;
4766 emit_insn (insn (operands[0], reg));
4771 ;; Pre-reload splitter to add memory clobber to the pattern.
4772 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4773 [(set (match_operand:X87MODEF 0 "register_operand" "")
4774 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4776 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4777 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4778 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4779 || TARGET_MIX_SSE_I387))
4780 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4781 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4782 && ((<SWI48x:MODE>mode == SImode
4783 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4784 && optimize_function_for_speed_p (cfun)
4785 && flag_trapping_math)
4786 || !(TARGET_INTER_UNIT_CONVERSIONS
4787 || optimize_function_for_size_p (cfun)))))
4788 && can_create_pseudo_p ()"
4791 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4792 (clobber (match_dup 2))])]
4794 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4796 /* Avoid store forwarding (partial memory) stall penalty
4797 by passing DImode value through XMM registers. */
4798 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4799 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4800 && optimize_function_for_speed_p (cfun))
4802 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4809 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4810 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4812 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4813 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4814 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4815 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4817 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4818 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4819 (set_attr "unit" "*,i387,*,*,*")
4820 (set_attr "athlon_decode" "*,*,double,direct,double")
4821 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4822 (set_attr "bdver1_decode" "*,*,double,direct,double")
4823 (set_attr "fp_int_src" "true")])
4825 (define_insn "*floatsi<mode>2_vector_mixed"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4827 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4828 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4829 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4833 [(set_attr "type" "fmov,sseicvt")
4834 (set_attr "mode" "<MODE>,<ssevecmode>")
4835 (set_attr "unit" "i387,*")
4836 (set_attr "athlon_decode" "*,direct")
4837 (set_attr "amdfam10_decode" "*,double")
4838 (set_attr "bdver1_decode" "*,direct")
4839 (set_attr "fp_int_src" "true")])
4841 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4842 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4844 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4845 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4846 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4847 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4849 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4850 (set_attr "mode" "<MODEF:MODE>")
4851 (set_attr "unit" "*,i387,*,*")
4852 (set_attr "athlon_decode" "*,*,double,direct")
4853 (set_attr "amdfam10_decode" "*,*,vector,double")
4854 (set_attr "bdver1_decode" "*,*,double,direct")
4855 (set_attr "fp_int_src" "true")])
4858 [(set (match_operand:MODEF 0 "register_operand" "")
4859 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4860 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4861 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4862 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4863 && TARGET_INTER_UNIT_CONVERSIONS
4865 && (SSE_REG_P (operands[0])
4866 || (GET_CODE (operands[0]) == SUBREG
4867 && SSE_REG_P (operands[0])))"
4868 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4871 [(set (match_operand:MODEF 0 "register_operand" "")
4872 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4873 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4874 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4875 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4876 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4878 && (SSE_REG_P (operands[0])
4879 || (GET_CODE (operands[0]) == SUBREG
4880 && SSE_REG_P (operands[0])))"
4881 [(set (match_dup 2) (match_dup 1))
4882 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4884 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4885 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4887 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4888 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4889 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4890 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4893 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4894 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4895 [(set_attr "type" "fmov,sseicvt,sseicvt")
4896 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4897 (set_attr "mode" "<MODEF:MODE>")
4898 (set (attr "prefix_rex")
4900 (and (eq_attr "prefix" "maybe_vex")
4901 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4903 (const_string "*")))
4904 (set_attr "unit" "i387,*,*")
4905 (set_attr "athlon_decode" "*,double,direct")
4906 (set_attr "amdfam10_decode" "*,vector,double")
4907 (set_attr "bdver1_decode" "*,double,direct")
4908 (set_attr "fp_int_src" "true")])
4910 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4911 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4913 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4914 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4915 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4916 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4919 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4920 [(set_attr "type" "fmov,sseicvt")
4921 (set_attr "prefix" "orig,maybe_vex")
4922 (set_attr "mode" "<MODEF:MODE>")
4923 (set (attr "prefix_rex")
4925 (and (eq_attr "prefix" "maybe_vex")
4926 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4928 (const_string "*")))
4929 (set_attr "athlon_decode" "*,direct")
4930 (set_attr "amdfam10_decode" "*,double")
4931 (set_attr "bdver1_decode" "*,direct")
4932 (set_attr "fp_int_src" "true")])
4934 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4935 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4937 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4938 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4939 "TARGET_SSE2 && TARGET_SSE_MATH
4940 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4942 [(set_attr "type" "sseicvt")
4943 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4944 (set_attr "athlon_decode" "double,direct,double")
4945 (set_attr "amdfam10_decode" "vector,double,double")
4946 (set_attr "bdver1_decode" "double,direct,double")
4947 (set_attr "fp_int_src" "true")])
4949 (define_insn "*floatsi<mode>2_vector_sse"
4950 [(set (match_operand:MODEF 0 "register_operand" "=x")
4951 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4952 "TARGET_SSE2 && TARGET_SSE_MATH
4953 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4955 [(set_attr "type" "sseicvt")
4956 (set_attr "mode" "<MODE>")
4957 (set_attr "athlon_decode" "direct")
4958 (set_attr "amdfam10_decode" "double")
4959 (set_attr "bdver1_decode" "direct")
4960 (set_attr "fp_int_src" "true")])
4963 [(set (match_operand:MODEF 0 "register_operand" "")
4964 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4965 (clobber (match_operand:SI 2 "memory_operand" ""))]
4966 "TARGET_SSE2 && TARGET_SSE_MATH
4967 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4969 && (SSE_REG_P (operands[0])
4970 || (GET_CODE (operands[0]) == SUBREG
4971 && SSE_REG_P (operands[0])))"
4974 rtx op1 = operands[1];
4976 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4978 if (GET_CODE (op1) == SUBREG)
4979 op1 = SUBREG_REG (op1);
4981 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4983 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4984 emit_insn (gen_sse2_loadld (operands[4],
4985 CONST0_RTX (V4SImode), operands[1]));
4987 /* We can ignore possible trapping value in the
4988 high part of SSE register for non-trapping math. */
4989 else if (SSE_REG_P (op1) && !flag_trapping_math)
4990 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4993 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4994 emit_move_insn (operands[2], operands[1]);
4995 emit_insn (gen_sse2_loadld (operands[4],
4996 CONST0_RTX (V4SImode), operands[2]));
4999 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5004 [(set (match_operand:MODEF 0 "register_operand" "")
5005 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5006 (clobber (match_operand:SI 2 "memory_operand" ""))]
5007 "TARGET_SSE2 && TARGET_SSE_MATH
5008 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5010 && (SSE_REG_P (operands[0])
5011 || (GET_CODE (operands[0]) == SUBREG
5012 && SSE_REG_P (operands[0])))"
5015 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5017 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5019 emit_insn (gen_sse2_loadld (operands[4],
5020 CONST0_RTX (V4SImode), operands[1]));
5022 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5027 [(set (match_operand:MODEF 0 "register_operand" "")
5028 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5029 "TARGET_SSE2 && TARGET_SSE_MATH
5030 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5032 && (SSE_REG_P (operands[0])
5033 || (GET_CODE (operands[0]) == SUBREG
5034 && SSE_REG_P (operands[0])))"
5037 rtx op1 = operands[1];
5039 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5041 if (GET_CODE (op1) == SUBREG)
5042 op1 = SUBREG_REG (op1);
5044 if (GENERAL_REG_P (op1))
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5047 if (TARGET_INTER_UNIT_MOVES)
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[1]));
5052 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5054 emit_insn (gen_sse2_loadld (operands[4],
5055 CONST0_RTX (V4SImode), operands[5]));
5056 ix86_free_from_memory (GET_MODE (operands[1]));
5059 /* We can ignore possible trapping value in the
5060 high part of SSE register for non-trapping math. */
5061 else if (SSE_REG_P (op1) && !flag_trapping_math)
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5066 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5071 [(set (match_operand:MODEF 0 "register_operand" "")
5072 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5073 "TARGET_SSE2 && TARGET_SSE_MATH
5074 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5076 && (SSE_REG_P (operands[0])
5077 || (GET_CODE (operands[0]) == SUBREG
5078 && SSE_REG_P (operands[0])))"
5081 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5083 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5085 emit_insn (gen_sse2_loadld (operands[4],
5086 CONST0_RTX (V4SImode), operands[1]));
5088 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5092 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5093 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5095 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5096 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5097 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5098 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5100 [(set_attr "type" "sseicvt")
5101 (set_attr "mode" "<MODEF:MODE>")
5102 (set_attr "athlon_decode" "double,direct")
5103 (set_attr "amdfam10_decode" "vector,double")
5104 (set_attr "bdver1_decode" "double,direct")
5105 (set_attr "fp_int_src" "true")])
5107 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5108 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5110 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5111 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5112 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5113 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5114 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5115 [(set_attr "type" "sseicvt")
5116 (set_attr "prefix" "maybe_vex")
5117 (set_attr "mode" "<MODEF:MODE>")
5118 (set (attr "prefix_rex")
5120 (and (eq_attr "prefix" "maybe_vex")
5121 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5123 (const_string "*")))
5124 (set_attr "athlon_decode" "double,direct")
5125 (set_attr "amdfam10_decode" "vector,double")
5126 (set_attr "bdver1_decode" "double,direct")
5127 (set_attr "fp_int_src" "true")])
5130 [(set (match_operand:MODEF 0 "register_operand" "")
5131 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5132 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5133 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5134 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5135 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5137 && (SSE_REG_P (operands[0])
5138 || (GET_CODE (operands[0]) == SUBREG
5139 && SSE_REG_P (operands[0])))"
5140 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5142 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5143 [(set (match_operand:MODEF 0 "register_operand" "=x")
5145 (match_operand:SWI48x 1 "memory_operand" "m")))]
5146 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5147 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5148 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5149 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5150 [(set_attr "type" "sseicvt")
5151 (set_attr "prefix" "maybe_vex")
5152 (set_attr "mode" "<MODEF:MODE>")
5153 (set (attr "prefix_rex")
5155 (and (eq_attr "prefix" "maybe_vex")
5156 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5158 (const_string "*")))
5159 (set_attr "athlon_decode" "direct")
5160 (set_attr "amdfam10_decode" "double")
5161 (set_attr "bdver1_decode" "direct")
5162 (set_attr "fp_int_src" "true")])
5165 [(set (match_operand:MODEF 0 "register_operand" "")
5166 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5167 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5168 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5169 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5170 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5172 && (SSE_REG_P (operands[0])
5173 || (GET_CODE (operands[0]) == SUBREG
5174 && SSE_REG_P (operands[0])))"
5175 [(set (match_dup 2) (match_dup 1))
5176 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5179 [(set (match_operand:MODEF 0 "register_operand" "")
5180 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5181 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5182 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5183 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5185 && (SSE_REG_P (operands[0])
5186 || (GET_CODE (operands[0]) == SUBREG
5187 && SSE_REG_P (operands[0])))"
5188 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5190 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5191 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5193 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5194 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5196 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5200 [(set_attr "type" "fmov,multi")
5201 (set_attr "mode" "<X87MODEF:MODE>")
5202 (set_attr "unit" "*,i387")
5203 (set_attr "fp_int_src" "true")])
5205 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5206 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5208 (match_operand:SWI48x 1 "memory_operand" "m")))]
5210 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5212 [(set_attr "type" "fmov")
5213 (set_attr "mode" "<X87MODEF:MODE>")
5214 (set_attr "fp_int_src" "true")])
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 2) (match_dup 1))
5224 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5227 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5228 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5229 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5231 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5232 && reload_completed"
5233 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5235 ;; Avoid store forwarding (partial memory) stall penalty
5236 ;; by passing DImode value through XMM registers. */
5238 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5239 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5241 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5242 (clobber (match_scratch:V4SI 3 "=X,x"))
5243 (clobber (match_scratch:V4SI 4 "=X,x"))
5244 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5245 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5246 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5247 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5249 [(set_attr "type" "multi")
5250 (set_attr "mode" "<X87MODEF:MODE>")
5251 (set_attr "unit" "i387")
5252 (set_attr "fp_int_src" "true")])
5255 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5256 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5257 (clobber (match_scratch:V4SI 3 ""))
5258 (clobber (match_scratch:V4SI 4 ""))
5259 (clobber (match_operand:DI 2 "memory_operand" ""))]
5260 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5261 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5262 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5263 && reload_completed"
5264 [(set (match_dup 2) (match_dup 3))
5265 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5267 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5268 Assemble the 64-bit DImode value in an xmm register. */
5269 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5270 gen_rtx_SUBREG (SImode, operands[1], 0)));
5271 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5272 gen_rtx_SUBREG (SImode, operands[1], 4)));
5273 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5276 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5280 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5281 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5282 (clobber (match_scratch:V4SI 3 ""))
5283 (clobber (match_scratch:V4SI 4 ""))
5284 (clobber (match_operand:DI 2 "memory_operand" ""))]
5285 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5287 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5288 && reload_completed"
5289 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5291 ;; Avoid store forwarding (partial memory) stall penalty by extending
5292 ;; SImode value to DImode through XMM register instead of pushing two
5293 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5294 ;; targets benefit from this optimization. Also note that fild
5295 ;; loads from memory only.
5297 (define_insn "*floatunssi<mode>2_1"
5298 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5299 (unsigned_float:X87MODEF
5300 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5301 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5302 (clobber (match_scratch:SI 3 "=X,x"))]
5304 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 [(set_attr "type" "multi")
5308 (set_attr "mode" "<MODE>")])
5311 [(set (match_operand:X87MODEF 0 "register_operand" "")
5312 (unsigned_float:X87MODEF
5313 (match_operand:SI 1 "register_operand" "")))
5314 (clobber (match_operand:DI 2 "memory_operand" ""))
5315 (clobber (match_scratch:SI 3 ""))]
5317 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5319 && reload_completed"
5320 [(set (match_dup 2) (match_dup 1))
5322 (float:X87MODEF (match_dup 2)))]
5323 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "memory_operand" "")))
5329 (clobber (match_operand:DI 2 "memory_operand" ""))
5330 (clobber (match_scratch:SI 3 ""))]
5332 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 && reload_completed"
5335 [(set (match_dup 2) (match_dup 3))
5337 (float:X87MODEF (match_dup 2)))]
5339 emit_move_insn (operands[3], operands[1]);
5340 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5343 (define_expand "floatunssi<mode>2"
5345 [(set (match_operand:X87MODEF 0 "register_operand" "")
5346 (unsigned_float:X87MODEF
5347 (match_operand:SI 1 "nonimmediate_operand" "")))
5348 (clobber (match_dup 2))
5349 (clobber (match_scratch:SI 3 ""))])]
5351 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5353 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5355 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5357 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5362 enum ix86_stack_slot slot = (virtuals_instantiated
5365 operands[2] = assign_386_stack_local (DImode, slot);
5369 (define_expand "floatunsdisf2"
5370 [(use (match_operand:SF 0 "register_operand" ""))
5371 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5372 "TARGET_64BIT && TARGET_SSE_MATH"
5373 "x86_emit_floatuns (operands); DONE;")
5375 (define_expand "floatunsdidf2"
5376 [(use (match_operand:DF 0 "register_operand" ""))
5377 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5378 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5379 && TARGET_SSE2 && TARGET_SSE_MATH"
5382 x86_emit_floatuns (operands);
5384 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5390 (define_expand "add<mode>3"
5391 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5392 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5393 (match_operand:SDWIM 2 "<general_operand>" "")))]
5395 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5397 (define_insn_and_split "*add<dwi>3_doubleword"
5398 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5400 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5401 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5402 (clobber (reg:CC FLAGS_REG))]
5403 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5406 [(parallel [(set (reg:CC FLAGS_REG)
5407 (unspec:CC [(match_dup 1) (match_dup 2)]
5410 (plus:DWIH (match_dup 1) (match_dup 2)))])
5411 (parallel [(set (match_dup 3)
5415 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5417 (clobber (reg:CC FLAGS_REG))])]
5418 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5420 (define_insn "*add<mode>3_cc"
5421 [(set (reg:CC FLAGS_REG)
5423 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5424 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5426 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5427 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5428 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5429 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5430 [(set_attr "type" "alu")
5431 (set_attr "mode" "<MODE>")])
5433 (define_insn "addqi3_cc"
5434 [(set (reg:CC FLAGS_REG)
5436 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5437 (match_operand:QI 2 "general_operand" "qn,qm")]
5439 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5440 (plus:QI (match_dup 1) (match_dup 2)))]
5441 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5442 "add{b}\t{%2, %0|%0, %2}"
5443 [(set_attr "type" "alu")
5444 (set_attr "mode" "QI")])
5446 (define_insn "*lea_1"
5447 [(set (match_operand:SWI48 0 "register_operand" "=r")
5448 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5450 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5451 [(set_attr "type" "lea")
5452 (set_attr "mode" "<MODE>")])
5454 (define_insn "*lea_1_zext"
5455 [(set (match_operand:DI 0 "register_operand" "=r")
5457 (match_operand:SI 1 "lea_address_operand" "p")))]
5459 "lea{l}\t{%a1, %k0|%k0, %a1}"
5460 [(set_attr "type" "lea")
5461 (set_attr "mode" "SI")])
5463 (define_insn "*lea_2"
5464 [(set (match_operand:SI 0 "register_operand" "=r")
5465 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5467 "lea{l}\t{%a1, %0|%0, %a1}"
5468 [(set_attr "type" "lea")
5469 (set_attr "mode" "SI")])
5471 (define_insn "*lea_2_zext"
5472 [(set (match_operand:DI 0 "register_operand" "=r")
5474 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
5476 "lea{l}\t{%a1, %k0|%k0, %a1}"
5477 [(set_attr "type" "lea")
5478 (set_attr "mode" "SI")])
5480 (define_insn "*add<mode>_1"
5481 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5483 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5484 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5488 switch (get_attr_type (insn))
5494 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5495 if (operands[2] == const1_rtx)
5496 return "inc{<imodesuffix>}\t%0";
5499 gcc_assert (operands[2] == constm1_rtx);
5500 return "dec{<imodesuffix>}\t%0";
5504 /* For most processors, ADD is faster than LEA. This alternative
5505 was added to use ADD as much as possible. */
5506 if (which_alternative == 2)
5509 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5512 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5513 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5514 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5516 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5520 (cond [(eq_attr "alternative" "3")
5521 (const_string "lea")
5522 (match_operand:SWI48 2 "incdec_operand" "")
5523 (const_string "incdec")
5525 (const_string "alu")))
5526 (set (attr "length_immediate")
5528 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5530 (const_string "*")))
5531 (set_attr "mode" "<MODE>")])
5533 ;; It may seem that nonimmediate operand is proper one for operand 1.
5534 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5535 ;; we take care in ix86_binary_operator_ok to not allow two memory
5536 ;; operands so proper swapping will be done in reload. This allow
5537 ;; patterns constructed from addsi_1 to match.
5539 (define_insn "addsi_1_zext"
5540 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5542 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5543 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5544 (clobber (reg:CC FLAGS_REG))]
5545 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5547 switch (get_attr_type (insn))
5553 if (operands[2] == const1_rtx)
5554 return "inc{l}\t%k0";
5557 gcc_assert (operands[2] == constm1_rtx);
5558 return "dec{l}\t%k0";
5562 /* For most processors, ADD is faster than LEA. This alternative
5563 was added to use ADD as much as possible. */
5564 if (which_alternative == 1)
5567 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5570 if (x86_maybe_negate_const_int (&operands[2], SImode))
5571 return "sub{l}\t{%2, %k0|%k0, %2}";
5573 return "add{l}\t{%2, %k0|%k0, %2}";
5577 (cond [(eq_attr "alternative" "2")
5578 (const_string "lea")
5579 (match_operand:SI 2 "incdec_operand" "")
5580 (const_string "incdec")
5582 (const_string "alu")))
5583 (set (attr "length_immediate")
5585 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5587 (const_string "*")))
5588 (set_attr "mode" "SI")])
5590 (define_insn "*addhi_1"
5591 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5592 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5593 (match_operand:HI 2 "general_operand" "rn,rm")))
5594 (clobber (reg:CC FLAGS_REG))]
5595 "TARGET_PARTIAL_REG_STALL
5596 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5598 switch (get_attr_type (insn))
5601 if (operands[2] == const1_rtx)
5602 return "inc{w}\t%0";
5605 gcc_assert (operands[2] == constm1_rtx);
5606 return "dec{w}\t%0";
5610 if (x86_maybe_negate_const_int (&operands[2], HImode))
5611 return "sub{w}\t{%2, %0|%0, %2}";
5613 return "add{w}\t{%2, %0|%0, %2}";
5617 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5618 (const_string "incdec")
5619 (const_string "alu")))
5620 (set (attr "length_immediate")
5622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5624 (const_string "*")))
5625 (set_attr "mode" "HI")])
5627 (define_insn "*addhi_1_lea"
5628 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5629 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5630 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "!TARGET_PARTIAL_REG_STALL
5633 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5635 switch (get_attr_type (insn))
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return "inc{w}\t%0";
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return "dec{w}\t%0";
5651 /* For most processors, ADD is faster than LEA. This alternative
5652 was added to use ADD as much as possible. */
5653 if (which_alternative == 2)
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], HImode))
5661 return "sub{w}\t{%2, %0|%0, %2}";
5663 return "add{w}\t{%2, %0|%0, %2}";
5667 (cond [(eq_attr "alternative" "3")
5668 (const_string "lea")
5669 (match_operand:HI 2 "incdec_operand" "")
5670 (const_string "incdec")
5672 (const_string "alu")))
5673 (set (attr "length_immediate")
5675 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5677 (const_string "*")))
5678 (set_attr "mode" "HI,HI,HI,SI")])
5680 ;; %%% Potential partial reg stall on alternative 2. What to do?
5681 (define_insn "*addqi_1"
5682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5683 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5684 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5685 (clobber (reg:CC FLAGS_REG))]
5686 "TARGET_PARTIAL_REG_STALL
5687 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5689 int widen = (which_alternative == 2);
5690 switch (get_attr_type (insn))
5693 if (operands[2] == const1_rtx)
5694 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5697 gcc_assert (operands[2] == constm1_rtx);
5698 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5702 if (x86_maybe_negate_const_int (&operands[2], QImode))
5705 return "sub{l}\t{%2, %k0|%k0, %2}";
5707 return "sub{b}\t{%2, %0|%0, %2}";
5710 return "add{l}\t{%k2, %k0|%k0, %k2}";
5712 return "add{b}\t{%2, %0|%0, %2}";
5716 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5717 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723 (const_string "*")))
5724 (set_attr "mode" "QI,QI,SI")])
5726 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5727 (define_insn "*addqi_1_lea"
5728 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5729 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5730 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "!TARGET_PARTIAL_REG_STALL
5733 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5735 int widen = (which_alternative == 3 || which_alternative == 4);
5737 switch (get_attr_type (insn))
5743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744 if (operands[2] == const1_rtx)
5745 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5748 gcc_assert (operands[2] == constm1_rtx);
5749 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5753 /* For most processors, ADD is faster than LEA. These alternatives
5754 were added to use ADD as much as possible. */
5755 if (which_alternative == 2 || which_alternative == 4)
5758 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5762 if (x86_maybe_negate_const_int (&operands[2], QImode))
5765 return "sub{l}\t{%2, %k0|%k0, %2}";
5767 return "sub{b}\t{%2, %0|%0, %2}";
5770 return "add{l}\t{%k2, %k0|%k0, %k2}";
5772 return "add{b}\t{%2, %0|%0, %2}";
5776 (cond [(eq_attr "alternative" "5")
5777 (const_string "lea")
5778 (match_operand:QI 2 "incdec_operand" "")
5779 (const_string "incdec")
5781 (const_string "alu")))
5782 (set (attr "length_immediate")
5784 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5786 (const_string "*")))
5787 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5789 (define_insn "*addqi_1_slp"
5790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5791 (plus:QI (match_dup 0)
5792 (match_operand:QI 1 "general_operand" "qn,qnm")))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5797 switch (get_attr_type (insn))
5800 if (operands[1] == const1_rtx)
5801 return "inc{b}\t%0";
5804 gcc_assert (operands[1] == constm1_rtx);
5805 return "dec{b}\t%0";
5809 if (x86_maybe_negate_const_int (&operands[1], QImode))
5810 return "sub{b}\t{%1, %0|%0, %1}";
5812 return "add{b}\t{%1, %0|%0, %1}";
5816 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5817 (const_string "incdec")
5818 (const_string "alu1")))
5819 (set (attr "memory")
5820 (if_then_else (match_operand 1 "memory_operand" "")
5821 (const_string "load")
5822 (const_string "none")))
5823 (set_attr "mode" "QI")])
5825 ;; Convert add to the lea pattern to avoid flags dependency.
5827 [(set (match_operand:SWI 0 "register_operand" "")
5828 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5829 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5830 (clobber (reg:CC FLAGS_REG))]
5831 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5834 enum machine_mode mode = <MODE>mode;
5837 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5840 operands[0] = gen_lowpart (mode, operands[0]);
5841 operands[1] = gen_lowpart (mode, operands[1]);
5842 operands[2] = gen_lowpart (mode, operands[2]);
5845 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5847 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5851 ;; Convert add to the lea pattern to avoid flags dependency.
5853 [(set (match_operand:DI 0 "register_operand" "")
5855 (plus:SI (match_operand:SI 1 "register_operand" "")
5856 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5860 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5862 (define_insn "*add<mode>_2"
5863 [(set (reg FLAGS_REG)
5866 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5869 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5870 (plus:SWI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{<imodesuffix>}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{<imodesuffix>}\t%0";
5886 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5887 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5889 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5893 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5900 (const_string "*")))
5901 (set_attr "mode" "<MODE>")])
5903 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5904 (define_insn "*addsi_2_zext"
5905 [(set (reg FLAGS_REG)
5907 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5908 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5910 (set (match_operand:DI 0 "register_operand" "=r")
5911 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5912 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5913 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5915 switch (get_attr_type (insn))
5918 if (operands[2] == const1_rtx)
5919 return "inc{l}\t%k0";
5922 gcc_assert (operands[2] == constm1_rtx);
5923 return "dec{l}\t%k0";
5927 if (x86_maybe_negate_const_int (&operands[2], SImode))
5928 return "sub{l}\t{%2, %k0|%k0, %2}";
5930 return "add{l}\t{%2, %k0|%k0, %2}";
5934 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5935 (const_string "incdec")
5936 (const_string "alu")))
5937 (set (attr "length_immediate")
5939 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5941 (const_string "*")))
5942 (set_attr "mode" "SI")])
5944 (define_insn "*add<mode>_3"
5945 [(set (reg FLAGS_REG)
5947 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5948 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5949 (clobber (match_scratch:SWI 0 "=<r>"))]
5950 "ix86_match_ccmode (insn, CCZmode)
5951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5953 switch (get_attr_type (insn))
5956 if (operands[2] == const1_rtx)
5957 return "inc{<imodesuffix>}\t%0";
5960 gcc_assert (operands[2] == constm1_rtx);
5961 return "dec{<imodesuffix>}\t%0";
5965 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5966 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5968 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5972 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5973 (const_string "incdec")
5974 (const_string "alu")))
5975 (set (attr "length_immediate")
5977 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5979 (const_string "*")))
5980 (set_attr "mode" "<MODE>")])
5982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5983 (define_insn "*addsi_3_zext"
5984 [(set (reg FLAGS_REG)
5986 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5987 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5988 (set (match_operand:DI 0 "register_operand" "=r")
5989 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5990 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5991 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5993 switch (get_attr_type (insn))
5996 if (operands[2] == const1_rtx)
5997 return "inc{l}\t%k0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{l}\t%k0";
6005 if (x86_maybe_negate_const_int (&operands[2], SImode))
6006 return "sub{l}\t{%2, %k0|%k0, %2}";
6008 return "add{l}\t{%2, %k0|%k0, %2}";
6012 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6013 (const_string "incdec")
6014 (const_string "alu")))
6015 (set (attr "length_immediate")
6017 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6019 (const_string "*")))
6020 (set_attr "mode" "SI")])
6022 ; For comparisons against 1, -1 and 128, we may generate better code
6023 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6024 ; is matched then. We can't accept general immediate, because for
6025 ; case of overflows, the result is messed up.
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6029 (define_insn "*adddi_4"
6030 [(set (reg FLAGS_REG)
6032 (match_operand:DI 1 "nonimmediate_operand" "0")
6033 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6034 (clobber (match_scratch:DI 0 "=rm"))]
6036 && ix86_match_ccmode (insn, CCGCmode)"
6038 switch (get_attr_type (insn))
6041 if (operands[2] == constm1_rtx)
6042 return "inc{q}\t%0";
6045 gcc_assert (operands[2] == const1_rtx);
6046 return "dec{q}\t%0";
6050 if (x86_maybe_negate_const_int (&operands[2], DImode))
6051 return "add{q}\t{%2, %0|%0, %2}";
6053 return "sub{q}\t{%2, %0|%0, %2}";
6057 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6058 (const_string "incdec")
6059 (const_string "alu")))
6060 (set (attr "length_immediate")
6062 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6064 (const_string "*")))
6065 (set_attr "mode" "DI")])
6067 ; For comparisons against 1, -1 and 128, we may generate better code
6068 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6069 ; is matched then. We can't accept general immediate, because for
6070 ; case of overflows, the result is messed up.
6071 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6072 ; only for comparisons not depending on it.
6074 (define_insn "*add<mode>_4"
6075 [(set (reg FLAGS_REG)
6077 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6078 (match_operand:SWI124 2 "const_int_operand" "n")))
6079 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6080 "ix86_match_ccmode (insn, CCGCmode)"
6082 switch (get_attr_type (insn))
6085 if (operands[2] == constm1_rtx)
6086 return "inc{<imodesuffix>}\t%0";
6089 gcc_assert (operands[2] == const1_rtx);
6090 return "dec{<imodesuffix>}\t%0";
6094 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6095 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6097 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6101 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set (attr "length_immediate")
6106 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6108 (const_string "*")))
6109 (set_attr "mode" "<MODE>")])
6111 (define_insn "*add<mode>_5"
6112 [(set (reg FLAGS_REG)
6115 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6116 (match_operand:SWI 2 "<general_operand>" "<g>"))
6118 (clobber (match_scratch:SWI 0 "=<r>"))]
6119 "ix86_match_ccmode (insn, CCGOCmode)
6120 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6122 switch (get_attr_type (insn))
6125 if (operands[2] == const1_rtx)
6126 return "inc{<imodesuffix>}\t%0";
6129 gcc_assert (operands[2] == constm1_rtx);
6130 return "dec{<imodesuffix>}\t%0";
6134 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6135 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6141 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6142 (const_string "incdec")
6143 (const_string "alu")))
6144 (set (attr "length_immediate")
6146 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6148 (const_string "*")))
6149 (set_attr "mode" "<MODE>")])
6151 (define_insn "*addqi_ext_1_rex64"
6152 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6157 (match_operand 1 "ext_register_operand" "0")
6160 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6161 (clobber (reg:CC FLAGS_REG))]
6164 switch (get_attr_type (insn))
6167 if (operands[2] == const1_rtx)
6168 return "inc{b}\t%h0";
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{b}\t%h0";
6176 return "add{b}\t{%2, %h0|%h0, %2}";
6180 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set_attr "modrm" "1")
6184 (set_attr "mode" "QI")])
6186 (define_insn "addqi_ext_1"
6187 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6192 (match_operand 1 "ext_register_operand" "0")
6195 (match_operand:QI 2 "general_operand" "Qmn")))
6196 (clobber (reg:CC FLAGS_REG))]
6199 switch (get_attr_type (insn))
6202 if (operands[2] == const1_rtx)
6203 return "inc{b}\t%h0";
6206 gcc_assert (operands[2] == constm1_rtx);
6207 return "dec{b}\t%h0";
6211 return "add{b}\t{%2, %h0|%h0, %2}";
6215 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "modrm" "1")
6219 (set_attr "mode" "QI")])
6221 (define_insn "*addqi_ext_2"
6222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6227 (match_operand 1 "ext_register_operand" "%0")
6231 (match_operand 2 "ext_register_operand" "Q")
6234 (clobber (reg:CC FLAGS_REG))]
6236 "add{b}\t{%h2, %h0|%h0, %h2}"
6237 [(set_attr "type" "alu")
6238 (set_attr "mode" "QI")])
6240 ;; The lea patterns for modes less than 32 bits need to be matched by
6241 ;; several insns converted to real lea by splitters.
6243 (define_insn_and_split "*lea_general_1"
6244 [(set (match_operand 0 "register_operand" "=r")
6245 (plus (plus (match_operand 1 "index_register_operand" "l")
6246 (match_operand 2 "register_operand" "r"))
6247 (match_operand 3 "immediate_operand" "i")))]
6248 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6251 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6252 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6253 || GET_MODE (operands[3]) == VOIDmode)"
6255 "&& reload_completed"
6258 enum machine_mode mode = SImode;
6261 operands[0] = gen_lowpart (mode, operands[0]);
6262 operands[1] = gen_lowpart (mode, operands[1]);
6263 operands[2] = gen_lowpart (mode, operands[2]);
6264 operands[3] = gen_lowpart (mode, operands[3]);
6266 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6269 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6272 [(set_attr "type" "lea")
6273 (set_attr "mode" "SI")])
6275 (define_insn_and_split "*lea_general_2"
6276 [(set (match_operand 0 "register_operand" "=r")
6277 (plus (mult (match_operand 1 "index_register_operand" "l")
6278 (match_operand 2 "const248_operand" "n"))
6279 (match_operand 3 "nonmemory_operand" "ri")))]
6280 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6281 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6282 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6283 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6284 || GET_MODE (operands[3]) == VOIDmode)"
6286 "&& reload_completed"
6289 enum machine_mode mode = SImode;
6292 operands[0] = gen_lowpart (mode, operands[0]);
6293 operands[1] = gen_lowpart (mode, operands[1]);
6294 operands[3] = gen_lowpart (mode, operands[3]);
6296 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6299 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6302 [(set_attr "type" "lea")
6303 (set_attr "mode" "SI")])
6305 (define_insn_and_split "*lea_general_3"
6306 [(set (match_operand 0 "register_operand" "=r")
6307 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6308 (match_operand 2 "const248_operand" "n"))
6309 (match_operand 3 "register_operand" "r"))
6310 (match_operand 4 "immediate_operand" "i")))]
6311 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6312 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6313 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6314 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6316 "&& reload_completed"
6319 enum machine_mode mode = SImode;
6322 operands[0] = gen_lowpart (mode, operands[0]);
6323 operands[1] = gen_lowpart (mode, operands[1]);
6324 operands[3] = gen_lowpart (mode, operands[3]);
6325 operands[4] = gen_lowpart (mode, operands[4]);
6327 pat = gen_rtx_PLUS (mode,
6329 gen_rtx_MULT (mode, operands[1],
6334 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6337 [(set_attr "type" "lea")
6338 (set_attr "mode" "SI")])
6340 (define_insn_and_split "*lea_general_4"
6341 [(set (match_operand 0 "register_operand" "=r")
6343 (match_operand 1 "index_register_operand" "l")
6344 (match_operand 2 "const_int_operand" "n"))
6345 (match_operand 3 "const_int_operand" "n")))]
6346 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6347 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6348 || GET_MODE (operands[0]) == SImode
6349 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6350 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6351 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6352 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6353 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6355 "&& reload_completed"
6358 enum machine_mode mode = GET_MODE (operands[0]);
6361 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6364 operands[0] = gen_lowpart (mode, operands[0]);
6365 operands[1] = gen_lowpart (mode, operands[1]);
6368 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6370 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6371 INTVAL (operands[3]));
6373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6376 [(set_attr "type" "lea")
6378 (if_then_else (match_operand:DI 0 "" "")
6380 (const_string "SI")))])
6382 ;; Subtract instructions
6384 (define_expand "sub<mode>3"
6385 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6386 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6387 (match_operand:SDWIM 2 "<general_operand>" "")))]
6389 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6391 (define_insn_and_split "*sub<dwi>3_doubleword"
6392 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6394 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6395 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6396 (clobber (reg:CC FLAGS_REG))]
6397 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6400 [(parallel [(set (reg:CC FLAGS_REG)
6401 (compare:CC (match_dup 1) (match_dup 2)))
6403 (minus:DWIH (match_dup 1) (match_dup 2)))])
6404 (parallel [(set (match_dup 3)
6408 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6410 (clobber (reg:CC FLAGS_REG))])]
6411 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6413 (define_insn "*sub<mode>_1"
6414 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6416 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6417 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6418 (clobber (reg:CC FLAGS_REG))]
6419 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6420 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6421 [(set_attr "type" "alu")
6422 (set_attr "mode" "<MODE>")])
6424 (define_insn "*subsi_1_zext"
6425 [(set (match_operand:DI 0 "register_operand" "=r")
6427 (minus:SI (match_operand:SI 1 "register_operand" "0")
6428 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %k0|%k0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6435 (define_insn "*subqi_1_slp"
6436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6437 (minus:QI (match_dup 0)
6438 (match_operand:QI 1 "general_operand" "qn,qm")))
6439 (clobber (reg:CC FLAGS_REG))]
6440 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6442 "sub{b}\t{%1, %0|%0, %1}"
6443 [(set_attr "type" "alu1")
6444 (set_attr "mode" "QI")])
6446 (define_insn "*sub<mode>_2"
6447 [(set (reg FLAGS_REG)
6450 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6451 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6453 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6454 (minus:SWI (match_dup 1) (match_dup 2)))]
6455 "ix86_match_ccmode (insn, CCGOCmode)
6456 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6457 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6458 [(set_attr "type" "alu")
6459 (set_attr "mode" "<MODE>")])
6461 (define_insn "*subsi_2_zext"
6462 [(set (reg FLAGS_REG)
6464 (minus:SI (match_operand:SI 1 "register_operand" "0")
6465 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6467 (set (match_operand:DI 0 "register_operand" "=r")
6469 (minus:SI (match_dup 1)
6471 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6472 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6473 "sub{l}\t{%2, %k0|%k0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "mode" "SI")])
6477 (define_insn "*sub<mode>_3"
6478 [(set (reg FLAGS_REG)
6479 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6480 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6481 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6482 (minus:SWI (match_dup 1) (match_dup 2)))]
6483 "ix86_match_ccmode (insn, CCmode)
6484 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6485 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "mode" "<MODE>")])
6489 (define_insn "*subsi_3_zext"
6490 [(set (reg FLAGS_REG)
6491 (compare (match_operand:SI 1 "register_operand" "0")
6492 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6493 (set (match_operand:DI 0 "register_operand" "=r")
6495 (minus:SI (match_dup 1)
6497 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6498 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6499 "sub{l}\t{%2, %1|%1, %2}"
6500 [(set_attr "type" "alu")
6501 (set_attr "mode" "SI")])
6503 ;; Add with carry and subtract with borrow
6505 (define_expand "<plusminus_insn><mode>3_carry"
6507 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6509 (match_operand:SWI 1 "nonimmediate_operand" "")
6510 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6511 [(match_operand 3 "flags_reg_operand" "")
6513 (match_operand:SWI 2 "<general_operand>" ""))))
6514 (clobber (reg:CC FLAGS_REG))])]
6515 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6517 (define_insn "*<plusminus_insn><mode>3_carry"
6518 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6520 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6522 (match_operator 3 "ix86_carry_flag_operator"
6523 [(reg FLAGS_REG) (const_int 0)])
6524 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6525 (clobber (reg:CC FLAGS_REG))]
6526 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6527 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6528 [(set_attr "type" "alu")
6529 (set_attr "use_carry" "1")
6530 (set_attr "pent_pair" "pu")
6531 (set_attr "mode" "<MODE>")])
6533 (define_insn "*addsi3_carry_zext"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6536 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6537 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6538 [(reg FLAGS_REG) (const_int 0)])
6539 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6540 (clobber (reg:CC FLAGS_REG))]
6541 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6542 "adc{l}\t{%2, %k0|%k0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "use_carry" "1")
6545 (set_attr "pent_pair" "pu")
6546 (set_attr "mode" "SI")])
6548 (define_insn "*subsi3_carry_zext"
6549 [(set (match_operand:DI 0 "register_operand" "=r")
6551 (minus:SI (match_operand:SI 1 "register_operand" "0")
6552 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6553 [(reg FLAGS_REG) (const_int 0)])
6554 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6555 (clobber (reg:CC FLAGS_REG))]
6556 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6557 "sbb{l}\t{%2, %k0|%k0, %2}"
6558 [(set_attr "type" "alu")
6559 (set_attr "pent_pair" "pu")
6560 (set_attr "mode" "SI")])
6562 ;; Overflow setting add and subtract instructions
6564 (define_insn "*add<mode>3_cconly_overflow"
6565 [(set (reg:CCC FLAGS_REG)
6568 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6569 (match_operand:SWI 2 "<general_operand>" "<g>"))
6571 (clobber (match_scratch:SWI 0 "=<r>"))]
6572 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6573 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "mode" "<MODE>")])
6577 (define_insn "*sub<mode>3_cconly_overflow"
6578 [(set (reg:CCC FLAGS_REG)
6581 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6582 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6585 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6586 [(set_attr "type" "icmp")
6587 (set_attr "mode" "<MODE>")])
6589 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6590 [(set (reg:CCC FLAGS_REG)
6593 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6594 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6596 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6597 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6598 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6599 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6600 [(set_attr "type" "alu")
6601 (set_attr "mode" "<MODE>")])
6603 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6604 [(set (reg:CCC FLAGS_REG)
6607 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6608 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6610 (set (match_operand:DI 0 "register_operand" "=r")
6611 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6613 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "mode" "SI")])
6617 ;; The patterns that match these are at the end of this file.
6619 (define_expand "<plusminus_insn>xf3"
6620 [(set (match_operand:XF 0 "register_operand" "")
6622 (match_operand:XF 1 "register_operand" "")
6623 (match_operand:XF 2 "register_operand" "")))]
6626 (define_expand "<plusminus_insn><mode>3"
6627 [(set (match_operand:MODEF 0 "register_operand" "")
6629 (match_operand:MODEF 1 "register_operand" "")
6630 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6631 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6632 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6634 ;; Multiply instructions
6636 (define_expand "mul<mode>3"
6637 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6639 (match_operand:SWIM248 1 "register_operand" "")
6640 (match_operand:SWIM248 2 "<general_operand>" "")))
6641 (clobber (reg:CC FLAGS_REG))])])
6643 (define_expand "mulqi3"
6644 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6646 (match_operand:QI 1 "register_operand" "")
6647 (match_operand:QI 2 "nonimmediate_operand" "")))
6648 (clobber (reg:CC FLAGS_REG))])]
6649 "TARGET_QIMODE_MATH")
6652 ;; IMUL reg32/64, reg32/64, imm8 Direct
6653 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6654 ;; IMUL reg32/64, reg32/64, imm32 Direct
6655 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6656 ;; IMUL reg32/64, reg32/64 Direct
6657 ;; IMUL reg32/64, mem32/64 Direct
6659 ;; On BDVER1, all above IMULs use DirectPath
6661 (define_insn "*mul<mode>3_1"
6662 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6664 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6665 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6666 (clobber (reg:CC FLAGS_REG))]
6667 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6669 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6670 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6671 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6672 [(set_attr "type" "imul")
6673 (set_attr "prefix_0f" "0,0,1")
6674 (set (attr "athlon_decode")
6675 (cond [(eq_attr "cpu" "athlon")
6676 (const_string "vector")
6677 (eq_attr "alternative" "1")
6678 (const_string "vector")
6679 (and (eq_attr "alternative" "2")
6680 (match_operand 1 "memory_operand" ""))
6681 (const_string "vector")]
6682 (const_string "direct")))
6683 (set (attr "amdfam10_decode")
6684 (cond [(and (eq_attr "alternative" "0,1")
6685 (match_operand 1 "memory_operand" ""))
6686 (const_string "vector")]
6687 (const_string "direct")))
6688 (set_attr "bdver1_decode" "direct")
6689 (set_attr "mode" "<MODE>")])
6691 (define_insn "*mulsi3_1_zext"
6692 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6694 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6695 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6696 (clobber (reg:CC FLAGS_REG))]
6698 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6700 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6701 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6702 imul{l}\t{%2, %k0|%k0, %2}"
6703 [(set_attr "type" "imul")
6704 (set_attr "prefix_0f" "0,0,1")
6705 (set (attr "athlon_decode")
6706 (cond [(eq_attr "cpu" "athlon")
6707 (const_string "vector")
6708 (eq_attr "alternative" "1")
6709 (const_string "vector")
6710 (and (eq_attr "alternative" "2")
6711 (match_operand 1 "memory_operand" ""))
6712 (const_string "vector")]
6713 (const_string "direct")))
6714 (set (attr "amdfam10_decode")
6715 (cond [(and (eq_attr "alternative" "0,1")
6716 (match_operand 1 "memory_operand" ""))
6717 (const_string "vector")]
6718 (const_string "direct")))
6719 (set_attr "bdver1_decode" "direct")
6720 (set_attr "mode" "SI")])
6723 ;; IMUL reg16, reg16, imm8 VectorPath
6724 ;; IMUL reg16, mem16, imm8 VectorPath
6725 ;; IMUL reg16, reg16, imm16 VectorPath
6726 ;; IMUL reg16, mem16, imm16 VectorPath
6727 ;; IMUL reg16, reg16 Direct
6728 ;; IMUL reg16, mem16 Direct
6730 ;; On BDVER1, all HI MULs use DoublePath
6732 (define_insn "*mulhi3_1"
6733 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6734 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6735 (match_operand:HI 2 "general_operand" "K,n,mr")))
6736 (clobber (reg:CC FLAGS_REG))]
6738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6740 imul{w}\t{%2, %1, %0|%0, %1, %2}
6741 imul{w}\t{%2, %1, %0|%0, %1, %2}
6742 imul{w}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "imul")
6744 (set_attr "prefix_0f" "0,0,1")
6745 (set (attr "athlon_decode")
6746 (cond [(eq_attr "cpu" "athlon")
6747 (const_string "vector")
6748 (eq_attr "alternative" "1,2")
6749 (const_string "vector")]
6750 (const_string "direct")))
6751 (set (attr "amdfam10_decode")
6752 (cond [(eq_attr "alternative" "0,1")
6753 (const_string "vector")]
6754 (const_string "direct")))
6755 (set_attr "bdver1_decode" "double")
6756 (set_attr "mode" "HI")])
6758 ;;On AMDFAM10 and BDVER1
6762 (define_insn "*mulqi3_1"
6763 [(set (match_operand:QI 0 "register_operand" "=a")
6764 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6765 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6766 (clobber (reg:CC FLAGS_REG))]
6768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 [(set_attr "type" "imul")
6771 (set_attr "length_immediate" "0")
6772 (set (attr "athlon_decode")
6773 (if_then_else (eq_attr "cpu" "athlon")
6774 (const_string "vector")
6775 (const_string "direct")))
6776 (set_attr "amdfam10_decode" "direct")
6777 (set_attr "bdver1_decode" "direct")
6778 (set_attr "mode" "QI")])
6780 (define_expand "<u>mul<mode><dwi>3"
6781 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6784 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6786 (match_operand:DWIH 2 "register_operand" ""))))
6787 (clobber (reg:CC FLAGS_REG))])])
6789 (define_expand "<u>mulqihi3"
6790 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6793 (match_operand:QI 1 "nonimmediate_operand" ""))
6795 (match_operand:QI 2 "register_operand" ""))))
6796 (clobber (reg:CC FLAGS_REG))])]
6797 "TARGET_QIMODE_MATH")
6799 (define_insn "*<u>mul<mode><dwi>3_1"
6800 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6803 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6805 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6808 "<sgnprefix>mul{<imodesuffix>}\t%2"
6809 [(set_attr "type" "imul")
6810 (set_attr "length_immediate" "0")
6811 (set (attr "athlon_decode")
6812 (if_then_else (eq_attr "cpu" "athlon")
6813 (const_string "vector")
6814 (const_string "double")))
6815 (set_attr "amdfam10_decode" "double")
6816 (set_attr "bdver1_decode" "direct")
6817 (set_attr "mode" "<MODE>")])
6819 (define_insn "*<u>mulqihi3_1"
6820 [(set (match_operand:HI 0 "register_operand" "=a")
6823 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6825 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6826 (clobber (reg:CC FLAGS_REG))]
6828 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6829 "<sgnprefix>mul{b}\t%2"
6830 [(set_attr "type" "imul")
6831 (set_attr "length_immediate" "0")
6832 (set (attr "athlon_decode")
6833 (if_then_else (eq_attr "cpu" "athlon")
6834 (const_string "vector")
6835 (const_string "direct")))
6836 (set_attr "amdfam10_decode" "direct")
6837 (set_attr "bdver1_decode" "direct")
6838 (set_attr "mode" "QI")])
6840 (define_expand "<s>mul<mode>3_highpart"
6841 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6846 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6848 (match_operand:SWI48 2 "register_operand" "")))
6850 (clobber (match_scratch:SWI48 3 ""))
6851 (clobber (reg:CC FLAGS_REG))])]
6853 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6855 (define_insn "*<s>muldi3_highpart_1"
6856 [(set (match_operand:DI 0 "register_operand" "=d")
6861 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6863 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6865 (clobber (match_scratch:DI 3 "=1"))
6866 (clobber (reg:CC FLAGS_REG))]
6868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869 "<sgnprefix>mul{q}\t%2"
6870 [(set_attr "type" "imul")
6871 (set_attr "length_immediate" "0")
6872 (set (attr "athlon_decode")
6873 (if_then_else (eq_attr "cpu" "athlon")
6874 (const_string "vector")
6875 (const_string "double")))
6876 (set_attr "amdfam10_decode" "double")
6877 (set_attr "bdver1_decode" "direct")
6878 (set_attr "mode" "DI")])
6880 (define_insn "*<s>mulsi3_highpart_1"
6881 [(set (match_operand:SI 0 "register_operand" "=d")
6886 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6888 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6890 (clobber (match_scratch:SI 3 "=1"))
6891 (clobber (reg:CC FLAGS_REG))]
6892 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "<sgnprefix>mul{l}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "double")))
6900 (set_attr "amdfam10_decode" "double")
6901 (set_attr "bdver1_decode" "direct")
6902 (set_attr "mode" "SI")])
6904 (define_insn "*<s>mulsi3_highpart_zext"
6905 [(set (match_operand:DI 0 "register_operand" "=d")
6906 (zero_extend:DI (truncate:SI
6908 (mult:DI (any_extend:DI
6909 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6911 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6913 (clobber (match_scratch:SI 3 "=1"))
6914 (clobber (reg:CC FLAGS_REG))]
6916 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{l}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "SI")])
6928 ;; The patterns that match these are at the end of this file.
6930 (define_expand "mulxf3"
6931 [(set (match_operand:XF 0 "register_operand" "")
6932 (mult:XF (match_operand:XF 1 "register_operand" "")
6933 (match_operand:XF 2 "register_operand" "")))]
6936 (define_expand "mul<mode>3"
6937 [(set (match_operand:MODEF 0 "register_operand" "")
6938 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6939 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6940 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6941 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6943 ;; Divide instructions
6945 ;; The patterns that match these are at the end of this file.
6947 (define_expand "divxf3"
6948 [(set (match_operand:XF 0 "register_operand" "")
6949 (div:XF (match_operand:XF 1 "register_operand" "")
6950 (match_operand:XF 2 "register_operand" "")))]
6953 (define_expand "divdf3"
6954 [(set (match_operand:DF 0 "register_operand" "")
6955 (div:DF (match_operand:DF 1 "register_operand" "")
6956 (match_operand:DF 2 "nonimmediate_operand" "")))]
6957 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6958 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6960 (define_expand "divsf3"
6961 [(set (match_operand:SF 0 "register_operand" "")
6962 (div:SF (match_operand:SF 1 "register_operand" "")
6963 (match_operand:SF 2 "nonimmediate_operand" "")))]
6964 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6967 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6968 && flag_finite_math_only && !flag_trapping_math
6969 && flag_unsafe_math_optimizations)
6971 ix86_emit_swdivsf (operands[0], operands[1],
6972 operands[2], SFmode);
6977 ;; Divmod instructions.
6979 (define_expand "divmod<mode>4"
6980 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6982 (match_operand:SWIM248 1 "register_operand" "")
6983 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
6984 (set (match_operand:SWIM248 3 "register_operand" "")
6985 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6986 (clobber (reg:CC FLAGS_REG))])])
6988 ;; Split with 8bit unsigned divide:
6989 ;; if (dividend an divisor are in [0-255])
6990 ;; use 8bit unsigned integer divide
6992 ;; use original integer divide
6994 [(set (match_operand:SWI48 0 "register_operand" "")
6995 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
6996 (match_operand:SWI48 3 "nonimmediate_operand" "")))
6997 (set (match_operand:SWI48 1 "register_operand" "")
6998 (mod:SWI48 (match_dup 2) (match_dup 3)))
6999 (clobber (reg:CC FLAGS_REG))]
7000 "TARGET_USE_8BIT_IDIV
7001 && TARGET_QIMODE_MATH
7002 && can_create_pseudo_p ()
7003 && !optimize_insn_for_size_p ()"
7005 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7007 (define_insn_and_split "divmod<mode>4_1"
7008 [(set (match_operand:SWI48 0 "register_operand" "=a")
7009 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7010 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7011 (set (match_operand:SWI48 1 "register_operand" "=&d")
7012 (mod:SWI48 (match_dup 2) (match_dup 3)))
7013 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7014 (clobber (reg:CC FLAGS_REG))]
7018 [(parallel [(set (match_dup 1)
7019 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7020 (clobber (reg:CC FLAGS_REG))])
7021 (parallel [(set (match_dup 0)
7022 (div:SWI48 (match_dup 2) (match_dup 3)))
7024 (mod:SWI48 (match_dup 2) (match_dup 3)))
7026 (clobber (reg:CC FLAGS_REG))])]
7028 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7030 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7031 operands[4] = operands[2];
7034 /* Avoid use of cltd in favor of a mov+shift. */
7035 emit_move_insn (operands[1], operands[2]);
7036 operands[4] = operands[1];
7039 [(set_attr "type" "multi")
7040 (set_attr "mode" "<MODE>")])
7042 (define_insn_and_split "*divmod<mode>4"
7043 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7044 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7045 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7046 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7047 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7048 (clobber (reg:CC FLAGS_REG))]
7052 [(parallel [(set (match_dup 1)
7053 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7054 (clobber (reg:CC FLAGS_REG))])
7055 (parallel [(set (match_dup 0)
7056 (div:SWIM248 (match_dup 2) (match_dup 3)))
7058 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7060 (clobber (reg:CC FLAGS_REG))])]
7062 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7064 if (<MODE>mode != HImode
7065 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7066 operands[4] = operands[2];
7069 /* Avoid use of cltd in favor of a mov+shift. */
7070 emit_move_insn (operands[1], operands[2]);
7071 operands[4] = operands[1];
7074 [(set_attr "type" "multi")
7075 (set_attr "mode" "<MODE>")])
7077 (define_insn "*divmod<mode>4_noext"
7078 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081 (set (match_operand:SWIM248 1 "register_operand" "=d")
7082 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083 (use (match_operand:SWIM248 4 "register_operand" "1"))
7084 (clobber (reg:CC FLAGS_REG))]
7086 "idiv{<imodesuffix>}\t%3"
7087 [(set_attr "type" "idiv")
7088 (set_attr "mode" "<MODE>")])
7090 (define_expand "divmodqi4"
7091 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7093 (match_operand:QI 1 "register_operand" "")
7094 (match_operand:QI 2 "nonimmediate_operand" "")))
7095 (set (match_operand:QI 3 "register_operand" "")
7096 (mod:QI (match_dup 1) (match_dup 2)))
7097 (clobber (reg:CC FLAGS_REG))])]
7098 "TARGET_QIMODE_MATH"
7103 tmp0 = gen_reg_rtx (HImode);
7104 tmp1 = gen_reg_rtx (HImode);
7106 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7108 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7109 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7111 /* Extract remainder from AH. */
7112 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7113 insn = emit_move_insn (operands[3], tmp1);
7115 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7116 set_unique_reg_note (insn, REG_EQUAL, mod);
7118 /* Extract quotient from AL. */
7119 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7121 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7122 set_unique_reg_note (insn, REG_EQUAL, div);
7127 ;; Divide AX by r/m8, with result stored in
7130 ;; Change div/mod to HImode and extend the second argument to HImode
7131 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7132 ;; combine may fail.
7133 (define_insn "divmodhiqi3"
7134 [(set (match_operand:HI 0 "register_operand" "=a")
7139 (mod:HI (match_operand:HI 1 "register_operand" "0")
7141 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7145 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7146 (clobber (reg:CC FLAGS_REG))]
7147 "TARGET_QIMODE_MATH"
7149 [(set_attr "type" "idiv")
7150 (set_attr "mode" "QI")])
7152 (define_expand "udivmod<mode>4"
7153 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7155 (match_operand:SWIM248 1 "register_operand" "")
7156 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7157 (set (match_operand:SWIM248 3 "register_operand" "")
7158 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7159 (clobber (reg:CC FLAGS_REG))])])
7161 ;; Split with 8bit unsigned divide:
7162 ;; if (dividend an divisor are in [0-255])
7163 ;; use 8bit unsigned integer divide
7165 ;; use original integer divide
7167 [(set (match_operand:SWI48 0 "register_operand" "")
7168 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7169 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7170 (set (match_operand:SWI48 1 "register_operand" "")
7171 (umod:SWI48 (match_dup 2) (match_dup 3)))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "TARGET_USE_8BIT_IDIV
7174 && TARGET_QIMODE_MATH
7175 && can_create_pseudo_p ()
7176 && !optimize_insn_for_size_p ()"
7178 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7180 (define_insn_and_split "udivmod<mode>4_1"
7181 [(set (match_operand:SWI48 0 "register_operand" "=a")
7182 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7183 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7184 (set (match_operand:SWI48 1 "register_operand" "=&d")
7185 (umod:SWI48 (match_dup 2) (match_dup 3)))
7186 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7187 (clobber (reg:CC FLAGS_REG))]
7191 [(set (match_dup 1) (const_int 0))
7192 (parallel [(set (match_dup 0)
7193 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7195 (umod:SWI48 (match_dup 2) (match_dup 3)))
7197 (clobber (reg:CC FLAGS_REG))])]
7199 [(set_attr "type" "multi")
7200 (set_attr "mode" "<MODE>")])
7202 (define_insn_and_split "*udivmod<mode>4"
7203 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7204 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7205 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7206 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7207 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7208 (clobber (reg:CC FLAGS_REG))]
7212 [(set (match_dup 1) (const_int 0))
7213 (parallel [(set (match_dup 0)
7214 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7216 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7218 (clobber (reg:CC FLAGS_REG))])]
7220 [(set_attr "type" "multi")
7221 (set_attr "mode" "<MODE>")])
7223 (define_insn "*udivmod<mode>4_noext"
7224 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWIM248 1 "register_operand" "=d")
7228 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7229 (use (match_operand:SWIM248 4 "register_operand" "1"))
7230 (clobber (reg:CC FLAGS_REG))]
7232 "div{<imodesuffix>}\t%3"
7233 [(set_attr "type" "idiv")
7234 (set_attr "mode" "<MODE>")])
7236 (define_expand "udivmodqi4"
7237 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7239 (match_operand:QI 1 "register_operand" "")
7240 (match_operand:QI 2 "nonimmediate_operand" "")))
7241 (set (match_operand:QI 3 "register_operand" "")
7242 (umod:QI (match_dup 1) (match_dup 2)))
7243 (clobber (reg:CC FLAGS_REG))])]
7244 "TARGET_QIMODE_MATH"
7249 tmp0 = gen_reg_rtx (HImode);
7250 tmp1 = gen_reg_rtx (HImode);
7252 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7254 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7255 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7257 /* Extract remainder from AH. */
7258 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7259 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7260 insn = emit_move_insn (operands[3], tmp1);
7262 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7263 set_unique_reg_note (insn, REG_EQUAL, mod);
7265 /* Extract quotient from AL. */
7266 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7268 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7269 set_unique_reg_note (insn, REG_EQUAL, div);
7274 (define_insn "udivmodhiqi3"
7275 [(set (match_operand:HI 0 "register_operand" "=a")
7280 (mod:HI (match_operand:HI 1 "register_operand" "0")
7282 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7286 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7287 (clobber (reg:CC FLAGS_REG))]
7288 "TARGET_QIMODE_MATH"
7290 [(set_attr "type" "idiv")
7291 (set_attr "mode" "QI")])
7293 ;; We cannot use div/idiv for double division, because it causes
7294 ;; "division by zero" on the overflow and that's not what we expect
7295 ;; from truncate. Because true (non truncating) double division is
7296 ;; never generated, we can't create this insn anyway.
7299 ; [(set (match_operand:SI 0 "register_operand" "=a")
7301 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7303 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7304 ; (set (match_operand:SI 3 "register_operand" "=d")
7306 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7307 ; (clobber (reg:CC FLAGS_REG))]
7309 ; "div{l}\t{%2, %0|%0, %2}"
7310 ; [(set_attr "type" "idiv")])
7312 ;;- Logical AND instructions
7314 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7315 ;; Note that this excludes ah.
7317 (define_expand "testsi_ccno_1"
7318 [(set (reg:CCNO FLAGS_REG)
7320 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7321 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7324 (define_expand "testqi_ccz_1"
7325 [(set (reg:CCZ FLAGS_REG)
7326 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7327 (match_operand:QI 1 "nonmemory_operand" ""))
7330 (define_expand "testdi_ccno_1"
7331 [(set (reg:CCNO FLAGS_REG)
7333 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7334 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7336 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7338 (define_insn "*testdi_1"
7339 [(set (reg FLAGS_REG)
7342 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7343 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7345 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7348 test{l}\t{%k1, %k0|%k0, %k1}
7349 test{l}\t{%k1, %k0|%k0, %k1}
7350 test{q}\t{%1, %0|%0, %1}
7351 test{q}\t{%1, %0|%0, %1}
7352 test{q}\t{%1, %0|%0, %1}"
7353 [(set_attr "type" "test")
7354 (set_attr "modrm" "0,1,0,1,1")
7355 (set_attr "mode" "SI,SI,DI,DI,DI")])
7357 (define_insn "*testqi_1_maybe_si"
7358 [(set (reg FLAGS_REG)
7361 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7362 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7364 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7365 && ix86_match_ccmode (insn,
7366 CONST_INT_P (operands[1])
7367 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7369 if (which_alternative == 3)
7371 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7372 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7373 return "test{l}\t{%1, %k0|%k0, %1}";
7375 return "test{b}\t{%1, %0|%0, %1}";
7377 [(set_attr "type" "test")
7378 (set_attr "modrm" "0,1,1,1")
7379 (set_attr "mode" "QI,QI,QI,SI")
7380 (set_attr "pent_pair" "uv,np,uv,np")])
7382 (define_insn "*test<mode>_1"
7383 [(set (reg FLAGS_REG)
7386 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7387 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7389 "ix86_match_ccmode (insn, CCNOmode)
7390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7391 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7392 [(set_attr "type" "test")
7393 (set_attr "modrm" "0,1,1")
7394 (set_attr "mode" "<MODE>")
7395 (set_attr "pent_pair" "uv,np,uv")])
7397 (define_expand "testqi_ext_ccno_0"
7398 [(set (reg:CCNO FLAGS_REG)
7402 (match_operand 0 "ext_register_operand" "")
7405 (match_operand 1 "const_int_operand" ""))
7408 (define_insn "*testqi_ext_0"
7409 [(set (reg FLAGS_REG)
7413 (match_operand 0 "ext_register_operand" "Q")
7416 (match_operand 1 "const_int_operand" "n"))
7418 "ix86_match_ccmode (insn, CCNOmode)"
7419 "test{b}\t{%1, %h0|%h0, %1}"
7420 [(set_attr "type" "test")
7421 (set_attr "mode" "QI")
7422 (set_attr "length_immediate" "1")
7423 (set_attr "modrm" "1")
7424 (set_attr "pent_pair" "np")])
7426 (define_insn "*testqi_ext_1_rex64"
7427 [(set (reg FLAGS_REG)
7431 (match_operand 0 "ext_register_operand" "Q")
7435 (match_operand:QI 1 "register_operand" "Q")))
7437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7438 "test{b}\t{%1, %h0|%h0, %1}"
7439 [(set_attr "type" "test")
7440 (set_attr "mode" "QI")])
7442 (define_insn "*testqi_ext_1"
7443 [(set (reg FLAGS_REG)
7447 (match_operand 0 "ext_register_operand" "Q")
7451 (match_operand:QI 1 "general_operand" "Qm")))
7453 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7454 "test{b}\t{%1, %h0|%h0, %1}"
7455 [(set_attr "type" "test")
7456 (set_attr "mode" "QI")])
7458 (define_insn "*testqi_ext_2"
7459 [(set (reg FLAGS_REG)
7463 (match_operand 0 "ext_register_operand" "Q")
7467 (match_operand 1 "ext_register_operand" "Q")
7471 "ix86_match_ccmode (insn, CCNOmode)"
7472 "test{b}\t{%h1, %h0|%h0, %h1}"
7473 [(set_attr "type" "test")
7474 (set_attr "mode" "QI")])
7476 (define_insn "*testqi_ext_3_rex64"
7477 [(set (reg FLAGS_REG)
7478 (compare (zero_extract:DI
7479 (match_operand 0 "nonimmediate_operand" "rm")
7480 (match_operand:DI 1 "const_int_operand" "")
7481 (match_operand:DI 2 "const_int_operand" ""))
7484 && ix86_match_ccmode (insn, CCNOmode)
7485 && INTVAL (operands[1]) > 0
7486 && INTVAL (operands[2]) >= 0
7487 /* Ensure that resulting mask is zero or sign extended operand. */
7488 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7489 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7490 && INTVAL (operands[1]) > 32))
7491 && (GET_MODE (operands[0]) == SImode
7492 || GET_MODE (operands[0]) == DImode
7493 || GET_MODE (operands[0]) == HImode
7494 || GET_MODE (operands[0]) == QImode)"
7497 ;; Combine likes to form bit extractions for some tests. Humor it.
7498 (define_insn "*testqi_ext_3"
7499 [(set (reg FLAGS_REG)
7500 (compare (zero_extract:SI
7501 (match_operand 0 "nonimmediate_operand" "rm")
7502 (match_operand:SI 1 "const_int_operand" "")
7503 (match_operand:SI 2 "const_int_operand" ""))
7505 "ix86_match_ccmode (insn, CCNOmode)
7506 && INTVAL (operands[1]) > 0
7507 && INTVAL (operands[2]) >= 0
7508 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7509 && (GET_MODE (operands[0]) == SImode
7510 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7511 || GET_MODE (operands[0]) == HImode
7512 || GET_MODE (operands[0]) == QImode)"
7516 [(set (match_operand 0 "flags_reg_operand" "")
7517 (match_operator 1 "compare_operator"
7519 (match_operand 2 "nonimmediate_operand" "")
7520 (match_operand 3 "const_int_operand" "")
7521 (match_operand 4 "const_int_operand" ""))
7523 "ix86_match_ccmode (insn, CCNOmode)"
7524 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7526 rtx val = operands[2];
7527 HOST_WIDE_INT len = INTVAL (operands[3]);
7528 HOST_WIDE_INT pos = INTVAL (operands[4]);
7530 enum machine_mode mode, submode;
7532 mode = GET_MODE (val);
7535 /* ??? Combine likes to put non-volatile mem extractions in QImode
7536 no matter the size of the test. So find a mode that works. */
7537 if (! MEM_VOLATILE_P (val))
7539 mode = smallest_mode_for_size (pos + len, MODE_INT);
7540 val = adjust_address (val, mode, 0);
7543 else if (GET_CODE (val) == SUBREG
7544 && (submode = GET_MODE (SUBREG_REG (val)),
7545 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7546 && pos + len <= GET_MODE_BITSIZE (submode)
7547 && GET_MODE_CLASS (submode) == MODE_INT)
7549 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7551 val = SUBREG_REG (val);
7553 else if (mode == HImode && pos + len <= 8)
7555 /* Small HImode tests can be converted to QImode. */
7557 val = gen_lowpart (QImode, val);
7560 if (len == HOST_BITS_PER_WIDE_INT)
7563 mask = ((HOST_WIDE_INT)1 << len) - 1;
7566 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7569 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7570 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7571 ;; this is relatively important trick.
7572 ;; Do the conversion only post-reload to avoid limiting of the register class
7575 [(set (match_operand 0 "flags_reg_operand" "")
7576 (match_operator 1 "compare_operator"
7577 [(and (match_operand 2 "register_operand" "")
7578 (match_operand 3 "const_int_operand" ""))
7581 && QI_REG_P (operands[2])
7582 && GET_MODE (operands[2]) != QImode
7583 && ((ix86_match_ccmode (insn, CCZmode)
7584 && !(INTVAL (operands[3]) & ~(255 << 8)))
7585 || (ix86_match_ccmode (insn, CCNOmode)
7586 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7589 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7592 "operands[2] = gen_lowpart (SImode, operands[2]);
7593 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7596 [(set (match_operand 0 "flags_reg_operand" "")
7597 (match_operator 1 "compare_operator"
7598 [(and (match_operand 2 "nonimmediate_operand" "")
7599 (match_operand 3 "const_int_operand" ""))
7602 && GET_MODE (operands[2]) != QImode
7603 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7604 && ((ix86_match_ccmode (insn, CCZmode)
7605 && !(INTVAL (operands[3]) & ~255))
7606 || (ix86_match_ccmode (insn, CCNOmode)
7607 && !(INTVAL (operands[3]) & ~127)))"
7609 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7611 "operands[2] = gen_lowpart (QImode, operands[2]);
7612 operands[3] = gen_lowpart (QImode, operands[3]);")
7614 ;; %%% This used to optimize known byte-wide and operations to memory,
7615 ;; and sometimes to QImode registers. If this is considered useful,
7616 ;; it should be done with splitters.
7618 (define_expand "and<mode>3"
7619 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7620 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7621 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7623 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7625 (define_insn "*anddi_1"
7626 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7628 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7629 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7630 (clobber (reg:CC FLAGS_REG))]
7631 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7633 switch (get_attr_type (insn))
7637 enum machine_mode mode;
7639 gcc_assert (CONST_INT_P (operands[2]));
7640 if (INTVAL (operands[2]) == 0xff)
7644 gcc_assert (INTVAL (operands[2]) == 0xffff);
7648 operands[1] = gen_lowpart (mode, operands[1]);
7650 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7652 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7657 if (get_attr_mode (insn) == MODE_SI)
7658 return "and{l}\t{%k2, %k0|%k0, %k2}";
7660 return "and{q}\t{%2, %0|%0, %2}";
7663 [(set_attr "type" "alu,alu,alu,imovx")
7664 (set_attr "length_immediate" "*,*,*,0")
7665 (set (attr "prefix_rex")
7667 (and (eq_attr "type" "imovx")
7668 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7669 (match_operand 1 "ext_QIreg_operand" "")))
7671 (const_string "*")))
7672 (set_attr "mode" "SI,DI,DI,SI")])
7674 (define_insn "*andsi_1"
7675 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7676 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7677 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7678 (clobber (reg:CC FLAGS_REG))]
7679 "ix86_binary_operator_ok (AND, SImode, operands)"
7681 switch (get_attr_type (insn))
7685 enum machine_mode mode;
7687 gcc_assert (CONST_INT_P (operands[2]));
7688 if (INTVAL (operands[2]) == 0xff)
7692 gcc_assert (INTVAL (operands[2]) == 0xffff);
7696 operands[1] = gen_lowpart (mode, operands[1]);
7698 return "movz{bl|x}\t{%1, %0|%0, %1}";
7700 return "movz{wl|x}\t{%1, %0|%0, %1}";
7704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705 return "and{l}\t{%2, %0|%0, %2}";
7708 [(set_attr "type" "alu,alu,imovx")
7709 (set (attr "prefix_rex")
7711 (and (eq_attr "type" "imovx")
7712 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7713 (match_operand 1 "ext_QIreg_operand" "")))
7715 (const_string "*")))
7716 (set_attr "length_immediate" "*,*,0")
7717 (set_attr "mode" "SI")])
7719 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7720 (define_insn "*andsi_1_zext"
7721 [(set (match_operand:DI 0 "register_operand" "=r")
7723 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7724 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7725 (clobber (reg:CC FLAGS_REG))]
7726 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7727 "and{l}\t{%2, %k0|%k0, %2}"
7728 [(set_attr "type" "alu")
7729 (set_attr "mode" "SI")])
7731 (define_insn "*andhi_1"
7732 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7733 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7734 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7735 (clobber (reg:CC FLAGS_REG))]
7736 "ix86_binary_operator_ok (AND, HImode, operands)"
7738 switch (get_attr_type (insn))
7741 gcc_assert (CONST_INT_P (operands[2]));
7742 gcc_assert (INTVAL (operands[2]) == 0xff);
7743 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7746 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748 return "and{w}\t{%2, %0|%0, %2}";
7751 [(set_attr "type" "alu,alu,imovx")
7752 (set_attr "length_immediate" "*,*,0")
7753 (set (attr "prefix_rex")
7755 (and (eq_attr "type" "imovx")
7756 (match_operand 1 "ext_QIreg_operand" ""))
7758 (const_string "*")))
7759 (set_attr "mode" "HI,HI,SI")])
7761 ;; %%% Potential partial reg stall on alternative 2. What to do?
7762 (define_insn "*andqi_1"
7763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7764 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7765 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "ix86_binary_operator_ok (AND, QImode, operands)"
7769 and{b}\t{%2, %0|%0, %2}
7770 and{b}\t{%2, %0|%0, %2}
7771 and{l}\t{%k2, %k0|%k0, %k2}"
7772 [(set_attr "type" "alu")
7773 (set_attr "mode" "QI,QI,SI")])
7775 (define_insn "*andqi_1_slp"
7776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7777 (and:QI (match_dup 0)
7778 (match_operand:QI 1 "general_operand" "qn,qmn")))
7779 (clobber (reg:CC FLAGS_REG))]
7780 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7782 "and{b}\t{%1, %0|%0, %1}"
7783 [(set_attr "type" "alu1")
7784 (set_attr "mode" "QI")])
7787 [(set (match_operand 0 "register_operand" "")
7789 (const_int -65536)))
7790 (clobber (reg:CC FLAGS_REG))]
7791 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7792 || optimize_function_for_size_p (cfun)"
7793 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7794 "operands[1] = gen_lowpart (HImode, operands[0]);")
7797 [(set (match_operand 0 "ext_register_operand" "")
7800 (clobber (reg:CC FLAGS_REG))]
7801 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7802 && reload_completed"
7803 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7804 "operands[1] = gen_lowpart (QImode, operands[0]);")
7807 [(set (match_operand 0 "ext_register_operand" "")
7809 (const_int -65281)))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7812 && reload_completed"
7813 [(parallel [(set (zero_extract:SI (match_dup 0)
7817 (zero_extract:SI (match_dup 0)
7820 (zero_extract:SI (match_dup 0)
7823 (clobber (reg:CC FLAGS_REG))])]
7824 "operands[0] = gen_lowpart (SImode, operands[0]);")
7826 (define_insn "*anddi_2"
7827 [(set (reg FLAGS_REG)
7830 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7831 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7833 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7834 (and:DI (match_dup 1) (match_dup 2)))]
7835 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7836 && ix86_binary_operator_ok (AND, DImode, operands)"
7838 and{l}\t{%k2, %k0|%k0, %k2}
7839 and{q}\t{%2, %0|%0, %2}
7840 and{q}\t{%2, %0|%0, %2}"
7841 [(set_attr "type" "alu")
7842 (set_attr "mode" "SI,DI,DI")])
7844 (define_insn "*andqi_2_maybe_si"
7845 [(set (reg FLAGS_REG)
7847 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7848 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7850 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7851 (and:QI (match_dup 1) (match_dup 2)))]
7852 "ix86_binary_operator_ok (AND, QImode, operands)
7853 && ix86_match_ccmode (insn,
7854 CONST_INT_P (operands[2])
7855 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7857 if (which_alternative == 2)
7859 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7860 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7861 return "and{l}\t{%2, %k0|%k0, %2}";
7863 return "and{b}\t{%2, %0|%0, %2}";
7865 [(set_attr "type" "alu")
7866 (set_attr "mode" "QI,QI,SI")])
7868 (define_insn "*and<mode>_2"
7869 [(set (reg FLAGS_REG)
7870 (compare (and:SWI124
7871 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7872 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7874 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7875 (and:SWI124 (match_dup 1) (match_dup 2)))]
7876 "ix86_match_ccmode (insn, CCNOmode)
7877 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7878 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7879 [(set_attr "type" "alu")
7880 (set_attr "mode" "<MODE>")])
7882 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7883 (define_insn "*andsi_2_zext"
7884 [(set (reg FLAGS_REG)
7886 (match_operand:SI 1 "nonimmediate_operand" "%0")
7887 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7889 (set (match_operand:DI 0 "register_operand" "=r")
7890 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7891 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && ix86_binary_operator_ok (AND, SImode, operands)"
7893 "and{l}\t{%2, %k0|%k0, %2}"
7894 [(set_attr "type" "alu")
7895 (set_attr "mode" "SI")])
7897 (define_insn "*andqi_2_slp"
7898 [(set (reg FLAGS_REG)
7900 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7901 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7903 (set (strict_low_part (match_dup 0))
7904 (and:QI (match_dup 0) (match_dup 1)))]
7905 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7906 && ix86_match_ccmode (insn, CCNOmode)
7907 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908 "and{b}\t{%1, %0|%0, %1}"
7909 [(set_attr "type" "alu1")
7910 (set_attr "mode" "QI")])
7912 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7913 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7914 ;; for a QImode operand, which of course failed.
7915 (define_insn "andqi_ext_0"
7916 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7921 (match_operand 1 "ext_register_operand" "0")
7924 (match_operand 2 "const_int_operand" "n")))
7925 (clobber (reg:CC FLAGS_REG))]
7927 "and{b}\t{%2, %h0|%h0, %2}"
7928 [(set_attr "type" "alu")
7929 (set_attr "length_immediate" "1")
7930 (set_attr "modrm" "1")
7931 (set_attr "mode" "QI")])
7933 ;; Generated by peephole translating test to and. This shows up
7934 ;; often in fp comparisons.
7935 (define_insn "*andqi_ext_0_cc"
7936 [(set (reg FLAGS_REG)
7940 (match_operand 1 "ext_register_operand" "0")
7943 (match_operand 2 "const_int_operand" "n"))
7945 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7954 "ix86_match_ccmode (insn, CCNOmode)"
7955 "and{b}\t{%2, %h0|%h0, %2}"
7956 [(set_attr "type" "alu")
7957 (set_attr "length_immediate" "1")
7958 (set_attr "modrm" "1")
7959 (set_attr "mode" "QI")])
7961 (define_insn "*andqi_ext_1_rex64"
7962 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7967 (match_operand 1 "ext_register_operand" "0")
7971 (match_operand 2 "ext_register_operand" "Q"))))
7972 (clobber (reg:CC FLAGS_REG))]
7974 "and{b}\t{%2, %h0|%h0, %2}"
7975 [(set_attr "type" "alu")
7976 (set_attr "length_immediate" "0")
7977 (set_attr "mode" "QI")])
7979 (define_insn "*andqi_ext_1"
7980 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7985 (match_operand 1 "ext_register_operand" "0")
7989 (match_operand:QI 2 "general_operand" "Qm"))))
7990 (clobber (reg:CC FLAGS_REG))]
7992 "and{b}\t{%2, %h0|%h0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "length_immediate" "0")
7995 (set_attr "mode" "QI")])
7997 (define_insn "*andqi_ext_2"
7998 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8003 (match_operand 1 "ext_register_operand" "%0")
8007 (match_operand 2 "ext_register_operand" "Q")
8010 (clobber (reg:CC FLAGS_REG))]
8012 "and{b}\t{%h2, %h0|%h0, %h2}"
8013 [(set_attr "type" "alu")
8014 (set_attr "length_immediate" "0")
8015 (set_attr "mode" "QI")])
8017 ;; Convert wide AND instructions with immediate operand to shorter QImode
8018 ;; equivalents when possible.
8019 ;; Don't do the splitting with memory operands, since it introduces risk
8020 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8021 ;; for size, but that can (should?) be handled by generic code instead.
8023 [(set (match_operand 0 "register_operand" "")
8024 (and (match_operand 1 "register_operand" "")
8025 (match_operand 2 "const_int_operand" "")))
8026 (clobber (reg:CC FLAGS_REG))]
8028 && QI_REG_P (operands[0])
8029 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8030 && !(~INTVAL (operands[2]) & ~(255 << 8))
8031 && GET_MODE (operands[0]) != QImode"
8032 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8033 (and:SI (zero_extract:SI (match_dup 1)
8034 (const_int 8) (const_int 8))
8036 (clobber (reg:CC FLAGS_REG))])]
8037 "operands[0] = gen_lowpart (SImode, operands[0]);
8038 operands[1] = gen_lowpart (SImode, operands[1]);
8039 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8041 ;; Since AND can be encoded with sign extended immediate, this is only
8042 ;; profitable when 7th bit is not set.
8044 [(set (match_operand 0 "register_operand" "")
8045 (and (match_operand 1 "general_operand" "")
8046 (match_operand 2 "const_int_operand" "")))
8047 (clobber (reg:CC FLAGS_REG))]
8049 && ANY_QI_REG_P (operands[0])
8050 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8051 && !(~INTVAL (operands[2]) & ~255)
8052 && !(INTVAL (operands[2]) & 128)
8053 && GET_MODE (operands[0]) != QImode"
8054 [(parallel [(set (strict_low_part (match_dup 0))
8055 (and:QI (match_dup 1)
8057 (clobber (reg:CC FLAGS_REG))])]
8058 "operands[0] = gen_lowpart (QImode, operands[0]);
8059 operands[1] = gen_lowpart (QImode, operands[1]);
8060 operands[2] = gen_lowpart (QImode, operands[2]);")
8062 ;; Logical inclusive and exclusive OR instructions
8064 ;; %%% This used to optimize known byte-wide and operations to memory.
8065 ;; If this is considered useful, it should be done with splitters.
8067 (define_expand "<code><mode>3"
8068 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8069 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8070 (match_operand:SWIM 2 "<general_operand>" "")))]
8072 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8074 (define_insn "*<code><mode>_1"
8075 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8077 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8078 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8079 (clobber (reg:CC FLAGS_REG))]
8080 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8081 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8082 [(set_attr "type" "alu")
8083 (set_attr "mode" "<MODE>")])
8085 ;; %%% Potential partial reg stall on alternative 2. What to do?
8086 (define_insn "*<code>qi_1"
8087 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8088 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8089 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8090 (clobber (reg:CC FLAGS_REG))]
8091 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8093 <logic>{b}\t{%2, %0|%0, %2}
8094 <logic>{b}\t{%2, %0|%0, %2}
8095 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8096 [(set_attr "type" "alu")
8097 (set_attr "mode" "QI,QI,SI")])
8099 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8100 (define_insn "*<code>si_1_zext"
8101 [(set (match_operand:DI 0 "register_operand" "=r")
8103 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8104 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8105 (clobber (reg:CC FLAGS_REG))]
8106 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8107 "<logic>{l}\t{%2, %k0|%k0, %2}"
8108 [(set_attr "type" "alu")
8109 (set_attr "mode" "SI")])
8111 (define_insn "*<code>si_1_zext_imm"
8112 [(set (match_operand:DI 0 "register_operand" "=r")
8114 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8115 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8118 "<logic>{l}\t{%2, %k0|%k0, %2}"
8119 [(set_attr "type" "alu")
8120 (set_attr "mode" "SI")])
8122 (define_insn "*<code>qi_1_slp"
8123 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8124 (any_or:QI (match_dup 0)
8125 (match_operand:QI 1 "general_operand" "qmn,qn")))
8126 (clobber (reg:CC FLAGS_REG))]
8127 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129 "<logic>{b}\t{%1, %0|%0, %1}"
8130 [(set_attr "type" "alu1")
8131 (set_attr "mode" "QI")])
8133 (define_insn "*<code><mode>_2"
8134 [(set (reg FLAGS_REG)
8135 (compare (any_or:SWI
8136 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8137 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8139 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8140 (any_or:SWI (match_dup 1) (match_dup 2)))]
8141 "ix86_match_ccmode (insn, CCNOmode)
8142 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8143 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8144 [(set_attr "type" "alu")
8145 (set_attr "mode" "<MODE>")])
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 ;; ??? Special case for immediate operand is missing - it is tricky.
8149 (define_insn "*<code>si_2_zext"
8150 [(set (reg FLAGS_REG)
8151 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8154 (set (match_operand:DI 0 "register_operand" "=r")
8155 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8156 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8157 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8158 "<logic>{l}\t{%2, %k0|%k0, %2}"
8159 [(set_attr "type" "alu")
8160 (set_attr "mode" "SI")])
8162 (define_insn "*<code>si_2_zext_imm"
8163 [(set (reg FLAGS_REG)
8165 (match_operand:SI 1 "nonimmediate_operand" "%0")
8166 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8168 (set (match_operand:DI 0 "register_operand" "=r")
8169 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8170 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8171 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8172 "<logic>{l}\t{%2, %k0|%k0, %2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "mode" "SI")])
8176 (define_insn "*<code>qi_2_slp"
8177 [(set (reg FLAGS_REG)
8178 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8179 (match_operand:QI 1 "general_operand" "qmn,qn"))
8181 (set (strict_low_part (match_dup 0))
8182 (any_or:QI (match_dup 0) (match_dup 1)))]
8183 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8184 && ix86_match_ccmode (insn, CCNOmode)
8185 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8186 "<logic>{b}\t{%1, %0|%0, %1}"
8187 [(set_attr "type" "alu1")
8188 (set_attr "mode" "QI")])
8190 (define_insn "*<code><mode>_3"
8191 [(set (reg FLAGS_REG)
8192 (compare (any_or:SWI
8193 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8194 (match_operand:SWI 2 "<general_operand>" "<g>"))
8196 (clobber (match_scratch:SWI 0 "=<r>"))]
8197 "ix86_match_ccmode (insn, CCNOmode)
8198 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8199 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "<MODE>")])
8203 (define_insn "*<code>qi_ext_0"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8209 (match_operand 1 "ext_register_operand" "0")
8212 (match_operand 2 "const_int_operand" "n")))
8213 (clobber (reg:CC FLAGS_REG))]
8214 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8215 "<logic>{b}\t{%2, %h0|%h0, %2}"
8216 [(set_attr "type" "alu")
8217 (set_attr "length_immediate" "1")
8218 (set_attr "modrm" "1")
8219 (set_attr "mode" "QI")])
8221 (define_insn "*<code>qi_ext_1_rex64"
8222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8227 (match_operand 1 "ext_register_operand" "0")
8231 (match_operand 2 "ext_register_operand" "Q"))))
8232 (clobber (reg:CC FLAGS_REG))]
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8235 "<logic>{b}\t{%2, %h0|%h0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "length_immediate" "0")
8238 (set_attr "mode" "QI")])
8240 (define_insn "*<code>qi_ext_1"
8241 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8246 (match_operand 1 "ext_register_operand" "0")
8250 (match_operand:QI 2 "general_operand" "Qm"))))
8251 (clobber (reg:CC FLAGS_REG))]
8253 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8254 "<logic>{b}\t{%2, %h0|%h0, %2}"
8255 [(set_attr "type" "alu")
8256 (set_attr "length_immediate" "0")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*<code>qi_ext_2"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8264 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8267 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8270 (clobber (reg:CC FLAGS_REG))]
8271 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8272 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "length_immediate" "0")
8275 (set_attr "mode" "QI")])
8278 [(set (match_operand 0 "register_operand" "")
8279 (any_or (match_operand 1 "register_operand" "")
8280 (match_operand 2 "const_int_operand" "")))
8281 (clobber (reg:CC FLAGS_REG))]
8283 && QI_REG_P (operands[0])
8284 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8285 && !(INTVAL (operands[2]) & ~(255 << 8))
8286 && GET_MODE (operands[0]) != QImode"
8287 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8288 (any_or:SI (zero_extract:SI (match_dup 1)
8289 (const_int 8) (const_int 8))
8291 (clobber (reg:CC FLAGS_REG))])]
8292 "operands[0] = gen_lowpart (SImode, operands[0]);
8293 operands[1] = gen_lowpart (SImode, operands[1]);
8294 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8296 ;; Since OR can be encoded with sign extended immediate, this is only
8297 ;; profitable when 7th bit is set.
8299 [(set (match_operand 0 "register_operand" "")
8300 (any_or (match_operand 1 "general_operand" "")
8301 (match_operand 2 "const_int_operand" "")))
8302 (clobber (reg:CC FLAGS_REG))]
8304 && ANY_QI_REG_P (operands[0])
8305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8306 && !(INTVAL (operands[2]) & ~255)
8307 && (INTVAL (operands[2]) & 128)
8308 && GET_MODE (operands[0]) != QImode"
8309 [(parallel [(set (strict_low_part (match_dup 0))
8310 (any_or:QI (match_dup 1)
8312 (clobber (reg:CC FLAGS_REG))])]
8313 "operands[0] = gen_lowpart (QImode, operands[0]);
8314 operands[1] = gen_lowpart (QImode, operands[1]);
8315 operands[2] = gen_lowpart (QImode, operands[2]);")
8317 (define_expand "xorqi_cc_ext_1"
8319 (set (reg:CCNO FLAGS_REG)
8323 (match_operand 1 "ext_register_operand" "")
8326 (match_operand:QI 2 "general_operand" ""))
8328 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8338 (define_insn "*xorqi_cc_ext_1_rex64"
8339 [(set (reg FLAGS_REG)
8343 (match_operand 1 "ext_register_operand" "0")
8346 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8348 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8358 "xor{b}\t{%2, %h0|%h0, %2}"
8359 [(set_attr "type" "alu")
8360 (set_attr "modrm" "1")
8361 (set_attr "mode" "QI")])
8363 (define_insn "*xorqi_cc_ext_1"
8364 [(set (reg FLAGS_REG)
8368 (match_operand 1 "ext_register_operand" "0")
8371 (match_operand:QI 2 "general_operand" "qmn"))
8373 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8382 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8383 "xor{b}\t{%2, %h0|%h0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "modrm" "1")
8386 (set_attr "mode" "QI")])
8388 ;; Negation instructions
8390 (define_expand "neg<mode>2"
8391 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8392 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8394 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8396 (define_insn_and_split "*neg<dwi>2_doubleword"
8397 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8398 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8399 (clobber (reg:CC FLAGS_REG))]
8400 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8404 [(set (reg:CCZ FLAGS_REG)
8405 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8406 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8409 (plus:DWIH (match_dup 3)
8410 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8412 (clobber (reg:CC FLAGS_REG))])
8415 (neg:DWIH (match_dup 2)))
8416 (clobber (reg:CC FLAGS_REG))])]
8417 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8419 (define_insn "*neg<mode>2_1"
8420 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8421 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8424 "neg{<imodesuffix>}\t%0"
8425 [(set_attr "type" "negnot")
8426 (set_attr "mode" "<MODE>")])
8428 ;; Combine is quite creative about this pattern.
8429 (define_insn "*negsi2_1_zext"
8430 [(set (match_operand:DI 0 "register_operand" "=r")
8432 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8435 (clobber (reg:CC FLAGS_REG))]
8436 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8438 [(set_attr "type" "negnot")
8439 (set_attr "mode" "SI")])
8441 ;; The problem with neg is that it does not perform (compare x 0),
8442 ;; it really performs (compare 0 x), which leaves us with the zero
8443 ;; flag being the only useful item.
8445 (define_insn "*neg<mode>2_cmpz"
8446 [(set (reg:CCZ FLAGS_REG)
8448 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8450 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8451 (neg:SWI (match_dup 1)))]
8452 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8453 "neg{<imodesuffix>}\t%0"
8454 [(set_attr "type" "negnot")
8455 (set_attr "mode" "<MODE>")])
8457 (define_insn "*negsi2_cmpz_zext"
8458 [(set (reg:CCZ FLAGS_REG)
8462 (match_operand:DI 1 "register_operand" "0")
8466 (set (match_operand:DI 0 "register_operand" "=r")
8467 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8470 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8472 [(set_attr "type" "negnot")
8473 (set_attr "mode" "SI")])
8475 ;; Changing of sign for FP values is doable using integer unit too.
8477 (define_expand "<code><mode>2"
8478 [(set (match_operand:X87MODEF 0 "register_operand" "")
8479 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8480 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8481 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8483 (define_insn "*absneg<mode>2_mixed"
8484 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8485 (match_operator:MODEF 3 "absneg_operator"
8486 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8487 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8488 (clobber (reg:CC FLAGS_REG))]
8489 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8492 (define_insn "*absneg<mode>2_sse"
8493 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8494 (match_operator:MODEF 3 "absneg_operator"
8495 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8496 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8497 (clobber (reg:CC FLAGS_REG))]
8498 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8501 (define_insn "*absneg<mode>2_i387"
8502 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8503 (match_operator:X87MODEF 3 "absneg_operator"
8504 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8505 (use (match_operand 2 "" ""))
8506 (clobber (reg:CC FLAGS_REG))]
8507 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8510 (define_expand "<code>tf2"
8511 [(set (match_operand:TF 0 "register_operand" "")
8512 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8514 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8516 (define_insn "*absnegtf2_sse"
8517 [(set (match_operand:TF 0 "register_operand" "=x,x")
8518 (match_operator:TF 3 "absneg_operator"
8519 [(match_operand:TF 1 "register_operand" "0,x")]))
8520 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8521 (clobber (reg:CC FLAGS_REG))]
8525 ;; Splitters for fp abs and neg.
8528 [(set (match_operand 0 "fp_register_operand" "")
8529 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8530 (use (match_operand 2 "" ""))
8531 (clobber (reg:CC FLAGS_REG))]
8533 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8536 [(set (match_operand 0 "register_operand" "")
8537 (match_operator 3 "absneg_operator"
8538 [(match_operand 1 "register_operand" "")]))
8539 (use (match_operand 2 "nonimmediate_operand" ""))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "reload_completed && SSE_REG_P (operands[0])"
8542 [(set (match_dup 0) (match_dup 3))]
8544 enum machine_mode mode = GET_MODE (operands[0]);
8545 enum machine_mode vmode = GET_MODE (operands[2]);
8548 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8549 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8550 if (operands_match_p (operands[0], operands[2]))
8553 operands[1] = operands[2];
8556 if (GET_CODE (operands[3]) == ABS)
8557 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8559 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8564 [(set (match_operand:SF 0 "register_operand" "")
8565 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8566 (use (match_operand:V4SF 2 "" ""))
8567 (clobber (reg:CC FLAGS_REG))]
8569 [(parallel [(set (match_dup 0) (match_dup 1))
8570 (clobber (reg:CC FLAGS_REG))])]
8573 operands[0] = gen_lowpart (SImode, operands[0]);
8574 if (GET_CODE (operands[1]) == ABS)
8576 tmp = gen_int_mode (0x7fffffff, SImode);
8577 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8581 tmp = gen_int_mode (0x80000000, SImode);
8582 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8588 [(set (match_operand:DF 0 "register_operand" "")
8589 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8590 (use (match_operand 2 "" ""))
8591 (clobber (reg:CC FLAGS_REG))]
8593 [(parallel [(set (match_dup 0) (match_dup 1))
8594 (clobber (reg:CC FLAGS_REG))])]
8599 tmp = gen_lowpart (DImode, operands[0]);
8600 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8603 if (GET_CODE (operands[1]) == ABS)
8606 tmp = gen_rtx_NOT (DImode, tmp);
8610 operands[0] = gen_highpart (SImode, operands[0]);
8611 if (GET_CODE (operands[1]) == ABS)
8613 tmp = gen_int_mode (0x7fffffff, SImode);
8614 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8618 tmp = gen_int_mode (0x80000000, SImode);
8619 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8626 [(set (match_operand:XF 0 "register_operand" "")
8627 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8628 (use (match_operand 2 "" ""))
8629 (clobber (reg:CC FLAGS_REG))]
8631 [(parallel [(set (match_dup 0) (match_dup 1))
8632 (clobber (reg:CC FLAGS_REG))])]
8635 operands[0] = gen_rtx_REG (SImode,
8636 true_regnum (operands[0])
8637 + (TARGET_64BIT ? 1 : 2));
8638 if (GET_CODE (operands[1]) == ABS)
8640 tmp = GEN_INT (0x7fff);
8641 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8645 tmp = GEN_INT (0x8000);
8646 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8651 ;; Conditionalize these after reload. If they match before reload, we
8652 ;; lose the clobber and ability to use integer instructions.
8654 (define_insn "*<code><mode>2_1"
8655 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8656 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8658 && (reload_completed
8659 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8660 "f<absneg_mnemonic>"
8661 [(set_attr "type" "fsgn")
8662 (set_attr "mode" "<MODE>")])
8664 (define_insn "*<code>extendsfdf2"
8665 [(set (match_operand:DF 0 "register_operand" "=f")
8666 (absneg:DF (float_extend:DF
8667 (match_operand:SF 1 "register_operand" "0"))))]
8668 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8669 "f<absneg_mnemonic>"
8670 [(set_attr "type" "fsgn")
8671 (set_attr "mode" "DF")])
8673 (define_insn "*<code>extendsfxf2"
8674 [(set (match_operand:XF 0 "register_operand" "=f")
8675 (absneg:XF (float_extend:XF
8676 (match_operand:SF 1 "register_operand" "0"))))]
8678 "f<absneg_mnemonic>"
8679 [(set_attr "type" "fsgn")
8680 (set_attr "mode" "XF")])
8682 (define_insn "*<code>extenddfxf2"
8683 [(set (match_operand:XF 0 "register_operand" "=f")
8684 (absneg:XF (float_extend:XF
8685 (match_operand:DF 1 "register_operand" "0"))))]
8687 "f<absneg_mnemonic>"
8688 [(set_attr "type" "fsgn")
8689 (set_attr "mode" "XF")])
8691 ;; Copysign instructions
8693 (define_mode_iterator CSGNMODE [SF DF TF])
8694 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8696 (define_expand "copysign<mode>3"
8697 [(match_operand:CSGNMODE 0 "register_operand" "")
8698 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8699 (match_operand:CSGNMODE 2 "register_operand" "")]
8700 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8701 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8702 "ix86_expand_copysign (operands); DONE;")
8704 (define_insn_and_split "copysign<mode>3_const"
8705 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8707 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8708 (match_operand:CSGNMODE 2 "register_operand" "0")
8709 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8711 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8712 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8714 "&& reload_completed"
8716 "ix86_split_copysign_const (operands); DONE;")
8718 (define_insn "copysign<mode>3_var"
8719 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8721 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8722 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8723 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8724 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8726 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8727 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8728 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8732 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8734 [(match_operand:CSGNMODE 2 "register_operand" "")
8735 (match_operand:CSGNMODE 3 "register_operand" "")
8736 (match_operand:<CSGNVMODE> 4 "" "")
8737 (match_operand:<CSGNVMODE> 5 "" "")]
8739 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8740 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8741 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8742 && reload_completed"
8744 "ix86_split_copysign_var (operands); DONE;")
8746 ;; One complement instructions
8748 (define_expand "one_cmpl<mode>2"
8749 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8750 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8752 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8754 (define_insn "*one_cmpl<mode>2_1"
8755 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8756 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8757 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8758 "not{<imodesuffix>}\t%0"
8759 [(set_attr "type" "negnot")
8760 (set_attr "mode" "<MODE>")])
8762 ;; %%% Potential partial reg stall on alternative 1. What to do?
8763 (define_insn "*one_cmplqi2_1"
8764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8765 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8766 "ix86_unary_operator_ok (NOT, QImode, operands)"
8770 [(set_attr "type" "negnot")
8771 (set_attr "mode" "QI,SI")])
8773 ;; ??? Currently never generated - xor is used instead.
8774 (define_insn "*one_cmplsi2_1_zext"
8775 [(set (match_operand:DI 0 "register_operand" "=r")
8777 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8778 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8780 [(set_attr "type" "negnot")
8781 (set_attr "mode" "SI")])
8783 (define_insn "*one_cmpl<mode>2_2"
8784 [(set (reg FLAGS_REG)
8785 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8787 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8788 (not:SWI (match_dup 1)))]
8789 "ix86_match_ccmode (insn, CCNOmode)
8790 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8792 [(set_attr "type" "alu1")
8793 (set_attr "mode" "<MODE>")])
8796 [(set (match_operand 0 "flags_reg_operand" "")
8797 (match_operator 2 "compare_operator"
8798 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8800 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8801 (not:SWI (match_dup 3)))]
8802 "ix86_match_ccmode (insn, CCNOmode)"
8803 [(parallel [(set (match_dup 0)
8804 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8807 (xor:SWI (match_dup 3) (const_int -1)))])])
8809 ;; ??? Currently never generated - xor is used instead.
8810 (define_insn "*one_cmplsi2_2_zext"
8811 [(set (reg FLAGS_REG)
8812 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8814 (set (match_operand:DI 0 "register_operand" "=r")
8815 (zero_extend:DI (not:SI (match_dup 1))))]
8816 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8817 && ix86_unary_operator_ok (NOT, SImode, operands)"
8819 [(set_attr "type" "alu1")
8820 (set_attr "mode" "SI")])
8823 [(set (match_operand 0 "flags_reg_operand" "")
8824 (match_operator 2 "compare_operator"
8825 [(not:SI (match_operand:SI 3 "register_operand" ""))
8827 (set (match_operand:DI 1 "register_operand" "")
8828 (zero_extend:DI (not:SI (match_dup 3))))]
8829 "ix86_match_ccmode (insn, CCNOmode)"
8830 [(parallel [(set (match_dup 0)
8831 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8834 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8836 ;; Shift instructions
8838 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8839 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8840 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8841 ;; from the assembler input.
8843 ;; This instruction shifts the target reg/mem as usual, but instead of
8844 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8845 ;; is a left shift double, bits are taken from the high order bits of
8846 ;; reg, else if the insn is a shift right double, bits are taken from the
8847 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8848 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8850 ;; Since sh[lr]d does not change the `reg' operand, that is done
8851 ;; separately, making all shifts emit pairs of shift double and normal
8852 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8853 ;; support a 63 bit shift, each shift where the count is in a reg expands
8854 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8856 ;; If the shift count is a constant, we need never emit more than one
8857 ;; shift pair, instead using moves and sign extension for counts greater
8860 (define_expand "ashl<mode>3"
8861 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8862 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8863 (match_operand:QI 2 "nonmemory_operand" "")))]
8865 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8867 (define_insn "*ashl<mode>3_doubleword"
8868 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8869 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8870 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8871 (clobber (reg:CC FLAGS_REG))]
8874 [(set_attr "type" "multi")])
8877 [(set (match_operand:DWI 0 "register_operand" "")
8878 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8879 (match_operand:QI 2 "nonmemory_operand" "")))
8880 (clobber (reg:CC FLAGS_REG))]
8881 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8883 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8885 ;; By default we don't ask for a scratch register, because when DWImode
8886 ;; values are manipulated, registers are already at a premium. But if
8887 ;; we have one handy, we won't turn it away.
8890 [(match_scratch:DWIH 3 "r")
8891 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8893 (match_operand:<DWI> 1 "nonmemory_operand" "")
8894 (match_operand:QI 2 "nonmemory_operand" "")))
8895 (clobber (reg:CC FLAGS_REG))])
8899 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8901 (define_insn "x86_64_shld"
8902 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8903 (ior:DI (ashift:DI (match_dup 0)
8904 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8905 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8906 (minus:QI (const_int 64) (match_dup 2)))))
8907 (clobber (reg:CC FLAGS_REG))]
8909 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8910 [(set_attr "type" "ishift")
8911 (set_attr "prefix_0f" "1")
8912 (set_attr "mode" "DI")
8913 (set_attr "athlon_decode" "vector")
8914 (set_attr "amdfam10_decode" "vector")
8915 (set_attr "bdver1_decode" "vector")])
8917 (define_insn "x86_shld"
8918 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8919 (ior:SI (ashift:SI (match_dup 0)
8920 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8921 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8922 (minus:QI (const_int 32) (match_dup 2)))))
8923 (clobber (reg:CC FLAGS_REG))]
8925 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8926 [(set_attr "type" "ishift")
8927 (set_attr "prefix_0f" "1")
8928 (set_attr "mode" "SI")
8929 (set_attr "pent_pair" "np")
8930 (set_attr "athlon_decode" "vector")
8931 (set_attr "amdfam10_decode" "vector")
8932 (set_attr "bdver1_decode" "vector")])
8934 (define_expand "x86_shift<mode>_adj_1"
8935 [(set (reg:CCZ FLAGS_REG)
8936 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8939 (set (match_operand:SWI48 0 "register_operand" "")
8940 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8941 (match_operand:SWI48 1 "register_operand" "")
8944 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8945 (match_operand:SWI48 3 "register_operand" "r")
8948 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8950 (define_expand "x86_shift<mode>_adj_2"
8951 [(use (match_operand:SWI48 0 "register_operand" ""))
8952 (use (match_operand:SWI48 1 "register_operand" ""))
8953 (use (match_operand:QI 2 "register_operand" ""))]
8956 rtx label = gen_label_rtx ();
8959 emit_insn (gen_testqi_ccz_1 (operands[2],
8960 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8962 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8963 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8964 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8965 gen_rtx_LABEL_REF (VOIDmode, label),
8967 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8968 JUMP_LABEL (tmp) = label;
8970 emit_move_insn (operands[0], operands[1]);
8971 ix86_expand_clear (operands[1]);
8974 LABEL_NUSES (label) = 1;
8979 ;; Avoid useless masking of count operand.
8980 (define_insn_and_split "*ashl<mode>3_mask"
8981 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8983 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8986 (match_operand:SI 2 "nonimmediate_operand" "c")
8987 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8988 (clobber (reg:CC FLAGS_REG))]
8989 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8990 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8991 == GET_MODE_BITSIZE (<MODE>mode)-1"
8994 [(parallel [(set (match_dup 0)
8995 (ashift:SWI48 (match_dup 1) (match_dup 2)))
8996 (clobber (reg:CC FLAGS_REG))])]
8998 if (can_create_pseudo_p ())
8999 operands [2] = force_reg (SImode, operands[2]);
9001 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9003 [(set_attr "type" "ishift")
9004 (set_attr "mode" "<MODE>")])
9006 (define_insn "*ashl<mode>3_1"
9007 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9008 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9009 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9013 switch (get_attr_type (insn))
9019 gcc_assert (operands[2] == const1_rtx);
9020 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9021 return "add{<imodesuffix>}\t%0, %0";
9024 if (operands[2] == const1_rtx
9025 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9026 return "sal{<imodesuffix>}\t%0";
9028 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9032 (cond [(eq_attr "alternative" "1")
9033 (const_string "lea")
9034 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9036 (match_operand 0 "register_operand" ""))
9037 (match_operand 2 "const1_operand" ""))
9038 (const_string "alu")
9040 (const_string "ishift")))
9041 (set (attr "length_immediate")
9043 (ior (eq_attr "type" "alu")
9044 (and (eq_attr "type" "ishift")
9045 (and (match_operand 2 "const1_operand" "")
9046 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9049 (const_string "*")))
9050 (set_attr "mode" "<MODE>")])
9052 (define_insn "*ashlsi3_1_zext"
9053 [(set (match_operand:DI 0 "register_operand" "=r,r")
9055 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9056 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9060 switch (get_attr_type (insn))
9066 gcc_assert (operands[2] == const1_rtx);
9067 return "add{l}\t%k0, %k0";
9070 if (operands[2] == const1_rtx
9071 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9072 return "sal{l}\t%k0";
9074 return "sal{l}\t{%2, %k0|%k0, %2}";
9078 (cond [(eq_attr "alternative" "1")
9079 (const_string "lea")
9080 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9082 (match_operand 2 "const1_operand" ""))
9083 (const_string "alu")
9085 (const_string "ishift")))
9086 (set (attr "length_immediate")
9088 (ior (eq_attr "type" "alu")
9089 (and (eq_attr "type" "ishift")
9090 (and (match_operand 2 "const1_operand" "")
9091 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9094 (const_string "*")))
9095 (set_attr "mode" "SI")])
9097 (define_insn "*ashlhi3_1"
9098 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9099 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9100 (match_operand:QI 2 "nonmemory_operand" "cI")))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "TARGET_PARTIAL_REG_STALL
9103 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9105 switch (get_attr_type (insn))
9108 gcc_assert (operands[2] == const1_rtx);
9109 return "add{w}\t%0, %0";
9112 if (operands[2] == const1_rtx
9113 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9114 return "sal{w}\t%0";
9116 return "sal{w}\t{%2, %0|%0, %2}";
9120 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9122 (match_operand 0 "register_operand" ""))
9123 (match_operand 2 "const1_operand" ""))
9124 (const_string "alu")
9126 (const_string "ishift")))
9127 (set (attr "length_immediate")
9129 (ior (eq_attr "type" "alu")
9130 (and (eq_attr "type" "ishift")
9131 (and (match_operand 2 "const1_operand" "")
9132 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9135 (const_string "*")))
9136 (set_attr "mode" "HI")])
9138 (define_insn "*ashlhi3_1_lea"
9139 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9140 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9141 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "!TARGET_PARTIAL_REG_STALL
9144 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9146 switch (get_attr_type (insn))
9152 gcc_assert (operands[2] == const1_rtx);
9153 return "add{w}\t%0, %0";
9156 if (operands[2] == const1_rtx
9157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9158 return "sal{w}\t%0";
9160 return "sal{w}\t{%2, %0|%0, %2}";
9164 (cond [(eq_attr "alternative" "1")
9165 (const_string "lea")
9166 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9168 (match_operand 0 "register_operand" ""))
9169 (match_operand 2 "const1_operand" ""))
9170 (const_string "alu")
9172 (const_string "ishift")))
9173 (set (attr "length_immediate")
9175 (ior (eq_attr "type" "alu")
9176 (and (eq_attr "type" "ishift")
9177 (and (match_operand 2 "const1_operand" "")
9178 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9181 (const_string "*")))
9182 (set_attr "mode" "HI,SI")])
9184 (define_insn "*ashlqi3_1"
9185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9186 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9187 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "TARGET_PARTIAL_REG_STALL
9190 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9192 switch (get_attr_type (insn))
9195 gcc_assert (operands[2] == const1_rtx);
9196 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9197 return "add{l}\t%k0, %k0";
9199 return "add{b}\t%0, %0";
9202 if (operands[2] == const1_rtx
9203 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9205 if (get_attr_mode (insn) == MODE_SI)
9206 return "sal{l}\t%k0";
9208 return "sal{b}\t%0";
9212 if (get_attr_mode (insn) == MODE_SI)
9213 return "sal{l}\t{%2, %k0|%k0, %2}";
9215 return "sal{b}\t{%2, %0|%0, %2}";
9220 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9222 (match_operand 0 "register_operand" ""))
9223 (match_operand 2 "const1_operand" ""))
9224 (const_string "alu")
9226 (const_string "ishift")))
9227 (set (attr "length_immediate")
9229 (ior (eq_attr "type" "alu")
9230 (and (eq_attr "type" "ishift")
9231 (and (match_operand 2 "const1_operand" "")
9232 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9235 (const_string "*")))
9236 (set_attr "mode" "QI,SI")])
9238 ;; %%% Potential partial reg stall on alternative 2. What to do?
9239 (define_insn "*ashlqi3_1_lea"
9240 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9241 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9242 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9243 (clobber (reg:CC FLAGS_REG))]
9244 "!TARGET_PARTIAL_REG_STALL
9245 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9247 switch (get_attr_type (insn))
9253 gcc_assert (operands[2] == const1_rtx);
9254 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9255 return "add{l}\t%k0, %k0";
9257 return "add{b}\t%0, %0";
9260 if (operands[2] == const1_rtx
9261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9263 if (get_attr_mode (insn) == MODE_SI)
9264 return "sal{l}\t%k0";
9266 return "sal{b}\t%0";
9270 if (get_attr_mode (insn) == MODE_SI)
9271 return "sal{l}\t{%2, %k0|%k0, %2}";
9273 return "sal{b}\t{%2, %0|%0, %2}";
9278 (cond [(eq_attr "alternative" "2")
9279 (const_string "lea")
9280 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9282 (match_operand 0 "register_operand" ""))
9283 (match_operand 2 "const1_operand" ""))
9284 (const_string "alu")
9286 (const_string "ishift")))
9287 (set (attr "length_immediate")
9289 (ior (eq_attr "type" "alu")
9290 (and (eq_attr "type" "ishift")
9291 (and (match_operand 2 "const1_operand" "")
9292 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9295 (const_string "*")))
9296 (set_attr "mode" "QI,SI,SI")])
9298 (define_insn "*ashlqi3_1_slp"
9299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9300 (ashift:QI (match_dup 0)
9301 (match_operand:QI 1 "nonmemory_operand" "cI")))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "(optimize_function_for_size_p (cfun)
9304 || !TARGET_PARTIAL_FLAG_REG_STALL
9305 || (operands[1] == const1_rtx
9307 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9309 switch (get_attr_type (insn))
9312 gcc_assert (operands[1] == const1_rtx);
9313 return "add{b}\t%0, %0";
9316 if (operands[1] == const1_rtx
9317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9318 return "sal{b}\t%0";
9320 return "sal{b}\t{%1, %0|%0, %1}";
9324 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9326 (match_operand 0 "register_operand" ""))
9327 (match_operand 1 "const1_operand" ""))
9328 (const_string "alu")
9330 (const_string "ishift1")))
9331 (set (attr "length_immediate")
9333 (ior (eq_attr "type" "alu")
9334 (and (eq_attr "type" "ishift1")
9335 (and (match_operand 1 "const1_operand" "")
9336 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9339 (const_string "*")))
9340 (set_attr "mode" "QI")])
9342 ;; Convert ashift to the lea pattern to avoid flags dependency.
9344 [(set (match_operand 0 "register_operand" "")
9345 (ashift (match_operand 1 "index_register_operand" "")
9346 (match_operand:QI 2 "const_int_operand" "")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9350 && true_regnum (operands[0]) != true_regnum (operands[1])"
9353 enum machine_mode mode = GET_MODE (operands[0]);
9356 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9359 operands[0] = gen_lowpart (mode, operands[0]);
9360 operands[1] = gen_lowpart (mode, operands[1]);
9363 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9365 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9371 ;; Convert ashift to the lea pattern to avoid flags dependency.
9373 [(set (match_operand:DI 0 "register_operand" "")
9375 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9376 (match_operand:QI 2 "const_int_operand" ""))))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "TARGET_64BIT && reload_completed
9379 && true_regnum (operands[0]) != true_regnum (operands[1])"
9381 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9383 operands[1] = gen_lowpart (DImode, operands[1]);
9384 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9387 ;; This pattern can't accept a variable shift count, since shifts by
9388 ;; zero don't affect the flags. We assume that shifts by constant
9389 ;; zero are optimized away.
9390 (define_insn "*ashl<mode>3_cmp"
9391 [(set (reg FLAGS_REG)
9393 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9394 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9396 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9397 (ashift:SWI (match_dup 1) (match_dup 2)))]
9398 "(optimize_function_for_size_p (cfun)
9399 || !TARGET_PARTIAL_FLAG_REG_STALL
9400 || (operands[2] == const1_rtx
9402 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9403 && ix86_match_ccmode (insn, CCGOCmode)
9404 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9406 switch (get_attr_type (insn))
9409 gcc_assert (operands[2] == const1_rtx);
9410 return "add{<imodesuffix>}\t%0, %0";
9413 if (operands[2] == const1_rtx
9414 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9415 return "sal{<imodesuffix>}\t%0";
9417 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9421 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9423 (match_operand 0 "register_operand" ""))
9424 (match_operand 2 "const1_operand" ""))
9425 (const_string "alu")
9427 (const_string "ishift")))
9428 (set (attr "length_immediate")
9430 (ior (eq_attr "type" "alu")
9431 (and (eq_attr "type" "ishift")
9432 (and (match_operand 2 "const1_operand" "")
9433 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9436 (const_string "*")))
9437 (set_attr "mode" "<MODE>")])
9439 (define_insn "*ashlsi3_cmp_zext"
9440 [(set (reg FLAGS_REG)
9442 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9443 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9445 (set (match_operand:DI 0 "register_operand" "=r")
9446 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9448 && (optimize_function_for_size_p (cfun)
9449 || !TARGET_PARTIAL_FLAG_REG_STALL
9450 || (operands[2] == const1_rtx
9452 || TARGET_DOUBLE_WITH_ADD)))
9453 && ix86_match_ccmode (insn, CCGOCmode)
9454 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9456 switch (get_attr_type (insn))
9459 gcc_assert (operands[2] == const1_rtx);
9460 return "add{l}\t%k0, %k0";
9463 if (operands[2] == const1_rtx
9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465 return "sal{l}\t%k0";
9467 return "sal{l}\t{%2, %k0|%k0, %2}";
9471 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9473 (match_operand 2 "const1_operand" ""))
9474 (const_string "alu")
9476 (const_string "ishift")))
9477 (set (attr "length_immediate")
9479 (ior (eq_attr "type" "alu")
9480 (and (eq_attr "type" "ishift")
9481 (and (match_operand 2 "const1_operand" "")
9482 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9485 (const_string "*")))
9486 (set_attr "mode" "SI")])
9488 (define_insn "*ashl<mode>3_cconly"
9489 [(set (reg FLAGS_REG)
9491 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9492 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9494 (clobber (match_scratch:SWI 0 "=<r>"))]
9495 "(optimize_function_for_size_p (cfun)
9496 || !TARGET_PARTIAL_FLAG_REG_STALL
9497 || (operands[2] == const1_rtx
9499 || TARGET_DOUBLE_WITH_ADD)))
9500 && ix86_match_ccmode (insn, CCGOCmode)"
9502 switch (get_attr_type (insn))
9505 gcc_assert (operands[2] == const1_rtx);
9506 return "add{<imodesuffix>}\t%0, %0";
9509 if (operands[2] == const1_rtx
9510 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9511 return "sal{<imodesuffix>}\t%0";
9513 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9517 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9519 (match_operand 0 "register_operand" ""))
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 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9532 (const_string "*")))
9533 (set_attr "mode" "<MODE>")])
9535 ;; See comment above `ashl<mode>3' about how this works.
9537 (define_expand "<shiftrt_insn><mode>3"
9538 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9539 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9540 (match_operand:QI 2 "nonmemory_operand" "")))]
9542 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9544 ;; Avoid useless masking of count operand.
9545 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9546 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9548 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9551 (match_operand:SI 2 "nonimmediate_operand" "c")
9552 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9553 (clobber (reg:CC FLAGS_REG))]
9554 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9555 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9556 == GET_MODE_BITSIZE (<MODE>mode)-1"
9559 [(parallel [(set (match_dup 0)
9560 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9561 (clobber (reg:CC FLAGS_REG))])]
9563 if (can_create_pseudo_p ())
9564 operands [2] = force_reg (SImode, operands[2]);
9566 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9568 [(set_attr "type" "ishift")
9569 (set_attr "mode" "<MODE>")])
9571 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9572 [(set (match_operand:DWI 0 "register_operand" "=r")
9573 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9574 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9575 (clobber (reg:CC FLAGS_REG))]
9578 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9580 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9581 [(set_attr "type" "multi")])
9583 ;; By default we don't ask for a scratch register, because when DWImode
9584 ;; values are manipulated, registers are already at a premium. But if
9585 ;; we have one handy, we won't turn it away.
9588 [(match_scratch:DWIH 3 "r")
9589 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9591 (match_operand:<DWI> 1 "register_operand" "")
9592 (match_operand:QI 2 "nonmemory_operand" "")))
9593 (clobber (reg:CC FLAGS_REG))])
9597 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9599 (define_insn "x86_64_shrd"
9600 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9601 (ior:DI (ashiftrt:DI (match_dup 0)
9602 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9603 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9604 (minus:QI (const_int 64) (match_dup 2)))))
9605 (clobber (reg:CC FLAGS_REG))]
9607 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9608 [(set_attr "type" "ishift")
9609 (set_attr "prefix_0f" "1")
9610 (set_attr "mode" "DI")
9611 (set_attr "athlon_decode" "vector")
9612 (set_attr "amdfam10_decode" "vector")
9613 (set_attr "bdver1_decode" "vector")])
9615 (define_insn "x86_shrd"
9616 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9617 (ior:SI (ashiftrt:SI (match_dup 0)
9618 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9619 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9620 (minus:QI (const_int 32) (match_dup 2)))))
9621 (clobber (reg:CC FLAGS_REG))]
9623 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9624 [(set_attr "type" "ishift")
9625 (set_attr "prefix_0f" "1")
9626 (set_attr "mode" "SI")
9627 (set_attr "pent_pair" "np")
9628 (set_attr "athlon_decode" "vector")
9629 (set_attr "amdfam10_decode" "vector")
9630 (set_attr "bdver1_decode" "vector")])
9632 (define_insn "ashrdi3_cvt"
9633 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9634 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9635 (match_operand:QI 2 "const_int_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))]
9637 "TARGET_64BIT && INTVAL (operands[2]) == 63
9638 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9639 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9642 sar{q}\t{%2, %0|%0, %2}"
9643 [(set_attr "type" "imovx,ishift")
9644 (set_attr "prefix_0f" "0,*")
9645 (set_attr "length_immediate" "0,*")
9646 (set_attr "modrm" "0,1")
9647 (set_attr "mode" "DI")])
9649 (define_insn "ashrsi3_cvt"
9650 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9651 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9652 (match_operand:QI 2 "const_int_operand" "")))
9653 (clobber (reg:CC FLAGS_REG))]
9654 "INTVAL (operands[2]) == 31
9655 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9656 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9659 sar{l}\t{%2, %0|%0, %2}"
9660 [(set_attr "type" "imovx,ishift")
9661 (set_attr "prefix_0f" "0,*")
9662 (set_attr "length_immediate" "0,*")
9663 (set_attr "modrm" "0,1")
9664 (set_attr "mode" "SI")])
9666 (define_insn "*ashrsi3_cvt_zext"
9667 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9669 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9670 (match_operand:QI 2 "const_int_operand" ""))))
9671 (clobber (reg:CC FLAGS_REG))]
9672 "TARGET_64BIT && INTVAL (operands[2]) == 31
9673 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9674 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9677 sar{l}\t{%2, %k0|%k0, %2}"
9678 [(set_attr "type" "imovx,ishift")
9679 (set_attr "prefix_0f" "0,*")
9680 (set_attr "length_immediate" "0,*")
9681 (set_attr "modrm" "0,1")
9682 (set_attr "mode" "SI")])
9684 (define_expand "x86_shift<mode>_adj_3"
9685 [(use (match_operand:SWI48 0 "register_operand" ""))
9686 (use (match_operand:SWI48 1 "register_operand" ""))
9687 (use (match_operand:QI 2 "register_operand" ""))]
9690 rtx label = gen_label_rtx ();
9693 emit_insn (gen_testqi_ccz_1 (operands[2],
9694 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9696 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9697 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9698 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9699 gen_rtx_LABEL_REF (VOIDmode, label),
9701 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9702 JUMP_LABEL (tmp) = label;
9704 emit_move_insn (operands[0], operands[1]);
9705 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9706 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9708 LABEL_NUSES (label) = 1;
9713 (define_insn "*<shiftrt_insn><mode>3_1"
9714 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9715 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9716 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9720 if (operands[2] == const1_rtx
9721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722 return "<shiftrt>{<imodesuffix>}\t%0";
9724 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9726 [(set_attr "type" "ishift")
9727 (set (attr "length_immediate")
9729 (and (match_operand 2 "const1_operand" "")
9730 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9733 (const_string "*")))
9734 (set_attr "mode" "<MODE>")])
9736 (define_insn "*<shiftrt_insn>si3_1_zext"
9737 [(set (match_operand:DI 0 "register_operand" "=r")
9739 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9740 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9741 (clobber (reg:CC FLAGS_REG))]
9742 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9744 if (operands[2] == const1_rtx
9745 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9746 return "<shiftrt>{l}\t%k0";
9748 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9750 [(set_attr "type" "ishift")
9751 (set (attr "length_immediate")
9753 (and (match_operand 2 "const1_operand" "")
9754 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9757 (const_string "*")))
9758 (set_attr "mode" "SI")])
9760 (define_insn "*<shiftrt_insn>qi3_1_slp"
9761 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9762 (any_shiftrt:QI (match_dup 0)
9763 (match_operand:QI 1 "nonmemory_operand" "cI")))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "(optimize_function_for_size_p (cfun)
9766 || !TARGET_PARTIAL_REG_STALL
9767 || (operands[1] == const1_rtx
9770 if (operands[1] == const1_rtx
9771 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9772 return "<shiftrt>{b}\t%0";
9774 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9776 [(set_attr "type" "ishift1")
9777 (set (attr "length_immediate")
9779 (and (match_operand 1 "const1_operand" "")
9780 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9783 (const_string "*")))
9784 (set_attr "mode" "QI")])
9786 ;; This pattern can't accept a variable shift count, since shifts by
9787 ;; zero don't affect the flags. We assume that shifts by constant
9788 ;; zero are optimized away.
9789 (define_insn "*<shiftrt_insn><mode>3_cmp"
9790 [(set (reg FLAGS_REG)
9793 (match_operand:SWI 1 "nonimmediate_operand" "0")
9794 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9796 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9797 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9798 "(optimize_function_for_size_p (cfun)
9799 || !TARGET_PARTIAL_FLAG_REG_STALL
9800 || (operands[2] == const1_rtx
9802 && ix86_match_ccmode (insn, CCGOCmode)
9803 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9805 if (operands[2] == const1_rtx
9806 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807 return "<shiftrt>{<imodesuffix>}\t%0";
9809 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9811 [(set_attr "type" "ishift")
9812 (set (attr "length_immediate")
9814 (and (match_operand 2 "const1_operand" "")
9815 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9818 (const_string "*")))
9819 (set_attr "mode" "<MODE>")])
9821 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9822 [(set (reg FLAGS_REG)
9824 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9825 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9827 (set (match_operand:DI 0 "register_operand" "=r")
9828 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9830 && (optimize_function_for_size_p (cfun)
9831 || !TARGET_PARTIAL_FLAG_REG_STALL
9832 || (operands[2] == const1_rtx
9834 && ix86_match_ccmode (insn, CCGOCmode)
9835 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9837 if (operands[2] == const1_rtx
9838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9839 return "<shiftrt>{l}\t%k0";
9841 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9843 [(set_attr "type" "ishift")
9844 (set (attr "length_immediate")
9846 (and (match_operand 2 "const1_operand" "")
9847 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9850 (const_string "*")))
9851 (set_attr "mode" "SI")])
9853 (define_insn "*<shiftrt_insn><mode>3_cconly"
9854 [(set (reg FLAGS_REG)
9857 (match_operand:SWI 1 "register_operand" "0")
9858 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9860 (clobber (match_scratch:SWI 0 "=<r>"))]
9861 "(optimize_function_for_size_p (cfun)
9862 || !TARGET_PARTIAL_FLAG_REG_STALL
9863 || (operands[2] == const1_rtx
9865 && ix86_match_ccmode (insn, CCGOCmode)"
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shiftrt>{<imodesuffix>}\t%0";
9871 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9876 (and (match_operand 2 "const1_operand" "")
9877 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9880 (const_string "*")))
9881 (set_attr "mode" "<MODE>")])
9883 ;; Rotate instructions
9885 (define_expand "<rotate_insn>ti3"
9886 [(set (match_operand:TI 0 "register_operand" "")
9887 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9888 (match_operand:QI 2 "nonmemory_operand" "")))]
9891 if (const_1_to_63_operand (operands[2], VOIDmode))
9892 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9893 (operands[0], operands[1], operands[2]));
9900 (define_expand "<rotate_insn>di3"
9901 [(set (match_operand:DI 0 "shiftdi_operand" "")
9902 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9903 (match_operand:QI 2 "nonmemory_operand" "")))]
9907 ix86_expand_binary_operator (<CODE>, DImode, operands);
9908 else if (const_1_to_31_operand (operands[2], VOIDmode))
9909 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9910 (operands[0], operands[1], operands[2]));
9917 (define_expand "<rotate_insn><mode>3"
9918 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9919 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9920 (match_operand:QI 2 "nonmemory_operand" "")))]
9922 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9924 ;; Avoid useless masking of count operand.
9925 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9926 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9928 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9931 (match_operand:SI 2 "nonimmediate_operand" "c")
9932 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9935 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9936 == GET_MODE_BITSIZE (<MODE>mode)-1"
9939 [(parallel [(set (match_dup 0)
9940 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9941 (clobber (reg:CC FLAGS_REG))])]
9943 if (can_create_pseudo_p ())
9944 operands [2] = force_reg (SImode, operands[2]);
9946 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9948 [(set_attr "type" "rotate")
9949 (set_attr "mode" "<MODE>")])
9951 ;; Implement rotation using two double-precision
9952 ;; shift instructions and a scratch register.
9954 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9955 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9956 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9957 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9958 (clobber (reg:CC FLAGS_REG))
9959 (clobber (match_scratch:DWIH 3 "=&r"))]
9963 [(set (match_dup 3) (match_dup 4))
9966 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9967 (lshiftrt:DWIH (match_dup 5)
9968 (minus:QI (match_dup 6) (match_dup 2)))))
9969 (clobber (reg:CC FLAGS_REG))])
9972 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9973 (lshiftrt:DWIH (match_dup 3)
9974 (minus:QI (match_dup 6) (match_dup 2)))))
9975 (clobber (reg:CC FLAGS_REG))])]
9977 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9979 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9982 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9983 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9984 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9985 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9986 (clobber (reg:CC FLAGS_REG))
9987 (clobber (match_scratch:DWIH 3 "=&r"))]
9991 [(set (match_dup 3) (match_dup 4))
9994 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9995 (ashift:DWIH (match_dup 5)
9996 (minus:QI (match_dup 6) (match_dup 2)))))
9997 (clobber (reg:CC FLAGS_REG))])
10000 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10001 (ashift:DWIH (match_dup 3)
10002 (minus:QI (match_dup 6) (match_dup 2)))))
10003 (clobber (reg:CC FLAGS_REG))])]
10005 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10007 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10010 (define_insn "*<rotate_insn><mode>3_1"
10011 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10012 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10013 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10014 (clobber (reg:CC FLAGS_REG))]
10015 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10017 if (operands[2] == const1_rtx
10018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10019 return "<rotate>{<imodesuffix>}\t%0";
10021 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10023 [(set_attr "type" "rotate")
10024 (set (attr "length_immediate")
10026 (and (match_operand 2 "const1_operand" "")
10027 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10030 (const_string "*")))
10031 (set_attr "mode" "<MODE>")])
10033 (define_insn "*<rotate_insn>si3_1_zext"
10034 [(set (match_operand:DI 0 "register_operand" "=r")
10036 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10037 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10041 if (operands[2] == const1_rtx
10042 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10043 return "<rotate>{l}\t%k0";
10045 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10047 [(set_attr "type" "rotate")
10048 (set (attr "length_immediate")
10050 (and (match_operand 2 "const1_operand" "")
10051 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10054 (const_string "*")))
10055 (set_attr "mode" "SI")])
10057 (define_insn "*<rotate_insn>qi3_1_slp"
10058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10059 (any_rotate:QI (match_dup 0)
10060 (match_operand:QI 1 "nonmemory_operand" "cI")))
10061 (clobber (reg:CC FLAGS_REG))]
10062 "(optimize_function_for_size_p (cfun)
10063 || !TARGET_PARTIAL_REG_STALL
10064 || (operands[1] == const1_rtx
10065 && TARGET_SHIFT1))"
10067 if (operands[1] == const1_rtx
10068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069 return "<rotate>{b}\t%0";
10071 return "<rotate>{b}\t{%1, %0|%0, %1}";
10073 [(set_attr "type" "rotate1")
10074 (set (attr "length_immediate")
10076 (and (match_operand 1 "const1_operand" "")
10077 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10080 (const_string "*")))
10081 (set_attr "mode" "QI")])
10084 [(set (match_operand:HI 0 "register_operand" "")
10085 (any_rotate:HI (match_dup 0) (const_int 8)))
10086 (clobber (reg:CC FLAGS_REG))]
10088 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10089 [(parallel [(set (strict_low_part (match_dup 0))
10090 (bswap:HI (match_dup 0)))
10091 (clobber (reg:CC FLAGS_REG))])])
10093 ;; Bit set / bit test instructions
10095 (define_expand "extv"
10096 [(set (match_operand:SI 0 "register_operand" "")
10097 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10098 (match_operand:SI 2 "const8_operand" "")
10099 (match_operand:SI 3 "const8_operand" "")))]
10102 /* Handle extractions from %ah et al. */
10103 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10106 /* From mips.md: extract_bit_field doesn't verify that our source
10107 matches the predicate, so check it again here. */
10108 if (! ext_register_operand (operands[1], VOIDmode))
10112 (define_expand "extzv"
10113 [(set (match_operand:SI 0 "register_operand" "")
10114 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10115 (match_operand:SI 2 "const8_operand" "")
10116 (match_operand:SI 3 "const8_operand" "")))]
10119 /* Handle extractions from %ah et al. */
10120 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10123 /* From mips.md: extract_bit_field doesn't verify that our source
10124 matches the predicate, so check it again here. */
10125 if (! ext_register_operand (operands[1], VOIDmode))
10129 (define_expand "insv"
10130 [(set (zero_extract (match_operand 0 "register_operand" "")
10131 (match_operand 1 "const_int_operand" "")
10132 (match_operand 2 "const_int_operand" ""))
10133 (match_operand 3 "register_operand" ""))]
10136 rtx (*gen_mov_insv_1) (rtx, rtx);
10138 if (ix86_expand_pinsr (operands))
10141 /* Handle insertions to %ah et al. */
10142 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10145 /* From mips.md: insert_bit_field doesn't verify that our source
10146 matches the predicate, so check it again here. */
10147 if (! ext_register_operand (operands[0], VOIDmode))
10150 gen_mov_insv_1 = (TARGET_64BIT
10151 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10153 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10157 ;; %%% bts, btr, btc, bt.
10158 ;; In general these instructions are *slow* when applied to memory,
10159 ;; since they enforce atomic operation. When applied to registers,
10160 ;; it depends on the cpu implementation. They're never faster than
10161 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10162 ;; no point. But in 64-bit, we can't hold the relevant immediates
10163 ;; within the instruction itself, so operating on bits in the high
10164 ;; 32-bits of a register becomes easier.
10166 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10167 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10168 ;; negdf respectively, so they can never be disabled entirely.
10170 (define_insn "*btsq"
10171 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10173 (match_operand:DI 1 "const_0_to_63_operand" ""))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10177 "bts{q}\t{%1, %0|%0, %1}"
10178 [(set_attr "type" "alu1")
10179 (set_attr "prefix_0f" "1")
10180 (set_attr "mode" "DI")])
10182 (define_insn "*btrq"
10183 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10185 (match_operand:DI 1 "const_0_to_63_operand" ""))
10187 (clobber (reg:CC FLAGS_REG))]
10188 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10189 "btr{q}\t{%1, %0|%0, %1}"
10190 [(set_attr "type" "alu1")
10191 (set_attr "prefix_0f" "1")
10192 (set_attr "mode" "DI")])
10194 (define_insn "*btcq"
10195 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10197 (match_operand:DI 1 "const_0_to_63_operand" ""))
10198 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10199 (clobber (reg:CC FLAGS_REG))]
10200 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10201 "btc{q}\t{%1, %0|%0, %1}"
10202 [(set_attr "type" "alu1")
10203 (set_attr "prefix_0f" "1")
10204 (set_attr "mode" "DI")])
10206 ;; Allow Nocona to avoid these instructions if a register is available.
10209 [(match_scratch:DI 2 "r")
10210 (parallel [(set (zero_extract:DI
10211 (match_operand:DI 0 "register_operand" "")
10213 (match_operand:DI 1 "const_0_to_63_operand" ""))
10215 (clobber (reg:CC FLAGS_REG))])]
10216 "TARGET_64BIT && !TARGET_USE_BT"
10219 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10222 if (HOST_BITS_PER_WIDE_INT >= 64)
10223 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10224 else if (i < HOST_BITS_PER_WIDE_INT)
10225 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10227 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10229 op1 = immed_double_const (lo, hi, DImode);
10232 emit_move_insn (operands[2], op1);
10236 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10241 [(match_scratch:DI 2 "r")
10242 (parallel [(set (zero_extract:DI
10243 (match_operand:DI 0 "register_operand" "")
10245 (match_operand:DI 1 "const_0_to_63_operand" ""))
10247 (clobber (reg:CC FLAGS_REG))])]
10248 "TARGET_64BIT && !TARGET_USE_BT"
10251 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10254 if (HOST_BITS_PER_WIDE_INT >= 64)
10255 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10256 else if (i < HOST_BITS_PER_WIDE_INT)
10257 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10259 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10261 op1 = immed_double_const (~lo, ~hi, DImode);
10264 emit_move_insn (operands[2], op1);
10268 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10273 [(match_scratch:DI 2 "r")
10274 (parallel [(set (zero_extract:DI
10275 (match_operand:DI 0 "register_operand" "")
10277 (match_operand:DI 1 "const_0_to_63_operand" ""))
10278 (not:DI (zero_extract:DI
10279 (match_dup 0) (const_int 1) (match_dup 1))))
10280 (clobber (reg:CC FLAGS_REG))])]
10281 "TARGET_64BIT && !TARGET_USE_BT"
10284 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10287 if (HOST_BITS_PER_WIDE_INT >= 64)
10288 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10289 else if (i < HOST_BITS_PER_WIDE_INT)
10290 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10292 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10294 op1 = immed_double_const (lo, hi, DImode);
10297 emit_move_insn (operands[2], op1);
10301 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10305 (define_insn "*bt<mode>"
10306 [(set (reg:CCC FLAGS_REG)
10308 (zero_extract:SWI48
10309 (match_operand:SWI48 0 "register_operand" "r")
10311 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10313 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10314 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10315 [(set_attr "type" "alu1")
10316 (set_attr "prefix_0f" "1")
10317 (set_attr "mode" "<MODE>")])
10319 ;; Store-flag instructions.
10321 ;; For all sCOND expanders, also expand the compare or test insn that
10322 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10324 (define_insn_and_split "*setcc_di_1"
10325 [(set (match_operand:DI 0 "register_operand" "=q")
10326 (match_operator:DI 1 "ix86_comparison_operator"
10327 [(reg FLAGS_REG) (const_int 0)]))]
10328 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10330 "&& reload_completed"
10331 [(set (match_dup 2) (match_dup 1))
10332 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10334 PUT_MODE (operands[1], QImode);
10335 operands[2] = gen_lowpart (QImode, operands[0]);
10338 (define_insn_and_split "*setcc_si_1_and"
10339 [(set (match_operand:SI 0 "register_operand" "=q")
10340 (match_operator:SI 1 "ix86_comparison_operator"
10341 [(reg FLAGS_REG) (const_int 0)]))
10342 (clobber (reg:CC FLAGS_REG))]
10343 "!TARGET_PARTIAL_REG_STALL
10344 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10346 "&& reload_completed"
10347 [(set (match_dup 2) (match_dup 1))
10348 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10349 (clobber (reg:CC FLAGS_REG))])]
10351 PUT_MODE (operands[1], QImode);
10352 operands[2] = gen_lowpart (QImode, operands[0]);
10355 (define_insn_and_split "*setcc_si_1_movzbl"
10356 [(set (match_operand:SI 0 "register_operand" "=q")
10357 (match_operator:SI 1 "ix86_comparison_operator"
10358 [(reg FLAGS_REG) (const_int 0)]))]
10359 "!TARGET_PARTIAL_REG_STALL
10360 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10362 "&& reload_completed"
10363 [(set (match_dup 2) (match_dup 1))
10364 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10366 PUT_MODE (operands[1], QImode);
10367 operands[2] = gen_lowpart (QImode, operands[0]);
10370 (define_insn "*setcc_qi"
10371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10372 (match_operator:QI 1 "ix86_comparison_operator"
10373 [(reg FLAGS_REG) (const_int 0)]))]
10376 [(set_attr "type" "setcc")
10377 (set_attr "mode" "QI")])
10379 (define_insn "*setcc_qi_slp"
10380 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10381 (match_operator:QI 1 "ix86_comparison_operator"
10382 [(reg FLAGS_REG) (const_int 0)]))]
10385 [(set_attr "type" "setcc")
10386 (set_attr "mode" "QI")])
10388 ;; In general it is not safe to assume too much about CCmode registers,
10389 ;; so simplify-rtx stops when it sees a second one. Under certain
10390 ;; conditions this is safe on x86, so help combine not create
10397 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10398 (ne:QI (match_operator 1 "ix86_comparison_operator"
10399 [(reg FLAGS_REG) (const_int 0)])
10402 [(set (match_dup 0) (match_dup 1))]
10403 "PUT_MODE (operands[1], QImode);")
10406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10407 (ne:QI (match_operator 1 "ix86_comparison_operator"
10408 [(reg FLAGS_REG) (const_int 0)])
10411 [(set (match_dup 0) (match_dup 1))]
10412 "PUT_MODE (operands[1], QImode);")
10415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10416 (eq:QI (match_operator 1 "ix86_comparison_operator"
10417 [(reg FLAGS_REG) (const_int 0)])
10420 [(set (match_dup 0) (match_dup 1))]
10422 rtx new_op1 = copy_rtx (operands[1]);
10423 operands[1] = new_op1;
10424 PUT_MODE (new_op1, QImode);
10425 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10426 GET_MODE (XEXP (new_op1, 0))));
10428 /* Make sure that (a) the CCmode we have for the flags is strong
10429 enough for the reversed compare or (b) we have a valid FP compare. */
10430 if (! ix86_comparison_operator (new_op1, VOIDmode))
10435 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10436 (eq:QI (match_operator 1 "ix86_comparison_operator"
10437 [(reg FLAGS_REG) (const_int 0)])
10440 [(set (match_dup 0) (match_dup 1))]
10442 rtx new_op1 = copy_rtx (operands[1]);
10443 operands[1] = new_op1;
10444 PUT_MODE (new_op1, QImode);
10445 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10446 GET_MODE (XEXP (new_op1, 0))));
10448 /* Make sure that (a) the CCmode we have for the flags is strong
10449 enough for the reversed compare or (b) we have a valid FP compare. */
10450 if (! ix86_comparison_operator (new_op1, VOIDmode))
10454 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10455 ;; subsequent logical operations are used to imitate conditional moves.
10456 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10459 (define_insn "setcc_<mode>_sse"
10460 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10461 (match_operator:MODEF 3 "sse_comparison_operator"
10462 [(match_operand:MODEF 1 "register_operand" "0,x")
10463 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10464 "SSE_FLOAT_MODE_P (<MODE>mode)"
10466 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10467 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10468 [(set_attr "isa" "noavx,avx")
10469 (set_attr "type" "ssecmp")
10470 (set_attr "length_immediate" "1")
10471 (set_attr "prefix" "orig,vex")
10472 (set_attr "mode" "<MODE>")])
10474 ;; Basic conditional jump instructions.
10475 ;; We ignore the overflow flag for signed branch instructions.
10477 (define_insn "*jcc_1"
10479 (if_then_else (match_operator 1 "ix86_comparison_operator"
10480 [(reg FLAGS_REG) (const_int 0)])
10481 (label_ref (match_operand 0 "" ""))
10485 [(set_attr "type" "ibr")
10486 (set_attr "modrm" "0")
10487 (set (attr "length")
10488 (if_then_else (and (ge (minus (match_dup 0) (pc))
10490 (lt (minus (match_dup 0) (pc))
10495 (define_insn "*jcc_2"
10497 (if_then_else (match_operator 1 "ix86_comparison_operator"
10498 [(reg FLAGS_REG) (const_int 0)])
10500 (label_ref (match_operand 0 "" ""))))]
10503 [(set_attr "type" "ibr")
10504 (set_attr "modrm" "0")
10505 (set (attr "length")
10506 (if_then_else (and (ge (minus (match_dup 0) (pc))
10508 (lt (minus (match_dup 0) (pc))
10513 ;; In general it is not safe to assume too much about CCmode registers,
10514 ;; so simplify-rtx stops when it sees a second one. Under certain
10515 ;; conditions this is safe on x86, so help combine not create
10523 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10524 [(reg FLAGS_REG) (const_int 0)])
10526 (label_ref (match_operand 1 "" ""))
10530 (if_then_else (match_dup 0)
10531 (label_ref (match_dup 1))
10533 "PUT_MODE (operands[0], VOIDmode);")
10537 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10538 [(reg FLAGS_REG) (const_int 0)])
10540 (label_ref (match_operand 1 "" ""))
10544 (if_then_else (match_dup 0)
10545 (label_ref (match_dup 1))
10548 rtx new_op0 = copy_rtx (operands[0]);
10549 operands[0] = new_op0;
10550 PUT_MODE (new_op0, VOIDmode);
10551 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10552 GET_MODE (XEXP (new_op0, 0))));
10554 /* Make sure that (a) the CCmode we have for the flags is strong
10555 enough for the reversed compare or (b) we have a valid FP compare. */
10556 if (! ix86_comparison_operator (new_op0, VOIDmode))
10560 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10561 ;; pass generates from shift insn with QImode operand. Actually, the mode
10562 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10563 ;; appropriate modulo of the bit offset value.
10565 (define_insn_and_split "*jcc_bt<mode>"
10567 (if_then_else (match_operator 0 "bt_comparison_operator"
10568 [(zero_extract:SWI48
10569 (match_operand:SWI48 1 "register_operand" "r")
10572 (match_operand:QI 2 "register_operand" "r")))
10574 (label_ref (match_operand 3 "" ""))
10576 (clobber (reg:CC FLAGS_REG))]
10577 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10580 [(set (reg:CCC FLAGS_REG)
10582 (zero_extract:SWI48
10588 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10589 (label_ref (match_dup 3))
10592 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10594 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10597 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10598 ;; also for DImode, this is what combine produces.
10599 (define_insn_and_split "*jcc_bt<mode>_mask"
10601 (if_then_else (match_operator 0 "bt_comparison_operator"
10602 [(zero_extract:SWI48
10603 (match_operand:SWI48 1 "register_operand" "r")
10606 (match_operand:SI 2 "register_operand" "r")
10607 (match_operand:SI 3 "const_int_operand" "n")))])
10608 (label_ref (match_operand 4 "" ""))
10610 (clobber (reg:CC FLAGS_REG))]
10611 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10612 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10613 == GET_MODE_BITSIZE (<MODE>mode)-1"
10616 [(set (reg:CCC FLAGS_REG)
10618 (zero_extract:SWI48
10624 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10625 (label_ref (match_dup 4))
10628 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10630 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10633 (define_insn_and_split "*jcc_btsi_1"
10635 (if_then_else (match_operator 0 "bt_comparison_operator"
10638 (match_operand:SI 1 "register_operand" "r")
10639 (match_operand:QI 2 "register_operand" "r"))
10642 (label_ref (match_operand 3 "" ""))
10644 (clobber (reg:CC FLAGS_REG))]
10645 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10648 [(set (reg:CCC FLAGS_REG)
10656 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10657 (label_ref (match_dup 3))
10660 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10662 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10665 ;; avoid useless masking of bit offset operand
10666 (define_insn_and_split "*jcc_btsi_mask_1"
10669 (match_operator 0 "bt_comparison_operator"
10672 (match_operand:SI 1 "register_operand" "r")
10675 (match_operand:SI 2 "register_operand" "r")
10676 (match_operand:SI 3 "const_int_operand" "n")) 0))
10679 (label_ref (match_operand 4 "" ""))
10681 (clobber (reg:CC FLAGS_REG))]
10682 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10683 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10686 [(set (reg:CCC FLAGS_REG)
10694 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10695 (label_ref (match_dup 4))
10697 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10699 ;; Define combination compare-and-branch fp compare instructions to help
10702 (define_insn "*fp_jcc_1_387"
10704 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10705 [(match_operand 1 "register_operand" "f")
10706 (match_operand 2 "nonimmediate_operand" "fm")])
10707 (label_ref (match_operand 3 "" ""))
10709 (clobber (reg:CCFP FPSR_REG))
10710 (clobber (reg:CCFP FLAGS_REG))
10711 (clobber (match_scratch:HI 4 "=a"))]
10713 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10714 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10715 && SELECT_CC_MODE (GET_CODE (operands[0]),
10716 operands[1], operands[2]) == CCFPmode
10720 (define_insn "*fp_jcc_1r_387"
10722 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10723 [(match_operand 1 "register_operand" "f")
10724 (match_operand 2 "nonimmediate_operand" "fm")])
10726 (label_ref (match_operand 3 "" ""))))
10727 (clobber (reg:CCFP FPSR_REG))
10728 (clobber (reg:CCFP FLAGS_REG))
10729 (clobber (match_scratch:HI 4 "=a"))]
10731 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10732 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10733 && SELECT_CC_MODE (GET_CODE (operands[0]),
10734 operands[1], operands[2]) == CCFPmode
10738 (define_insn "*fp_jcc_2_387"
10740 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10741 [(match_operand 1 "register_operand" "f")
10742 (match_operand 2 "register_operand" "f")])
10743 (label_ref (match_operand 3 "" ""))
10745 (clobber (reg:CCFP FPSR_REG))
10746 (clobber (reg:CCFP FLAGS_REG))
10747 (clobber (match_scratch:HI 4 "=a"))]
10748 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10749 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10753 (define_insn "*fp_jcc_2r_387"
10755 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10756 [(match_operand 1 "register_operand" "f")
10757 (match_operand 2 "register_operand" "f")])
10759 (label_ref (match_operand 3 "" ""))))
10760 (clobber (reg:CCFP FPSR_REG))
10761 (clobber (reg:CCFP FLAGS_REG))
10762 (clobber (match_scratch:HI 4 "=a"))]
10763 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10764 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10768 (define_insn "*fp_jcc_3_387"
10770 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771 [(match_operand 1 "register_operand" "f")
10772 (match_operand 2 "const0_operand" "")])
10773 (label_ref (match_operand 3 "" ""))
10775 (clobber (reg:CCFP FPSR_REG))
10776 (clobber (reg:CCFP FLAGS_REG))
10777 (clobber (match_scratch:HI 4 "=a"))]
10778 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10779 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10780 && SELECT_CC_MODE (GET_CODE (operands[0]),
10781 operands[1], operands[2]) == CCFPmode
10787 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10788 [(match_operand 1 "register_operand" "")
10789 (match_operand 2 "nonimmediate_operand" "")])
10790 (match_operand 3 "" "")
10791 (match_operand 4 "" "")))
10792 (clobber (reg:CCFP FPSR_REG))
10793 (clobber (reg:CCFP FLAGS_REG))]
10797 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10798 operands[3], operands[4], NULL_RTX, NULL_RTX);
10804 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10805 [(match_operand 1 "register_operand" "")
10806 (match_operand 2 "general_operand" "")])
10807 (match_operand 3 "" "")
10808 (match_operand 4 "" "")))
10809 (clobber (reg:CCFP FPSR_REG))
10810 (clobber (reg:CCFP FLAGS_REG))
10811 (clobber (match_scratch:HI 5 "=a"))]
10815 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10816 operands[3], operands[4], operands[5], NULL_RTX);
10820 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10821 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10822 ;; with a precedence over other operators and is always put in the first
10823 ;; place. Swap condition and operands to match ficom instruction.
10825 (define_insn "*fp_jcc_4_<mode>_387"
10828 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10829 [(match_operator 1 "float_operator"
10830 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10831 (match_operand 3 "register_operand" "f,f")])
10832 (label_ref (match_operand 4 "" ""))
10834 (clobber (reg:CCFP FPSR_REG))
10835 (clobber (reg:CCFP FLAGS_REG))
10836 (clobber (match_scratch:HI 5 "=a,a"))]
10837 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10838 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10839 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10840 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10847 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10848 [(match_operator 1 "float_operator"
10849 [(match_operand:SWI24 2 "memory_operand" "")])
10850 (match_operand 3 "register_operand" "")])
10851 (match_operand 4 "" "")
10852 (match_operand 5 "" "")))
10853 (clobber (reg:CCFP FPSR_REG))
10854 (clobber (reg:CCFP FLAGS_REG))
10855 (clobber (match_scratch:HI 6 "=a"))]
10859 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10861 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10862 operands[3], operands[7],
10863 operands[4], operands[5], operands[6], NULL_RTX);
10867 ;; %%% Kill this when reload knows how to do it.
10871 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10872 [(match_operator 1 "float_operator"
10873 [(match_operand:SWI24 2 "register_operand" "")])
10874 (match_operand 3 "register_operand" "")])
10875 (match_operand 4 "" "")
10876 (match_operand 5 "" "")))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 6 "=a"))]
10883 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10884 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10886 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10887 operands[3], operands[7],
10888 operands[4], operands[5], operands[6], operands[2]);
10892 ;; Unconditional and other jump instructions
10894 (define_insn "jump"
10896 (label_ref (match_operand 0 "" "")))]
10899 [(set_attr "type" "ibr")
10900 (set (attr "length")
10901 (if_then_else (and (ge (minus (match_dup 0) (pc))
10903 (lt (minus (match_dup 0) (pc))
10907 (set_attr "modrm" "0")])
10909 (define_expand "indirect_jump"
10910 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10912 (define_insn "*indirect_jump"
10913 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10916 [(set_attr "type" "ibr")
10917 (set_attr "length_immediate" "0")])
10919 (define_expand "tablejump"
10920 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10921 (use (label_ref (match_operand 1 "" "")))])]
10924 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10925 relative. Convert the relative address to an absolute address. */
10929 enum rtx_code code;
10931 /* We can't use @GOTOFF for text labels on VxWorks;
10932 see gotoff_operand. */
10933 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10937 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10939 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10943 op1 = pic_offset_table_rtx;
10948 op0 = pic_offset_table_rtx;
10952 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10955 else if (TARGET_X32)
10956 operands[0] = convert_memory_address (Pmode, operands[0]);
10959 (define_insn "*tablejump_1"
10960 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10961 (use (label_ref (match_operand 1 "" "")))]
10964 [(set_attr "type" "ibr")
10965 (set_attr "length_immediate" "0")])
10967 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10970 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10971 (set (match_operand:QI 1 "register_operand" "")
10972 (match_operator:QI 2 "ix86_comparison_operator"
10973 [(reg FLAGS_REG) (const_int 0)]))
10974 (set (match_operand 3 "q_regs_operand" "")
10975 (zero_extend (match_dup 1)))]
10976 "(peep2_reg_dead_p (3, operands[1])
10977 || operands_match_p (operands[1], operands[3]))
10978 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10979 [(set (match_dup 4) (match_dup 0))
10980 (set (strict_low_part (match_dup 5))
10983 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10984 operands[5] = gen_lowpart (QImode, operands[3]);
10985 ix86_expand_clear (operands[3]);
10988 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
10991 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10992 (set (match_operand:QI 1 "register_operand" "")
10993 (match_operator:QI 2 "ix86_comparison_operator"
10994 [(reg FLAGS_REG) (const_int 0)]))
10995 (parallel [(set (match_operand 3 "q_regs_operand" "")
10996 (zero_extend (match_dup 1)))
10997 (clobber (reg:CC FLAGS_REG))])]
10998 "(peep2_reg_dead_p (3, operands[1])
10999 || operands_match_p (operands[1], operands[3]))
11000 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11001 [(set (match_dup 4) (match_dup 0))
11002 (set (strict_low_part (match_dup 5))
11005 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11006 operands[5] = gen_lowpart (QImode, operands[3]);
11007 ix86_expand_clear (operands[3]);
11010 ;; Call instructions.
11012 ;; The predicates normally associated with named expanders are not properly
11013 ;; checked for calls. This is a bug in the generic code, but it isn't that
11014 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11016 ;; P6 processors will jump to the address after the decrement when %esp
11017 ;; is used as a call operand, so they will execute return address as a code.
11018 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11020 ;; Register constraint for call instruction.
11021 (define_mode_attr c [(SI "l") (DI "r")])
11023 ;; Call subroutine returning no value.
11025 (define_expand "call"
11026 [(call (match_operand:QI 0 "" "")
11027 (match_operand 1 "" ""))
11028 (use (match_operand 2 "" ""))]
11031 ix86_expand_call (NULL, operands[0], operands[1],
11032 operands[2], NULL, false);
11036 (define_expand "sibcall"
11037 [(call (match_operand:QI 0 "" "")
11038 (match_operand 1 "" ""))
11039 (use (match_operand 2 "" ""))]
11042 ix86_expand_call (NULL, operands[0], operands[1],
11043 operands[2], NULL, true);
11047 (define_insn_and_split "*call_vzeroupper"
11048 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11049 (match_operand 1 "" ""))
11050 (unspec [(match_operand 2 "const_int_operand" "")]
11051 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11052 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11054 "&& reload_completed"
11056 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11057 [(set_attr "type" "call")])
11059 (define_insn "*call"
11060 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11061 (match_operand 1 "" ""))]
11062 "!SIBLING_CALL_P (insn)"
11063 "* return ix86_output_call_insn (insn, operands[0]);"
11064 [(set_attr "type" "call")])
11066 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11067 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11068 (match_operand 1 "" ""))
11069 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11070 (clobber (reg:TI XMM6_REG))
11071 (clobber (reg:TI XMM7_REG))
11072 (clobber (reg:TI XMM8_REG))
11073 (clobber (reg:TI XMM9_REG))
11074 (clobber (reg:TI XMM10_REG))
11075 (clobber (reg:TI XMM11_REG))
11076 (clobber (reg:TI XMM12_REG))
11077 (clobber (reg:TI XMM13_REG))
11078 (clobber (reg:TI XMM14_REG))
11079 (clobber (reg:TI XMM15_REG))
11080 (clobber (reg:DI SI_REG))
11081 (clobber (reg:DI DI_REG))
11082 (unspec [(match_operand 2 "const_int_operand" "")]
11083 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11084 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11086 "&& reload_completed"
11088 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11089 [(set_attr "type" "call")])
11091 (define_insn "*call_rex64_ms_sysv"
11092 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11093 (match_operand 1 "" ""))
11094 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11095 (clobber (reg:TI XMM6_REG))
11096 (clobber (reg:TI XMM7_REG))
11097 (clobber (reg:TI XMM8_REG))
11098 (clobber (reg:TI XMM9_REG))
11099 (clobber (reg:TI XMM10_REG))
11100 (clobber (reg:TI XMM11_REG))
11101 (clobber (reg:TI XMM12_REG))
11102 (clobber (reg:TI XMM13_REG))
11103 (clobber (reg:TI XMM14_REG))
11104 (clobber (reg:TI XMM15_REG))
11105 (clobber (reg:DI SI_REG))
11106 (clobber (reg:DI DI_REG))]
11107 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11108 "* return ix86_output_call_insn (insn, operands[0]);"
11109 [(set_attr "type" "call")])
11111 (define_insn_and_split "*sibcall_vzeroupper"
11112 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11113 (match_operand 1 "" ""))
11114 (unspec [(match_operand 2 "const_int_operand" "")]
11115 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11116 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11118 "&& reload_completed"
11120 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11121 [(set_attr "type" "call")])
11123 (define_insn "*sibcall"
11124 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11125 (match_operand 1 "" ""))]
11126 "SIBLING_CALL_P (insn)"
11127 "* return ix86_output_call_insn (insn, operands[0]);"
11128 [(set_attr "type" "call")])
11130 (define_expand "call_pop"
11131 [(parallel [(call (match_operand:QI 0 "" "")
11132 (match_operand:SI 1 "" ""))
11133 (set (reg:SI SP_REG)
11134 (plus:SI (reg:SI SP_REG)
11135 (match_operand:SI 3 "" "")))])]
11138 ix86_expand_call (NULL, operands[0], operands[1],
11139 operands[2], operands[3], false);
11143 (define_insn_and_split "*call_pop_vzeroupper"
11144 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11145 (match_operand:SI 1 "" ""))
11146 (set (reg:SI SP_REG)
11147 (plus:SI (reg:SI SP_REG)
11148 (match_operand:SI 2 "immediate_operand" "i")))
11149 (unspec [(match_operand 3 "const_int_operand" "")]
11150 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11151 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11153 "&& reload_completed"
11155 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11156 [(set_attr "type" "call")])
11158 (define_insn "*call_pop"
11159 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11160 (match_operand 1 "" ""))
11161 (set (reg:SI SP_REG)
11162 (plus:SI (reg:SI SP_REG)
11163 (match_operand:SI 2 "immediate_operand" "i")))]
11164 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11165 "* return ix86_output_call_insn (insn, operands[0]);"
11166 [(set_attr "type" "call")])
11168 (define_insn_and_split "*sibcall_pop_vzeroupper"
11169 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11170 (match_operand 1 "" ""))
11171 (set (reg:SI SP_REG)
11172 (plus:SI (reg:SI SP_REG)
11173 (match_operand:SI 2 "immediate_operand" "i")))
11174 (unspec [(match_operand 3 "const_int_operand" "")]
11175 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11176 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11178 "&& reload_completed"
11180 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11181 [(set_attr "type" "call")])
11183 (define_insn "*sibcall_pop"
11184 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11185 (match_operand 1 "" ""))
11186 (set (reg:SI SP_REG)
11187 (plus:SI (reg:SI SP_REG)
11188 (match_operand:SI 2 "immediate_operand" "i")))]
11189 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11190 "* return ix86_output_call_insn (insn, operands[0]);"
11191 [(set_attr "type" "call")])
11193 ;; Call subroutine, returning value in operand 0
11195 (define_expand "call_value"
11196 [(set (match_operand 0 "" "")
11197 (call (match_operand:QI 1 "" "")
11198 (match_operand 2 "" "")))
11199 (use (match_operand 3 "" ""))]
11202 ix86_expand_call (operands[0], operands[1], operands[2],
11203 operands[3], NULL, false);
11207 (define_expand "sibcall_value"
11208 [(set (match_operand 0 "" "")
11209 (call (match_operand:QI 1 "" "")
11210 (match_operand 2 "" "")))
11211 (use (match_operand 3 "" ""))]
11214 ix86_expand_call (operands[0], operands[1], operands[2],
11215 operands[3], NULL, true);
11219 (define_insn_and_split "*call_value_vzeroupper"
11220 [(set (match_operand 0 "" "")
11221 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11222 (match_operand 2 "" "")))
11223 (unspec [(match_operand 3 "const_int_operand" "")]
11224 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11225 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11227 "&& reload_completed"
11229 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11230 [(set_attr "type" "callv")])
11232 (define_insn "*call_value"
11233 [(set (match_operand 0 "" "")
11234 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11235 (match_operand 2 "" "")))]
11236 "!SIBLING_CALL_P (insn)"
11237 "* return ix86_output_call_insn (insn, operands[1]);"
11238 [(set_attr "type" "callv")])
11240 (define_insn_and_split "*sibcall_value_vzeroupper"
11241 [(set (match_operand 0 "" "")
11242 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11243 (match_operand 2 "" "")))
11244 (unspec [(match_operand 3 "const_int_operand" "")]
11245 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11246 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11248 "&& reload_completed"
11250 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11251 [(set_attr "type" "callv")])
11253 (define_insn "*sibcall_value"
11254 [(set (match_operand 0 "" "")
11255 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11256 (match_operand 2 "" "")))]
11257 "SIBLING_CALL_P (insn)"
11258 "* return ix86_output_call_insn (insn, operands[1]);"
11259 [(set_attr "type" "callv")])
11261 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11262 [(set (match_operand 0 "" "")
11263 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11264 (match_operand 2 "" "")))
11265 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11266 (clobber (reg:TI XMM6_REG))
11267 (clobber (reg:TI XMM7_REG))
11268 (clobber (reg:TI XMM8_REG))
11269 (clobber (reg:TI XMM9_REG))
11270 (clobber (reg:TI XMM10_REG))
11271 (clobber (reg:TI XMM11_REG))
11272 (clobber (reg:TI XMM12_REG))
11273 (clobber (reg:TI XMM13_REG))
11274 (clobber (reg:TI XMM14_REG))
11275 (clobber (reg:TI XMM15_REG))
11276 (clobber (reg:DI SI_REG))
11277 (clobber (reg:DI DI_REG))
11278 (unspec [(match_operand 3 "const_int_operand" "")]
11279 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11280 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11282 "&& reload_completed"
11284 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11285 [(set_attr "type" "callv")])
11287 (define_insn "*call_value_rex64_ms_sysv"
11288 [(set (match_operand 0 "" "")
11289 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11290 (match_operand 2 "" "")))
11291 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11292 (clobber (reg:TI XMM6_REG))
11293 (clobber (reg:TI XMM7_REG))
11294 (clobber (reg:TI XMM8_REG))
11295 (clobber (reg:TI XMM9_REG))
11296 (clobber (reg:TI XMM10_REG))
11297 (clobber (reg:TI XMM11_REG))
11298 (clobber (reg:TI XMM12_REG))
11299 (clobber (reg:TI XMM13_REG))
11300 (clobber (reg:TI XMM14_REG))
11301 (clobber (reg:TI XMM15_REG))
11302 (clobber (reg:DI SI_REG))
11303 (clobber (reg:DI DI_REG))]
11304 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11305 "* return ix86_output_call_insn (insn, operands[1]);"
11306 [(set_attr "type" "callv")])
11308 (define_expand "call_value_pop"
11309 [(parallel [(set (match_operand 0 "" "")
11310 (call (match_operand:QI 1 "" "")
11311 (match_operand:SI 2 "" "")))
11312 (set (reg:SI SP_REG)
11313 (plus:SI (reg:SI SP_REG)
11314 (match_operand:SI 4 "" "")))])]
11317 ix86_expand_call (operands[0], operands[1], operands[2],
11318 operands[3], operands[4], false);
11322 (define_insn_and_split "*call_value_pop_vzeroupper"
11323 [(set (match_operand 0 "" "")
11324 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11325 (match_operand 2 "" "")))
11326 (set (reg:SI SP_REG)
11327 (plus:SI (reg:SI SP_REG)
11328 (match_operand:SI 3 "immediate_operand" "i")))
11329 (unspec [(match_operand 4 "const_int_operand" "")]
11330 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11331 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11333 "&& reload_completed"
11335 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11336 [(set_attr "type" "callv")])
11338 (define_insn "*call_value_pop"
11339 [(set (match_operand 0 "" "")
11340 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11341 (match_operand 2 "" "")))
11342 (set (reg:SI SP_REG)
11343 (plus:SI (reg:SI SP_REG)
11344 (match_operand:SI 3 "immediate_operand" "i")))]
11345 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346 "* return ix86_output_call_insn (insn, operands[1]);"
11347 [(set_attr "type" "callv")])
11349 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11350 [(set (match_operand 0 "" "")
11351 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11352 (match_operand 2 "" "")))
11353 (set (reg:SI SP_REG)
11354 (plus:SI (reg:SI SP_REG)
11355 (match_operand:SI 3 "immediate_operand" "i")))
11356 (unspec [(match_operand 4 "const_int_operand" "")]
11357 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11358 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 "&& reload_completed"
11362 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11363 [(set_attr "type" "callv")])
11365 (define_insn "*sibcall_value_pop"
11366 [(set (match_operand 0 "" "")
11367 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11368 (match_operand 2 "" "")))
11369 (set (reg:SI SP_REG)
11370 (plus:SI (reg:SI SP_REG)
11371 (match_operand:SI 3 "immediate_operand" "i")))]
11372 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11373 "* return ix86_output_call_insn (insn, operands[1]);"
11374 [(set_attr "type" "callv")])
11376 ;; Call subroutine returning any type.
11378 (define_expand "untyped_call"
11379 [(parallel [(call (match_operand 0 "" "")
11381 (match_operand 1 "" "")
11382 (match_operand 2 "" "")])]
11387 /* In order to give reg-stack an easier job in validating two
11388 coprocessor registers as containing a possible return value,
11389 simply pretend the untyped call returns a complex long double
11392 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11393 and should have the default ABI. */
11395 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11396 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11397 operands[0], const0_rtx,
11398 GEN_INT ((TARGET_64BIT
11399 ? (ix86_abi == SYSV_ABI
11400 ? X86_64_SSE_REGPARM_MAX
11401 : X86_64_MS_SSE_REGPARM_MAX)
11402 : X86_32_SSE_REGPARM_MAX)
11406 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11408 rtx set = XVECEXP (operands[2], 0, i);
11409 emit_move_insn (SET_DEST (set), SET_SRC (set));
11412 /* The optimizer does not know that the call sets the function value
11413 registers we stored in the result block. We avoid problems by
11414 claiming that all hard registers are used and clobbered at this
11416 emit_insn (gen_blockage ());
11421 ;; Prologue and epilogue instructions
11423 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11424 ;; all of memory. This blocks insns from being moved across this point.
11426 (define_insn "blockage"
11427 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11430 [(set_attr "length" "0")])
11432 ;; Do not schedule instructions accessing memory across this point.
11434 (define_expand "memory_blockage"
11435 [(set (match_dup 0)
11436 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11439 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11440 MEM_VOLATILE_P (operands[0]) = 1;
11443 (define_insn "*memory_blockage"
11444 [(set (match_operand:BLK 0 "" "")
11445 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11448 [(set_attr "length" "0")])
11450 ;; As USE insns aren't meaningful after reload, this is used instead
11451 ;; to prevent deleting instructions setting registers for PIC code
11452 (define_insn "prologue_use"
11453 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11456 [(set_attr "length" "0")])
11458 ;; Insn emitted into the body of a function to return from a function.
11459 ;; This is only done if the function's epilogue is known to be simple.
11460 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11462 (define_expand "return"
11464 "ix86_can_use_return_insn_p ()"
11466 if (crtl->args.pops_args)
11468 rtx popc = GEN_INT (crtl->args.pops_args);
11469 emit_jump_insn (gen_return_pop_internal (popc));
11474 (define_insn "return_internal"
11478 [(set_attr "length" "1")
11479 (set_attr "atom_unit" "jeu")
11480 (set_attr "length_immediate" "0")
11481 (set_attr "modrm" "0")])
11483 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11484 ;; instruction Athlon and K8 have.
11486 (define_insn "return_internal_long"
11488 (unspec [(const_int 0)] UNSPEC_REP)]
11491 [(set_attr "length" "2")
11492 (set_attr "atom_unit" "jeu")
11493 (set_attr "length_immediate" "0")
11494 (set_attr "prefix_rep" "1")
11495 (set_attr "modrm" "0")])
11497 (define_insn "return_pop_internal"
11499 (use (match_operand:SI 0 "const_int_operand" ""))]
11502 [(set_attr "length" "3")
11503 (set_attr "atom_unit" "jeu")
11504 (set_attr "length_immediate" "2")
11505 (set_attr "modrm" "0")])
11507 (define_insn "return_indirect_internal"
11509 (use (match_operand:SI 0 "register_operand" "r"))]
11512 [(set_attr "type" "ibr")
11513 (set_attr "length_immediate" "0")])
11519 [(set_attr "length" "1")
11520 (set_attr "length_immediate" "0")
11521 (set_attr "modrm" "0")])
11523 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11524 (define_insn "nops"
11525 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11529 int num = INTVAL (operands[0]);
11531 gcc_assert (num >= 1 && num <= 8);
11534 fputs ("\tnop\n", asm_out_file);
11538 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11539 (set_attr "length_immediate" "0")
11540 (set_attr "modrm" "0")])
11542 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11543 ;; branch prediction penalty for the third jump in a 16-byte
11547 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11550 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11551 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11553 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11554 The align insn is used to avoid 3 jump instructions in the row to improve
11555 branch prediction and the benefits hardly outweigh the cost of extra 8
11556 nops on the average inserted by full alignment pseudo operation. */
11560 [(set_attr "length" "16")])
11562 (define_expand "prologue"
11565 "ix86_expand_prologue (); DONE;")
11567 (define_insn "set_got"
11568 [(set (match_operand:SI 0 "register_operand" "=r")
11569 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11570 (clobber (reg:CC FLAGS_REG))]
11572 "* return output_set_got (operands[0], NULL_RTX);"
11573 [(set_attr "type" "multi")
11574 (set_attr "length" "12")])
11576 (define_insn "set_got_labelled"
11577 [(set (match_operand:SI 0 "register_operand" "=r")
11578 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11580 (clobber (reg:CC FLAGS_REG))]
11582 "* return output_set_got (operands[0], operands[1]);"
11583 [(set_attr "type" "multi")
11584 (set_attr "length" "12")])
11586 (define_insn "set_got_rex64"
11587 [(set (match_operand:DI 0 "register_operand" "=r")
11588 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11590 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11591 [(set_attr "type" "lea")
11592 (set_attr "length_address" "4")
11593 (set_attr "mode" "DI")])
11595 (define_insn "set_rip_rex64"
11596 [(set (match_operand:DI 0 "register_operand" "=r")
11597 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11599 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11600 [(set_attr "type" "lea")
11601 (set_attr "length_address" "4")
11602 (set_attr "mode" "DI")])
11604 (define_insn "set_got_offset_rex64"
11605 [(set (match_operand:DI 0 "register_operand" "=r")
11607 [(label_ref (match_operand 1 "" ""))]
11608 UNSPEC_SET_GOT_OFFSET))]
11610 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11611 [(set_attr "type" "imov")
11612 (set_attr "length_immediate" "0")
11613 (set_attr "length_address" "8")
11614 (set_attr "mode" "DI")])
11616 (define_expand "epilogue"
11619 "ix86_expand_epilogue (1); DONE;")
11621 (define_expand "sibcall_epilogue"
11624 "ix86_expand_epilogue (0); DONE;")
11626 (define_expand "eh_return"
11627 [(use (match_operand 0 "register_operand" ""))]
11630 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11632 /* Tricky bit: we write the address of the handler to which we will
11633 be returning into someone else's stack frame, one word below the
11634 stack address we wish to restore. */
11635 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11636 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11637 tmp = gen_rtx_MEM (Pmode, tmp);
11638 emit_move_insn (tmp, ra);
11640 emit_jump_insn (gen_eh_return_internal ());
11645 (define_insn_and_split "eh_return_internal"
11649 "epilogue_completed"
11651 "ix86_expand_epilogue (2); DONE;")
11653 (define_insn "leave"
11654 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11655 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11656 (clobber (mem:BLK (scratch)))]
11659 [(set_attr "type" "leave")])
11661 (define_insn "leave_rex64"
11662 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11663 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11664 (clobber (mem:BLK (scratch)))]
11667 [(set_attr "type" "leave")])
11669 ;; Handle -fsplit-stack.
11671 (define_expand "split_stack_prologue"
11675 ix86_expand_split_stack_prologue ();
11679 ;; In order to support the call/return predictor, we use a return
11680 ;; instruction which the middle-end doesn't see.
11681 (define_insn "split_stack_return"
11682 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11683 UNSPECV_SPLIT_STACK_RETURN)]
11686 if (operands[0] == const0_rtx)
11691 [(set_attr "atom_unit" "jeu")
11692 (set_attr "modrm" "0")
11693 (set (attr "length")
11694 (if_then_else (match_operand:SI 0 "const0_operand" "")
11697 (set (attr "length_immediate")
11698 (if_then_else (match_operand:SI 0 "const0_operand" "")
11702 ;; If there are operand 0 bytes available on the stack, jump to
11705 (define_expand "split_stack_space_check"
11706 [(set (pc) (if_then_else
11707 (ltu (minus (reg SP_REG)
11708 (match_operand 0 "register_operand" ""))
11709 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11710 (label_ref (match_operand 1 "" ""))
11714 rtx reg, size, limit;
11716 reg = gen_reg_rtx (Pmode);
11717 size = force_reg (Pmode, operands[0]);
11718 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11719 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11720 UNSPEC_STACK_CHECK);
11721 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11722 ix86_expand_branch (GEU, reg, limit, operands[1]);
11727 ;; Bit manipulation instructions.
11729 (define_expand "ffs<mode>2"
11730 [(set (match_dup 2) (const_int -1))
11731 (parallel [(set (reg:CCZ FLAGS_REG)
11733 (match_operand:SWI48 1 "nonimmediate_operand" "")
11735 (set (match_operand:SWI48 0 "register_operand" "")
11736 (ctz:SWI48 (match_dup 1)))])
11737 (set (match_dup 0) (if_then_else:SWI48
11738 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11741 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11742 (clobber (reg:CC FLAGS_REG))])]
11745 if (<MODE>mode == SImode && !TARGET_CMOVE)
11747 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11750 operands[2] = gen_reg_rtx (<MODE>mode);
11753 (define_insn_and_split "ffssi2_no_cmove"
11754 [(set (match_operand:SI 0 "register_operand" "=r")
11755 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11756 (clobber (match_scratch:SI 2 "=&q"))
11757 (clobber (reg:CC FLAGS_REG))]
11760 "&& reload_completed"
11761 [(parallel [(set (reg:CCZ FLAGS_REG)
11762 (compare:CCZ (match_dup 1) (const_int 0)))
11763 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11764 (set (strict_low_part (match_dup 3))
11765 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11766 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11767 (clobber (reg:CC FLAGS_REG))])
11768 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11769 (clobber (reg:CC FLAGS_REG))])
11770 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11771 (clobber (reg:CC FLAGS_REG))])]
11773 operands[3] = gen_lowpart (QImode, operands[2]);
11774 ix86_expand_clear (operands[2]);
11777 (define_insn "*ffs<mode>_1"
11778 [(set (reg:CCZ FLAGS_REG)
11779 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11781 (set (match_operand:SWI48 0 "register_operand" "=r")
11782 (ctz:SWI48 (match_dup 1)))]
11784 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11785 [(set_attr "type" "alu1")
11786 (set_attr "prefix_0f" "1")
11787 (set_attr "mode" "<MODE>")])
11789 (define_insn "ctz<mode>2"
11790 [(set (match_operand:SWI248 0 "register_operand" "=r")
11791 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11792 (clobber (reg:CC FLAGS_REG))]
11796 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11798 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11800 [(set_attr "type" "alu1")
11801 (set_attr "prefix_0f" "1")
11802 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11803 (set_attr "mode" "<MODE>")])
11805 (define_expand "clz<mode>2"
11807 [(set (match_operand:SWI248 0 "register_operand" "")
11810 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11811 (clobber (reg:CC FLAGS_REG))])
11813 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11814 (clobber (reg:CC FLAGS_REG))])]
11819 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11822 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11825 (define_insn "clz<mode>2_lzcnt"
11826 [(set (match_operand:SWI248 0 "register_operand" "=r")
11827 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11828 (clobber (reg:CC FLAGS_REG))]
11830 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11831 [(set_attr "prefix_rep" "1")
11832 (set_attr "type" "bitmanip")
11833 (set_attr "mode" "<MODE>")])
11835 ;; BMI instructions.
11836 (define_insn "*bmi_andn_<mode>"
11837 [(set (match_operand:SWI48 0 "register_operand" "=r")
11840 (match_operand:SWI48 1 "register_operand" "r"))
11841 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11842 (clobber (reg:CC FLAGS_REG))]
11844 "andn\t{%2, %1, %0|%0, %1, %2}"
11845 [(set_attr "type" "bitmanip")
11846 (set_attr "mode" "<MODE>")])
11848 (define_insn "bmi_bextr_<mode>"
11849 [(set (match_operand:SWI48 0 "register_operand" "=r")
11850 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11851 (match_operand:SWI48 2 "register_operand" "r")]
11853 (clobber (reg:CC FLAGS_REG))]
11855 "bextr\t{%2, %1, %0|%0, %1, %2}"
11856 [(set_attr "type" "bitmanip")
11857 (set_attr "mode" "<MODE>")])
11859 (define_insn "*bmi_blsi_<mode>"
11860 [(set (match_operand:SWI48 0 "register_operand" "=r")
11863 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11865 (clobber (reg:CC FLAGS_REG))]
11867 "blsi\t{%1, %0|%0, %1}"
11868 [(set_attr "type" "bitmanip")
11869 (set_attr "mode" "<MODE>")])
11871 (define_insn "*bmi_blsmsk_<mode>"
11872 [(set (match_operand:SWI48 0 "register_operand" "=r")
11875 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11878 (clobber (reg:CC FLAGS_REG))]
11880 "blsmsk\t{%1, %0|%0, %1}"
11881 [(set_attr "type" "bitmanip")
11882 (set_attr "mode" "<MODE>")])
11884 (define_insn "*bmi_blsr_<mode>"
11885 [(set (match_operand:SWI48 0 "register_operand" "=r")
11888 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11891 (clobber (reg:CC FLAGS_REG))]
11893 "blsr\t{%1, %0|%0, %1}"
11894 [(set_attr "type" "bitmanip")
11895 (set_attr "mode" "<MODE>")])
11897 ;; TBM instructions.
11898 (define_insn "tbm_bextri_<mode>"
11899 [(set (match_operand:SWI48 0 "register_operand" "=r")
11900 (zero_extract:SWI48
11901 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11902 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11903 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11904 (clobber (reg:CC FLAGS_REG))]
11907 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11908 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "mode" "<MODE>")])
11913 (define_insn "*tbm_blcfill_<mode>"
11914 [(set (match_operand:SWI48 0 "register_operand" "=r")
11917 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11920 (clobber (reg:CC FLAGS_REG))]
11922 "blcfill\t{%1, %0|%0, %1}"
11923 [(set_attr "type" "bitmanip")
11924 (set_attr "mode" "<MODE>")])
11926 (define_insn "*tbm_blci_<mode>"
11927 [(set (match_operand:SWI48 0 "register_operand" "=r")
11931 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11934 (clobber (reg:CC FLAGS_REG))]
11936 "blci\t{%1, %0|%0, %1}"
11937 [(set_attr "type" "bitmanip")
11938 (set_attr "mode" "<MODE>")])
11940 (define_insn "*tbm_blcic_<mode>"
11941 [(set (match_operand:SWI48 0 "register_operand" "=r")
11944 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11948 (clobber (reg:CC FLAGS_REG))]
11950 "blcic\t{%1, %0|%0, %1}"
11951 [(set_attr "type" "bitmanip")
11952 (set_attr "mode" "<MODE>")])
11954 (define_insn "*tbm_blcmsk_<mode>"
11955 [(set (match_operand:SWI48 0 "register_operand" "=r")
11958 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11961 (clobber (reg:CC FLAGS_REG))]
11963 "blcmsk\t{%1, %0|%0, %1}"
11964 [(set_attr "type" "bitmanip")
11965 (set_attr "mode" "<MODE>")])
11967 (define_insn "*tbm_blcs_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11971 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11974 (clobber (reg:CC FLAGS_REG))]
11976 "blcs\t{%1, %0|%0, %1}"
11977 [(set_attr "type" "bitmanip")
11978 (set_attr "mode" "<MODE>")])
11980 (define_insn "*tbm_blsfill_<mode>"
11981 [(set (match_operand:SWI48 0 "register_operand" "=r")
11984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11987 (clobber (reg:CC FLAGS_REG))]
11989 "blsfill\t{%1, %0|%0, %1}"
11990 [(set_attr "type" "bitmanip")
11991 (set_attr "mode" "<MODE>")])
11993 (define_insn "*tbm_blsic_<mode>"
11994 [(set (match_operand:SWI48 0 "register_operand" "=r")
11997 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12001 (clobber (reg:CC FLAGS_REG))]
12003 "blsic\t{%1, %0|%0, %1}"
12004 [(set_attr "type" "bitmanip")
12005 (set_attr "mode" "<MODE>")])
12007 (define_insn "*tbm_t1mskc_<mode>"
12008 [(set (match_operand:SWI48 0 "register_operand" "=r")
12011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12015 (clobber (reg:CC FLAGS_REG))]
12017 "t1mskc\t{%1, %0|%0, %1}"
12018 [(set_attr "type" "bitmanip")
12019 (set_attr "mode" "<MODE>")])
12021 (define_insn "*tbm_tzmsk_<mode>"
12022 [(set (match_operand:SWI48 0 "register_operand" "=r")
12025 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12029 (clobber (reg:CC FLAGS_REG))]
12031 "tzmsk\t{%1, %0|%0, %1}"
12032 [(set_attr "type" "bitmanip")
12033 (set_attr "mode" "<MODE>")])
12035 (define_insn "bsr_rex64"
12036 [(set (match_operand:DI 0 "register_operand" "=r")
12037 (minus:DI (const_int 63)
12038 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12039 (clobber (reg:CC FLAGS_REG))]
12041 "bsr{q}\t{%1, %0|%0, %1}"
12042 [(set_attr "type" "alu1")
12043 (set_attr "prefix_0f" "1")
12044 (set_attr "mode" "DI")])
12047 [(set (match_operand:SI 0 "register_operand" "=r")
12048 (minus:SI (const_int 31)
12049 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12050 (clobber (reg:CC FLAGS_REG))]
12052 "bsr{l}\t{%1, %0|%0, %1}"
12053 [(set_attr "type" "alu1")
12054 (set_attr "prefix_0f" "1")
12055 (set_attr "mode" "SI")])
12057 (define_insn "*bsrhi"
12058 [(set (match_operand:HI 0 "register_operand" "=r")
12059 (minus:HI (const_int 15)
12060 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12061 (clobber (reg:CC FLAGS_REG))]
12063 "bsr{w}\t{%1, %0|%0, %1}"
12064 [(set_attr "type" "alu1")
12065 (set_attr "prefix_0f" "1")
12066 (set_attr "mode" "HI")])
12068 (define_insn "popcount<mode>2"
12069 [(set (match_operand:SWI248 0 "register_operand" "=r")
12071 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12072 (clobber (reg:CC FLAGS_REG))]
12076 return "popcnt\t{%1, %0|%0, %1}";
12078 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12081 [(set_attr "prefix_rep" "1")
12082 (set_attr "type" "bitmanip")
12083 (set_attr "mode" "<MODE>")])
12085 (define_insn "*popcount<mode>2_cmp"
12086 [(set (reg FLAGS_REG)
12089 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12091 (set (match_operand:SWI248 0 "register_operand" "=r")
12092 (popcount:SWI248 (match_dup 1)))]
12093 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12096 return "popcnt\t{%1, %0|%0, %1}";
12098 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12101 [(set_attr "prefix_rep" "1")
12102 (set_attr "type" "bitmanip")
12103 (set_attr "mode" "<MODE>")])
12105 (define_insn "*popcountsi2_cmp_zext"
12106 [(set (reg FLAGS_REG)
12108 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12110 (set (match_operand:DI 0 "register_operand" "=r")
12111 (zero_extend:DI(popcount:SI (match_dup 1))))]
12112 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12115 return "popcnt\t{%1, %0|%0, %1}";
12117 return "popcnt{l}\t{%1, %0|%0, %1}";
12120 [(set_attr "prefix_rep" "1")
12121 (set_attr "type" "bitmanip")
12122 (set_attr "mode" "SI")])
12124 (define_expand "bswap<mode>2"
12125 [(set (match_operand:SWI48 0 "register_operand" "")
12126 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12129 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12131 rtx x = operands[0];
12133 emit_move_insn (x, operands[1]);
12134 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12135 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12136 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12141 (define_insn "*bswap<mode>2_movbe"
12142 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12143 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12148 movbe\t{%1, %0|%0, %1}
12149 movbe\t{%1, %0|%0, %1}"
12150 [(set_attr "type" "bitmanip,imov,imov")
12151 (set_attr "modrm" "0,1,1")
12152 (set_attr "prefix_0f" "*,1,1")
12153 (set_attr "prefix_extra" "*,1,1")
12154 (set_attr "mode" "<MODE>")])
12156 (define_insn "*bswap<mode>2_1"
12157 [(set (match_operand:SWI48 0 "register_operand" "=r")
12158 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12161 [(set_attr "type" "bitmanip")
12162 (set_attr "modrm" "0")
12163 (set_attr "mode" "<MODE>")])
12165 (define_insn "*bswaphi_lowpart_1"
12166 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12167 (bswap:HI (match_dup 0)))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12171 xchg{b}\t{%h0, %b0|%b0, %h0}
12172 rol{w}\t{$8, %0|%0, 8}"
12173 [(set_attr "length" "2,4")
12174 (set_attr "mode" "QI,HI")])
12176 (define_insn "bswaphi_lowpart"
12177 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12178 (bswap:HI (match_dup 0)))
12179 (clobber (reg:CC FLAGS_REG))]
12181 "rol{w}\t{$8, %0|%0, 8}"
12182 [(set_attr "length" "4")
12183 (set_attr "mode" "HI")])
12185 (define_expand "paritydi2"
12186 [(set (match_operand:DI 0 "register_operand" "")
12187 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12190 rtx scratch = gen_reg_rtx (QImode);
12193 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12194 NULL_RTX, operands[1]));
12196 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12197 gen_rtx_REG (CCmode, FLAGS_REG),
12199 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12202 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12205 rtx tmp = gen_reg_rtx (SImode);
12207 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12208 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12213 (define_expand "paritysi2"
12214 [(set (match_operand:SI 0 "register_operand" "")
12215 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12218 rtx scratch = gen_reg_rtx (QImode);
12221 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12223 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12224 gen_rtx_REG (CCmode, FLAGS_REG),
12226 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12228 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12232 (define_insn_and_split "paritydi2_cmp"
12233 [(set (reg:CC FLAGS_REG)
12234 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12236 (clobber (match_scratch:DI 0 "=r"))
12237 (clobber (match_scratch:SI 1 "=&r"))
12238 (clobber (match_scratch:HI 2 "=Q"))]
12241 "&& reload_completed"
12243 [(set (match_dup 1)
12244 (xor:SI (match_dup 1) (match_dup 4)))
12245 (clobber (reg:CC FLAGS_REG))])
12247 [(set (reg:CC FLAGS_REG)
12248 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12249 (clobber (match_dup 1))
12250 (clobber (match_dup 2))])]
12252 operands[4] = gen_lowpart (SImode, operands[3]);
12256 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12257 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12260 operands[1] = gen_highpart (SImode, operands[3]);
12263 (define_insn_and_split "paritysi2_cmp"
12264 [(set (reg:CC FLAGS_REG)
12265 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12267 (clobber (match_scratch:SI 0 "=r"))
12268 (clobber (match_scratch:HI 1 "=&Q"))]
12271 "&& reload_completed"
12273 [(set (match_dup 1)
12274 (xor:HI (match_dup 1) (match_dup 3)))
12275 (clobber (reg:CC FLAGS_REG))])
12277 [(set (reg:CC FLAGS_REG)
12278 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12279 (clobber (match_dup 1))])]
12281 operands[3] = gen_lowpart (HImode, operands[2]);
12283 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12284 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12287 (define_insn "*parityhi2_cmp"
12288 [(set (reg:CC FLAGS_REG)
12289 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12291 (clobber (match_scratch:HI 0 "=Q"))]
12293 "xor{b}\t{%h0, %b0|%b0, %h0}"
12294 [(set_attr "length" "2")
12295 (set_attr "mode" "HI")])
12297 ;; Thread-local storage patterns for ELF.
12299 ;; Note that these code sequences must appear exactly as shown
12300 ;; in order to allow linker relaxation.
12302 (define_insn "*tls_global_dynamic_32_gnu"
12303 [(set (match_operand:SI 0 "register_operand" "=a")
12305 [(match_operand:SI 1 "register_operand" "b")
12306 (match_operand:SI 2 "tls_symbolic_operand" "")
12307 (match_operand:SI 3 "constant_call_address_operand" "z")]
12309 (clobber (match_scratch:SI 4 "=d"))
12310 (clobber (match_scratch:SI 5 "=c"))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "!TARGET_64BIT && TARGET_GNU_TLS"
12315 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12316 if (TARGET_SUN_TLS)
12317 #ifdef HAVE_AS_IX86_TLSGDPLT
12318 return "call\t%a2@tlsgdplt";
12320 return "call\t%p3@plt";
12322 return "call\t%P3";
12324 [(set_attr "type" "multi")
12325 (set_attr "length" "12")])
12327 (define_expand "tls_global_dynamic_32"
12329 [(set (match_operand:SI 0 "register_operand" "")
12330 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12331 (match_operand:SI 1 "tls_symbolic_operand" "")
12332 (match_operand:SI 3 "constant_call_address_operand" "")]
12334 (clobber (match_scratch:SI 4 ""))
12335 (clobber (match_scratch:SI 5 ""))
12336 (clobber (reg:CC FLAGS_REG))])])
12338 (define_insn "*tls_global_dynamic_64"
12339 [(set (match_operand:DI 0 "register_operand" "=a")
12341 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12342 (match_operand:DI 3 "" "")))
12343 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12348 fputs (ASM_BYTE "0x66\n", asm_out_file);
12350 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12351 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12352 fputs ("\trex64\n", asm_out_file);
12353 if (TARGET_SUN_TLS)
12354 return "call\t%p2@plt";
12355 return "call\t%P2";
12357 [(set_attr "type" "multi")
12358 (set (attr "length")
12359 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12361 (define_expand "tls_global_dynamic_64"
12363 [(set (match_operand:DI 0 "register_operand" "")
12365 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12367 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12370 (define_insn "*tls_local_dynamic_base_32_gnu"
12371 [(set (match_operand:SI 0 "register_operand" "=a")
12373 [(match_operand:SI 1 "register_operand" "b")
12374 (match_operand:SI 2 "constant_call_address_operand" "z")]
12375 UNSPEC_TLS_LD_BASE))
12376 (clobber (match_scratch:SI 3 "=d"))
12377 (clobber (match_scratch:SI 4 "=c"))
12378 (clobber (reg:CC FLAGS_REG))]
12379 "!TARGET_64BIT && TARGET_GNU_TLS"
12382 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12383 if (TARGET_SUN_TLS)
12384 #ifdef HAVE_AS_IX86_TLSLDMPLT
12385 return "call\t%&@tlsldmplt";
12387 return "call\t%p2@plt";
12389 return "call\t%P2";
12391 [(set_attr "type" "multi")
12392 (set_attr "length" "11")])
12394 (define_expand "tls_local_dynamic_base_32"
12396 [(set (match_operand:SI 0 "register_operand" "")
12398 [(match_operand:SI 1 "register_operand" "")
12399 (match_operand:SI 2 "constant_call_address_operand" "")]
12400 UNSPEC_TLS_LD_BASE))
12401 (clobber (match_scratch:SI 3 ""))
12402 (clobber (match_scratch:SI 4 ""))
12403 (clobber (reg:CC FLAGS_REG))])])
12405 (define_insn "*tls_local_dynamic_base_64"
12406 [(set (match_operand:DI 0 "register_operand" "=a")
12408 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12409 (match_operand:DI 2 "" "")))
12410 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12414 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12415 if (TARGET_SUN_TLS)
12416 return "call\t%p1@plt";
12417 return "call\t%P1";
12419 [(set_attr "type" "multi")
12420 (set_attr "length" "12")])
12422 (define_expand "tls_local_dynamic_base_64"
12424 [(set (match_operand:DI 0 "register_operand" "")
12426 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12428 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12430 ;; Local dynamic of a single variable is a lose. Show combine how
12431 ;; to convert that back to global dynamic.
12433 (define_insn_and_split "*tls_local_dynamic_32_once"
12434 [(set (match_operand:SI 0 "register_operand" "=a")
12436 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12437 (match_operand:SI 2 "constant_call_address_operand" "z")]
12438 UNSPEC_TLS_LD_BASE)
12439 (const:SI (unspec:SI
12440 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12442 (clobber (match_scratch:SI 4 "=d"))
12443 (clobber (match_scratch:SI 5 "=c"))
12444 (clobber (reg:CC FLAGS_REG))]
12449 [(set (match_dup 0)
12450 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12452 (clobber (match_dup 4))
12453 (clobber (match_dup 5))
12454 (clobber (reg:CC FLAGS_REG))])])
12456 ;; Segment register for the thread base ptr load
12457 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12459 ;; Load and add the thread base pointer from %<tp_seg>:0.
12460 (define_insn "*load_tp_x32"
12461 [(set (match_operand:SI 0 "register_operand" "=r")
12462 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12464 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12465 [(set_attr "type" "imov")
12466 (set_attr "modrm" "0")
12467 (set_attr "length" "7")
12468 (set_attr "memory" "load")
12469 (set_attr "imm_disp" "false")])
12471 (define_insn "*load_tp_x32_zext"
12472 [(set (match_operand:DI 0 "register_operand" "=r")
12473 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12475 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12476 [(set_attr "type" "imov")
12477 (set_attr "modrm" "0")
12478 (set_attr "length" "7")
12479 (set_attr "memory" "load")
12480 (set_attr "imm_disp" "false")])
12482 (define_insn "*load_tp_<mode>"
12483 [(set (match_operand:P 0 "register_operand" "=r")
12484 (unspec:P [(const_int 0)] UNSPEC_TP))]
12486 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12487 [(set_attr "type" "imov")
12488 (set_attr "modrm" "0")
12489 (set_attr "length" "7")
12490 (set_attr "memory" "load")
12491 (set_attr "imm_disp" "false")])
12493 (define_insn "*add_tp_x32"
12494 [(set (match_operand:SI 0 "register_operand" "=r")
12495 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12496 (match_operand:SI 1 "register_operand" "0")))
12497 (clobber (reg:CC FLAGS_REG))]
12499 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12500 [(set_attr "type" "alu")
12501 (set_attr "modrm" "0")
12502 (set_attr "length" "7")
12503 (set_attr "memory" "load")
12504 (set_attr "imm_disp" "false")])
12506 (define_insn "*add_tp_x32_zext"
12507 [(set (match_operand:DI 0 "register_operand" "=r")
12509 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12510 (match_operand:SI 1 "register_operand" "0"))))
12511 (clobber (reg:CC FLAGS_REG))]
12513 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12514 [(set_attr "type" "alu")
12515 (set_attr "modrm" "0")
12516 (set_attr "length" "7")
12517 (set_attr "memory" "load")
12518 (set_attr "imm_disp" "false")])
12520 (define_insn "*add_tp_<mode>"
12521 [(set (match_operand:P 0 "register_operand" "=r")
12522 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12523 (match_operand:P 1 "register_operand" "0")))
12524 (clobber (reg:CC FLAGS_REG))]
12526 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12527 [(set_attr "type" "alu")
12528 (set_attr "modrm" "0")
12529 (set_attr "length" "7")
12530 (set_attr "memory" "load")
12531 (set_attr "imm_disp" "false")])
12533 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12534 ;; %rax as destination of the initial executable code sequence.
12535 (define_insn "tls_initial_exec_64_sun"
12536 [(set (match_operand:DI 0 "register_operand" "=a")
12538 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12539 UNSPEC_TLS_IE_SUN))
12540 (clobber (reg:CC FLAGS_REG))]
12541 "TARGET_64BIT && TARGET_SUN_TLS"
12544 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12545 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12547 [(set_attr "type" "multi")])
12549 ;; GNU2 TLS patterns can be split.
12551 (define_expand "tls_dynamic_gnu2_32"
12552 [(set (match_dup 3)
12553 (plus:SI (match_operand:SI 2 "register_operand" "")
12555 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12558 [(set (match_operand:SI 0 "register_operand" "")
12559 (unspec:SI [(match_dup 1) (match_dup 3)
12560 (match_dup 2) (reg:SI SP_REG)]
12562 (clobber (reg:CC FLAGS_REG))])]
12563 "!TARGET_64BIT && TARGET_GNU2_TLS"
12565 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12566 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12569 (define_insn "*tls_dynamic_gnu2_lea_32"
12570 [(set (match_operand:SI 0 "register_operand" "=r")
12571 (plus:SI (match_operand:SI 1 "register_operand" "b")
12573 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12574 UNSPEC_TLSDESC))))]
12575 "!TARGET_64BIT && TARGET_GNU2_TLS"
12576 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12577 [(set_attr "type" "lea")
12578 (set_attr "mode" "SI")
12579 (set_attr "length" "6")
12580 (set_attr "length_address" "4")])
12582 (define_insn "*tls_dynamic_gnu2_call_32"
12583 [(set (match_operand:SI 0 "register_operand" "=a")
12584 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12585 (match_operand:SI 2 "register_operand" "0")
12586 ;; we have to make sure %ebx still points to the GOT
12587 (match_operand:SI 3 "register_operand" "b")
12590 (clobber (reg:CC FLAGS_REG))]
12591 "!TARGET_64BIT && TARGET_GNU2_TLS"
12592 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12593 [(set_attr "type" "call")
12594 (set_attr "length" "2")
12595 (set_attr "length_address" "0")])
12597 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12598 [(set (match_operand:SI 0 "register_operand" "=&a")
12600 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12601 (match_operand:SI 4 "" "")
12602 (match_operand:SI 2 "register_operand" "b")
12605 (const:SI (unspec:SI
12606 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12608 (clobber (reg:CC FLAGS_REG))]
12609 "!TARGET_64BIT && TARGET_GNU2_TLS"
12612 [(set (match_dup 0) (match_dup 5))]
12614 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12615 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12618 (define_expand "tls_dynamic_gnu2_64"
12619 [(set (match_dup 2)
12620 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12623 [(set (match_operand:DI 0 "register_operand" "")
12624 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12626 (clobber (reg:CC FLAGS_REG))])]
12627 "TARGET_64BIT && TARGET_GNU2_TLS"
12629 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12630 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12633 (define_insn "*tls_dynamic_gnu2_lea_64"
12634 [(set (match_operand:DI 0 "register_operand" "=r")
12635 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12637 "TARGET_64BIT && TARGET_GNU2_TLS"
12638 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12639 [(set_attr "type" "lea")
12640 (set_attr "mode" "DI")
12641 (set_attr "length" "7")
12642 (set_attr "length_address" "4")])
12644 (define_insn "*tls_dynamic_gnu2_call_64"
12645 [(set (match_operand:DI 0 "register_operand" "=a")
12646 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12647 (match_operand:DI 2 "register_operand" "0")
12650 (clobber (reg:CC FLAGS_REG))]
12651 "TARGET_64BIT && TARGET_GNU2_TLS"
12652 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12653 [(set_attr "type" "call")
12654 (set_attr "length" "2")
12655 (set_attr "length_address" "0")])
12657 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12658 [(set (match_operand:DI 0 "register_operand" "=&a")
12660 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12661 (match_operand:DI 3 "" "")
12664 (const:DI (unspec:DI
12665 [(match_operand 1 "tls_symbolic_operand" "")]
12667 (clobber (reg:CC FLAGS_REG))]
12668 "TARGET_64BIT && TARGET_GNU2_TLS"
12671 [(set (match_dup 0) (match_dup 4))]
12673 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12674 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12677 ;; These patterns match the binary 387 instructions for addM3, subM3,
12678 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12679 ;; SFmode. The first is the normal insn, the second the same insn but
12680 ;; with one operand a conversion, and the third the same insn but with
12681 ;; the other operand a conversion. The conversion may be SFmode or
12682 ;; SImode if the target mode DFmode, but only SImode if the target mode
12685 ;; Gcc is slightly more smart about handling normal two address instructions
12686 ;; so use special patterns for add and mull.
12688 (define_insn "*fop_<mode>_comm_mixed"
12689 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12690 (match_operator:MODEF 3 "binary_fp_operator"
12691 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12692 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12693 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12694 && COMMUTATIVE_ARITH_P (operands[3])
12695 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12696 "* return output_387_binary_op (insn, operands);"
12697 [(set (attr "type")
12698 (if_then_else (eq_attr "alternative" "1,2")
12699 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12700 (const_string "ssemul")
12701 (const_string "sseadd"))
12702 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12703 (const_string "fmul")
12704 (const_string "fop"))))
12705 (set_attr "isa" "*,noavx,avx")
12706 (set_attr "prefix" "orig,orig,vex")
12707 (set_attr "mode" "<MODE>")])
12709 (define_insn "*fop_<mode>_comm_sse"
12710 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12711 (match_operator:MODEF 3 "binary_fp_operator"
12712 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12713 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12714 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12715 && COMMUTATIVE_ARITH_P (operands[3])
12716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12717 "* return output_387_binary_op (insn, operands);"
12718 [(set (attr "type")
12719 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12720 (const_string "ssemul")
12721 (const_string "sseadd")))
12722 (set_attr "isa" "noavx,avx")
12723 (set_attr "prefix" "orig,vex")
12724 (set_attr "mode" "<MODE>")])
12726 (define_insn "*fop_<mode>_comm_i387"
12727 [(set (match_operand:MODEF 0 "register_operand" "=f")
12728 (match_operator:MODEF 3 "binary_fp_operator"
12729 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12730 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12731 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12732 && COMMUTATIVE_ARITH_P (operands[3])
12733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12734 "* return output_387_binary_op (insn, operands);"
12735 [(set (attr "type")
12736 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12737 (const_string "fmul")
12738 (const_string "fop")))
12739 (set_attr "mode" "<MODE>")])
12741 (define_insn "*fop_<mode>_1_mixed"
12742 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12743 (match_operator:MODEF 3 "binary_fp_operator"
12744 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12745 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12746 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12747 && !COMMUTATIVE_ARITH_P (operands[3])
12748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12749 "* return output_387_binary_op (insn, operands);"
12750 [(set (attr "type")
12751 (cond [(and (eq_attr "alternative" "2,3")
12752 (match_operand:MODEF 3 "mult_operator" ""))
12753 (const_string "ssemul")
12754 (and (eq_attr "alternative" "2,3")
12755 (match_operand:MODEF 3 "div_operator" ""))
12756 (const_string "ssediv")
12757 (eq_attr "alternative" "2,3")
12758 (const_string "sseadd")
12759 (match_operand:MODEF 3 "mult_operator" "")
12760 (const_string "fmul")
12761 (match_operand:MODEF 3 "div_operator" "")
12762 (const_string "fdiv")
12764 (const_string "fop")))
12765 (set_attr "isa" "*,*,noavx,avx")
12766 (set_attr "prefix" "orig,orig,orig,vex")
12767 (set_attr "mode" "<MODE>")])
12769 (define_insn "*rcpsf2_sse"
12770 [(set (match_operand:SF 0 "register_operand" "=x")
12771 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12774 "%vrcpss\t{%1, %d0|%d0, %1}"
12775 [(set_attr "type" "sse")
12776 (set_attr "atom_sse_attr" "rcp")
12777 (set_attr "prefix" "maybe_vex")
12778 (set_attr "mode" "SF")])
12780 (define_insn "*fop_<mode>_1_sse"
12781 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12782 (match_operator:MODEF 3 "binary_fp_operator"
12783 [(match_operand:MODEF 1 "register_operand" "0,x")
12784 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12785 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12786 && !COMMUTATIVE_ARITH_P (operands[3])"
12787 "* return output_387_binary_op (insn, operands);"
12788 [(set (attr "type")
12789 (cond [(match_operand:MODEF 3 "mult_operator" "")
12790 (const_string "ssemul")
12791 (match_operand:MODEF 3 "div_operator" "")
12792 (const_string "ssediv")
12794 (const_string "sseadd")))
12795 (set_attr "isa" "noavx,avx")
12796 (set_attr "prefix" "orig,vex")
12797 (set_attr "mode" "<MODE>")])
12799 ;; This pattern is not fully shadowed by the pattern above.
12800 (define_insn "*fop_<mode>_1_i387"
12801 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12802 (match_operator:MODEF 3 "binary_fp_operator"
12803 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12804 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12805 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12806 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12807 && !COMMUTATIVE_ARITH_P (operands[3])
12808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12809 "* return output_387_binary_op (insn, operands);"
12810 [(set (attr "type")
12811 (cond [(match_operand:MODEF 3 "mult_operator" "")
12812 (const_string "fmul")
12813 (match_operand:MODEF 3 "div_operator" "")
12814 (const_string "fdiv")
12816 (const_string "fop")))
12817 (set_attr "mode" "<MODE>")])
12819 ;; ??? Add SSE splitters for these!
12820 (define_insn "*fop_<MODEF:mode>_2_i387"
12821 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12822 (match_operator:MODEF 3 "binary_fp_operator"
12824 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12825 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12826 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12827 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12828 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12829 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12830 [(set (attr "type")
12831 (cond [(match_operand:MODEF 3 "mult_operator" "")
12832 (const_string "fmul")
12833 (match_operand:MODEF 3 "div_operator" "")
12834 (const_string "fdiv")
12836 (const_string "fop")))
12837 (set_attr "fp_int_src" "true")
12838 (set_attr "mode" "<SWI24:MODE>")])
12840 (define_insn "*fop_<MODEF:mode>_3_i387"
12841 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12842 (match_operator:MODEF 3 "binary_fp_operator"
12843 [(match_operand:MODEF 1 "register_operand" "0,0")
12845 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12846 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12847 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12848 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12849 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12850 [(set (attr "type")
12851 (cond [(match_operand:MODEF 3 "mult_operator" "")
12852 (const_string "fmul")
12853 (match_operand:MODEF 3 "div_operator" "")
12854 (const_string "fdiv")
12856 (const_string "fop")))
12857 (set_attr "fp_int_src" "true")
12858 (set_attr "mode" "<MODE>")])
12860 (define_insn "*fop_df_4_i387"
12861 [(set (match_operand:DF 0 "register_operand" "=f,f")
12862 (match_operator:DF 3 "binary_fp_operator"
12864 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12865 (match_operand:DF 2 "register_operand" "0,f")]))]
12866 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12867 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12869 "* return output_387_binary_op (insn, operands);"
12870 [(set (attr "type")
12871 (cond [(match_operand:DF 3 "mult_operator" "")
12872 (const_string "fmul")
12873 (match_operand:DF 3 "div_operator" "")
12874 (const_string "fdiv")
12876 (const_string "fop")))
12877 (set_attr "mode" "SF")])
12879 (define_insn "*fop_df_5_i387"
12880 [(set (match_operand:DF 0 "register_operand" "=f,f")
12881 (match_operator:DF 3 "binary_fp_operator"
12882 [(match_operand:DF 1 "register_operand" "0,f")
12884 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12885 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12886 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12887 "* return output_387_binary_op (insn, operands);"
12888 [(set (attr "type")
12889 (cond [(match_operand:DF 3 "mult_operator" "")
12890 (const_string "fmul")
12891 (match_operand:DF 3 "div_operator" "")
12892 (const_string "fdiv")
12894 (const_string "fop")))
12895 (set_attr "mode" "SF")])
12897 (define_insn "*fop_df_6_i387"
12898 [(set (match_operand:DF 0 "register_operand" "=f,f")
12899 (match_operator:DF 3 "binary_fp_operator"
12901 (match_operand:SF 1 "register_operand" "0,f"))
12903 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12904 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12905 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12906 "* return output_387_binary_op (insn, operands);"
12907 [(set (attr "type")
12908 (cond [(match_operand:DF 3 "mult_operator" "")
12909 (const_string "fmul")
12910 (match_operand:DF 3 "div_operator" "")
12911 (const_string "fdiv")
12913 (const_string "fop")))
12914 (set_attr "mode" "SF")])
12916 (define_insn "*fop_xf_comm_i387"
12917 [(set (match_operand:XF 0 "register_operand" "=f")
12918 (match_operator:XF 3 "binary_fp_operator"
12919 [(match_operand:XF 1 "register_operand" "%0")
12920 (match_operand:XF 2 "register_operand" "f")]))]
12922 && COMMUTATIVE_ARITH_P (operands[3])"
12923 "* return output_387_binary_op (insn, operands);"
12924 [(set (attr "type")
12925 (if_then_else (match_operand:XF 3 "mult_operator" "")
12926 (const_string "fmul")
12927 (const_string "fop")))
12928 (set_attr "mode" "XF")])
12930 (define_insn "*fop_xf_1_i387"
12931 [(set (match_operand:XF 0 "register_operand" "=f,f")
12932 (match_operator:XF 3 "binary_fp_operator"
12933 [(match_operand:XF 1 "register_operand" "0,f")
12934 (match_operand:XF 2 "register_operand" "f,0")]))]
12936 && !COMMUTATIVE_ARITH_P (operands[3])"
12937 "* return output_387_binary_op (insn, operands);"
12938 [(set (attr "type")
12939 (cond [(match_operand:XF 3 "mult_operator" "")
12940 (const_string "fmul")
12941 (match_operand:XF 3 "div_operator" "")
12942 (const_string "fdiv")
12944 (const_string "fop")))
12945 (set_attr "mode" "XF")])
12947 (define_insn "*fop_xf_2_i387"
12948 [(set (match_operand:XF 0 "register_operand" "=f,f")
12949 (match_operator:XF 3 "binary_fp_operator"
12951 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12952 (match_operand:XF 2 "register_operand" "0,0")]))]
12953 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12954 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12955 [(set (attr "type")
12956 (cond [(match_operand:XF 3 "mult_operator" "")
12957 (const_string "fmul")
12958 (match_operand:XF 3 "div_operator" "")
12959 (const_string "fdiv")
12961 (const_string "fop")))
12962 (set_attr "fp_int_src" "true")
12963 (set_attr "mode" "<MODE>")])
12965 (define_insn "*fop_xf_3_i387"
12966 [(set (match_operand:XF 0 "register_operand" "=f,f")
12967 (match_operator:XF 3 "binary_fp_operator"
12968 [(match_operand:XF 1 "register_operand" "0,0")
12970 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12971 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12972 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12973 [(set (attr "type")
12974 (cond [(match_operand:XF 3 "mult_operator" "")
12975 (const_string "fmul")
12976 (match_operand:XF 3 "div_operator" "")
12977 (const_string "fdiv")
12979 (const_string "fop")))
12980 (set_attr "fp_int_src" "true")
12981 (set_attr "mode" "<MODE>")])
12983 (define_insn "*fop_xf_4_i387"
12984 [(set (match_operand:XF 0 "register_operand" "=f,f")
12985 (match_operator:XF 3 "binary_fp_operator"
12987 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12988 (match_operand:XF 2 "register_operand" "0,f")]))]
12990 "* return output_387_binary_op (insn, operands);"
12991 [(set (attr "type")
12992 (cond [(match_operand:XF 3 "mult_operator" "")
12993 (const_string "fmul")
12994 (match_operand:XF 3 "div_operator" "")
12995 (const_string "fdiv")
12997 (const_string "fop")))
12998 (set_attr "mode" "<MODE>")])
13000 (define_insn "*fop_xf_5_i387"
13001 [(set (match_operand:XF 0 "register_operand" "=f,f")
13002 (match_operator:XF 3 "binary_fp_operator"
13003 [(match_operand:XF 1 "register_operand" "0,f")
13005 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13007 "* return output_387_binary_op (insn, operands);"
13008 [(set (attr "type")
13009 (cond [(match_operand:XF 3 "mult_operator" "")
13010 (const_string "fmul")
13011 (match_operand:XF 3 "div_operator" "")
13012 (const_string "fdiv")
13014 (const_string "fop")))
13015 (set_attr "mode" "<MODE>")])
13017 (define_insn "*fop_xf_6_i387"
13018 [(set (match_operand:XF 0 "register_operand" "=f,f")
13019 (match_operator:XF 3 "binary_fp_operator"
13021 (match_operand:MODEF 1 "register_operand" "0,f"))
13023 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13025 "* return output_387_binary_op (insn, operands);"
13026 [(set (attr "type")
13027 (cond [(match_operand:XF 3 "mult_operator" "")
13028 (const_string "fmul")
13029 (match_operand:XF 3 "div_operator" "")
13030 (const_string "fdiv")
13032 (const_string "fop")))
13033 (set_attr "mode" "<MODE>")])
13036 [(set (match_operand 0 "register_operand" "")
13037 (match_operator 3 "binary_fp_operator"
13038 [(float (match_operand:SWI24 1 "register_operand" ""))
13039 (match_operand 2 "register_operand" "")]))]
13041 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13042 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13045 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13046 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13047 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13048 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13049 GET_MODE (operands[3]),
13052 ix86_free_from_memory (GET_MODE (operands[1]));
13057 [(set (match_operand 0 "register_operand" "")
13058 (match_operator 3 "binary_fp_operator"
13059 [(match_operand 1 "register_operand" "")
13060 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13062 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13063 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13066 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13067 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13068 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13069 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13070 GET_MODE (operands[3]),
13073 ix86_free_from_memory (GET_MODE (operands[2]));
13077 ;; FPU special functions.
13079 ;; This pattern implements a no-op XFmode truncation for
13080 ;; all fancy i386 XFmode math functions.
13082 (define_insn "truncxf<mode>2_i387_noop_unspec"
13083 [(set (match_operand:MODEF 0 "register_operand" "=f")
13084 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13085 UNSPEC_TRUNC_NOOP))]
13086 "TARGET_USE_FANCY_MATH_387"
13087 "* return output_387_reg_move (insn, operands);"
13088 [(set_attr "type" "fmov")
13089 (set_attr "mode" "<MODE>")])
13091 (define_insn "sqrtxf2"
13092 [(set (match_operand:XF 0 "register_operand" "=f")
13093 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13094 "TARGET_USE_FANCY_MATH_387"
13096 [(set_attr "type" "fpspc")
13097 (set_attr "mode" "XF")
13098 (set_attr "athlon_decode" "direct")
13099 (set_attr "amdfam10_decode" "direct")
13100 (set_attr "bdver1_decode" "direct")])
13102 (define_insn "sqrt_extend<mode>xf2_i387"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13106 (match_operand:MODEF 1 "register_operand" "0"))))]
13107 "TARGET_USE_FANCY_MATH_387"
13109 [(set_attr "type" "fpspc")
13110 (set_attr "mode" "XF")
13111 (set_attr "athlon_decode" "direct")
13112 (set_attr "amdfam10_decode" "direct")
13113 (set_attr "bdver1_decode" "direct")])
13115 (define_insn "*rsqrtsf2_sse"
13116 [(set (match_operand:SF 0 "register_operand" "=x")
13117 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13120 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13121 [(set_attr "type" "sse")
13122 (set_attr "atom_sse_attr" "rcp")
13123 (set_attr "prefix" "maybe_vex")
13124 (set_attr "mode" "SF")])
13126 (define_expand "rsqrtsf2"
13127 [(set (match_operand:SF 0 "register_operand" "")
13128 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13132 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13136 (define_insn "*sqrt<mode>2_sse"
13137 [(set (match_operand:MODEF 0 "register_operand" "=x")
13139 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13140 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13141 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13142 [(set_attr "type" "sse")
13143 (set_attr "atom_sse_attr" "sqrt")
13144 (set_attr "prefix" "maybe_vex")
13145 (set_attr "mode" "<MODE>")
13146 (set_attr "athlon_decode" "*")
13147 (set_attr "amdfam10_decode" "*")
13148 (set_attr "bdver1_decode" "*")])
13150 (define_expand "sqrt<mode>2"
13151 [(set (match_operand:MODEF 0 "register_operand" "")
13153 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13154 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13155 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13157 if (<MODE>mode == SFmode
13158 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13159 && flag_finite_math_only && !flag_trapping_math
13160 && flag_unsafe_math_optimizations)
13162 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13166 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13168 rtx op0 = gen_reg_rtx (XFmode);
13169 rtx op1 = force_reg (<MODE>mode, operands[1]);
13171 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13172 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13177 (define_insn "fpremxf4_i387"
13178 [(set (match_operand:XF 0 "register_operand" "=f")
13179 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13180 (match_operand:XF 3 "register_operand" "1")]
13182 (set (match_operand:XF 1 "register_operand" "=u")
13183 (unspec:XF [(match_dup 2) (match_dup 3)]
13185 (set (reg:CCFP FPSR_REG)
13186 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13188 "TARGET_USE_FANCY_MATH_387"
13190 [(set_attr "type" "fpspc")
13191 (set_attr "mode" "XF")])
13193 (define_expand "fmodxf3"
13194 [(use (match_operand:XF 0 "register_operand" ""))
13195 (use (match_operand:XF 1 "general_operand" ""))
13196 (use (match_operand:XF 2 "general_operand" ""))]
13197 "TARGET_USE_FANCY_MATH_387"
13199 rtx label = gen_label_rtx ();
13201 rtx op1 = gen_reg_rtx (XFmode);
13202 rtx op2 = gen_reg_rtx (XFmode);
13204 emit_move_insn (op2, operands[2]);
13205 emit_move_insn (op1, operands[1]);
13207 emit_label (label);
13208 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13209 ix86_emit_fp_unordered_jump (label);
13210 LABEL_NUSES (label) = 1;
13212 emit_move_insn (operands[0], op1);
13216 (define_expand "fmod<mode>3"
13217 [(use (match_operand:MODEF 0 "register_operand" ""))
13218 (use (match_operand:MODEF 1 "general_operand" ""))
13219 (use (match_operand:MODEF 2 "general_operand" ""))]
13220 "TARGET_USE_FANCY_MATH_387"
13222 rtx (*gen_truncxf) (rtx, rtx);
13224 rtx label = gen_label_rtx ();
13226 rtx op1 = gen_reg_rtx (XFmode);
13227 rtx op2 = gen_reg_rtx (XFmode);
13229 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13230 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13232 emit_label (label);
13233 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13234 ix86_emit_fp_unordered_jump (label);
13235 LABEL_NUSES (label) = 1;
13237 /* Truncate the result properly for strict SSE math. */
13238 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13239 && !TARGET_MIX_SSE_I387)
13240 gen_truncxf = gen_truncxf<mode>2;
13242 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13244 emit_insn (gen_truncxf (operands[0], op1));
13248 (define_insn "fprem1xf4_i387"
13249 [(set (match_operand:XF 0 "register_operand" "=f")
13250 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13251 (match_operand:XF 3 "register_operand" "1")]
13253 (set (match_operand:XF 1 "register_operand" "=u")
13254 (unspec:XF [(match_dup 2) (match_dup 3)]
13256 (set (reg:CCFP FPSR_REG)
13257 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13259 "TARGET_USE_FANCY_MATH_387"
13261 [(set_attr "type" "fpspc")
13262 (set_attr "mode" "XF")])
13264 (define_expand "remainderxf3"
13265 [(use (match_operand:XF 0 "register_operand" ""))
13266 (use (match_operand:XF 1 "general_operand" ""))
13267 (use (match_operand:XF 2 "general_operand" ""))]
13268 "TARGET_USE_FANCY_MATH_387"
13270 rtx label = gen_label_rtx ();
13272 rtx op1 = gen_reg_rtx (XFmode);
13273 rtx op2 = gen_reg_rtx (XFmode);
13275 emit_move_insn (op2, operands[2]);
13276 emit_move_insn (op1, operands[1]);
13278 emit_label (label);
13279 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13280 ix86_emit_fp_unordered_jump (label);
13281 LABEL_NUSES (label) = 1;
13283 emit_move_insn (operands[0], op1);
13287 (define_expand "remainder<mode>3"
13288 [(use (match_operand:MODEF 0 "register_operand" ""))
13289 (use (match_operand:MODEF 1 "general_operand" ""))
13290 (use (match_operand:MODEF 2 "general_operand" ""))]
13291 "TARGET_USE_FANCY_MATH_387"
13293 rtx (*gen_truncxf) (rtx, rtx);
13295 rtx label = gen_label_rtx ();
13297 rtx op1 = gen_reg_rtx (XFmode);
13298 rtx op2 = gen_reg_rtx (XFmode);
13300 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13301 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13303 emit_label (label);
13305 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13306 ix86_emit_fp_unordered_jump (label);
13307 LABEL_NUSES (label) = 1;
13309 /* Truncate the result properly for strict SSE math. */
13310 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13311 && !TARGET_MIX_SSE_I387)
13312 gen_truncxf = gen_truncxf<mode>2;
13314 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13316 emit_insn (gen_truncxf (operands[0], op1));
13320 (define_insn "*sinxf2_i387"
13321 [(set (match_operand:XF 0 "register_operand" "=f")
13322 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13323 "TARGET_USE_FANCY_MATH_387
13324 && flag_unsafe_math_optimizations"
13326 [(set_attr "type" "fpspc")
13327 (set_attr "mode" "XF")])
13329 (define_insn "*sin_extend<mode>xf2_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(float_extend:XF
13332 (match_operand:MODEF 1 "register_operand" "0"))]
13334 "TARGET_USE_FANCY_MATH_387
13335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336 || TARGET_MIX_SSE_I387)
13337 && flag_unsafe_math_optimizations"
13339 [(set_attr "type" "fpspc")
13340 (set_attr "mode" "XF")])
13342 (define_insn "*cosxf2_i387"
13343 [(set (match_operand:XF 0 "register_operand" "=f")
13344 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13345 "TARGET_USE_FANCY_MATH_387
13346 && flag_unsafe_math_optimizations"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13351 (define_insn "*cos_extend<mode>xf2_i387"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13353 (unspec:XF [(float_extend:XF
13354 (match_operand:MODEF 1 "register_operand" "0"))]
13356 "TARGET_USE_FANCY_MATH_387
13357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13358 || TARGET_MIX_SSE_I387)
13359 && flag_unsafe_math_optimizations"
13361 [(set_attr "type" "fpspc")
13362 (set_attr "mode" "XF")])
13364 ;; When sincos pattern is defined, sin and cos builtin functions will be
13365 ;; expanded to sincos pattern with one of its outputs left unused.
13366 ;; CSE pass will figure out if two sincos patterns can be combined,
13367 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13368 ;; depending on the unused output.
13370 (define_insn "sincosxf3"
13371 [(set (match_operand:XF 0 "register_operand" "=f")
13372 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13373 UNSPEC_SINCOS_COS))
13374 (set (match_operand:XF 1 "register_operand" "=u")
13375 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13376 "TARGET_USE_FANCY_MATH_387
13377 && flag_unsafe_math_optimizations"
13379 [(set_attr "type" "fpspc")
13380 (set_attr "mode" "XF")])
13383 [(set (match_operand:XF 0 "register_operand" "")
13384 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13385 UNSPEC_SINCOS_COS))
13386 (set (match_operand:XF 1 "register_operand" "")
13387 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13388 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13389 && can_create_pseudo_p ()"
13390 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13393 [(set (match_operand:XF 0 "register_operand" "")
13394 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13395 UNSPEC_SINCOS_COS))
13396 (set (match_operand:XF 1 "register_operand" "")
13397 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13398 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13399 && can_create_pseudo_p ()"
13400 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13402 (define_insn "sincos_extend<mode>xf3_i387"
13403 [(set (match_operand:XF 0 "register_operand" "=f")
13404 (unspec:XF [(float_extend:XF
13405 (match_operand:MODEF 2 "register_operand" "0"))]
13406 UNSPEC_SINCOS_COS))
13407 (set (match_operand:XF 1 "register_operand" "=u")
13408 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13409 "TARGET_USE_FANCY_MATH_387
13410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13411 || TARGET_MIX_SSE_I387)
13412 && flag_unsafe_math_optimizations"
13414 [(set_attr "type" "fpspc")
13415 (set_attr "mode" "XF")])
13418 [(set (match_operand:XF 0 "register_operand" "")
13419 (unspec:XF [(float_extend:XF
13420 (match_operand:MODEF 2 "register_operand" ""))]
13421 UNSPEC_SINCOS_COS))
13422 (set (match_operand:XF 1 "register_operand" "")
13423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13424 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13425 && can_create_pseudo_p ()"
13426 [(set (match_dup 1)
13427 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13430 [(set (match_operand:XF 0 "register_operand" "")
13431 (unspec:XF [(float_extend:XF
13432 (match_operand:MODEF 2 "register_operand" ""))]
13433 UNSPEC_SINCOS_COS))
13434 (set (match_operand:XF 1 "register_operand" "")
13435 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13436 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13437 && can_create_pseudo_p ()"
13438 [(set (match_dup 0)
13439 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13441 (define_expand "sincos<mode>3"
13442 [(use (match_operand:MODEF 0 "register_operand" ""))
13443 (use (match_operand:MODEF 1 "register_operand" ""))
13444 (use (match_operand:MODEF 2 "register_operand" ""))]
13445 "TARGET_USE_FANCY_MATH_387
13446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13447 || TARGET_MIX_SSE_I387)
13448 && flag_unsafe_math_optimizations"
13450 rtx op0 = gen_reg_rtx (XFmode);
13451 rtx op1 = gen_reg_rtx (XFmode);
13453 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13459 (define_insn "fptanxf4_i387"
13460 [(set (match_operand:XF 0 "register_operand" "=f")
13461 (match_operand:XF 3 "const_double_operand" "F"))
13462 (set (match_operand:XF 1 "register_operand" "=u")
13463 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13465 "TARGET_USE_FANCY_MATH_387
13466 && flag_unsafe_math_optimizations
13467 && standard_80387_constant_p (operands[3]) == 2"
13469 [(set_attr "type" "fpspc")
13470 (set_attr "mode" "XF")])
13472 (define_insn "fptan_extend<mode>xf4_i387"
13473 [(set (match_operand:MODEF 0 "register_operand" "=f")
13474 (match_operand:MODEF 3 "const_double_operand" "F"))
13475 (set (match_operand:XF 1 "register_operand" "=u")
13476 (unspec:XF [(float_extend:XF
13477 (match_operand:MODEF 2 "register_operand" "0"))]
13479 "TARGET_USE_FANCY_MATH_387
13480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13481 || TARGET_MIX_SSE_I387)
13482 && flag_unsafe_math_optimizations
13483 && standard_80387_constant_p (operands[3]) == 2"
13485 [(set_attr "type" "fpspc")
13486 (set_attr "mode" "XF")])
13488 (define_expand "tanxf2"
13489 [(use (match_operand:XF 0 "register_operand" ""))
13490 (use (match_operand:XF 1 "register_operand" ""))]
13491 "TARGET_USE_FANCY_MATH_387
13492 && flag_unsafe_math_optimizations"
13494 rtx one = gen_reg_rtx (XFmode);
13495 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13497 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13501 (define_expand "tan<mode>2"
13502 [(use (match_operand:MODEF 0 "register_operand" ""))
13503 (use (match_operand:MODEF 1 "register_operand" ""))]
13504 "TARGET_USE_FANCY_MATH_387
13505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13506 || TARGET_MIX_SSE_I387)
13507 && flag_unsafe_math_optimizations"
13509 rtx op0 = gen_reg_rtx (XFmode);
13511 rtx one = gen_reg_rtx (<MODE>mode);
13512 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13514 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13515 operands[1], op2));
13516 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13520 (define_insn "*fpatanxf3_i387"
13521 [(set (match_operand:XF 0 "register_operand" "=f")
13522 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13523 (match_operand:XF 2 "register_operand" "u")]
13525 (clobber (match_scratch:XF 3 "=2"))]
13526 "TARGET_USE_FANCY_MATH_387
13527 && flag_unsafe_math_optimizations"
13529 [(set_attr "type" "fpspc")
13530 (set_attr "mode" "XF")])
13532 (define_insn "fpatan_extend<mode>xf3_i387"
13533 [(set (match_operand:XF 0 "register_operand" "=f")
13534 (unspec:XF [(float_extend:XF
13535 (match_operand:MODEF 1 "register_operand" "0"))
13537 (match_operand:MODEF 2 "register_operand" "u"))]
13539 (clobber (match_scratch:XF 3 "=2"))]
13540 "TARGET_USE_FANCY_MATH_387
13541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13542 || TARGET_MIX_SSE_I387)
13543 && flag_unsafe_math_optimizations"
13545 [(set_attr "type" "fpspc")
13546 (set_attr "mode" "XF")])
13548 (define_expand "atan2xf3"
13549 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13550 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13551 (match_operand:XF 1 "register_operand" "")]
13553 (clobber (match_scratch:XF 3 ""))])]
13554 "TARGET_USE_FANCY_MATH_387
13555 && flag_unsafe_math_optimizations")
13557 (define_expand "atan2<mode>3"
13558 [(use (match_operand:MODEF 0 "register_operand" ""))
13559 (use (match_operand:MODEF 1 "register_operand" ""))
13560 (use (match_operand:MODEF 2 "register_operand" ""))]
13561 "TARGET_USE_FANCY_MATH_387
13562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13563 || TARGET_MIX_SSE_I387)
13564 && flag_unsafe_math_optimizations"
13566 rtx op0 = gen_reg_rtx (XFmode);
13568 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13573 (define_expand "atanxf2"
13574 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13575 (unspec:XF [(match_dup 2)
13576 (match_operand:XF 1 "register_operand" "")]
13578 (clobber (match_scratch:XF 3 ""))])]
13579 "TARGET_USE_FANCY_MATH_387
13580 && flag_unsafe_math_optimizations"
13582 operands[2] = gen_reg_rtx (XFmode);
13583 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13586 (define_expand "atan<mode>2"
13587 [(use (match_operand:MODEF 0 "register_operand" ""))
13588 (use (match_operand:MODEF 1 "register_operand" ""))]
13589 "TARGET_USE_FANCY_MATH_387
13590 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13591 || TARGET_MIX_SSE_I387)
13592 && flag_unsafe_math_optimizations"
13594 rtx op0 = gen_reg_rtx (XFmode);
13596 rtx op2 = gen_reg_rtx (<MODE>mode);
13597 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13599 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13600 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13604 (define_expand "asinxf2"
13605 [(set (match_dup 2)
13606 (mult:XF (match_operand:XF 1 "register_operand" "")
13608 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13609 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13610 (parallel [(set (match_operand:XF 0 "register_operand" "")
13611 (unspec:XF [(match_dup 5) (match_dup 1)]
13613 (clobber (match_scratch:XF 6 ""))])]
13614 "TARGET_USE_FANCY_MATH_387
13615 && flag_unsafe_math_optimizations"
13619 if (optimize_insn_for_size_p ())
13622 for (i = 2; i < 6; i++)
13623 operands[i] = gen_reg_rtx (XFmode);
13625 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13628 (define_expand "asin<mode>2"
13629 [(use (match_operand:MODEF 0 "register_operand" ""))
13630 (use (match_operand:MODEF 1 "general_operand" ""))]
13631 "TARGET_USE_FANCY_MATH_387
13632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13633 || TARGET_MIX_SSE_I387)
13634 && flag_unsafe_math_optimizations"
13636 rtx op0 = gen_reg_rtx (XFmode);
13637 rtx op1 = gen_reg_rtx (XFmode);
13639 if (optimize_insn_for_size_p ())
13642 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13643 emit_insn (gen_asinxf2 (op0, op1));
13644 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13648 (define_expand "acosxf2"
13649 [(set (match_dup 2)
13650 (mult:XF (match_operand:XF 1 "register_operand" "")
13652 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13653 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13654 (parallel [(set (match_operand:XF 0 "register_operand" "")
13655 (unspec:XF [(match_dup 1) (match_dup 5)]
13657 (clobber (match_scratch:XF 6 ""))])]
13658 "TARGET_USE_FANCY_MATH_387
13659 && flag_unsafe_math_optimizations"
13663 if (optimize_insn_for_size_p ())
13666 for (i = 2; i < 6; i++)
13667 operands[i] = gen_reg_rtx (XFmode);
13669 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13672 (define_expand "acos<mode>2"
13673 [(use (match_operand:MODEF 0 "register_operand" ""))
13674 (use (match_operand:MODEF 1 "general_operand" ""))]
13675 "TARGET_USE_FANCY_MATH_387
13676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13677 || TARGET_MIX_SSE_I387)
13678 && flag_unsafe_math_optimizations"
13680 rtx op0 = gen_reg_rtx (XFmode);
13681 rtx op1 = gen_reg_rtx (XFmode);
13683 if (optimize_insn_for_size_p ())
13686 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13687 emit_insn (gen_acosxf2 (op0, op1));
13688 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13692 (define_insn "fyl2xxf3_i387"
13693 [(set (match_operand:XF 0 "register_operand" "=f")
13694 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13695 (match_operand:XF 2 "register_operand" "u")]
13697 (clobber (match_scratch:XF 3 "=2"))]
13698 "TARGET_USE_FANCY_MATH_387
13699 && flag_unsafe_math_optimizations"
13701 [(set_attr "type" "fpspc")
13702 (set_attr "mode" "XF")])
13704 (define_insn "fyl2x_extend<mode>xf3_i387"
13705 [(set (match_operand:XF 0 "register_operand" "=f")
13706 (unspec:XF [(float_extend:XF
13707 (match_operand:MODEF 1 "register_operand" "0"))
13708 (match_operand:XF 2 "register_operand" "u")]
13710 (clobber (match_scratch:XF 3 "=2"))]
13711 "TARGET_USE_FANCY_MATH_387
13712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13713 || TARGET_MIX_SSE_I387)
13714 && flag_unsafe_math_optimizations"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13719 (define_expand "logxf2"
13720 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13721 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13722 (match_dup 2)] UNSPEC_FYL2X))
13723 (clobber (match_scratch:XF 3 ""))])]
13724 "TARGET_USE_FANCY_MATH_387
13725 && flag_unsafe_math_optimizations"
13727 operands[2] = gen_reg_rtx (XFmode);
13728 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13731 (define_expand "log<mode>2"
13732 [(use (match_operand:MODEF 0 "register_operand" ""))
13733 (use (match_operand:MODEF 1 "register_operand" ""))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736 || TARGET_MIX_SSE_I387)
13737 && flag_unsafe_math_optimizations"
13739 rtx op0 = gen_reg_rtx (XFmode);
13741 rtx op2 = gen_reg_rtx (XFmode);
13742 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13744 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13749 (define_expand "log10xf2"
13750 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13751 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13752 (match_dup 2)] UNSPEC_FYL2X))
13753 (clobber (match_scratch:XF 3 ""))])]
13754 "TARGET_USE_FANCY_MATH_387
13755 && flag_unsafe_math_optimizations"
13757 operands[2] = gen_reg_rtx (XFmode);
13758 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13761 (define_expand "log10<mode>2"
13762 [(use (match_operand:MODEF 0 "register_operand" ""))
13763 (use (match_operand:MODEF 1 "register_operand" ""))]
13764 "TARGET_USE_FANCY_MATH_387
13765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13766 || TARGET_MIX_SSE_I387)
13767 && flag_unsafe_math_optimizations"
13769 rtx op0 = gen_reg_rtx (XFmode);
13771 rtx op2 = gen_reg_rtx (XFmode);
13772 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13774 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13775 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13779 (define_expand "log2xf2"
13780 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13781 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13782 (match_dup 2)] UNSPEC_FYL2X))
13783 (clobber (match_scratch:XF 3 ""))])]
13784 "TARGET_USE_FANCY_MATH_387
13785 && flag_unsafe_math_optimizations"
13787 operands[2] = gen_reg_rtx (XFmode);
13788 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13791 (define_expand "log2<mode>2"
13792 [(use (match_operand:MODEF 0 "register_operand" ""))
13793 (use (match_operand:MODEF 1 "register_operand" ""))]
13794 "TARGET_USE_FANCY_MATH_387
13795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13796 || TARGET_MIX_SSE_I387)
13797 && flag_unsafe_math_optimizations"
13799 rtx op0 = gen_reg_rtx (XFmode);
13801 rtx op2 = gen_reg_rtx (XFmode);
13802 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13804 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13805 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13809 (define_insn "fyl2xp1xf3_i387"
13810 [(set (match_operand:XF 0 "register_operand" "=f")
13811 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13812 (match_operand:XF 2 "register_operand" "u")]
13814 (clobber (match_scratch:XF 3 "=2"))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && flag_unsafe_math_optimizations"
13818 [(set_attr "type" "fpspc")
13819 (set_attr "mode" "XF")])
13821 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13822 [(set (match_operand:XF 0 "register_operand" "=f")
13823 (unspec:XF [(float_extend:XF
13824 (match_operand:MODEF 1 "register_operand" "0"))
13825 (match_operand:XF 2 "register_operand" "u")]
13827 (clobber (match_scratch:XF 3 "=2"))]
13828 "TARGET_USE_FANCY_MATH_387
13829 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13830 || TARGET_MIX_SSE_I387)
13831 && flag_unsafe_math_optimizations"
13833 [(set_attr "type" "fpspc")
13834 (set_attr "mode" "XF")])
13836 (define_expand "log1pxf2"
13837 [(use (match_operand:XF 0 "register_operand" ""))
13838 (use (match_operand:XF 1 "register_operand" ""))]
13839 "TARGET_USE_FANCY_MATH_387
13840 && flag_unsafe_math_optimizations"
13842 if (optimize_insn_for_size_p ())
13845 ix86_emit_i387_log1p (operands[0], operands[1]);
13849 (define_expand "log1p<mode>2"
13850 [(use (match_operand:MODEF 0 "register_operand" ""))
13851 (use (match_operand:MODEF 1 "register_operand" ""))]
13852 "TARGET_USE_FANCY_MATH_387
13853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13854 || TARGET_MIX_SSE_I387)
13855 && flag_unsafe_math_optimizations"
13859 if (optimize_insn_for_size_p ())
13862 op0 = gen_reg_rtx (XFmode);
13864 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13866 ix86_emit_i387_log1p (op0, operands[1]);
13867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13871 (define_insn "fxtractxf3_i387"
13872 [(set (match_operand:XF 0 "register_operand" "=f")
13873 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13874 UNSPEC_XTRACT_FRACT))
13875 (set (match_operand:XF 1 "register_operand" "=u")
13876 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && flag_unsafe_math_optimizations"
13880 [(set_attr "type" "fpspc")
13881 (set_attr "mode" "XF")])
13883 (define_insn "fxtract_extend<mode>xf3_i387"
13884 [(set (match_operand:XF 0 "register_operand" "=f")
13885 (unspec:XF [(float_extend:XF
13886 (match_operand:MODEF 2 "register_operand" "0"))]
13887 UNSPEC_XTRACT_FRACT))
13888 (set (match_operand:XF 1 "register_operand" "=u")
13889 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13898 (define_expand "logbxf2"
13899 [(parallel [(set (match_dup 2)
13900 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13901 UNSPEC_XTRACT_FRACT))
13902 (set (match_operand:XF 0 "register_operand" "")
13903 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13904 "TARGET_USE_FANCY_MATH_387
13905 && flag_unsafe_math_optimizations"
13906 "operands[2] = gen_reg_rtx (XFmode);")
13908 (define_expand "logb<mode>2"
13909 [(use (match_operand:MODEF 0 "register_operand" ""))
13910 (use (match_operand:MODEF 1 "register_operand" ""))]
13911 "TARGET_USE_FANCY_MATH_387
13912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13913 || TARGET_MIX_SSE_I387)
13914 && flag_unsafe_math_optimizations"
13916 rtx op0 = gen_reg_rtx (XFmode);
13917 rtx op1 = gen_reg_rtx (XFmode);
13919 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13920 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13924 (define_expand "ilogbxf2"
13925 [(use (match_operand:SI 0 "register_operand" ""))
13926 (use (match_operand:XF 1 "register_operand" ""))]
13927 "TARGET_USE_FANCY_MATH_387
13928 && flag_unsafe_math_optimizations"
13932 if (optimize_insn_for_size_p ())
13935 op0 = gen_reg_rtx (XFmode);
13936 op1 = gen_reg_rtx (XFmode);
13938 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13939 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13943 (define_expand "ilogb<mode>2"
13944 [(use (match_operand:SI 0 "register_operand" ""))
13945 (use (match_operand:MODEF 1 "register_operand" ""))]
13946 "TARGET_USE_FANCY_MATH_387
13947 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948 || TARGET_MIX_SSE_I387)
13949 && flag_unsafe_math_optimizations"
13953 if (optimize_insn_for_size_p ())
13956 op0 = gen_reg_rtx (XFmode);
13957 op1 = gen_reg_rtx (XFmode);
13959 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13960 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13964 (define_insn "*f2xm1xf2_i387"
13965 [(set (match_operand:XF 0 "register_operand" "=f")
13966 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13968 "TARGET_USE_FANCY_MATH_387
13969 && flag_unsafe_math_optimizations"
13971 [(set_attr "type" "fpspc")
13972 (set_attr "mode" "XF")])
13974 (define_insn "*fscalexf4_i387"
13975 [(set (match_operand:XF 0 "register_operand" "=f")
13976 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13977 (match_operand:XF 3 "register_operand" "1")]
13978 UNSPEC_FSCALE_FRACT))
13979 (set (match_operand:XF 1 "register_operand" "=u")
13980 (unspec:XF [(match_dup 2) (match_dup 3)]
13981 UNSPEC_FSCALE_EXP))]
13982 "TARGET_USE_FANCY_MATH_387
13983 && flag_unsafe_math_optimizations"
13985 [(set_attr "type" "fpspc")
13986 (set_attr "mode" "XF")])
13988 (define_expand "expNcorexf3"
13989 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13990 (match_operand:XF 2 "register_operand" "")))
13991 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13992 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13993 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13994 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13995 (parallel [(set (match_operand:XF 0 "register_operand" "")
13996 (unspec:XF [(match_dup 8) (match_dup 4)]
13997 UNSPEC_FSCALE_FRACT))
13999 (unspec:XF [(match_dup 8) (match_dup 4)]
14000 UNSPEC_FSCALE_EXP))])]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations"
14006 if (optimize_insn_for_size_p ())
14009 for (i = 3; i < 10; i++)
14010 operands[i] = gen_reg_rtx (XFmode);
14012 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14015 (define_expand "expxf2"
14016 [(use (match_operand:XF 0 "register_operand" ""))
14017 (use (match_operand:XF 1 "register_operand" ""))]
14018 "TARGET_USE_FANCY_MATH_387
14019 && flag_unsafe_math_optimizations"
14023 if (optimize_insn_for_size_p ())
14026 op2 = gen_reg_rtx (XFmode);
14027 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14029 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14033 (define_expand "exp<mode>2"
14034 [(use (match_operand:MODEF 0 "register_operand" ""))
14035 (use (match_operand:MODEF 1 "general_operand" ""))]
14036 "TARGET_USE_FANCY_MATH_387
14037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14038 || TARGET_MIX_SSE_I387)
14039 && flag_unsafe_math_optimizations"
14043 if (optimize_insn_for_size_p ())
14046 op0 = gen_reg_rtx (XFmode);
14047 op1 = gen_reg_rtx (XFmode);
14049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14050 emit_insn (gen_expxf2 (op0, op1));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14055 (define_expand "exp10xf2"
14056 [(use (match_operand:XF 0 "register_operand" ""))
14057 (use (match_operand:XF 1 "register_operand" ""))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations"
14063 if (optimize_insn_for_size_p ())
14066 op2 = gen_reg_rtx (XFmode);
14067 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14069 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14073 (define_expand "exp10<mode>2"
14074 [(use (match_operand:MODEF 0 "register_operand" ""))
14075 (use (match_operand:MODEF 1 "general_operand" ""))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14083 if (optimize_insn_for_size_p ())
14086 op0 = gen_reg_rtx (XFmode);
14087 op1 = gen_reg_rtx (XFmode);
14089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090 emit_insn (gen_exp10xf2 (op0, op1));
14091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14095 (define_expand "exp2xf2"
14096 [(use (match_operand:XF 0 "register_operand" ""))
14097 (use (match_operand:XF 1 "register_operand" ""))]
14098 "TARGET_USE_FANCY_MATH_387
14099 && flag_unsafe_math_optimizations"
14103 if (optimize_insn_for_size_p ())
14106 op2 = gen_reg_rtx (XFmode);
14107 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14109 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14113 (define_expand "exp2<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "general_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14123 if (optimize_insn_for_size_p ())
14126 op0 = gen_reg_rtx (XFmode);
14127 op1 = gen_reg_rtx (XFmode);
14129 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130 emit_insn (gen_exp2xf2 (op0, op1));
14131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135 (define_expand "expm1xf2"
14136 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14138 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14139 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14140 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14141 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14142 (parallel [(set (match_dup 7)
14143 (unspec:XF [(match_dup 6) (match_dup 4)]
14144 UNSPEC_FSCALE_FRACT))
14146 (unspec:XF [(match_dup 6) (match_dup 4)]
14147 UNSPEC_FSCALE_EXP))])
14148 (parallel [(set (match_dup 10)
14149 (unspec:XF [(match_dup 9) (match_dup 8)]
14150 UNSPEC_FSCALE_FRACT))
14151 (set (match_dup 11)
14152 (unspec:XF [(match_dup 9) (match_dup 8)]
14153 UNSPEC_FSCALE_EXP))])
14154 (set (match_dup 12) (minus:XF (match_dup 10)
14155 (float_extend:XF (match_dup 13))))
14156 (set (match_operand:XF 0 "register_operand" "")
14157 (plus:XF (match_dup 12) (match_dup 7)))]
14158 "TARGET_USE_FANCY_MATH_387
14159 && flag_unsafe_math_optimizations"
14163 if (optimize_insn_for_size_p ())
14166 for (i = 2; i < 13; i++)
14167 operands[i] = gen_reg_rtx (XFmode);
14170 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14172 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14175 (define_expand "expm1<mode>2"
14176 [(use (match_operand:MODEF 0 "register_operand" ""))
14177 (use (match_operand:MODEF 1 "general_operand" ""))]
14178 "TARGET_USE_FANCY_MATH_387
14179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14180 || TARGET_MIX_SSE_I387)
14181 && flag_unsafe_math_optimizations"
14185 if (optimize_insn_for_size_p ())
14188 op0 = gen_reg_rtx (XFmode);
14189 op1 = gen_reg_rtx (XFmode);
14191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14192 emit_insn (gen_expm1xf2 (op0, op1));
14193 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14197 (define_expand "ldexpxf3"
14198 [(set (match_dup 3)
14199 (float:XF (match_operand:SI 2 "register_operand" "")))
14200 (parallel [(set (match_operand:XF 0 " register_operand" "")
14201 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14203 UNSPEC_FSCALE_FRACT))
14205 (unspec:XF [(match_dup 1) (match_dup 3)]
14206 UNSPEC_FSCALE_EXP))])]
14207 "TARGET_USE_FANCY_MATH_387
14208 && flag_unsafe_math_optimizations"
14210 if (optimize_insn_for_size_p ())
14213 operands[3] = gen_reg_rtx (XFmode);
14214 operands[4] = gen_reg_rtx (XFmode);
14217 (define_expand "ldexp<mode>3"
14218 [(use (match_operand:MODEF 0 "register_operand" ""))
14219 (use (match_operand:MODEF 1 "general_operand" ""))
14220 (use (match_operand:SI 2 "register_operand" ""))]
14221 "TARGET_USE_FANCY_MATH_387
14222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14223 || TARGET_MIX_SSE_I387)
14224 && flag_unsafe_math_optimizations"
14228 if (optimize_insn_for_size_p ())
14231 op0 = gen_reg_rtx (XFmode);
14232 op1 = gen_reg_rtx (XFmode);
14234 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14235 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14240 (define_expand "scalbxf3"
14241 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14242 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14243 (match_operand:XF 2 "register_operand" "")]
14244 UNSPEC_FSCALE_FRACT))
14246 (unspec:XF [(match_dup 1) (match_dup 2)]
14247 UNSPEC_FSCALE_EXP))])]
14248 "TARGET_USE_FANCY_MATH_387
14249 && flag_unsafe_math_optimizations"
14251 if (optimize_insn_for_size_p ())
14254 operands[3] = gen_reg_rtx (XFmode);
14257 (define_expand "scalb<mode>3"
14258 [(use (match_operand:MODEF 0 "register_operand" ""))
14259 (use (match_operand:MODEF 1 "general_operand" ""))
14260 (use (match_operand:MODEF 2 "general_operand" ""))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations"
14268 if (optimize_insn_for_size_p ())
14271 op0 = gen_reg_rtx (XFmode);
14272 op1 = gen_reg_rtx (XFmode);
14273 op2 = gen_reg_rtx (XFmode);
14275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14277 emit_insn (gen_scalbxf3 (op0, op1, op2));
14278 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14282 (define_expand "significandxf2"
14283 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14284 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14285 UNSPEC_XTRACT_FRACT))
14287 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14290 "operands[2] = gen_reg_rtx (XFmode);")
14292 (define_expand "significand<mode>2"
14293 [(use (match_operand:MODEF 0 "register_operand" ""))
14294 (use (match_operand:MODEF 1 "register_operand" ""))]
14295 "TARGET_USE_FANCY_MATH_387
14296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14297 || TARGET_MIX_SSE_I387)
14298 && flag_unsafe_math_optimizations"
14300 rtx op0 = gen_reg_rtx (XFmode);
14301 rtx op1 = gen_reg_rtx (XFmode);
14303 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14304 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14309 (define_insn "sse4_1_round<mode>2"
14310 [(set (match_operand:MODEF 0 "register_operand" "=x")
14311 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14312 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14315 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14316 [(set_attr "type" "ssecvt")
14317 (set_attr "prefix_extra" "1")
14318 (set_attr "prefix" "maybe_vex")
14319 (set_attr "mode" "<MODE>")])
14321 (define_insn "rintxf2"
14322 [(set (match_operand:XF 0 "register_operand" "=f")
14323 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14325 "TARGET_USE_FANCY_MATH_387
14326 && flag_unsafe_math_optimizations"
14328 [(set_attr "type" "fpspc")
14329 (set_attr "mode" "XF")])
14331 (define_expand "rint<mode>2"
14332 [(use (match_operand:MODEF 0 "register_operand" ""))
14333 (use (match_operand:MODEF 1 "register_operand" ""))]
14334 "(TARGET_USE_FANCY_MATH_387
14335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14336 || TARGET_MIX_SSE_I387)
14337 && flag_unsafe_math_optimizations)
14338 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14339 && !flag_trapping_math)"
14341 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14342 && !flag_trapping_math)
14344 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14347 emit_insn (gen_sse4_1_round<mode>2
14348 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14350 ix86_expand_rint (operand0, operand1);
14354 rtx op0 = gen_reg_rtx (XFmode);
14355 rtx op1 = gen_reg_rtx (XFmode);
14357 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358 emit_insn (gen_rintxf2 (op0, op1));
14360 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14365 (define_expand "round<mode>2"
14366 [(match_operand:MODEF 0 "register_operand" "")
14367 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14368 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14369 && !flag_trapping_math && !flag_rounding_math"
14371 if (optimize_insn_for_size_p ())
14373 if (TARGET_64BIT || (<MODE>mode != DFmode))
14374 ix86_expand_round (operand0, operand1);
14376 ix86_expand_rounddf_32 (operand0, operand1);
14380 (define_insn_and_split "*fistdi2_1"
14381 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14382 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14384 "TARGET_USE_FANCY_MATH_387
14385 && can_create_pseudo_p ()"
14390 if (memory_operand (operands[0], VOIDmode))
14391 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14394 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14395 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14400 [(set_attr "type" "fpspc")
14401 (set_attr "mode" "DI")])
14403 (define_insn "fistdi2"
14404 [(set (match_operand:DI 0 "memory_operand" "=m")
14405 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14407 (clobber (match_scratch:XF 2 "=&1f"))]
14408 "TARGET_USE_FANCY_MATH_387"
14409 "* return output_fix_trunc (insn, operands, false);"
14410 [(set_attr "type" "fpspc")
14411 (set_attr "mode" "DI")])
14413 (define_insn "fistdi2_with_temp"
14414 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14415 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14417 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14418 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14419 "TARGET_USE_FANCY_MATH_387"
14421 [(set_attr "type" "fpspc")
14422 (set_attr "mode" "DI")])
14425 [(set (match_operand:DI 0 "register_operand" "")
14426 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14428 (clobber (match_operand:DI 2 "memory_operand" ""))
14429 (clobber (match_scratch 3 ""))]
14431 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14432 (clobber (match_dup 3))])
14433 (set (match_dup 0) (match_dup 2))])
14436 [(set (match_operand:DI 0 "memory_operand" "")
14437 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14439 (clobber (match_operand:DI 2 "memory_operand" ""))
14440 (clobber (match_scratch 3 ""))]
14442 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14443 (clobber (match_dup 3))])])
14445 (define_insn_and_split "*fist<mode>2_1"
14446 [(set (match_operand:SWI24 0 "register_operand" "")
14447 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14449 "TARGET_USE_FANCY_MATH_387
14450 && can_create_pseudo_p ()"
14455 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14456 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14460 [(set_attr "type" "fpspc")
14461 (set_attr "mode" "<MODE>")])
14463 (define_insn "fist<mode>2"
14464 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14465 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14467 "TARGET_USE_FANCY_MATH_387"
14468 "* return output_fix_trunc (insn, operands, false);"
14469 [(set_attr "type" "fpspc")
14470 (set_attr "mode" "<MODE>")])
14472 (define_insn "fist<mode>2_with_temp"
14473 [(set (match_operand:SWI24 0 "register_operand" "=r")
14474 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14476 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14477 "TARGET_USE_FANCY_MATH_387"
14479 [(set_attr "type" "fpspc")
14480 (set_attr "mode" "<MODE>")])
14483 [(set (match_operand:SWI24 0 "register_operand" "")
14484 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14486 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14488 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14489 (set (match_dup 0) (match_dup 2))])
14492 [(set (match_operand:SWI24 0 "memory_operand" "")
14493 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14495 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14497 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14499 (define_expand "lrintxf<mode>2"
14500 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14501 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14503 "TARGET_USE_FANCY_MATH_387")
14505 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14506 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14507 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14508 UNSPEC_FIX_NOTRUNC))]
14509 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14510 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14512 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14513 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14514 (match_operand:MODEF 1 "register_operand" "")]
14515 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14516 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14517 && !flag_trapping_math && !flag_rounding_math"
14519 if (optimize_insn_for_size_p ())
14521 ix86_expand_lround (operand0, operand1);
14525 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14526 (define_insn_and_split "frndintxf2_floor"
14527 [(set (match_operand:XF 0 "register_operand" "")
14528 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14529 UNSPEC_FRNDINT_FLOOR))
14530 (clobber (reg:CC FLAGS_REG))]
14531 "TARGET_USE_FANCY_MATH_387
14532 && flag_unsafe_math_optimizations
14533 && can_create_pseudo_p ()"
14538 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14540 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14541 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14543 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14544 operands[2], operands[3]));
14547 [(set_attr "type" "frndint")
14548 (set_attr "i387_cw" "floor")
14549 (set_attr "mode" "XF")])
14551 (define_insn "frndintxf2_floor_i387"
14552 [(set (match_operand:XF 0 "register_operand" "=f")
14553 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14554 UNSPEC_FRNDINT_FLOOR))
14555 (use (match_operand:HI 2 "memory_operand" "m"))
14556 (use (match_operand:HI 3 "memory_operand" "m"))]
14557 "TARGET_USE_FANCY_MATH_387
14558 && flag_unsafe_math_optimizations"
14559 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14560 [(set_attr "type" "frndint")
14561 (set_attr "i387_cw" "floor")
14562 (set_attr "mode" "XF")])
14564 (define_expand "floorxf2"
14565 [(use (match_operand:XF 0 "register_operand" ""))
14566 (use (match_operand:XF 1 "register_operand" ""))]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14570 if (optimize_insn_for_size_p ())
14572 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14576 (define_expand "floor<mode>2"
14577 [(use (match_operand:MODEF 0 "register_operand" ""))
14578 (use (match_operand:MODEF 1 "register_operand" ""))]
14579 "(TARGET_USE_FANCY_MATH_387
14580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14581 || TARGET_MIX_SSE_I387)
14582 && flag_unsafe_math_optimizations)
14583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14584 && !flag_trapping_math)"
14586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14587 && !flag_trapping_math
14588 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14590 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14593 emit_insn (gen_sse4_1_round<mode>2
14594 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14595 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14596 ix86_expand_floorceil (operand0, operand1, true);
14598 ix86_expand_floorceildf_32 (operand0, operand1, true);
14604 if (optimize_insn_for_size_p ())
14607 op0 = gen_reg_rtx (XFmode);
14608 op1 = gen_reg_rtx (XFmode);
14609 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14610 emit_insn (gen_frndintxf2_floor (op0, op1));
14612 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14617 (define_insn_and_split "*fist<mode>2_floor_1"
14618 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14619 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14620 UNSPEC_FIST_FLOOR))
14621 (clobber (reg:CC FLAGS_REG))]
14622 "TARGET_USE_FANCY_MATH_387
14623 && flag_unsafe_math_optimizations
14624 && can_create_pseudo_p ()"
14629 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14631 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14632 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14633 if (memory_operand (operands[0], VOIDmode))
14634 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14635 operands[2], operands[3]));
14638 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14639 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14640 operands[2], operands[3],
14645 [(set_attr "type" "fistp")
14646 (set_attr "i387_cw" "floor")
14647 (set_attr "mode" "<MODE>")])
14649 (define_insn "fistdi2_floor"
14650 [(set (match_operand:DI 0 "memory_operand" "=m")
14651 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14652 UNSPEC_FIST_FLOOR))
14653 (use (match_operand:HI 2 "memory_operand" "m"))
14654 (use (match_operand:HI 3 "memory_operand" "m"))
14655 (clobber (match_scratch:XF 4 "=&1f"))]
14656 "TARGET_USE_FANCY_MATH_387
14657 && flag_unsafe_math_optimizations"
14658 "* return output_fix_trunc (insn, operands, false);"
14659 [(set_attr "type" "fistp")
14660 (set_attr "i387_cw" "floor")
14661 (set_attr "mode" "DI")])
14663 (define_insn "fistdi2_floor_with_temp"
14664 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14665 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14666 UNSPEC_FIST_FLOOR))
14667 (use (match_operand:HI 2 "memory_operand" "m,m"))
14668 (use (match_operand:HI 3 "memory_operand" "m,m"))
14669 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14670 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14671 "TARGET_USE_FANCY_MATH_387
14672 && flag_unsafe_math_optimizations"
14674 [(set_attr "type" "fistp")
14675 (set_attr "i387_cw" "floor")
14676 (set_attr "mode" "DI")])
14679 [(set (match_operand:DI 0 "register_operand" "")
14680 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14681 UNSPEC_FIST_FLOOR))
14682 (use (match_operand:HI 2 "memory_operand" ""))
14683 (use (match_operand:HI 3 "memory_operand" ""))
14684 (clobber (match_operand:DI 4 "memory_operand" ""))
14685 (clobber (match_scratch 5 ""))]
14687 [(parallel [(set (match_dup 4)
14688 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14689 (use (match_dup 2))
14690 (use (match_dup 3))
14691 (clobber (match_dup 5))])
14692 (set (match_dup 0) (match_dup 4))])
14695 [(set (match_operand:DI 0 "memory_operand" "")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14697 UNSPEC_FIST_FLOOR))
14698 (use (match_operand:HI 2 "memory_operand" ""))
14699 (use (match_operand:HI 3 "memory_operand" ""))
14700 (clobber (match_operand:DI 4 "memory_operand" ""))
14701 (clobber (match_scratch 5 ""))]
14703 [(parallel [(set (match_dup 0)
14704 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14705 (use (match_dup 2))
14706 (use (match_dup 3))
14707 (clobber (match_dup 5))])])
14709 (define_insn "fist<mode>2_floor"
14710 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14711 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14712 UNSPEC_FIST_FLOOR))
14713 (use (match_operand:HI 2 "memory_operand" "m"))
14714 (use (match_operand:HI 3 "memory_operand" "m"))]
14715 "TARGET_USE_FANCY_MATH_387
14716 && flag_unsafe_math_optimizations"
14717 "* return output_fix_trunc (insn, operands, false);"
14718 [(set_attr "type" "fistp")
14719 (set_attr "i387_cw" "floor")
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "fist<mode>2_floor_with_temp"
14723 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14725 UNSPEC_FIST_FLOOR))
14726 (use (match_operand:HI 2 "memory_operand" "m,m"))
14727 (use (match_operand:HI 3 "memory_operand" "m,m"))
14728 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14729 "TARGET_USE_FANCY_MATH_387
14730 && flag_unsafe_math_optimizations"
14732 [(set_attr "type" "fistp")
14733 (set_attr "i387_cw" "floor")
14734 (set_attr "mode" "<MODE>")])
14737 [(set (match_operand:SWI24 0 "register_operand" "")
14738 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14739 UNSPEC_FIST_FLOOR))
14740 (use (match_operand:HI 2 "memory_operand" ""))
14741 (use (match_operand:HI 3 "memory_operand" ""))
14742 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14744 [(parallel [(set (match_dup 4)
14745 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14746 (use (match_dup 2))
14747 (use (match_dup 3))])
14748 (set (match_dup 0) (match_dup 4))])
14751 [(set (match_operand:SWI24 0 "memory_operand" "")
14752 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14753 UNSPEC_FIST_FLOOR))
14754 (use (match_operand:HI 2 "memory_operand" ""))
14755 (use (match_operand:HI 3 "memory_operand" ""))
14756 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14758 [(parallel [(set (match_dup 0)
14759 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14760 (use (match_dup 2))
14761 (use (match_dup 3))])])
14763 (define_expand "lfloorxf<mode>2"
14764 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14765 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14766 UNSPEC_FIST_FLOOR))
14767 (clobber (reg:CC FLAGS_REG))])]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14770 && flag_unsafe_math_optimizations")
14772 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14773 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14774 (match_operand:MODEF 1 "register_operand" "")]
14775 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14776 && !flag_trapping_math"
14778 if (TARGET_64BIT && optimize_insn_for_size_p ())
14780 ix86_expand_lfloorceil (operand0, operand1, true);
14784 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14785 (define_insn_and_split "frndintxf2_ceil"
14786 [(set (match_operand:XF 0 "register_operand" "")
14787 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14788 UNSPEC_FRNDINT_CEIL))
14789 (clobber (reg:CC FLAGS_REG))]
14790 "TARGET_USE_FANCY_MATH_387
14791 && flag_unsafe_math_optimizations
14792 && can_create_pseudo_p ()"
14797 ix86_optimize_mode_switching[I387_CEIL] = 1;
14799 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14800 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14802 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14803 operands[2], operands[3]));
14806 [(set_attr "type" "frndint")
14807 (set_attr "i387_cw" "ceil")
14808 (set_attr "mode" "XF")])
14810 (define_insn "frndintxf2_ceil_i387"
14811 [(set (match_operand:XF 0 "register_operand" "=f")
14812 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14813 UNSPEC_FRNDINT_CEIL))
14814 (use (match_operand:HI 2 "memory_operand" "m"))
14815 (use (match_operand:HI 3 "memory_operand" "m"))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && flag_unsafe_math_optimizations"
14818 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14819 [(set_attr "type" "frndint")
14820 (set_attr "i387_cw" "ceil")
14821 (set_attr "mode" "XF")])
14823 (define_expand "ceilxf2"
14824 [(use (match_operand:XF 0 "register_operand" ""))
14825 (use (match_operand:XF 1 "register_operand" ""))]
14826 "TARGET_USE_FANCY_MATH_387
14827 && flag_unsafe_math_optimizations"
14829 if (optimize_insn_for_size_p ())
14831 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14835 (define_expand "ceil<mode>2"
14836 [(use (match_operand:MODEF 0 "register_operand" ""))
14837 (use (match_operand:MODEF 1 "register_operand" ""))]
14838 "(TARGET_USE_FANCY_MATH_387
14839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14840 || TARGET_MIX_SSE_I387)
14841 && flag_unsafe_math_optimizations)
14842 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14843 && !flag_trapping_math)"
14845 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math
14847 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14850 emit_insn (gen_sse4_1_round<mode>2
14851 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14852 else if (optimize_insn_for_size_p ())
14854 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14855 ix86_expand_floorceil (operand0, operand1, false);
14857 ix86_expand_floorceildf_32 (operand0, operand1, false);
14863 if (optimize_insn_for_size_p ())
14866 op0 = gen_reg_rtx (XFmode);
14867 op1 = gen_reg_rtx (XFmode);
14868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14869 emit_insn (gen_frndintxf2_ceil (op0, op1));
14871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14876 (define_insn_and_split "*fist<mode>2_ceil_1"
14877 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14878 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14880 (clobber (reg:CC FLAGS_REG))]
14881 "TARGET_USE_FANCY_MATH_387
14882 && flag_unsafe_math_optimizations
14883 && can_create_pseudo_p ()"
14888 ix86_optimize_mode_switching[I387_CEIL] = 1;
14890 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14891 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14892 if (memory_operand (operands[0], VOIDmode))
14893 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14894 operands[2], operands[3]));
14897 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14898 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14899 operands[2], operands[3],
14904 [(set_attr "type" "fistp")
14905 (set_attr "i387_cw" "ceil")
14906 (set_attr "mode" "<MODE>")])
14908 (define_insn "fistdi2_ceil"
14909 [(set (match_operand:DI 0 "memory_operand" "=m")
14910 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14912 (use (match_operand:HI 2 "memory_operand" "m"))
14913 (use (match_operand:HI 3 "memory_operand" "m"))
14914 (clobber (match_scratch:XF 4 "=&1f"))]
14915 "TARGET_USE_FANCY_MATH_387
14916 && flag_unsafe_math_optimizations"
14917 "* return output_fix_trunc (insn, operands, false);"
14918 [(set_attr "type" "fistp")
14919 (set_attr "i387_cw" "ceil")
14920 (set_attr "mode" "DI")])
14922 (define_insn "fistdi2_ceil_with_temp"
14923 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14924 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14926 (use (match_operand:HI 2 "memory_operand" "m,m"))
14927 (use (match_operand:HI 3 "memory_operand" "m,m"))
14928 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14929 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14930 "TARGET_USE_FANCY_MATH_387
14931 && flag_unsafe_math_optimizations"
14933 [(set_attr "type" "fistp")
14934 (set_attr "i387_cw" "ceil")
14935 (set_attr "mode" "DI")])
14938 [(set (match_operand:DI 0 "register_operand" "")
14939 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14941 (use (match_operand:HI 2 "memory_operand" ""))
14942 (use (match_operand:HI 3 "memory_operand" ""))
14943 (clobber (match_operand:DI 4 "memory_operand" ""))
14944 (clobber (match_scratch 5 ""))]
14946 [(parallel [(set (match_dup 4)
14947 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14948 (use (match_dup 2))
14949 (use (match_dup 3))
14950 (clobber (match_dup 5))])
14951 (set (match_dup 0) (match_dup 4))])
14954 [(set (match_operand:DI 0 "memory_operand" "")
14955 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14957 (use (match_operand:HI 2 "memory_operand" ""))
14958 (use (match_operand:HI 3 "memory_operand" ""))
14959 (clobber (match_operand:DI 4 "memory_operand" ""))
14960 (clobber (match_scratch 5 ""))]
14962 [(parallel [(set (match_dup 0)
14963 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14964 (use (match_dup 2))
14965 (use (match_dup 3))
14966 (clobber (match_dup 5))])])
14968 (define_insn "fist<mode>2_ceil"
14969 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14970 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14972 (use (match_operand:HI 2 "memory_operand" "m"))
14973 (use (match_operand:HI 3 "memory_operand" "m"))]
14974 "TARGET_USE_FANCY_MATH_387
14975 && flag_unsafe_math_optimizations"
14976 "* return output_fix_trunc (insn, operands, false);"
14977 [(set_attr "type" "fistp")
14978 (set_attr "i387_cw" "ceil")
14979 (set_attr "mode" "<MODE>")])
14981 (define_insn "fist<mode>2_ceil_with_temp"
14982 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14983 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14985 (use (match_operand:HI 2 "memory_operand" "m,m"))
14986 (use (match_operand:HI 3 "memory_operand" "m,m"))
14987 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14991 [(set_attr "type" "fistp")
14992 (set_attr "i387_cw" "ceil")
14993 (set_attr "mode" "<MODE>")])
14996 [(set (match_operand:SWI24 0 "register_operand" "")
14997 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14999 (use (match_operand:HI 2 "memory_operand" ""))
15000 (use (match_operand:HI 3 "memory_operand" ""))
15001 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15003 [(parallel [(set (match_dup 4)
15004 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15005 (use (match_dup 2))
15006 (use (match_dup 3))])
15007 (set (match_dup 0) (match_dup 4))])
15010 [(set (match_operand:SWI24 0 "memory_operand" "")
15011 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15013 (use (match_operand:HI 2 "memory_operand" ""))
15014 (use (match_operand:HI 3 "memory_operand" ""))
15015 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15017 [(parallel [(set (match_dup 0)
15018 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15019 (use (match_dup 2))
15020 (use (match_dup 3))])])
15022 (define_expand "lceilxf<mode>2"
15023 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15024 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15026 (clobber (reg:CC FLAGS_REG))])]
15027 "TARGET_USE_FANCY_MATH_387
15028 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15029 && flag_unsafe_math_optimizations")
15031 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15032 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15033 (match_operand:MODEF 1 "register_operand" "")]
15034 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15035 && !flag_trapping_math"
15037 ix86_expand_lfloorceil (operand0, operand1, false);
15041 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15042 (define_insn_and_split "frndintxf2_trunc"
15043 [(set (match_operand:XF 0 "register_operand" "")
15044 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15045 UNSPEC_FRNDINT_TRUNC))
15046 (clobber (reg:CC FLAGS_REG))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations
15049 && can_create_pseudo_p ()"
15054 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15056 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15057 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15059 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15060 operands[2], operands[3]));
15063 [(set_attr "type" "frndint")
15064 (set_attr "i387_cw" "trunc")
15065 (set_attr "mode" "XF")])
15067 (define_insn "frndintxf2_trunc_i387"
15068 [(set (match_operand:XF 0 "register_operand" "=f")
15069 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15070 UNSPEC_FRNDINT_TRUNC))
15071 (use (match_operand:HI 2 "memory_operand" "m"))
15072 (use (match_operand:HI 3 "memory_operand" "m"))]
15073 "TARGET_USE_FANCY_MATH_387
15074 && flag_unsafe_math_optimizations"
15075 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15076 [(set_attr "type" "frndint")
15077 (set_attr "i387_cw" "trunc")
15078 (set_attr "mode" "XF")])
15080 (define_expand "btruncxf2"
15081 [(use (match_operand:XF 0 "register_operand" ""))
15082 (use (match_operand:XF 1 "register_operand" ""))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && flag_unsafe_math_optimizations"
15086 if (optimize_insn_for_size_p ())
15088 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15092 (define_expand "btrunc<mode>2"
15093 [(use (match_operand:MODEF 0 "register_operand" ""))
15094 (use (match_operand:MODEF 1 "register_operand" ""))]
15095 "(TARGET_USE_FANCY_MATH_387
15096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15097 || TARGET_MIX_SSE_I387)
15098 && flag_unsafe_math_optimizations)
15099 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15100 && !flag_trapping_math)"
15102 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15103 && !flag_trapping_math
15104 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15107 emit_insn (gen_sse4_1_round<mode>2
15108 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15109 else if (optimize_insn_for_size_p ())
15111 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15112 ix86_expand_trunc (operand0, operand1);
15114 ix86_expand_truncdf_32 (operand0, operand1);
15120 if (optimize_insn_for_size_p ())
15123 op0 = gen_reg_rtx (XFmode);
15124 op1 = gen_reg_rtx (XFmode);
15125 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15126 emit_insn (gen_frndintxf2_trunc (op0, op1));
15128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15134 (define_insn_and_split "frndintxf2_mask_pm"
15135 [(set (match_operand:XF 0 "register_operand" "")
15136 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15137 UNSPEC_FRNDINT_MASK_PM))
15138 (clobber (reg:CC FLAGS_REG))]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations
15141 && can_create_pseudo_p ()"
15146 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15148 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15149 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15151 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15152 operands[2], operands[3]));
15155 [(set_attr "type" "frndint")
15156 (set_attr "i387_cw" "mask_pm")
15157 (set_attr "mode" "XF")])
15159 (define_insn "frndintxf2_mask_pm_i387"
15160 [(set (match_operand:XF 0 "register_operand" "=f")
15161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15162 UNSPEC_FRNDINT_MASK_PM))
15163 (use (match_operand:HI 2 "memory_operand" "m"))
15164 (use (match_operand:HI 3 "memory_operand" "m"))]
15165 "TARGET_USE_FANCY_MATH_387
15166 && flag_unsafe_math_optimizations"
15167 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15168 [(set_attr "type" "frndint")
15169 (set_attr "i387_cw" "mask_pm")
15170 (set_attr "mode" "XF")])
15172 (define_expand "nearbyintxf2"
15173 [(use (match_operand:XF 0 "register_operand" ""))
15174 (use (match_operand:XF 1 "register_operand" ""))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations"
15178 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15182 (define_expand "nearbyint<mode>2"
15183 [(use (match_operand:MODEF 0 "register_operand" ""))
15184 (use (match_operand:MODEF 1 "register_operand" ""))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15187 || TARGET_MIX_SSE_I387)
15188 && flag_unsafe_math_optimizations"
15190 rtx op0 = gen_reg_rtx (XFmode);
15191 rtx op1 = gen_reg_rtx (XFmode);
15193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15194 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15200 (define_insn "fxam<mode>2_i387"
15201 [(set (match_operand:HI 0 "register_operand" "=a")
15203 [(match_operand:X87MODEF 1 "register_operand" "f")]
15205 "TARGET_USE_FANCY_MATH_387"
15206 "fxam\n\tfnstsw\t%0"
15207 [(set_attr "type" "multi")
15208 (set_attr "length" "4")
15209 (set_attr "unit" "i387")
15210 (set_attr "mode" "<MODE>")])
15212 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15213 [(set (match_operand:HI 0 "register_operand" "")
15215 [(match_operand:MODEF 1 "memory_operand" "")]
15217 "TARGET_USE_FANCY_MATH_387
15218 && can_create_pseudo_p ()"
15221 [(set (match_dup 2)(match_dup 1))
15223 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15225 operands[2] = gen_reg_rtx (<MODE>mode);
15227 MEM_VOLATILE_P (operands[1]) = 1;
15229 [(set_attr "type" "multi")
15230 (set_attr "unit" "i387")
15231 (set_attr "mode" "<MODE>")])
15233 (define_expand "isinfxf2"
15234 [(use (match_operand:SI 0 "register_operand" ""))
15235 (use (match_operand:XF 1 "register_operand" ""))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && TARGET_C99_FUNCTIONS"
15239 rtx mask = GEN_INT (0x45);
15240 rtx val = GEN_INT (0x05);
15244 rtx scratch = gen_reg_rtx (HImode);
15245 rtx res = gen_reg_rtx (QImode);
15247 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15249 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15250 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15251 cond = gen_rtx_fmt_ee (EQ, QImode,
15252 gen_rtx_REG (CCmode, FLAGS_REG),
15254 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15255 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15259 (define_expand "isinf<mode>2"
15260 [(use (match_operand:SI 0 "register_operand" ""))
15261 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15262 "TARGET_USE_FANCY_MATH_387
15263 && TARGET_C99_FUNCTIONS
15264 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15266 rtx mask = GEN_INT (0x45);
15267 rtx val = GEN_INT (0x05);
15271 rtx scratch = gen_reg_rtx (HImode);
15272 rtx res = gen_reg_rtx (QImode);
15274 /* Remove excess precision by forcing value through memory. */
15275 if (memory_operand (operands[1], VOIDmode))
15276 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15279 enum ix86_stack_slot slot = (virtuals_instantiated
15282 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15284 emit_move_insn (temp, operands[1]);
15285 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15288 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15289 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15290 cond = gen_rtx_fmt_ee (EQ, QImode,
15291 gen_rtx_REG (CCmode, FLAGS_REG),
15293 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15294 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15298 (define_expand "signbitxf2"
15299 [(use (match_operand:SI 0 "register_operand" ""))
15300 (use (match_operand:XF 1 "register_operand" ""))]
15301 "TARGET_USE_FANCY_MATH_387"
15303 rtx scratch = gen_reg_rtx (HImode);
15305 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15306 emit_insn (gen_andsi3 (operands[0],
15307 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15311 (define_insn "movmsk_df"
15312 [(set (match_operand:SI 0 "register_operand" "=r")
15314 [(match_operand:DF 1 "register_operand" "x")]
15316 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15317 "%vmovmskpd\t{%1, %0|%0, %1}"
15318 [(set_attr "type" "ssemov")
15319 (set_attr "prefix" "maybe_vex")
15320 (set_attr "mode" "DF")])
15322 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15323 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15324 (define_expand "signbitdf2"
15325 [(use (match_operand:SI 0 "register_operand" ""))
15326 (use (match_operand:DF 1 "register_operand" ""))]
15327 "TARGET_USE_FANCY_MATH_387
15328 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15330 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15332 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15333 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15337 rtx scratch = gen_reg_rtx (HImode);
15339 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15340 emit_insn (gen_andsi3 (operands[0],
15341 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15346 (define_expand "signbitsf2"
15347 [(use (match_operand:SI 0 "register_operand" ""))
15348 (use (match_operand:SF 1 "register_operand" ""))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15352 rtx scratch = gen_reg_rtx (HImode);
15354 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15355 emit_insn (gen_andsi3 (operands[0],
15356 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15360 ;; Block operation instructions
15363 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15366 [(set_attr "length" "1")
15367 (set_attr "length_immediate" "0")
15368 (set_attr "modrm" "0")])
15370 (define_expand "movmem<mode>"
15371 [(use (match_operand:BLK 0 "memory_operand" ""))
15372 (use (match_operand:BLK 1 "memory_operand" ""))
15373 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15374 (use (match_operand:SWI48 3 "const_int_operand" ""))
15375 (use (match_operand:SI 4 "const_int_operand" ""))
15376 (use (match_operand:SI 5 "const_int_operand" ""))]
15379 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15380 operands[4], operands[5]))
15386 ;; Most CPUs don't like single string operations
15387 ;; Handle this case here to simplify previous expander.
15389 (define_expand "strmov"
15390 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15391 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15392 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15393 (clobber (reg:CC FLAGS_REG))])
15394 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15395 (clobber (reg:CC FLAGS_REG))])]
15398 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15400 /* If .md ever supports :P for Pmode, these can be directly
15401 in the pattern above. */
15402 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15403 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15405 /* Can't use this if the user has appropriated esi or edi. */
15406 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15407 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15409 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15410 operands[2], operands[3],
15411 operands[5], operands[6]));
15415 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15418 (define_expand "strmov_singleop"
15419 [(parallel [(set (match_operand 1 "memory_operand" "")
15420 (match_operand 3 "memory_operand" ""))
15421 (set (match_operand 0 "register_operand" "")
15422 (match_operand 4 "" ""))
15423 (set (match_operand 2 "register_operand" "")
15424 (match_operand 5 "" ""))])]
15426 "ix86_current_function_needs_cld = 1;")
15428 (define_insn "*strmovdi_rex_1"
15429 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15430 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15431 (set (match_operand:DI 0 "register_operand" "=D")
15432 (plus:DI (match_dup 2)
15434 (set (match_operand:DI 1 "register_operand" "=S")
15435 (plus:DI (match_dup 3)
15438 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15440 [(set_attr "type" "str")
15441 (set_attr "memory" "both")
15442 (set_attr "mode" "DI")])
15444 (define_insn "*strmovsi_1"
15445 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15446 (mem:SI (match_operand:P 3 "register_operand" "1")))
15447 (set (match_operand:P 0 "register_operand" "=D")
15448 (plus:P (match_dup 2)
15450 (set (match_operand:P 1 "register_operand" "=S")
15451 (plus:P (match_dup 3)
15453 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15455 [(set_attr "type" "str")
15456 (set_attr "memory" "both")
15457 (set_attr "mode" "SI")])
15459 (define_insn "*strmovhi_1"
15460 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15461 (mem:HI (match_operand:P 3 "register_operand" "1")))
15462 (set (match_operand:P 0 "register_operand" "=D")
15463 (plus:P (match_dup 2)
15465 (set (match_operand:P 1 "register_operand" "=S")
15466 (plus:P (match_dup 3)
15468 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15470 [(set_attr "type" "str")
15471 (set_attr "memory" "both")
15472 (set_attr "mode" "HI")])
15474 (define_insn "*strmovqi_1"
15475 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15476 (mem:QI (match_operand:P 3 "register_operand" "1")))
15477 (set (match_operand:P 0 "register_operand" "=D")
15478 (plus:P (match_dup 2)
15480 (set (match_operand:P 1 "register_operand" "=S")
15481 (plus:P (match_dup 3)
15483 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15485 [(set_attr "type" "str")
15486 (set_attr "memory" "both")
15487 (set (attr "prefix_rex")
15489 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15491 (const_string "*")))
15492 (set_attr "mode" "QI")])
15494 (define_expand "rep_mov"
15495 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15496 (set (match_operand 0 "register_operand" "")
15497 (match_operand 5 "" ""))
15498 (set (match_operand 2 "register_operand" "")
15499 (match_operand 6 "" ""))
15500 (set (match_operand 1 "memory_operand" "")
15501 (match_operand 3 "memory_operand" ""))
15502 (use (match_dup 4))])]
15504 "ix86_current_function_needs_cld = 1;")
15506 (define_insn "*rep_movdi_rex64"
15507 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15508 (set (match_operand:DI 0 "register_operand" "=D")
15509 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15511 (match_operand:DI 3 "register_operand" "0")))
15512 (set (match_operand:DI 1 "register_operand" "=S")
15513 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15514 (match_operand:DI 4 "register_operand" "1")))
15515 (set (mem:BLK (match_dup 3))
15516 (mem:BLK (match_dup 4)))
15517 (use (match_dup 5))]
15519 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15521 [(set_attr "type" "str")
15522 (set_attr "prefix_rep" "1")
15523 (set_attr "memory" "both")
15524 (set_attr "mode" "DI")])
15526 (define_insn "*rep_movsi"
15527 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15528 (set (match_operand:P 0 "register_operand" "=D")
15529 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15531 (match_operand:P 3 "register_operand" "0")))
15532 (set (match_operand:P 1 "register_operand" "=S")
15533 (plus:P (ashift:P (match_dup 5) (const_int 2))
15534 (match_operand:P 4 "register_operand" "1")))
15535 (set (mem:BLK (match_dup 3))
15536 (mem:BLK (match_dup 4)))
15537 (use (match_dup 5))]
15538 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15539 "rep{%;} movs{l|d}"
15540 [(set_attr "type" "str")
15541 (set_attr "prefix_rep" "1")
15542 (set_attr "memory" "both")
15543 (set_attr "mode" "SI")])
15545 (define_insn "*rep_movqi"
15546 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15547 (set (match_operand:P 0 "register_operand" "=D")
15548 (plus:P (match_operand:P 3 "register_operand" "0")
15549 (match_operand:P 5 "register_operand" "2")))
15550 (set (match_operand:P 1 "register_operand" "=S")
15551 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15552 (set (mem:BLK (match_dup 3))
15553 (mem:BLK (match_dup 4)))
15554 (use (match_dup 5))]
15555 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15557 [(set_attr "type" "str")
15558 (set_attr "prefix_rep" "1")
15559 (set_attr "memory" "both")
15560 (set_attr "mode" "QI")])
15562 (define_expand "setmem<mode>"
15563 [(use (match_operand:BLK 0 "memory_operand" ""))
15564 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15565 (use (match_operand:QI 2 "nonmemory_operand" ""))
15566 (use (match_operand 3 "const_int_operand" ""))
15567 (use (match_operand:SI 4 "const_int_operand" ""))
15568 (use (match_operand:SI 5 "const_int_operand" ""))]
15571 if (ix86_expand_setmem (operands[0], operands[1],
15572 operands[2], operands[3],
15573 operands[4], operands[5]))
15579 ;; Most CPUs don't like single string operations
15580 ;; Handle this case here to simplify previous expander.
15582 (define_expand "strset"
15583 [(set (match_operand 1 "memory_operand" "")
15584 (match_operand 2 "register_operand" ""))
15585 (parallel [(set (match_operand 0 "register_operand" "")
15587 (clobber (reg:CC FLAGS_REG))])]
15590 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15591 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15593 /* If .md ever supports :P for Pmode, this can be directly
15594 in the pattern above. */
15595 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15596 GEN_INT (GET_MODE_SIZE (GET_MODE
15598 /* Can't use this if the user has appropriated eax or edi. */
15599 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15600 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15602 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15608 (define_expand "strset_singleop"
15609 [(parallel [(set (match_operand 1 "memory_operand" "")
15610 (match_operand 2 "register_operand" ""))
15611 (set (match_operand 0 "register_operand" "")
15612 (match_operand 3 "" ""))])]
15614 "ix86_current_function_needs_cld = 1;")
15616 (define_insn "*strsetdi_rex_1"
15617 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15618 (match_operand:DI 2 "register_operand" "a"))
15619 (set (match_operand:DI 0 "register_operand" "=D")
15620 (plus:DI (match_dup 1)
15623 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15625 [(set_attr "type" "str")
15626 (set_attr "memory" "store")
15627 (set_attr "mode" "DI")])
15629 (define_insn "*strsetsi_1"
15630 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15631 (match_operand:SI 2 "register_operand" "a"))
15632 (set (match_operand:P 0 "register_operand" "=D")
15633 (plus:P (match_dup 1)
15635 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15637 [(set_attr "type" "str")
15638 (set_attr "memory" "store")
15639 (set_attr "mode" "SI")])
15641 (define_insn "*strsethi_1"
15642 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15643 (match_operand:HI 2 "register_operand" "a"))
15644 (set (match_operand:P 0 "register_operand" "=D")
15645 (plus:P (match_dup 1)
15647 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15649 [(set_attr "type" "str")
15650 (set_attr "memory" "store")
15651 (set_attr "mode" "HI")])
15653 (define_insn "*strsetqi_1"
15654 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15655 (match_operand:QI 2 "register_operand" "a"))
15656 (set (match_operand:P 0 "register_operand" "=D")
15657 (plus:P (match_dup 1)
15659 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15661 [(set_attr "type" "str")
15662 (set_attr "memory" "store")
15663 (set (attr "prefix_rex")
15665 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15667 (const_string "*")))
15668 (set_attr "mode" "QI")])
15670 (define_expand "rep_stos"
15671 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15672 (set (match_operand 0 "register_operand" "")
15673 (match_operand 4 "" ""))
15674 (set (match_operand 2 "memory_operand" "") (const_int 0))
15675 (use (match_operand 3 "register_operand" ""))
15676 (use (match_dup 1))])]
15678 "ix86_current_function_needs_cld = 1;")
15680 (define_insn "*rep_stosdi_rex64"
15681 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15682 (set (match_operand:DI 0 "register_operand" "=D")
15683 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15685 (match_operand:DI 3 "register_operand" "0")))
15686 (set (mem:BLK (match_dup 3))
15688 (use (match_operand:DI 2 "register_operand" "a"))
15689 (use (match_dup 4))]
15691 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15693 [(set_attr "type" "str")
15694 (set_attr "prefix_rep" "1")
15695 (set_attr "memory" "store")
15696 (set_attr "mode" "DI")])
15698 (define_insn "*rep_stossi"
15699 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15700 (set (match_operand:P 0 "register_operand" "=D")
15701 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15703 (match_operand:P 3 "register_operand" "0")))
15704 (set (mem:BLK (match_dup 3))
15706 (use (match_operand:SI 2 "register_operand" "a"))
15707 (use (match_dup 4))]
15708 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15709 "rep{%;} stos{l|d}"
15710 [(set_attr "type" "str")
15711 (set_attr "prefix_rep" "1")
15712 (set_attr "memory" "store")
15713 (set_attr "mode" "SI")])
15715 (define_insn "*rep_stosqi"
15716 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15717 (set (match_operand:P 0 "register_operand" "=D")
15718 (plus:P (match_operand:P 3 "register_operand" "0")
15719 (match_operand:P 4 "register_operand" "1")))
15720 (set (mem:BLK (match_dup 3))
15722 (use (match_operand:QI 2 "register_operand" "a"))
15723 (use (match_dup 4))]
15724 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15726 [(set_attr "type" "str")
15727 (set_attr "prefix_rep" "1")
15728 (set_attr "memory" "store")
15729 (set (attr "prefix_rex")
15731 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15733 (const_string "*")))
15734 (set_attr "mode" "QI")])
15736 (define_expand "cmpstrnsi"
15737 [(set (match_operand:SI 0 "register_operand" "")
15738 (compare:SI (match_operand:BLK 1 "general_operand" "")
15739 (match_operand:BLK 2 "general_operand" "")))
15740 (use (match_operand 3 "general_operand" ""))
15741 (use (match_operand 4 "immediate_operand" ""))]
15744 rtx addr1, addr2, out, outlow, count, countreg, align;
15746 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15749 /* Can't use this if the user has appropriated ecx, esi or edi. */
15750 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15755 out = gen_reg_rtx (SImode);
15757 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15758 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15759 if (addr1 != XEXP (operands[1], 0))
15760 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15761 if (addr2 != XEXP (operands[2], 0))
15762 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15764 count = operands[3];
15765 countreg = ix86_zero_extend_to_Pmode (count);
15767 /* %%% Iff we are testing strict equality, we can use known alignment
15768 to good advantage. This may be possible with combine, particularly
15769 once cc0 is dead. */
15770 align = operands[4];
15772 if (CONST_INT_P (count))
15774 if (INTVAL (count) == 0)
15776 emit_move_insn (operands[0], const0_rtx);
15779 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15780 operands[1], operands[2]));
15784 rtx (*gen_cmp) (rtx, rtx);
15786 gen_cmp = (TARGET_64BIT
15787 ? gen_cmpdi_1 : gen_cmpsi_1);
15789 emit_insn (gen_cmp (countreg, countreg));
15790 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15791 operands[1], operands[2]));
15794 outlow = gen_lowpart (QImode, out);
15795 emit_insn (gen_cmpintqi (outlow));
15796 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15798 if (operands[0] != out)
15799 emit_move_insn (operands[0], out);
15804 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15806 (define_expand "cmpintqi"
15807 [(set (match_dup 1)
15808 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15810 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15811 (parallel [(set (match_operand:QI 0 "register_operand" "")
15812 (minus:QI (match_dup 1)
15814 (clobber (reg:CC FLAGS_REG))])]
15817 operands[1] = gen_reg_rtx (QImode);
15818 operands[2] = gen_reg_rtx (QImode);
15821 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15822 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15824 (define_expand "cmpstrnqi_nz_1"
15825 [(parallel [(set (reg:CC FLAGS_REG)
15826 (compare:CC (match_operand 4 "memory_operand" "")
15827 (match_operand 5 "memory_operand" "")))
15828 (use (match_operand 2 "register_operand" ""))
15829 (use (match_operand:SI 3 "immediate_operand" ""))
15830 (clobber (match_operand 0 "register_operand" ""))
15831 (clobber (match_operand 1 "register_operand" ""))
15832 (clobber (match_dup 2))])]
15834 "ix86_current_function_needs_cld = 1;")
15836 (define_insn "*cmpstrnqi_nz_1"
15837 [(set (reg:CC FLAGS_REG)
15838 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15839 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15840 (use (match_operand:P 6 "register_operand" "2"))
15841 (use (match_operand:SI 3 "immediate_operand" "i"))
15842 (clobber (match_operand:P 0 "register_operand" "=S"))
15843 (clobber (match_operand:P 1 "register_operand" "=D"))
15844 (clobber (match_operand:P 2 "register_operand" "=c"))]
15845 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15847 [(set_attr "type" "str")
15848 (set_attr "mode" "QI")
15849 (set (attr "prefix_rex")
15851 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15853 (const_string "*")))
15854 (set_attr "prefix_rep" "1")])
15856 ;; The same, but the count is not known to not be zero.
15858 (define_expand "cmpstrnqi_1"
15859 [(parallel [(set (reg:CC FLAGS_REG)
15860 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15862 (compare:CC (match_operand 4 "memory_operand" "")
15863 (match_operand 5 "memory_operand" ""))
15865 (use (match_operand:SI 3 "immediate_operand" ""))
15866 (use (reg:CC FLAGS_REG))
15867 (clobber (match_operand 0 "register_operand" ""))
15868 (clobber (match_operand 1 "register_operand" ""))
15869 (clobber (match_dup 2))])]
15871 "ix86_current_function_needs_cld = 1;")
15873 (define_insn "*cmpstrnqi_1"
15874 [(set (reg:CC FLAGS_REG)
15875 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15877 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15878 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15880 (use (match_operand:SI 3 "immediate_operand" "i"))
15881 (use (reg:CC FLAGS_REG))
15882 (clobber (match_operand:P 0 "register_operand" "=S"))
15883 (clobber (match_operand:P 1 "register_operand" "=D"))
15884 (clobber (match_operand:P 2 "register_operand" "=c"))]
15885 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15887 [(set_attr "type" "str")
15888 (set_attr "mode" "QI")
15889 (set (attr "prefix_rex")
15891 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15893 (const_string "*")))
15894 (set_attr "prefix_rep" "1")])
15896 (define_expand "strlen<mode>"
15897 [(set (match_operand:P 0 "register_operand" "")
15898 (unspec:P [(match_operand:BLK 1 "general_operand" "")
15899 (match_operand:QI 2 "immediate_operand" "")
15900 (match_operand 3 "immediate_operand" "")]
15904 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15910 (define_expand "strlenqi_1"
15911 [(parallel [(set (match_operand 0 "register_operand" "")
15912 (match_operand 2 "" ""))
15913 (clobber (match_operand 1 "register_operand" ""))
15914 (clobber (reg:CC FLAGS_REG))])]
15916 "ix86_current_function_needs_cld = 1;")
15918 (define_insn "*strlenqi_1"
15919 [(set (match_operand:P 0 "register_operand" "=&c")
15920 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15921 (match_operand:QI 2 "register_operand" "a")
15922 (match_operand:P 3 "immediate_operand" "i")
15923 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15924 (clobber (match_operand:P 1 "register_operand" "=D"))
15925 (clobber (reg:CC FLAGS_REG))]
15926 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15928 [(set_attr "type" "str")
15929 (set_attr "mode" "QI")
15930 (set (attr "prefix_rex")
15932 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15934 (const_string "*")))
15935 (set_attr "prefix_rep" "1")])
15937 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15938 ;; handled in combine, but it is not currently up to the task.
15939 ;; When used for their truth value, the cmpstrn* expanders generate
15948 ;; The intermediate three instructions are unnecessary.
15950 ;; This one handles cmpstrn*_nz_1...
15953 (set (reg:CC FLAGS_REG)
15954 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15955 (mem:BLK (match_operand 5 "register_operand" ""))))
15956 (use (match_operand 6 "register_operand" ""))
15957 (use (match_operand:SI 3 "immediate_operand" ""))
15958 (clobber (match_operand 0 "register_operand" ""))
15959 (clobber (match_operand 1 "register_operand" ""))
15960 (clobber (match_operand 2 "register_operand" ""))])
15961 (set (match_operand:QI 7 "register_operand" "")
15962 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15963 (set (match_operand:QI 8 "register_operand" "")
15964 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15965 (set (reg FLAGS_REG)
15966 (compare (match_dup 7) (match_dup 8)))
15968 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15970 (set (reg:CC FLAGS_REG)
15971 (compare:CC (mem:BLK (match_dup 4))
15972 (mem:BLK (match_dup 5))))
15973 (use (match_dup 6))
15974 (use (match_dup 3))
15975 (clobber (match_dup 0))
15976 (clobber (match_dup 1))
15977 (clobber (match_dup 2))])])
15979 ;; ...and this one handles cmpstrn*_1.
15982 (set (reg:CC FLAGS_REG)
15983 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15985 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15986 (mem:BLK (match_operand 5 "register_operand" "")))
15988 (use (match_operand:SI 3 "immediate_operand" ""))
15989 (use (reg:CC FLAGS_REG))
15990 (clobber (match_operand 0 "register_operand" ""))
15991 (clobber (match_operand 1 "register_operand" ""))
15992 (clobber (match_operand 2 "register_operand" ""))])
15993 (set (match_operand:QI 7 "register_operand" "")
15994 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15995 (set (match_operand:QI 8 "register_operand" "")
15996 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15997 (set (reg FLAGS_REG)
15998 (compare (match_dup 7) (match_dup 8)))
16000 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16002 (set (reg:CC FLAGS_REG)
16003 (if_then_else:CC (ne (match_dup 6)
16005 (compare:CC (mem:BLK (match_dup 4))
16006 (mem:BLK (match_dup 5)))
16008 (use (match_dup 3))
16009 (use (reg:CC FLAGS_REG))
16010 (clobber (match_dup 0))
16011 (clobber (match_dup 1))
16012 (clobber (match_dup 2))])])
16014 ;; Conditional move instructions.
16016 (define_expand "mov<mode>cc"
16017 [(set (match_operand:SWIM 0 "register_operand" "")
16018 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16019 (match_operand:SWIM 2 "<general_operand>" "")
16020 (match_operand:SWIM 3 "<general_operand>" "")))]
16022 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16024 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16025 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16026 ;; So just document what we're doing explicitly.
16028 (define_expand "x86_mov<mode>cc_0_m1"
16030 [(set (match_operand:SWI48 0 "register_operand" "")
16031 (if_then_else:SWI48
16032 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16033 [(match_operand 1 "flags_reg_operand" "")
16037 (clobber (reg:CC FLAGS_REG))])])
16039 (define_insn "*x86_mov<mode>cc_0_m1"
16040 [(set (match_operand:SWI48 0 "register_operand" "=r")
16041 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16042 [(reg FLAGS_REG) (const_int 0)])
16045 (clobber (reg:CC FLAGS_REG))]
16047 "sbb{<imodesuffix>}\t%0, %0"
16048 ; Since we don't have the proper number of operands for an alu insn,
16049 ; fill in all the blanks.
16050 [(set_attr "type" "alu")
16051 (set_attr "use_carry" "1")
16052 (set_attr "pent_pair" "pu")
16053 (set_attr "memory" "none")
16054 (set_attr "imm_disp" "false")
16055 (set_attr "mode" "<MODE>")
16056 (set_attr "length_immediate" "0")])
16058 (define_insn "*x86_mov<mode>cc_0_m1_se"
16059 [(set (match_operand:SWI48 0 "register_operand" "=r")
16060 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16061 [(reg FLAGS_REG) (const_int 0)])
16064 (clobber (reg:CC FLAGS_REG))]
16066 "sbb{<imodesuffix>}\t%0, %0"
16067 [(set_attr "type" "alu")
16068 (set_attr "use_carry" "1")
16069 (set_attr "pent_pair" "pu")
16070 (set_attr "memory" "none")
16071 (set_attr "imm_disp" "false")
16072 (set_attr "mode" "<MODE>")
16073 (set_attr "length_immediate" "0")])
16075 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16076 [(set (match_operand:SWI48 0 "register_operand" "=r")
16077 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16078 [(reg FLAGS_REG) (const_int 0)])))]
16080 "sbb{<imodesuffix>}\t%0, %0"
16081 [(set_attr "type" "alu")
16082 (set_attr "use_carry" "1")
16083 (set_attr "pent_pair" "pu")
16084 (set_attr "memory" "none")
16085 (set_attr "imm_disp" "false")
16086 (set_attr "mode" "<MODE>")
16087 (set_attr "length_immediate" "0")])
16089 (define_insn "*mov<mode>cc_noc"
16090 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16091 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16092 [(reg FLAGS_REG) (const_int 0)])
16093 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16094 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16095 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16097 cmov%O2%C1\t{%2, %0|%0, %2}
16098 cmov%O2%c1\t{%3, %0|%0, %3}"
16099 [(set_attr "type" "icmov")
16100 (set_attr "mode" "<MODE>")])
16102 (define_insn_and_split "*movqicc_noc"
16103 [(set (match_operand:QI 0 "register_operand" "=r,r")
16104 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16105 [(match_operand 4 "flags_reg_operand" "")
16107 (match_operand:QI 2 "register_operand" "r,0")
16108 (match_operand:QI 3 "register_operand" "0,r")))]
16109 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16111 "&& reload_completed"
16112 [(set (match_dup 0)
16113 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16116 "operands[0] = gen_lowpart (SImode, operands[0]);
16117 operands[2] = gen_lowpart (SImode, operands[2]);
16118 operands[3] = gen_lowpart (SImode, operands[3]);"
16119 [(set_attr "type" "icmov")
16120 (set_attr "mode" "SI")])
16122 (define_expand "mov<mode>cc"
16123 [(set (match_operand:X87MODEF 0 "register_operand" "")
16124 (if_then_else:X87MODEF
16125 (match_operand 1 "ix86_fp_comparison_operator" "")
16126 (match_operand:X87MODEF 2 "register_operand" "")
16127 (match_operand:X87MODEF 3 "register_operand" "")))]
16128 "(TARGET_80387 && TARGET_CMOVE)
16129 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16130 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16132 (define_insn "*movxfcc_1"
16133 [(set (match_operand:XF 0 "register_operand" "=f,f")
16134 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16135 [(reg FLAGS_REG) (const_int 0)])
16136 (match_operand:XF 2 "register_operand" "f,0")
16137 (match_operand:XF 3 "register_operand" "0,f")))]
16138 "TARGET_80387 && TARGET_CMOVE"
16140 fcmov%F1\t{%2, %0|%0, %2}
16141 fcmov%f1\t{%3, %0|%0, %3}"
16142 [(set_attr "type" "fcmov")
16143 (set_attr "mode" "XF")])
16145 (define_insn "*movdfcc_1_rex64"
16146 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16147 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16148 [(reg FLAGS_REG) (const_int 0)])
16149 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16150 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16151 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16152 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16154 fcmov%F1\t{%2, %0|%0, %2}
16155 fcmov%f1\t{%3, %0|%0, %3}
16156 cmov%O2%C1\t{%2, %0|%0, %2}
16157 cmov%O2%c1\t{%3, %0|%0, %3}"
16158 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16159 (set_attr "mode" "DF,DF,DI,DI")])
16161 (define_insn "*movdfcc_1"
16162 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16163 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16164 [(reg FLAGS_REG) (const_int 0)])
16165 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16166 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16167 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16168 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16170 fcmov%F1\t{%2, %0|%0, %2}
16171 fcmov%f1\t{%3, %0|%0, %3}
16174 [(set_attr "type" "fcmov,fcmov,multi,multi")
16175 (set_attr "mode" "DF,DF,DI,DI")])
16178 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16179 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16180 [(match_operand 4 "flags_reg_operand" "")
16182 (match_operand:DF 2 "nonimmediate_operand" "")
16183 (match_operand:DF 3 "nonimmediate_operand" "")))]
16184 "!TARGET_64BIT && reload_completed"
16185 [(set (match_dup 2)
16186 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16190 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16194 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16195 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16198 (define_insn "*movsfcc_1_387"
16199 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16200 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16201 [(reg FLAGS_REG) (const_int 0)])
16202 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16203 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16204 "TARGET_80387 && TARGET_CMOVE
16205 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16207 fcmov%F1\t{%2, %0|%0, %2}
16208 fcmov%f1\t{%3, %0|%0, %3}
16209 cmov%O2%C1\t{%2, %0|%0, %2}
16210 cmov%O2%c1\t{%3, %0|%0, %3}"
16211 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16212 (set_attr "mode" "SF,SF,SI,SI")])
16214 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16215 ;; the scalar versions to have only XMM registers as operands.
16217 ;; XOP conditional move
16218 (define_insn "*xop_pcmov_<mode>"
16219 [(set (match_operand:MODEF 0 "register_operand" "=x")
16220 (if_then_else:MODEF
16221 (match_operand:MODEF 1 "register_operand" "x")
16222 (match_operand:MODEF 2 "register_operand" "x")
16223 (match_operand:MODEF 3 "register_operand" "x")))]
16225 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16226 [(set_attr "type" "sse4arg")])
16228 ;; These versions of the min/max patterns are intentionally ignorant of
16229 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16230 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16231 ;; are undefined in this condition, we're certain this is correct.
16233 (define_insn "<code><mode>3"
16234 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16236 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16237 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16238 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16240 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16241 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16242 [(set_attr "isa" "noavx,avx")
16243 (set_attr "prefix" "orig,vex")
16244 (set_attr "type" "sseadd")
16245 (set_attr "mode" "<MODE>")])
16247 ;; These versions of the min/max patterns implement exactly the operations
16248 ;; min = (op1 < op2 ? op1 : op2)
16249 ;; max = (!(op1 < op2) ? op1 : op2)
16250 ;; Their operands are not commutative, and thus they may be used in the
16251 ;; presence of -0.0 and NaN.
16253 (define_insn "*ieee_smin<mode>3"
16254 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16256 [(match_operand:MODEF 1 "register_operand" "0,x")
16257 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16259 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16261 min<ssemodesuffix>\t{%2, %0|%0, %2}
16262 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16263 [(set_attr "isa" "noavx,avx")
16264 (set_attr "prefix" "orig,vex")
16265 (set_attr "type" "sseadd")
16266 (set_attr "mode" "<MODE>")])
16268 (define_insn "*ieee_smax<mode>3"
16269 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16271 [(match_operand:MODEF 1 "register_operand" "0,x")
16272 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16274 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16276 max<ssemodesuffix>\t{%2, %0|%0, %2}
16277 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16278 [(set_attr "isa" "noavx,avx")
16279 (set_attr "prefix" "orig,vex")
16280 (set_attr "type" "sseadd")
16281 (set_attr "mode" "<MODE>")])
16283 ;; Make two stack loads independent:
16285 ;; fld %st(0) -> fld bb
16286 ;; fmul bb fmul %st(1), %st
16288 ;; Actually we only match the last two instructions for simplicity.
16290 [(set (match_operand 0 "fp_register_operand" "")
16291 (match_operand 1 "fp_register_operand" ""))
16293 (match_operator 2 "binary_fp_operator"
16295 (match_operand 3 "memory_operand" "")]))]
16296 "REGNO (operands[0]) != REGNO (operands[1])"
16297 [(set (match_dup 0) (match_dup 3))
16298 (set (match_dup 0) (match_dup 4))]
16300 ;; The % modifier is not operational anymore in peephole2's, so we have to
16301 ;; swap the operands manually in the case of addition and multiplication.
16302 "if (COMMUTATIVE_ARITH_P (operands[2]))
16303 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16304 GET_MODE (operands[2]),
16305 operands[0], operands[1]);
16307 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16308 GET_MODE (operands[2]),
16309 operands[1], operands[0]);")
16311 ;; Conditional addition patterns
16312 (define_expand "add<mode>cc"
16313 [(match_operand:SWI 0 "register_operand" "")
16314 (match_operand 1 "ordered_comparison_operator" "")
16315 (match_operand:SWI 2 "register_operand" "")
16316 (match_operand:SWI 3 "const_int_operand" "")]
16318 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16320 ;; Misc patterns (?)
16322 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16323 ;; Otherwise there will be nothing to keep
16325 ;; [(set (reg ebp) (reg esp))]
16326 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16327 ;; (clobber (eflags)]
16328 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16330 ;; in proper program order.
16332 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16333 [(set (match_operand:P 0 "register_operand" "=r,r")
16334 (plus:P (match_operand:P 1 "register_operand" "0,r")
16335 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16336 (clobber (reg:CC FLAGS_REG))
16337 (clobber (mem:BLK (scratch)))]
16340 switch (get_attr_type (insn))
16343 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16346 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16347 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16348 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16350 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16353 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16354 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16357 [(set (attr "type")
16358 (cond [(and (eq_attr "alternative" "0")
16359 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16360 (const_string "alu")
16361 (match_operand:<MODE> 2 "const0_operand" "")
16362 (const_string "imov")
16364 (const_string "lea")))
16365 (set (attr "length_immediate")
16366 (cond [(eq_attr "type" "imov")
16368 (and (eq_attr "type" "alu")
16369 (match_operand 2 "const128_operand" ""))
16372 (const_string "*")))
16373 (set_attr "mode" "<MODE>")])
16375 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16376 [(set (match_operand:P 0 "register_operand" "=r")
16377 (minus:P (match_operand:P 1 "register_operand" "0")
16378 (match_operand:P 2 "register_operand" "r")))
16379 (clobber (reg:CC FLAGS_REG))
16380 (clobber (mem:BLK (scratch)))]
16382 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16383 [(set_attr "type" "alu")
16384 (set_attr "mode" "<MODE>")])
16386 (define_insn "allocate_stack_worker_probe_<mode>"
16387 [(set (match_operand:P 0 "register_operand" "=a")
16388 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16389 UNSPECV_STACK_PROBE))
16390 (clobber (reg:CC FLAGS_REG))]
16391 "ix86_target_stack_probe ()"
16392 "call\t___chkstk_ms"
16393 [(set_attr "type" "multi")
16394 (set_attr "length" "5")])
16396 (define_expand "allocate_stack"
16397 [(match_operand 0 "register_operand" "")
16398 (match_operand 1 "general_operand" "")]
16399 "ix86_target_stack_probe ()"
16403 #ifndef CHECK_STACK_LIMIT
16404 #define CHECK_STACK_LIMIT 0
16407 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16408 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16410 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16411 stack_pointer_rtx, 0, OPTAB_DIRECT);
16412 if (x != stack_pointer_rtx)
16413 emit_move_insn (stack_pointer_rtx, x);
16417 x = copy_to_mode_reg (Pmode, operands[1]);
16419 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16421 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16422 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16423 stack_pointer_rtx, 0, OPTAB_DIRECT);
16424 if (x != stack_pointer_rtx)
16425 emit_move_insn (stack_pointer_rtx, x);
16428 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16432 ;; Use IOR for stack probes, this is shorter.
16433 (define_expand "probe_stack"
16434 [(match_operand 0 "memory_operand" "")]
16437 rtx (*gen_ior3) (rtx, rtx, rtx);
16439 gen_ior3 = (GET_MODE (operands[0]) == DImode
16440 ? gen_iordi3 : gen_iorsi3);
16442 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16446 (define_insn "adjust_stack_and_probe<mode>"
16447 [(set (match_operand:P 0 "register_operand" "=r")
16448 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16449 UNSPECV_PROBE_STACK_RANGE))
16450 (set (reg:P SP_REG)
16451 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16452 (clobber (reg:CC FLAGS_REG))
16453 (clobber (mem:BLK (scratch)))]
16455 "* return output_adjust_stack_and_probe (operands[0]);"
16456 [(set_attr "type" "multi")])
16458 (define_insn "probe_stack_range<mode>"
16459 [(set (match_operand:P 0 "register_operand" "=r")
16460 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16461 (match_operand:P 2 "const_int_operand" "n")]
16462 UNSPECV_PROBE_STACK_RANGE))
16463 (clobber (reg:CC FLAGS_REG))]
16465 "* return output_probe_stack_range (operands[0], operands[2]);"
16466 [(set_attr "type" "multi")])
16468 (define_expand "builtin_setjmp_receiver"
16469 [(label_ref (match_operand 0 "" ""))]
16470 "!TARGET_64BIT && flag_pic"
16476 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16477 rtx label_rtx = gen_label_rtx ();
16478 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16479 xops[0] = xops[1] = picreg;
16480 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16481 ix86_expand_binary_operator (MINUS, SImode, xops);
16485 emit_insn (gen_set_got (pic_offset_table_rtx));
16489 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16492 [(set (match_operand 0 "register_operand" "")
16493 (match_operator 3 "promotable_binary_operator"
16494 [(match_operand 1 "register_operand" "")
16495 (match_operand 2 "aligned_operand" "")]))
16496 (clobber (reg:CC FLAGS_REG))]
16497 "! TARGET_PARTIAL_REG_STALL && reload_completed
16498 && ((GET_MODE (operands[0]) == HImode
16499 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16500 /* ??? next two lines just !satisfies_constraint_K (...) */
16501 || !CONST_INT_P (operands[2])
16502 || satisfies_constraint_K (operands[2])))
16503 || (GET_MODE (operands[0]) == QImode
16504 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16505 [(parallel [(set (match_dup 0)
16506 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16507 (clobber (reg:CC FLAGS_REG))])]
16508 "operands[0] = gen_lowpart (SImode, operands[0]);
16509 operands[1] = gen_lowpart (SImode, operands[1]);
16510 if (GET_CODE (operands[3]) != ASHIFT)
16511 operands[2] = gen_lowpart (SImode, operands[2]);
16512 PUT_MODE (operands[3], SImode);")
16514 ; Promote the QImode tests, as i386 has encoding of the AND
16515 ; instruction with 32-bit sign-extended immediate and thus the
16516 ; instruction size is unchanged, except in the %eax case for
16517 ; which it is increased by one byte, hence the ! optimize_size.
16519 [(set (match_operand 0 "flags_reg_operand" "")
16520 (match_operator 2 "compare_operator"
16521 [(and (match_operand 3 "aligned_operand" "")
16522 (match_operand 4 "const_int_operand" ""))
16524 (set (match_operand 1 "register_operand" "")
16525 (and (match_dup 3) (match_dup 4)))]
16526 "! TARGET_PARTIAL_REG_STALL && reload_completed
16527 && optimize_insn_for_speed_p ()
16528 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16529 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16530 /* Ensure that the operand will remain sign-extended immediate. */
16531 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16532 [(parallel [(set (match_dup 0)
16533 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16536 (and:SI (match_dup 3) (match_dup 4)))])]
16539 = gen_int_mode (INTVAL (operands[4])
16540 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16541 operands[1] = gen_lowpart (SImode, operands[1]);
16542 operands[3] = gen_lowpart (SImode, operands[3]);
16545 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16546 ; the TEST instruction with 32-bit sign-extended immediate and thus
16547 ; the instruction size would at least double, which is not what we
16548 ; want even with ! optimize_size.
16550 [(set (match_operand 0 "flags_reg_operand" "")
16551 (match_operator 1 "compare_operator"
16552 [(and (match_operand:HI 2 "aligned_operand" "")
16553 (match_operand:HI 3 "const_int_operand" ""))
16555 "! TARGET_PARTIAL_REG_STALL && reload_completed
16556 && ! TARGET_FAST_PREFIX
16557 && optimize_insn_for_speed_p ()
16558 /* Ensure that the operand will remain sign-extended immediate. */
16559 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16560 [(set (match_dup 0)
16561 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16565 = gen_int_mode (INTVAL (operands[3])
16566 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16567 operands[2] = gen_lowpart (SImode, operands[2]);
16571 [(set (match_operand 0 "register_operand" "")
16572 (neg (match_operand 1 "register_operand" "")))
16573 (clobber (reg:CC FLAGS_REG))]
16574 "! TARGET_PARTIAL_REG_STALL && reload_completed
16575 && (GET_MODE (operands[0]) == HImode
16576 || (GET_MODE (operands[0]) == QImode
16577 && (TARGET_PROMOTE_QImode
16578 || optimize_insn_for_size_p ())))"
16579 [(parallel [(set (match_dup 0)
16580 (neg:SI (match_dup 1)))
16581 (clobber (reg:CC FLAGS_REG))])]
16582 "operands[0] = gen_lowpart (SImode, operands[0]);
16583 operands[1] = gen_lowpart (SImode, operands[1]);")
16586 [(set (match_operand 0 "register_operand" "")
16587 (not (match_operand 1 "register_operand" "")))]
16588 "! TARGET_PARTIAL_REG_STALL && reload_completed
16589 && (GET_MODE (operands[0]) == HImode
16590 || (GET_MODE (operands[0]) == QImode
16591 && (TARGET_PROMOTE_QImode
16592 || optimize_insn_for_size_p ())))"
16593 [(set (match_dup 0)
16594 (not:SI (match_dup 1)))]
16595 "operands[0] = gen_lowpart (SImode, operands[0]);
16596 operands[1] = gen_lowpart (SImode, operands[1]);")
16599 [(set (match_operand 0 "register_operand" "")
16600 (if_then_else (match_operator 1 "ordered_comparison_operator"
16601 [(reg FLAGS_REG) (const_int 0)])
16602 (match_operand 2 "register_operand" "")
16603 (match_operand 3 "register_operand" "")))]
16604 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16605 && (GET_MODE (operands[0]) == HImode
16606 || (GET_MODE (operands[0]) == QImode
16607 && (TARGET_PROMOTE_QImode
16608 || optimize_insn_for_size_p ())))"
16609 [(set (match_dup 0)
16610 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16611 "operands[0] = gen_lowpart (SImode, operands[0]);
16612 operands[2] = gen_lowpart (SImode, operands[2]);
16613 operands[3] = gen_lowpart (SImode, operands[3]);")
16615 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16616 ;; transform a complex memory operation into two memory to register operations.
16618 ;; Don't push memory operands
16620 [(set (match_operand:SWI 0 "push_operand" "")
16621 (match_operand:SWI 1 "memory_operand" ""))
16622 (match_scratch:SWI 2 "<r>")]
16623 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16624 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16625 [(set (match_dup 2) (match_dup 1))
16626 (set (match_dup 0) (match_dup 2))])
16628 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16631 [(set (match_operand:SF 0 "push_operand" "")
16632 (match_operand:SF 1 "memory_operand" ""))
16633 (match_scratch:SF 2 "r")]
16634 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16635 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16636 [(set (match_dup 2) (match_dup 1))
16637 (set (match_dup 0) (match_dup 2))])
16639 ;; Don't move an immediate directly to memory when the instruction
16642 [(match_scratch:SWI124 1 "<r>")
16643 (set (match_operand:SWI124 0 "memory_operand" "")
16645 "optimize_insn_for_speed_p ()
16646 && !TARGET_USE_MOV0
16647 && TARGET_SPLIT_LONG_MOVES
16648 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16649 && peep2_regno_dead_p (0, FLAGS_REG)"
16650 [(parallel [(set (match_dup 2) (const_int 0))
16651 (clobber (reg:CC FLAGS_REG))])
16652 (set (match_dup 0) (match_dup 1))]
16653 "operands[2] = gen_lowpart (SImode, operands[1]);")
16656 [(match_scratch:SWI124 2 "<r>")
16657 (set (match_operand:SWI124 0 "memory_operand" "")
16658 (match_operand:SWI124 1 "immediate_operand" ""))]
16659 "optimize_insn_for_speed_p ()
16660 && TARGET_SPLIT_LONG_MOVES
16661 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16662 [(set (match_dup 2) (match_dup 1))
16663 (set (match_dup 0) (match_dup 2))])
16665 ;; Don't compare memory with zero, load and use a test instead.
16667 [(set (match_operand 0 "flags_reg_operand" "")
16668 (match_operator 1 "compare_operator"
16669 [(match_operand:SI 2 "memory_operand" "")
16671 (match_scratch:SI 3 "r")]
16672 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16673 [(set (match_dup 3) (match_dup 2))
16674 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16676 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16677 ;; Don't split NOTs with a displacement operand, because resulting XOR
16678 ;; will not be pairable anyway.
16680 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16681 ;; represented using a modRM byte. The XOR replacement is long decoded,
16682 ;; so this split helps here as well.
16684 ;; Note: Can't do this as a regular split because we can't get proper
16685 ;; lifetime information then.
16688 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16689 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16690 "optimize_insn_for_speed_p ()
16691 && ((TARGET_NOT_UNPAIRABLE
16692 && (!MEM_P (operands[0])
16693 || !memory_displacement_operand (operands[0], <MODE>mode)))
16694 || (TARGET_NOT_VECTORMODE
16695 && long_memory_operand (operands[0], <MODE>mode)))
16696 && peep2_regno_dead_p (0, FLAGS_REG)"
16697 [(parallel [(set (match_dup 0)
16698 (xor:SWI124 (match_dup 1) (const_int -1)))
16699 (clobber (reg:CC FLAGS_REG))])])
16701 ;; Non pairable "test imm, reg" instructions can be translated to
16702 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16703 ;; byte opcode instead of two, have a short form for byte operands),
16704 ;; so do it for other CPUs as well. Given that the value was dead,
16705 ;; this should not create any new dependencies. Pass on the sub-word
16706 ;; versions if we're concerned about partial register stalls.
16709 [(set (match_operand 0 "flags_reg_operand" "")
16710 (match_operator 1 "compare_operator"
16711 [(and:SI (match_operand:SI 2 "register_operand" "")
16712 (match_operand:SI 3 "immediate_operand" ""))
16714 "ix86_match_ccmode (insn, CCNOmode)
16715 && (true_regnum (operands[2]) != AX_REG
16716 || satisfies_constraint_K (operands[3]))
16717 && peep2_reg_dead_p (1, operands[2])"
16719 [(set (match_dup 0)
16720 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16723 (and:SI (match_dup 2) (match_dup 3)))])])
16725 ;; We don't need to handle HImode case, because it will be promoted to SImode
16726 ;; on ! TARGET_PARTIAL_REG_STALL
16729 [(set (match_operand 0 "flags_reg_operand" "")
16730 (match_operator 1 "compare_operator"
16731 [(and:QI (match_operand:QI 2 "register_operand" "")
16732 (match_operand:QI 3 "immediate_operand" ""))
16734 "! TARGET_PARTIAL_REG_STALL
16735 && ix86_match_ccmode (insn, CCNOmode)
16736 && true_regnum (operands[2]) != AX_REG
16737 && peep2_reg_dead_p (1, operands[2])"
16739 [(set (match_dup 0)
16740 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16743 (and:QI (match_dup 2) (match_dup 3)))])])
16746 [(set (match_operand 0 "flags_reg_operand" "")
16747 (match_operator 1 "compare_operator"
16750 (match_operand 2 "ext_register_operand" "")
16753 (match_operand 3 "const_int_operand" ""))
16755 "! TARGET_PARTIAL_REG_STALL
16756 && ix86_match_ccmode (insn, CCNOmode)
16757 && true_regnum (operands[2]) != AX_REG
16758 && peep2_reg_dead_p (1, operands[2])"
16759 [(parallel [(set (match_dup 0)
16768 (set (zero_extract:SI (match_dup 2)
16776 (match_dup 3)))])])
16778 ;; Don't do logical operations with memory inputs.
16780 [(match_scratch:SI 2 "r")
16781 (parallel [(set (match_operand:SI 0 "register_operand" "")
16782 (match_operator:SI 3 "arith_or_logical_operator"
16784 (match_operand:SI 1 "memory_operand" "")]))
16785 (clobber (reg:CC FLAGS_REG))])]
16786 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16787 [(set (match_dup 2) (match_dup 1))
16788 (parallel [(set (match_dup 0)
16789 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16790 (clobber (reg:CC FLAGS_REG))])])
16793 [(match_scratch:SI 2 "r")
16794 (parallel [(set (match_operand:SI 0 "register_operand" "")
16795 (match_operator:SI 3 "arith_or_logical_operator"
16796 [(match_operand:SI 1 "memory_operand" "")
16798 (clobber (reg:CC FLAGS_REG))])]
16799 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16800 [(set (match_dup 2) (match_dup 1))
16801 (parallel [(set (match_dup 0)
16802 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16803 (clobber (reg:CC FLAGS_REG))])])
16805 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16806 ;; refers to the destination of the load!
16809 [(set (match_operand:SI 0 "register_operand" "")
16810 (match_operand:SI 1 "register_operand" ""))
16811 (parallel [(set (match_dup 0)
16812 (match_operator:SI 3 "commutative_operator"
16814 (match_operand:SI 2 "memory_operand" "")]))
16815 (clobber (reg:CC FLAGS_REG))])]
16816 "REGNO (operands[0]) != REGNO (operands[1])
16817 && GENERAL_REGNO_P (REGNO (operands[0]))
16818 && GENERAL_REGNO_P (REGNO (operands[1]))"
16819 [(set (match_dup 0) (match_dup 4))
16820 (parallel [(set (match_dup 0)
16821 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16822 (clobber (reg:CC FLAGS_REG))])]
16823 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16826 [(set (match_operand 0 "register_operand" "")
16827 (match_operand 1 "register_operand" ""))
16829 (match_operator 3 "commutative_operator"
16831 (match_operand 2 "memory_operand" "")]))]
16832 "REGNO (operands[0]) != REGNO (operands[1])
16833 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16834 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16835 [(set (match_dup 0) (match_dup 2))
16837 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16839 ; Don't do logical operations with memory outputs
16841 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16842 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16843 ; the same decoder scheduling characteristics as the original.
16846 [(match_scratch:SI 2 "r")
16847 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16848 (match_operator:SI 3 "arith_or_logical_operator"
16850 (match_operand:SI 1 "nonmemory_operand" "")]))
16851 (clobber (reg:CC FLAGS_REG))])]
16852 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16853 /* Do not split stack checking probes. */
16854 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16855 [(set (match_dup 2) (match_dup 0))
16856 (parallel [(set (match_dup 2)
16857 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16858 (clobber (reg:CC FLAGS_REG))])
16859 (set (match_dup 0) (match_dup 2))])
16862 [(match_scratch:SI 2 "r")
16863 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16864 (match_operator:SI 3 "arith_or_logical_operator"
16865 [(match_operand:SI 1 "nonmemory_operand" "")
16867 (clobber (reg:CC FLAGS_REG))])]
16868 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16869 /* Do not split stack checking probes. */
16870 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16871 [(set (match_dup 2) (match_dup 0))
16872 (parallel [(set (match_dup 2)
16873 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16874 (clobber (reg:CC FLAGS_REG))])
16875 (set (match_dup 0) (match_dup 2))])
16877 ;; Attempt to use arith or logical operations with memory outputs with
16878 ;; setting of flags.
16880 [(set (match_operand:SWI 0 "register_operand" "")
16881 (match_operand:SWI 1 "memory_operand" ""))
16882 (parallel [(set (match_dup 0)
16883 (match_operator:SWI 3 "plusminuslogic_operator"
16885 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16886 (clobber (reg:CC FLAGS_REG))])
16887 (set (match_dup 1) (match_dup 0))
16888 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16889 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16890 && peep2_reg_dead_p (4, operands[0])
16891 && !reg_overlap_mentioned_p (operands[0], operands[1])
16892 && ix86_match_ccmode (peep2_next_insn (3),
16893 (GET_CODE (operands[3]) == PLUS
16894 || GET_CODE (operands[3]) == MINUS)
16895 ? CCGOCmode : CCNOmode)"
16896 [(parallel [(set (match_dup 4) (match_dup 5))
16897 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16898 (match_dup 2)]))])]
16899 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16900 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16901 copy_rtx (operands[1]),
16902 copy_rtx (operands[2]));
16903 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16904 operands[5], const0_rtx);")
16907 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16908 (match_operator:SWI 2 "plusminuslogic_operator"
16910 (match_operand:SWI 1 "memory_operand" "")]))
16911 (clobber (reg:CC FLAGS_REG))])
16912 (set (match_dup 1) (match_dup 0))
16913 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16914 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16915 && GET_CODE (operands[2]) != MINUS
16916 && peep2_reg_dead_p (3, operands[0])
16917 && !reg_overlap_mentioned_p (operands[0], operands[1])
16918 && ix86_match_ccmode (peep2_next_insn (2),
16919 GET_CODE (operands[2]) == PLUS
16920 ? CCGOCmode : CCNOmode)"
16921 [(parallel [(set (match_dup 3) (match_dup 4))
16922 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16923 (match_dup 0)]))])]
16924 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16925 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16926 copy_rtx (operands[1]),
16927 copy_rtx (operands[0]));
16928 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16929 operands[4], const0_rtx);")
16932 [(set (match_operand:SWI12 0 "register_operand" "")
16933 (match_operand:SWI12 1 "memory_operand" ""))
16934 (parallel [(set (match_operand:SI 4 "register_operand" "")
16935 (match_operator:SI 3 "plusminuslogic_operator"
16937 (match_operand:SI 2 "nonmemory_operand" "")]))
16938 (clobber (reg:CC FLAGS_REG))])
16939 (set (match_dup 1) (match_dup 0))
16940 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16941 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16942 && REG_P (operands[0]) && REG_P (operands[4])
16943 && REGNO (operands[0]) == REGNO (operands[4])
16944 && peep2_reg_dead_p (4, operands[0])
16945 && !reg_overlap_mentioned_p (operands[0], operands[1])
16946 && ix86_match_ccmode (peep2_next_insn (3),
16947 (GET_CODE (operands[3]) == PLUS
16948 || GET_CODE (operands[3]) == MINUS)
16949 ? CCGOCmode : CCNOmode)"
16950 [(parallel [(set (match_dup 4) (match_dup 5))
16951 (set (match_dup 1) (match_dup 6))])]
16952 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16953 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16954 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16955 copy_rtx (operands[1]), operands[2]);
16956 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16957 operands[5], const0_rtx);
16958 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16959 copy_rtx (operands[1]),
16960 copy_rtx (operands[2]));")
16962 ;; Attempt to always use XOR for zeroing registers.
16964 [(set (match_operand 0 "register_operand" "")
16965 (match_operand 1 "const0_operand" ""))]
16966 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16967 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16968 && GENERAL_REG_P (operands[0])
16969 && peep2_regno_dead_p (0, FLAGS_REG)"
16970 [(parallel [(set (match_dup 0) (const_int 0))
16971 (clobber (reg:CC FLAGS_REG))])]
16972 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16975 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16977 "(GET_MODE (operands[0]) == QImode
16978 || GET_MODE (operands[0]) == HImode)
16979 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16980 && peep2_regno_dead_p (0, FLAGS_REG)"
16981 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16982 (clobber (reg:CC FLAGS_REG))])])
16984 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16986 [(set (match_operand:SWI248 0 "register_operand" "")
16988 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16989 && peep2_regno_dead_p (0, FLAGS_REG)"
16990 [(parallel [(set (match_dup 0) (const_int -1))
16991 (clobber (reg:CC FLAGS_REG))])]
16993 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16994 operands[0] = gen_lowpart (SImode, operands[0]);
16997 ;; Attempt to convert simple lea to add/shift.
16998 ;; These can be created by move expanders.
17001 [(set (match_operand:SWI48 0 "register_operand" "")
17002 (plus:SWI48 (match_dup 0)
17003 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17004 "peep2_regno_dead_p (0, FLAGS_REG)"
17005 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17006 (clobber (reg:CC FLAGS_REG))])])
17009 [(set (match_operand:SI 0 "register_operand" "")
17010 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17011 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17013 && peep2_regno_dead_p (0, FLAGS_REG)
17014 && REGNO (operands[0]) == REGNO (operands[1])"
17015 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17016 (clobber (reg:CC FLAGS_REG))])]
17017 "operands[2] = gen_lowpart (SImode, operands[2]);")
17020 [(set (match_operand:SWI48 0 "register_operand" "")
17021 (mult:SWI48 (match_dup 0)
17022 (match_operand:SWI48 1 "const_int_operand" "")))]
17023 "exact_log2 (INTVAL (operands[1])) >= 0
17024 && peep2_regno_dead_p (0, FLAGS_REG)"
17025 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17026 (clobber (reg:CC FLAGS_REG))])]
17027 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17030 [(set (match_operand:SI 0 "register_operand" "")
17031 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17032 (match_operand:DI 2 "const_int_operand" "")) 0))]
17034 && exact_log2 (INTVAL (operands[2])) >= 0
17035 && REGNO (operands[0]) == REGNO (operands[1])
17036 && peep2_regno_dead_p (0, FLAGS_REG)"
17037 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17038 (clobber (reg:CC FLAGS_REG))])]
17039 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17041 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17042 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17043 ;; On many CPUs it is also faster, since special hardware to avoid esp
17044 ;; dependencies is present.
17046 ;; While some of these conversions may be done using splitters, we use
17047 ;; peepholes in order to allow combine_stack_adjustments pass to see
17048 ;; nonobfuscated RTL.
17050 ;; Convert prologue esp subtractions to push.
17051 ;; We need register to push. In order to keep verify_flow_info happy we have
17053 ;; - use scratch and clobber it in order to avoid dependencies
17054 ;; - use already live register
17055 ;; We can't use the second way right now, since there is no reliable way how to
17056 ;; verify that given register is live. First choice will also most likely in
17057 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17058 ;; call clobbered registers are dead. We may want to use base pointer as an
17059 ;; alternative when no register is available later.
17062 [(match_scratch:P 1 "r")
17063 (parallel [(set (reg:P SP_REG)
17064 (plus:P (reg:P SP_REG)
17065 (match_operand:P 0 "const_int_operand" "")))
17066 (clobber (reg:CC FLAGS_REG))
17067 (clobber (mem:BLK (scratch)))])]
17068 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17069 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17070 [(clobber (match_dup 1))
17071 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17072 (clobber (mem:BLK (scratch)))])])
17075 [(match_scratch:P 1 "r")
17076 (parallel [(set (reg:P SP_REG)
17077 (plus:P (reg:P SP_REG)
17078 (match_operand:P 0 "const_int_operand" "")))
17079 (clobber (reg:CC FLAGS_REG))
17080 (clobber (mem:BLK (scratch)))])]
17081 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17082 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17083 [(clobber (match_dup 1))
17084 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17085 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17086 (clobber (mem:BLK (scratch)))])])
17088 ;; Convert esp subtractions to push.
17090 [(match_scratch:P 1 "r")
17091 (parallel [(set (reg:P SP_REG)
17092 (plus:P (reg:P SP_REG)
17093 (match_operand:P 0 "const_int_operand" "")))
17094 (clobber (reg:CC FLAGS_REG))])]
17095 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17096 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17097 [(clobber (match_dup 1))
17098 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17101 [(match_scratch:P 1 "r")
17102 (parallel [(set (reg:P SP_REG)
17103 (plus:P (reg:P SP_REG)
17104 (match_operand:P 0 "const_int_operand" "")))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17107 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17108 [(clobber (match_dup 1))
17109 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17110 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17112 ;; Convert epilogue deallocator to pop.
17114 [(match_scratch:P 1 "r")
17115 (parallel [(set (reg:P SP_REG)
17116 (plus:P (reg:P SP_REG)
17117 (match_operand:P 0 "const_int_operand" "")))
17118 (clobber (reg:CC FLAGS_REG))
17119 (clobber (mem:BLK (scratch)))])]
17120 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17121 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17122 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17123 (clobber (mem:BLK (scratch)))])])
17125 ;; Two pops case is tricky, since pop causes dependency
17126 ;; on destination register. We use two registers if available.
17128 [(match_scratch:P 1 "r")
17129 (match_scratch:P 2 "r")
17130 (parallel [(set (reg:P SP_REG)
17131 (plus:P (reg:P SP_REG)
17132 (match_operand:P 0 "const_int_operand" "")))
17133 (clobber (reg:CC FLAGS_REG))
17134 (clobber (mem:BLK (scratch)))])]
17135 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17136 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17137 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17138 (clobber (mem:BLK (scratch)))])
17139 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17142 [(match_scratch:P 1 "r")
17143 (parallel [(set (reg:P SP_REG)
17144 (plus:P (reg:P SP_REG)
17145 (match_operand:P 0 "const_int_operand" "")))
17146 (clobber (reg:CC FLAGS_REG))
17147 (clobber (mem:BLK (scratch)))])]
17148 "optimize_insn_for_size_p ()
17149 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17150 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17151 (clobber (mem:BLK (scratch)))])
17152 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17154 ;; Convert esp additions to pop.
17156 [(match_scratch:P 1 "r")
17157 (parallel [(set (reg:P SP_REG)
17158 (plus:P (reg:P SP_REG)
17159 (match_operand:P 0 "const_int_operand" "")))
17160 (clobber (reg:CC FLAGS_REG))])]
17161 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17162 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17164 ;; Two pops case is tricky, since pop causes dependency
17165 ;; on destination register. We use two registers if available.
17167 [(match_scratch:P 1 "r")
17168 (match_scratch:P 2 "r")
17169 (parallel [(set (reg:P SP_REG)
17170 (plus:P (reg:P SP_REG)
17171 (match_operand:P 0 "const_int_operand" "")))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17174 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17175 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17178 [(match_scratch:P 1 "r")
17179 (parallel [(set (reg:P SP_REG)
17180 (plus:P (reg:P SP_REG)
17181 (match_operand:P 0 "const_int_operand" "")))
17182 (clobber (reg:CC FLAGS_REG))])]
17183 "optimize_insn_for_size_p ()
17184 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17185 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17186 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17188 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17189 ;; required and register dies. Similarly for 128 to -128.
17191 [(set (match_operand 0 "flags_reg_operand" "")
17192 (match_operator 1 "compare_operator"
17193 [(match_operand 2 "register_operand" "")
17194 (match_operand 3 "const_int_operand" "")]))]
17195 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17196 && incdec_operand (operands[3], GET_MODE (operands[3])))
17197 || (!TARGET_FUSE_CMP_AND_BRANCH
17198 && INTVAL (operands[3]) == 128))
17199 && ix86_match_ccmode (insn, CCGCmode)
17200 && peep2_reg_dead_p (1, operands[2])"
17201 [(parallel [(set (match_dup 0)
17202 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17203 (clobber (match_dup 2))])])
17205 ;; Convert imul by three, five and nine into lea
17208 [(set (match_operand:SWI48 0 "register_operand" "")
17209 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17210 (match_operand:SWI48 2 "const359_operand" "")))
17211 (clobber (reg:CC FLAGS_REG))])]
17212 "!TARGET_PARTIAL_REG_STALL
17213 || <MODE>mode == SImode
17214 || optimize_function_for_size_p (cfun)"
17215 [(set (match_dup 0)
17216 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17218 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17222 [(set (match_operand:SWI48 0 "register_operand" "")
17223 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17224 (match_operand:SWI48 2 "const359_operand" "")))
17225 (clobber (reg:CC FLAGS_REG))])]
17226 "optimize_insn_for_speed_p ()
17227 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17228 [(set (match_dup 0) (match_dup 1))
17230 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17232 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17234 ;; imul $32bit_imm, mem, reg is vector decoded, while
17235 ;; imul $32bit_imm, reg, reg is direct decoded.
17237 [(match_scratch:SWI48 3 "r")
17238 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17239 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17240 (match_operand:SWI48 2 "immediate_operand" "")))
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17243 && !satisfies_constraint_K (operands[2])"
17244 [(set (match_dup 3) (match_dup 1))
17245 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17246 (clobber (reg:CC FLAGS_REG))])])
17249 [(match_scratch:SI 3 "r")
17250 (parallel [(set (match_operand:DI 0 "register_operand" "")
17252 (mult:SI (match_operand:SI 1 "memory_operand" "")
17253 (match_operand:SI 2 "immediate_operand" ""))))
17254 (clobber (reg:CC FLAGS_REG))])]
17256 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17257 && !satisfies_constraint_K (operands[2])"
17258 [(set (match_dup 3) (match_dup 1))
17259 (parallel [(set (match_dup 0)
17260 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17261 (clobber (reg:CC FLAGS_REG))])])
17263 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17264 ;; Convert it into imul reg, reg
17265 ;; It would be better to force assembler to encode instruction using long
17266 ;; immediate, but there is apparently no way to do so.
17268 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17270 (match_operand:SWI248 1 "nonimmediate_operand" "")
17271 (match_operand:SWI248 2 "const_int_operand" "")))
17272 (clobber (reg:CC FLAGS_REG))])
17273 (match_scratch:SWI248 3 "r")]
17274 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17275 && satisfies_constraint_K (operands[2])"
17276 [(set (match_dup 3) (match_dup 2))
17277 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17278 (clobber (reg:CC FLAGS_REG))])]
17280 if (!rtx_equal_p (operands[0], operands[1]))
17281 emit_move_insn (operands[0], operands[1]);
17284 ;; After splitting up read-modify operations, array accesses with memory
17285 ;; operands might end up in form:
17287 ;; movl 4(%esp), %edx
17289 ;; instead of pre-splitting:
17291 ;; addl 4(%esp), %eax
17293 ;; movl 4(%esp), %edx
17294 ;; leal (%edx,%eax,4), %eax
17297 [(match_scratch:P 5 "r")
17298 (parallel [(set (match_operand 0 "register_operand" "")
17299 (ashift (match_operand 1 "register_operand" "")
17300 (match_operand 2 "const_int_operand" "")))
17301 (clobber (reg:CC FLAGS_REG))])
17302 (parallel [(set (match_operand 3 "register_operand" "")
17303 (plus (match_dup 0)
17304 (match_operand 4 "x86_64_general_operand" "")))
17305 (clobber (reg:CC FLAGS_REG))])]
17306 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17307 /* Validate MODE for lea. */
17308 && ((!TARGET_PARTIAL_REG_STALL
17309 && (GET_MODE (operands[0]) == QImode
17310 || GET_MODE (operands[0]) == HImode))
17311 || GET_MODE (operands[0]) == SImode
17312 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17313 && (rtx_equal_p (operands[0], operands[3])
17314 || peep2_reg_dead_p (2, operands[0]))
17315 /* We reorder load and the shift. */
17316 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17317 [(set (match_dup 5) (match_dup 4))
17318 (set (match_dup 0) (match_dup 1))]
17320 enum machine_mode op1mode = GET_MODE (operands[1]);
17321 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17322 int scale = 1 << INTVAL (operands[2]);
17323 rtx index = gen_lowpart (Pmode, operands[1]);
17324 rtx base = gen_lowpart (Pmode, operands[5]);
17325 rtx dest = gen_lowpart (mode, operands[3]);
17327 operands[1] = gen_rtx_PLUS (Pmode, base,
17328 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17329 operands[5] = base;
17331 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17332 if (op1mode != Pmode)
17333 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17334 operands[0] = dest;
17337 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17338 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17339 ;; caught for use by garbage collectors and the like. Using an insn that
17340 ;; maps to SIGILL makes it more likely the program will rightfully die.
17341 ;; Keeping with tradition, "6" is in honor of #UD.
17342 (define_insn "trap"
17343 [(trap_if (const_int 1) (const_int 6))]
17345 { return ASM_SHORT "0x0b0f"; }
17346 [(set_attr "length" "2")])
17348 (define_expand "prefetch"
17349 [(prefetch (match_operand 0 "address_operand" "")
17350 (match_operand:SI 1 "const_int_operand" "")
17351 (match_operand:SI 2 "const_int_operand" ""))]
17352 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17354 int rw = INTVAL (operands[1]);
17355 int locality = INTVAL (operands[2]);
17357 gcc_assert (rw == 0 || rw == 1);
17358 gcc_assert (locality >= 0 && locality <= 3);
17359 gcc_assert (GET_MODE (operands[0]) == Pmode
17360 || GET_MODE (operands[0]) == VOIDmode);
17362 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17363 supported by SSE counterpart or the SSE prefetch is not available
17364 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17366 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17367 operands[2] = GEN_INT (3);
17369 operands[1] = const0_rtx;
17372 (define_insn "*prefetch_sse_<mode>"
17373 [(prefetch (match_operand:P 0 "address_operand" "p")
17375 (match_operand:SI 1 "const_int_operand" ""))]
17376 "TARGET_PREFETCH_SSE"
17378 static const char * const patterns[4] = {
17379 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17382 int locality = INTVAL (operands[1]);
17383 gcc_assert (locality >= 0 && locality <= 3);
17385 return patterns[locality];
17387 [(set_attr "type" "sse")
17388 (set_attr "atom_sse_attr" "prefetch")
17389 (set (attr "length_address")
17390 (symbol_ref "memory_address_length (operands[0])"))
17391 (set_attr "memory" "none")])
17393 (define_insn "*prefetch_3dnow_<mode>"
17394 [(prefetch (match_operand:P 0 "address_operand" "p")
17395 (match_operand:SI 1 "const_int_operand" "n")
17399 if (INTVAL (operands[1]) == 0)
17400 return "prefetch\t%a0";
17402 return "prefetchw\t%a0";
17404 [(set_attr "type" "mmx")
17405 (set (attr "length_address")
17406 (symbol_ref "memory_address_length (operands[0])"))
17407 (set_attr "memory" "none")])
17409 (define_expand "stack_protect_set"
17410 [(match_operand 0 "memory_operand" "")
17411 (match_operand 1 "memory_operand" "")]
17414 rtx (*insn)(rtx, rtx);
17416 #ifdef TARGET_THREAD_SSP_OFFSET
17417 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17418 insn = (TARGET_LP64
17419 ? gen_stack_tls_protect_set_di
17420 : gen_stack_tls_protect_set_si);
17422 insn = (TARGET_LP64
17423 ? gen_stack_protect_set_di
17424 : gen_stack_protect_set_si);
17427 emit_insn (insn (operands[0], operands[1]));
17431 (define_insn "stack_protect_set_<mode>"
17432 [(set (match_operand:PTR 0 "memory_operand" "=m")
17433 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17435 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17436 (clobber (reg:CC FLAGS_REG))]
17438 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17439 [(set_attr "type" "multi")])
17441 (define_insn "stack_tls_protect_set_<mode>"
17442 [(set (match_operand:PTR 0 "memory_operand" "=m")
17443 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17444 UNSPEC_SP_TLS_SET))
17445 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17446 (clobber (reg:CC FLAGS_REG))]
17448 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17449 [(set_attr "type" "multi")])
17451 (define_expand "stack_protect_test"
17452 [(match_operand 0 "memory_operand" "")
17453 (match_operand 1 "memory_operand" "")
17454 (match_operand 2 "" "")]
17457 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17459 rtx (*insn)(rtx, rtx, rtx);
17461 #ifdef TARGET_THREAD_SSP_OFFSET
17462 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17463 insn = (TARGET_LP64
17464 ? gen_stack_tls_protect_test_di
17465 : gen_stack_tls_protect_test_si);
17467 insn = (TARGET_LP64
17468 ? gen_stack_protect_test_di
17469 : gen_stack_protect_test_si);
17472 emit_insn (insn (flags, operands[0], operands[1]));
17474 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17475 flags, const0_rtx, operands[2]));
17479 (define_insn "stack_protect_test_<mode>"
17480 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17481 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17482 (match_operand:PTR 2 "memory_operand" "m")]
17484 (clobber (match_scratch:PTR 3 "=&r"))]
17486 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17487 [(set_attr "type" "multi")])
17489 (define_insn "stack_tls_protect_test_<mode>"
17490 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17491 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17492 (match_operand:PTR 2 "const_int_operand" "i")]
17493 UNSPEC_SP_TLS_TEST))
17494 (clobber (match_scratch:PTR 3 "=r"))]
17496 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17497 [(set_attr "type" "multi")])
17499 (define_insn "sse4_2_crc32<mode>"
17500 [(set (match_operand:SI 0 "register_operand" "=r")
17502 [(match_operand:SI 1 "register_operand" "0")
17503 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17505 "TARGET_SSE4_2 || TARGET_CRC32"
17506 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17507 [(set_attr "type" "sselog1")
17508 (set_attr "prefix_rep" "1")
17509 (set_attr "prefix_extra" "1")
17510 (set (attr "prefix_data16")
17511 (if_then_else (match_operand:HI 2 "" "")
17513 (const_string "*")))
17514 (set (attr "prefix_rex")
17515 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17517 (const_string "*")))
17518 (set_attr "mode" "SI")])
17520 (define_insn "sse4_2_crc32di"
17521 [(set (match_operand:DI 0 "register_operand" "=r")
17523 [(match_operand:DI 1 "register_operand" "0")
17524 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17526 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17527 "crc32{q}\t{%2, %0|%0, %2}"
17528 [(set_attr "type" "sselog1")
17529 (set_attr "prefix_rep" "1")
17530 (set_attr "prefix_extra" "1")
17531 (set_attr "mode" "DI")])
17533 (define_expand "rdpmc"
17534 [(match_operand:DI 0 "register_operand" "")
17535 (match_operand:SI 1 "register_operand" "")]
17538 rtx reg = gen_reg_rtx (DImode);
17541 /* Force operand 1 into ECX. */
17542 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17543 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17544 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17549 rtvec vec = rtvec_alloc (2);
17550 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17551 rtx upper = gen_reg_rtx (DImode);
17552 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17553 gen_rtvec (1, const0_rtx),
17555 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17556 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17558 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17559 NULL, 1, OPTAB_DIRECT);
17560 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17564 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17565 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17569 (define_insn "*rdpmc"
17570 [(set (match_operand:DI 0 "register_operand" "=A")
17571 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17575 [(set_attr "type" "other")
17576 (set_attr "length" "2")])
17578 (define_insn "*rdpmc_rex64"
17579 [(set (match_operand:DI 0 "register_operand" "=a")
17580 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17582 (set (match_operand:DI 1 "register_operand" "=d")
17583 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17586 [(set_attr "type" "other")
17587 (set_attr "length" "2")])
17589 (define_expand "rdtsc"
17590 [(set (match_operand:DI 0 "register_operand" "")
17591 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17596 rtvec vec = rtvec_alloc (2);
17597 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17598 rtx upper = gen_reg_rtx (DImode);
17599 rtx lower = gen_reg_rtx (DImode);
17600 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17601 gen_rtvec (1, const0_rtx),
17603 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17604 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17606 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17607 NULL, 1, OPTAB_DIRECT);
17608 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17610 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17615 (define_insn "*rdtsc"
17616 [(set (match_operand:DI 0 "register_operand" "=A")
17617 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17620 [(set_attr "type" "other")
17621 (set_attr "length" "2")])
17623 (define_insn "*rdtsc_rex64"
17624 [(set (match_operand:DI 0 "register_operand" "=a")
17625 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17626 (set (match_operand:DI 1 "register_operand" "=d")
17627 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17630 [(set_attr "type" "other")
17631 (set_attr "length" "2")])
17633 (define_expand "rdtscp"
17634 [(match_operand:DI 0 "register_operand" "")
17635 (match_operand:SI 1 "memory_operand" "")]
17638 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17639 gen_rtvec (1, const0_rtx),
17641 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17642 gen_rtvec (1, const0_rtx),
17644 rtx reg = gen_reg_rtx (DImode);
17645 rtx tmp = gen_reg_rtx (SImode);
17649 rtvec vec = rtvec_alloc (3);
17650 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17651 rtx upper = gen_reg_rtx (DImode);
17652 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17653 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17654 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17656 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17657 NULL, 1, OPTAB_DIRECT);
17658 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17663 rtvec vec = rtvec_alloc (2);
17664 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17665 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17666 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17670 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17674 (define_insn "*rdtscp"
17675 [(set (match_operand:DI 0 "register_operand" "=A")
17676 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17677 (set (match_operand:SI 1 "register_operand" "=c")
17678 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17681 [(set_attr "type" "other")
17682 (set_attr "length" "3")])
17684 (define_insn "*rdtscp_rex64"
17685 [(set (match_operand:DI 0 "register_operand" "=a")
17686 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17687 (set (match_operand:DI 1 "register_operand" "=d")
17688 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17689 (set (match_operand:SI 2 "register_operand" "=c")
17690 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17693 [(set_attr "type" "other")
17694 (set_attr "length" "3")])
17696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17698 ;; LWP instructions
17700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17702 (define_expand "lwp_llwpcb"
17703 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17704 UNSPECV_LLWP_INTRINSIC)]
17707 (define_insn "*lwp_llwpcb<mode>1"
17708 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17709 UNSPECV_LLWP_INTRINSIC)]
17712 [(set_attr "type" "lwp")
17713 (set_attr "mode" "<MODE>")
17714 (set_attr "length" "5")])
17716 (define_expand "lwp_slwpcb"
17717 [(set (match_operand 0 "register_operand" "=r")
17718 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17723 insn = (TARGET_64BIT
17725 : gen_lwp_slwpcbsi);
17727 emit_insn (insn (operands[0]));
17731 (define_insn "lwp_slwpcb<mode>"
17732 [(set (match_operand:P 0 "register_operand" "=r")
17733 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17736 [(set_attr "type" "lwp")
17737 (set_attr "mode" "<MODE>")
17738 (set_attr "length" "5")])
17740 (define_expand "lwp_lwpval<mode>3"
17741 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17742 (match_operand:SI 2 "nonimmediate_operand" "rm")
17743 (match_operand:SI 3 "const_int_operand" "i")]
17744 UNSPECV_LWPVAL_INTRINSIC)]
17746 "/* Avoid unused variable warning. */
17749 (define_insn "*lwp_lwpval<mode>3_1"
17750 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17751 (match_operand:SI 1 "nonimmediate_operand" "rm")
17752 (match_operand:SI 2 "const_int_operand" "i")]
17753 UNSPECV_LWPVAL_INTRINSIC)]
17755 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17756 [(set_attr "type" "lwp")
17757 (set_attr "mode" "<MODE>")
17758 (set (attr "length")
17759 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17761 (define_expand "lwp_lwpins<mode>3"
17762 [(set (reg:CCC FLAGS_REG)
17763 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17764 (match_operand:SI 2 "nonimmediate_operand" "rm")
17765 (match_operand:SI 3 "const_int_operand" "i")]
17766 UNSPECV_LWPINS_INTRINSIC))
17767 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17768 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17771 (define_insn "*lwp_lwpins<mode>3_1"
17772 [(set (reg:CCC FLAGS_REG)
17773 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17774 (match_operand:SI 1 "nonimmediate_operand" "rm")
17775 (match_operand:SI 2 "const_int_operand" "i")]
17776 UNSPECV_LWPINS_INTRINSIC))]
17778 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17779 [(set_attr "type" "lwp")
17780 (set_attr "mode" "<MODE>")
17781 (set (attr "length")
17782 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17784 (define_insn "rdfsbase<mode>"
17785 [(set (match_operand:SWI48 0 "register_operand" "=r")
17786 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17787 "TARGET_64BIT && TARGET_FSGSBASE"
17789 [(set_attr "type" "other")
17790 (set_attr "prefix_extra" "2")])
17792 (define_insn "rdgsbase<mode>"
17793 [(set (match_operand:SWI48 0 "register_operand" "=r")
17794 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17795 "TARGET_64BIT && TARGET_FSGSBASE"
17797 [(set_attr "type" "other")
17798 (set_attr "prefix_extra" "2")])
17800 (define_insn "wrfsbase<mode>"
17801 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17803 "TARGET_64BIT && TARGET_FSGSBASE"
17805 [(set_attr "type" "other")
17806 (set_attr "prefix_extra" "2")])
17808 (define_insn "wrgsbase<mode>"
17809 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17811 "TARGET_64BIT && TARGET_FSGSBASE"
17813 [(set_attr "type" "other")
17814 (set_attr "prefix_extra" "2")])
17816 (define_insn "rdrand<mode>_1"
17817 [(set (match_operand:SWI248 0 "register_operand" "=r")
17818 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17819 (set (reg:CCC FLAGS_REG)
17820 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17823 [(set_attr "type" "other")
17824 (set_attr "prefix_extra" "1")])
17826 (define_expand "pause"
17827 [(set (match_dup 0)
17828 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17831 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17832 MEM_VOLATILE_P (operands[0]) = 1;
17835 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17836 ;; They have the same encoding.
17837 (define_insn "*pause"
17838 [(set (match_operand:BLK 0 "" "")
17839 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17842 [(set_attr "length" "2")
17843 (set_attr "memory" "unknown")])
17847 (include "sync.md")