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 "i") (DI "e")])
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (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 "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 "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 "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 "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 ;; Scheduling descriptions
957 (include "pentium.md")
960 (include "athlon.md")
961 (include "bdver1.md")
967 ;; Operand and operator predicates and constraints
969 (include "predicates.md")
970 (include "constraints.md")
973 ;; Compare and branch/compare and store instructions.
975 (define_expand "cbranch<mode>4"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978 (match_operand:SDWIM 2 "<general_operand>" "")))
979 (set (pc) (if_then_else
980 (match_operator 0 "ordered_comparison_operator"
981 [(reg:CC FLAGS_REG) (const_int 0)])
982 (label_ref (match_operand 3 "" ""))
986 if (MEM_P (operands[1]) && MEM_P (operands[2]))
987 operands[1] = force_reg (<MODE>mode, operands[1]);
988 ix86_expand_branch (GET_CODE (operands[0]),
989 operands[1], operands[2], operands[3]);
993 (define_expand "cstore<mode>4"
994 [(set (reg:CC FLAGS_REG)
995 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996 (match_operand:SWIM 3 "<general_operand>" "")))
997 (set (match_operand:QI 0 "register_operand" "")
998 (match_operator 1 "ordered_comparison_operator"
999 [(reg:CC FLAGS_REG) (const_int 0)]))]
1002 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003 operands[2] = force_reg (<MODE>mode, operands[2]);
1004 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005 operands[2], operands[3]);
1009 (define_expand "cmp<mode>_1"
1010 [(set (reg:CC FLAGS_REG)
1011 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012 (match_operand:SWI48 1 "<general_operand>" "")))])
1014 (define_insn "*cmp<mode>_ccno_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017 (match_operand:SWI 1 "const0_operand" "")))]
1018 "ix86_match_ccmode (insn, CCNOmode)"
1020 test{<imodesuffix>}\t%0, %0
1021 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "test,icmp")
1023 (set_attr "length_immediate" "0,1")
1024 (set_attr "mode" "<MODE>")])
1026 (define_insn "*cmp<mode>_1"
1027 [(set (reg FLAGS_REG)
1028 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030 "ix86_match_ccmode (insn, CCmode)"
1031 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "<MODE>")])
1035 (define_insn "*cmp<mode>_minus_1"
1036 [(set (reg FLAGS_REG)
1038 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1041 "ix86_match_ccmode (insn, CCGOCmode)"
1042 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "<MODE>")])
1046 (define_insn "*cmpqi_ext_1"
1047 [(set (reg FLAGS_REG)
1049 (match_operand:QI 0 "general_operand" "Qm")
1052 (match_operand 1 "ext_register_operand" "Q")
1054 (const_int 8)) 0)))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_1_rex64"
1061 [(set (reg FLAGS_REG)
1063 (match_operand:QI 0 "register_operand" "Q")
1066 (match_operand 1 "ext_register_operand" "Q")
1068 (const_int 8)) 0)))]
1069 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%h1, %0|%0, %h1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_2"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1082 (match_operand:QI 1 "const0_operand" "")))]
1083 "ix86_match_ccmode (insn, CCNOmode)"
1085 [(set_attr "type" "test")
1086 (set_attr "length_immediate" "0")
1087 (set_attr "mode" "QI")])
1089 (define_expand "cmpqi_ext_3"
1090 [(set (reg:CC FLAGS_REG)
1094 (match_operand 0 "ext_register_operand" "")
1097 (match_operand:QI 1 "immediate_operand" "")))])
1099 (define_insn "*cmpqi_ext_3_insn"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1107 (match_operand:QI 1 "general_operand" "Qmn")))]
1108 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%1, %h0|%h0, %1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "modrm" "1")
1112 (set_attr "mode" "QI")])
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115 [(set (reg FLAGS_REG)
1119 (match_operand 0 "ext_register_operand" "Q")
1122 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124 "cmp{b}\t{%1, %h0|%h0, %1}"
1125 [(set_attr "type" "icmp")
1126 (set_attr "modrm" "1")
1127 (set_attr "mode" "QI")])
1129 (define_insn "*cmpqi_ext_4"
1130 [(set (reg FLAGS_REG)
1134 (match_operand 0 "ext_register_operand" "Q")
1139 (match_operand 1 "ext_register_operand" "Q")
1141 (const_int 8)) 0)))]
1142 "ix86_match_ccmode (insn, CCmode)"
1143 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144 [(set_attr "type" "icmp")
1145 (set_attr "mode" "QI")])
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares. Which is what
1150 ;; the old patterns did, but with many more of them.
1152 (define_expand "cbranchxf4"
1153 [(set (reg:CC FLAGS_REG)
1154 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155 (match_operand:XF 2 "nonmemory_operand" "")))
1156 (set (pc) (if_then_else
1157 (match_operator 0 "ix86_fp_comparison_operator"
1160 (label_ref (match_operand 3 "" ""))
1164 ix86_expand_branch (GET_CODE (operands[0]),
1165 operands[1], operands[2], operands[3]);
1169 (define_expand "cstorexf4"
1170 [(set (reg:CC FLAGS_REG)
1171 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172 (match_operand:XF 3 "nonmemory_operand" "")))
1173 (set (match_operand:QI 0 "register_operand" "")
1174 (match_operator 1 "ix86_fp_comparison_operator"
1179 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180 operands[2], operands[3]);
1184 (define_expand "cbranch<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188 (set (pc) (if_then_else
1189 (match_operator 0 "ix86_fp_comparison_operator"
1192 (label_ref (match_operand 3 "" ""))
1194 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1196 ix86_expand_branch (GET_CODE (operands[0]),
1197 operands[1], operands[2], operands[3]);
1201 (define_expand "cstore<mode>4"
1202 [(set (reg:CC FLAGS_REG)
1203 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205 (set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "ix86_fp_comparison_operator"
1209 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1216 (define_expand "cbranchcc4"
1217 [(set (pc) (if_then_else
1218 (match_operator 0 "comparison_operator"
1219 [(match_operand 1 "flags_reg_operand" "")
1220 (match_operand 2 "const0_operand" "")])
1221 (label_ref (match_operand 3 "" ""))
1225 ix86_expand_branch (GET_CODE (operands[0]),
1226 operands[1], operands[2], operands[3]);
1230 (define_expand "cstorecc4"
1231 [(set (match_operand:QI 0 "register_operand" "")
1232 (match_operator 1 "comparison_operator"
1233 [(match_operand 2 "flags_reg_operand" "")
1234 (match_operand 3 "const0_operand" "")]))]
1237 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238 operands[2], operands[3]);
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1246 ;; CCFPmode compare with exceptions
1247 ;; CCFPUmode compare with no exceptions
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1252 (define_insn "*cmpfp_0"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand 1 "register_operand" "f")
1257 (match_operand 2 "const0_operand" ""))]
1259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "* return output_fp_compare (insn, operands, false, false);"
1262 [(set_attr "type" "multi")
1263 (set_attr "unit" "i387")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))])
1272 (define_insn_and_split "*cmpfp_0_cc"
1273 [(set (reg:CCFP FLAGS_REG)
1275 (match_operand 1 "register_operand" "f")
1276 (match_operand 2 "const0_operand" "")))
1277 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279 && TARGET_SAHF && !TARGET_CMOVE
1280 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282 "&& reload_completed"
1285 [(compare:CCFP (match_dup 1)(match_dup 2))]
1287 (set (reg:CC FLAGS_REG)
1288 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1293 (cond [(match_operand:SF 1 "" "")
1295 (match_operand:DF 1 "" "")
1298 (const_string "XF")))])
1300 (define_insn "*cmpfp_xf"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:XF 1 "register_operand" "f")
1317 (match_operand:XF 2 "register_operand" "f")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "XF")])
1334 (define_insn "*cmpfp_<mode>"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1342 "* return output_fp_compare (insn, operands, false, false);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348 [(set (reg:CCFP FLAGS_REG)
1350 (match_operand:MODEF 1 "register_operand" "f")
1351 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354 && TARGET_SAHF && !TARGET_CMOVE"
1356 "&& reload_completed"
1359 [(compare:CCFP (match_dup 1)(match_dup 2))]
1361 (set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1364 [(set_attr "type" "multi")
1365 (set_attr "unit" "i387")
1366 (set_attr "mode" "<MODE>")])
1368 (define_insn "*cmpfp_u"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operand 2 "register_operand" "f"))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "* return output_fp_compare (insn, operands, false, true);"
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1381 (cond [(match_operand:SF 1 "" "")
1383 (match_operand:DF 1 "" "")
1386 (const_string "XF")))])
1388 (define_insn_and_split "*cmpfp_u_cc"
1389 [(set (reg:CCFPU FLAGS_REG)
1391 (match_operand 1 "register_operand" "f")
1392 (match_operand 2 "register_operand" "f")))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && TARGET_SAHF && !TARGET_CMOVE
1396 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1398 "&& reload_completed"
1401 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1409 (cond [(match_operand:SF 1 "" "")
1411 (match_operand:DF 1 "" "")
1414 (const_string "XF")))])
1416 (define_insn "*cmpfp_<mode>"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (match_operand 1 "register_operand" "f")
1421 (match_operator 3 "float_operator"
1422 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1424 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427 "* return output_fp_compare (insn, operands, false, false);"
1428 [(set_attr "type" "multi")
1429 (set_attr "unit" "i387")
1430 (set_attr "fp_int_src" "true")
1431 (set_attr "mode" "<MODE>")])
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434 [(set (reg:CCFP FLAGS_REG)
1436 (match_operand 1 "register_operand" "f")
1437 (match_operator 3 "float_operator"
1438 [(match_operand:SWI24 2 "memory_operand" "m")])))
1439 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441 && TARGET_SAHF && !TARGET_CMOVE
1442 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1445 "&& reload_completed"
1450 (match_op_dup 3 [(match_dup 2)]))]
1452 (set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1455 [(set_attr "type" "multi")
1456 (set_attr "unit" "i387")
1457 (set_attr "fp_int_src" "true")
1458 (set_attr "mode" "<MODE>")])
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1463 (define_insn "x86_fnstsw_1"
1464 [(set (match_operand:HI 0 "register_operand" "=a")
1465 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1468 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469 (set_attr "mode" "SI")
1470 (set_attr "unit" "i387")])
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1475 (define_insn "x86_sahf_1"
1476 [(set (reg:CC FLAGS_REG)
1477 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1481 #ifndef HAVE_AS_IX86_SAHF
1483 return ASM_BYTE "0x9e";
1488 [(set_attr "length" "1")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "direct")
1492 (set_attr "mode" "SI")])
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500 "TARGET_MIX_SSE_I387
1501 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp,ssecomi")
1505 (set_attr "prefix" "orig,maybe_vex")
1507 (if_then_else (match_operand:SF 1 "" "")
1509 (const_string "DF")))
1510 (set (attr "prefix_rep")
1511 (if_then_else (eq_attr "type" "ssecomi")
1513 (const_string "*")))
1514 (set (attr "prefix_data16")
1515 (cond [(eq_attr "type" "fcmp")
1517 (eq_attr "mode" "DF")
1520 (const_string "0")))
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 (define_insn "*cmpfp_i_sse"
1526 [(set (reg:CCFP FLAGS_REG)
1527 (compare:CCFP (match_operand 0 "register_operand" "x")
1528 (match_operand 1 "nonimmediate_operand" "xm")))]
1530 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532 "* return output_fp_compare (insn, operands, true, false);"
1533 [(set_attr "type" "ssecomi")
1534 (set_attr "prefix" "maybe_vex")
1536 (if_then_else (match_operand:SF 1 "" "")
1538 (const_string "DF")))
1539 (set_attr "prefix_rep" "0")
1540 (set (attr "prefix_data16")
1541 (if_then_else (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_i_i387"
1549 [(set (reg:CCFP FLAGS_REG)
1550 (compare:CCFP (match_operand 0 "register_operand" "f")
1551 (match_operand 1 "register_operand" "f")))]
1552 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, false);"
1557 [(set_attr "type" "fcmp")
1559 (cond [(match_operand:SF 1 "" "")
1561 (match_operand:DF 1 "" "")
1564 (const_string "XF")))
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "amdfam10_decode" "direct")
1567 (set_attr "bdver1_decode" "double")])
1569 (define_insn "*cmpfp_iu_mixed"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573 "TARGET_MIX_SSE_I387
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp,ssecomi")
1578 (set_attr "prefix" "orig,maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set (attr "prefix_rep")
1584 (if_then_else (eq_attr "type" "ssecomi")
1586 (const_string "*")))
1587 (set (attr "prefix_data16")
1588 (cond [(eq_attr "type" "fcmp")
1590 (eq_attr "mode" "DF")
1593 (const_string "0")))
1594 (set_attr "athlon_decode" "vector")
1595 (set_attr "amdfam10_decode" "direct")
1596 (set_attr "bdver1_decode" "double")])
1598 (define_insn "*cmpfp_iu_sse"
1599 [(set (reg:CCFPU FLAGS_REG)
1600 (compare:CCFPU (match_operand 0 "register_operand" "x")
1601 (match_operand 1 "nonimmediate_operand" "xm")))]
1603 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605 "* return output_fp_compare (insn, operands, true, true);"
1606 [(set_attr "type" "ssecomi")
1607 (set_attr "prefix" "maybe_vex")
1609 (if_then_else (match_operand:SF 1 "" "")
1611 (const_string "DF")))
1612 (set_attr "prefix_rep" "0")
1613 (set (attr "prefix_data16")
1614 (if_then_else (eq_attr "mode" "DF")
1616 (const_string "0")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "double")])
1621 (define_insn "*cmpfp_iu_387"
1622 [(set (reg:CCFPU FLAGS_REG)
1623 (compare:CCFPU (match_operand 0 "register_operand" "f")
1624 (match_operand 1 "register_operand" "f")))]
1625 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1627 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629 "* return output_fp_compare (insn, operands, true, true);"
1630 [(set_attr "type" "fcmp")
1632 (cond [(match_operand:SF 1 "" "")
1634 (match_operand:DF 1 "" "")
1637 (const_string "XF")))
1638 (set_attr "athlon_decode" "vector")
1639 (set_attr "amdfam10_decode" "direct")
1640 (set_attr "bdver1_decode" "direct")])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651 [(set (match_operand:TI 0 "push_operand" "")
1652 (match_operand:TI 1 "general_operand" ""))]
1653 "TARGET_64BIT && reload_completed
1654 && !SSE_REG_P (operands[1])"
1656 "ix86_split_long_move (operands); DONE;")
1658 (define_insn "*pushdi2_rex64"
1659 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665 [(set_attr "type" "push,multi")
1666 (set_attr "mode" "DI")])
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it. In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1673 [(match_scratch:DI 2 "r")
1674 (set (match_operand:DI 0 "push_operand" "")
1675 (match_operand:DI 1 "immediate_operand" ""))]
1676 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677 && !x86_64_immediate_operand (operands[1], DImode)"
1678 [(set (match_dup 2) (match_dup 1))
1679 (set (match_dup 0) (match_dup 2))])
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1685 [(set (match_operand:DI 0 "push_operand" "")
1686 (match_operand:DI 1 "immediate_operand" ""))]
1687 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689 [(set (match_dup 0) (match_dup 1))
1690 (set (match_dup 2) (match_dup 3))]
1692 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1694 operands[1] = gen_lowpart (DImode, operands[2]);
1695 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700 [(set (match_operand:DI 0 "push_operand" "")
1701 (match_operand:DI 1 "immediate_operand" ""))]
1702 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703 ? epilogue_completed : reload_completed)
1704 && !symbolic_operand (operands[1], DImode)
1705 && !x86_64_immediate_operand (operands[1], DImode)"
1706 [(set (match_dup 0) (match_dup 1))
1707 (set (match_dup 2) (match_dup 3))]
1709 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1711 operands[1] = gen_lowpart (DImode, operands[2]);
1712 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1722 "ix86_split_long_move (operands); DONE;")
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "*pop<mode>1"
1763 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:P 1 "pop_operand" ">"))]
1766 "pop{<imodesuffix>}\t%0"
1767 [(set_attr "type" "pop")
1768 (set_attr "mode" "<MODE>")])
1770 (define_insn "*pop<mode>1_epilogue"
1771 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:P 1 "pop_operand" ">"))
1773 (clobber (mem:BLK (scratch)))]
1775 "pop{<imodesuffix>}\t%0"
1776 [(set_attr "type" "pop")
1777 (set_attr "mode" "<MODE>")])
1779 ;; Move instructions.
1781 (define_expand "movoi"
1782 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783 (match_operand:OI 1 "general_operand" ""))]
1785 "ix86_expand_move (OImode, operands); DONE;")
1787 (define_expand "movti"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789 (match_operand:TI 1 "nonimmediate_operand" ""))]
1790 "TARGET_64BIT || TARGET_SSE"
1793 ix86_expand_move (TImode, operands);
1794 else if (push_operand (operands[0], TImode))
1795 ix86_expand_push (TImode, operands[1]);
1797 ix86_expand_vector_move (TImode, operands);
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern. Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807 (match_operand:CDI 1 "general_operand" ""))]
1810 if (push_operand (operands[0], CDImode))
1811 emit_move_complex_push (CDImode, operands[0], operands[1]);
1813 emit_move_complex_parts (operands[0], operands[1]);
1817 (define_expand "mov<mode>"
1818 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819 (match_operand:SWI1248x 1 "general_operand" ""))]
1821 "ix86_expand_move (<MODE>mode, operands); DONE;")
1823 (define_insn "*mov<mode>_xor"
1824 [(set (match_operand:SWI48 0 "register_operand" "=r")
1825 (match_operand:SWI48 1 "const0_operand" ""))
1826 (clobber (reg:CC FLAGS_REG))]
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "SI")
1831 (set_attr "length_immediate" "0")])
1833 (define_insn "*mov<mode>_or"
1834 [(set (match_operand:SWI48 0 "register_operand" "=r")
1835 (match_operand:SWI48 1 "const_int_operand" ""))
1836 (clobber (reg:CC FLAGS_REG))]
1838 && operands[1] == constm1_rtx"
1839 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840 [(set_attr "type" "alu1")
1841 (set_attr "mode" "<MODE>")
1842 (set_attr "length_immediate" "1")])
1844 (define_insn "*movoi_internal_avx"
1845 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1849 switch (which_alternative)
1852 return standard_sse_constant_opcode (insn, operands[1]);
1855 if (misaligned_operand (operands[0], OImode)
1856 || misaligned_operand (operands[1], OImode))
1857 return "vmovdqu\t{%1, %0|%0, %1}";
1859 return "vmovdqa\t{%1, %0|%0, %1}";
1864 [(set_attr "type" "sselog1,ssemov,ssemov")
1865 (set_attr "prefix" "vex")
1866 (set_attr "mode" "OI")])
1868 (define_insn "*movti_internal_rex64"
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1873 switch (which_alternative)
1879 return standard_sse_constant_opcode (insn, operands[1]);
1882 /* TDmode values are passed as TImode on the stack. Moving them
1883 to stack may result in unaligned memory access. */
1884 if (misaligned_operand (operands[0], TImode)
1885 || misaligned_operand (operands[1], TImode))
1887 if (get_attr_mode (insn) == MODE_V4SF)
1888 return "%vmovups\t{%1, %0|%0, %1}";
1890 return "%vmovdqu\t{%1, %0|%0, %1}";
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vmovaps\t{%1, %0|%0, %1}";
1897 return "%vmovdqa\t{%1, %0|%0, %1}";
1903 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1906 (cond [(eq_attr "alternative" "2,3")
1908 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1910 (const_string "V4SF")
1911 (const_string "TI"))
1912 (eq_attr "alternative" "4")
1914 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1916 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1918 (const_string "V4SF")
1919 (const_string "TI"))]
1920 (const_string "DI")))])
1923 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924 (match_operand:TI 1 "general_operand" ""))]
1926 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1928 "ix86_split_long_move (operands); DONE;")
1930 (define_insn "*movti_internal_sse"
1931 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933 "TARGET_SSE && !TARGET_64BIT
1934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 switch (which_alternative)
1939 return standard_sse_constant_opcode (insn, operands[1]);
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1989 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994 /* Handle broken assemblers that require movd instead of movq. */
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "%vmovd\t{%1, %0|%0, %1}";
1998 return "%vmovq\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 "movd\t{%1, %0|%0, %1}";
2005 return "movq\t{%1, %0|%0, %1}";
2008 return standard_sse_constant_opcode (insn, operands[1]);
2011 return "pxor\t%0, %0";
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2020 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2026 return "mov{q}\t{%1, %0|%0, %1}";
2030 (cond [(eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (eq_attr "alternative" "5")
2033 (const_string "mmx")
2034 (eq_attr "alternative" "6,7,8,9")
2035 (const_string "mmxmov")
2036 (eq_attr "alternative" "10")
2037 (const_string "sselog1")
2038 (eq_attr "alternative" "11,12,13,14,15")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "16,17")
2041 (const_string "ssecvt")
2042 (match_operand:DI 1 "pic_32bit_operand" "")
2043 (const_string "lea")
2045 (const_string "imov")))
2048 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2050 (const_string "*")))
2051 (set (attr "length_immediate")
2053 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2055 (const_string "*")))
2056 (set (attr "prefix_rex")
2057 (if_then_else (eq_attr "alternative" "8,9")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "11")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))])
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098 ? epilogue_completed : reload_completed)
2099 && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2105 (define_insn "*movdi_internal"
2106 [(set (match_operand:DI 0 "nonimmediate_operand"
2107 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108 (match_operand:DI 1 "general_operand"
2109 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2112 switch (get_attr_type (insn))
2115 if (SSE_REG_P (operands[0]))
2116 return "movq2dq\t{%1, %0|%0, %1}";
2118 return "movdq2q\t{%1, %0|%0, %1}";
2121 switch (get_attr_mode (insn))
2124 return "%vmovdqa\t{%1, %0|%0, %1}";
2126 return "%vmovq\t{%1, %0|%0, %1}";
2128 return "movaps\t{%1, %0|%0, %1}";
2130 return "movlps\t{%1, %0|%0, %1}";
2136 return "movq\t{%1, %0|%0, %1}";
2139 return standard_sse_constant_opcode (insn, operands[1]);
2142 return "pxor\t%0, %0";
2152 (if_then_else (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2154 (const_string "*")))
2156 (cond [(eq_attr "alternative" "0,1")
2157 (const_string "multi")
2158 (eq_attr "alternative" "2")
2159 (const_string "mmx")
2160 (eq_attr "alternative" "3,4")
2161 (const_string "mmxmov")
2162 (eq_attr "alternative" "5,9")
2163 (const_string "sselog1")
2164 (eq_attr "alternative" "13,14")
2165 (const_string "ssecvt")
2167 (const_string "ssemov")))
2168 (set (attr "prefix")
2169 (if_then_else (eq_attr "alternative" "5,6,7,8")
2170 (const_string "maybe_vex")
2171 (const_string "orig")))
2172 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176 (match_operand:DI 1 "general_operand" ""))]
2177 "!TARGET_64BIT && reload_completed
2178 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2181 "ix86_split_long_move (operands); DONE;")
2183 (define_insn "*movsi_internal"
2184 [(set (match_operand:SI 0 "nonimmediate_operand"
2185 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186 (match_operand:SI 1 "general_operand"
2187 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2188 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2190 switch (get_attr_type (insn))
2193 return standard_sse_constant_opcode (insn, operands[1]);
2196 switch (get_attr_mode (insn))
2199 return "%vmovdqa\t{%1, %0|%0, %1}";
2201 return "%vmovaps\t{%1, %0|%0, %1}";
2203 return "%vmovd\t{%1, %0|%0, %1}";
2205 return "%vmovss\t{%1, %0|%0, %1}";
2211 return "pxor\t%0, %0";
2214 if (get_attr_mode (insn) == MODE_DI)
2215 return "movq\t{%1, %0|%0, %1}";
2216 return "movd\t{%1, %0|%0, %1}";
2219 return "lea{l}\t{%a1, %0|%0, %a1}";
2222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223 return "mov{l}\t{%1, %0|%0, %1}";
2227 (cond [(eq_attr "alternative" "2")
2228 (const_string "mmx")
2229 (eq_attr "alternative" "3,4,5")
2230 (const_string "mmxmov")
2231 (eq_attr "alternative" "6")
2232 (const_string "sselog1")
2233 (eq_attr "alternative" "7,8,9,10,11")
2234 (const_string "ssemov")
2235 (match_operand:DI 1 "pic_32bit_operand" "")
2236 (const_string "lea")
2238 (const_string "imov")))
2239 (set (attr "prefix")
2240 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241 (const_string "orig")
2242 (const_string "maybe_vex")))
2243 (set (attr "prefix_data16")
2244 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2246 (const_string "*")))
2248 (cond [(eq_attr "alternative" "2,3")
2250 (eq_attr "alternative" "6,7")
2252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253 (const_string "V4SF")
2254 (const_string "TI"))
2255 (and (eq_attr "alternative" "8,9,10,11")
2256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2259 (const_string "SI")))])
2261 (define_insn "*movhi_internal"
2262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 /* movzwl is faster than movw on p2 due to partial word stalls,
2270 though not as fast as an aligned movl. */
2271 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2273 if (get_attr_mode (insn) == MODE_SI)
2274 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2276 return "mov{w}\t{%1, %0|%0, %1}";
2280 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2282 (const_string "imov")
2283 (and (eq_attr "alternative" "0")
2284 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2286 (eq (symbol_ref "TARGET_HIMODE_MATH")
2288 (const_string "imov")
2289 (and (eq_attr "alternative" "1,2")
2290 (match_operand:HI 1 "aligned_operand" ""))
2291 (const_string "imov")
2292 (and (ne (symbol_ref "TARGET_MOVX")
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2297 (const_string "imov")))
2299 (cond [(eq_attr "type" "imovx")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand" ""))
2304 (and (eq_attr "alternative" "0")
2305 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2307 (eq (symbol_ref "TARGET_HIMODE_MATH")
2311 (const_string "HI")))])
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2328 switch (get_attr_type (insn))
2331 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2334 if (get_attr_mode (insn) == MODE_SI)
2335 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2337 return "mov{b}\t{%1, %0|%0, %1}";
2341 (cond [(and (eq_attr "alternative" "5")
2342 (not (match_operand:QI 1 "aligned_operand" "")))
2343 (const_string "imovx")
2344 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "3")
2348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2350 (eq (symbol_ref "TARGET_QIMODE_MATH")
2352 (const_string "imov")
2353 (eq_attr "alternative" "3,5")
2354 (const_string "imovx")
2355 (and (ne (symbol_ref "TARGET_MOVX")
2357 (eq_attr "alternative" "2"))
2358 (const_string "imovx")
2360 (const_string "imov")))
2362 (cond [(eq_attr "alternative" "3,4,5")
2364 (eq_attr "alternative" "6")
2366 (eq_attr "type" "imovx")
2368 (and (eq_attr "type" "imov")
2369 (and (eq_attr "alternative" "0,1")
2370 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2372 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2374 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2377 ;; Avoid partial register stalls when not using QImode arithmetic
2378 (and (eq_attr "type" "imov")
2379 (and (eq_attr "alternative" "0,1")
2380 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2382 (eq (symbol_ref "TARGET_QIMODE_MATH")
2386 (const_string "QI")))])
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2396 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398 [(set_attr "type" "imov")
2399 (set_attr "modrm" "0,*")
2400 (set_attr "length_address" "8,0")
2401 (set_attr "length_immediate" "0,*")
2402 (set_attr "memory" "store")
2403 (set_attr "mode" "<MODE>")])
2405 (define_insn "*movabs<mode>_2"
2406 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2410 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "modrm" "0,*")
2414 (set_attr "length_address" "8,0")
2415 (set_attr "length_immediate" "0")
2416 (set_attr "memory" "load")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*swap<mode>"
2420 [(set (match_operand:SWI48 0 "register_operand" "+r")
2421 (match_operand:SWI48 1 "register_operand" "+r"))
2425 "xchg{<imodesuffix>}\t%1, %0"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")
2428 (set_attr "pent_pair" "np")
2429 (set_attr "athlon_decode" "vector")
2430 (set_attr "amdfam10_decode" "double")
2431 (set_attr "bdver1_decode" "double")])
2433 (define_insn "*swap<mode>_1"
2434 [(set (match_operand:SWI12 0 "register_operand" "+r")
2435 (match_operand:SWI12 1 "register_operand" "+r"))
2438 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2440 [(set_attr "type" "imov")
2441 (set_attr "mode" "SI")
2442 (set_attr "pent_pair" "np")
2443 (set_attr "athlon_decode" "vector")
2444 (set_attr "amdfam10_decode" "double")
2445 (set_attr "bdver1_decode" "double")])
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451 (match_operand:SWI12 1 "register_operand" "+<r>"))
2454 "TARGET_PARTIAL_REG_STALL"
2455 "xchg{<imodesuffix>}\t%1, %0"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")
2458 (set_attr "pent_pair" "np")
2459 (set_attr "athlon_decode" "vector")])
2461 (define_expand "movstrict<mode>"
2462 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463 (match_operand:SWI12 1 "general_operand" ""))]
2466 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2468 if (GET_CODE (operands[0]) == SUBREG
2469 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2471 /* Don't generate memory->memory moves, go through a register */
2472 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473 operands[1] = force_reg (<MODE>mode, operands[1]);
2476 (define_insn "*movstrict<mode>_1"
2477 [(set (strict_low_part
2478 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483 [(set_attr "type" "imov")
2484 (set_attr "mode" "<MODE>")])
2486 (define_insn "*movstrict<mode>_xor"
2487 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488 (match_operand:SWI12 1 "const0_operand" ""))
2489 (clobber (reg:CC FLAGS_REG))]
2491 "xor{<imodesuffix>}\t%0, %0"
2492 [(set_attr "type" "alu1")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "length_immediate" "0")])
2496 (define_insn "*mov<mode>_extv_1"
2497 [(set (match_operand:SWI24 0 "register_operand" "=R")
2498 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2502 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503 [(set_attr "type" "imovx")
2504 (set_attr "mode" "SI")])
2506 (define_insn "*movqi_extv_1_rex64"
2507 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2513 switch (get_attr_type (insn))
2516 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2518 return "mov{b}\t{%h1, %0|%0, %h1}";
2522 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (ne (symbol_ref "TARGET_MOVX")
2525 (const_string "imovx")
2526 (const_string "imov")))
2528 (if_then_else (eq_attr "type" "imovx")
2530 (const_string "QI")))])
2532 (define_insn "*movqi_extv_1"
2533 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2539 switch (get_attr_type (insn))
2542 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2544 return "mov{b}\t{%h1, %0|%0, %h1}";
2548 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550 (ne (symbol_ref "TARGET_MOVX")
2552 (const_string "imovx")
2553 (const_string "imov")))
2555 (if_then_else (eq_attr "type" "imovx")
2557 (const_string "QI")))])
2559 (define_insn "*mov<mode>_extzv_1"
2560 [(set (match_operand:SWI48 0 "register_operand" "=R")
2561 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2565 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566 [(set_attr "type" "imovx")
2567 (set_attr "mode" "SI")])
2569 (define_insn "*movqi_extzv_2_rex64"
2570 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2572 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2577 switch (get_attr_type (insn))
2580 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2582 return "mov{b}\t{%h1, %0|%0, %h1}";
2586 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587 (ne (symbol_ref "TARGET_MOVX")
2589 (const_string "imovx")
2590 (const_string "imov")))
2592 (if_then_else (eq_attr "type" "imovx")
2594 (const_string "QI")))])
2596 (define_insn "*movqi_extzv_2"
2597 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2604 switch (get_attr_type (insn))
2607 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2609 return "mov{b}\t{%h1, %0|%0, %h1}";
2613 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615 (ne (symbol_ref "TARGET_MOVX")
2617 (const_string "imovx")
2618 (const_string "imov")))
2620 (if_then_else (eq_attr "type" "imovx")
2622 (const_string "QI")))])
2624 (define_expand "mov<mode>_insv_1"
2625 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2628 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2634 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2636 "mov{b}\t{%b1, %h0|%h0, %b1}"
2637 [(set_attr "type" "imov")
2638 (set_attr "mode" "QI")])
2640 (define_insn "*movsi_insv_1"
2641 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2644 (match_operand:SI 1 "general_operand" "Qmn"))]
2646 "mov{b}\t{%b1, %h0|%h0, %b1}"
2647 [(set_attr "type" "imov")
2648 (set_attr "mode" "QI")])
2650 (define_insn "*movqi_insv_2"
2651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2654 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2657 "mov{b}\t{%h1, %h0|%h0, %h1}"
2658 [(set_attr "type" "imov")
2659 (set_attr "mode" "QI")])
2661 ;; Floating point push instructions.
2663 (define_insn "*pushtf"
2664 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2668 /* This insn should be already split before reg-stack. */
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "sse,*,*")
2673 (set_attr "mode" "TF,SI,SI")])
2675 ;; %%% Kill this when call knows how to work this out.
2677 [(set (match_operand:TF 0 "push_operand" "")
2678 (match_operand:TF 1 "sse_reg_operand" ""))]
2679 "TARGET_SSE2 && reload_completed"
2680 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2683 (define_insn "*pushxf"
2684 [(set (match_operand:XF 0 "push_operand" "=<,<")
2685 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686 "optimize_function_for_speed_p (cfun)"
2688 /* This insn should be already split before reg-stack. */
2691 [(set_attr "type" "multi")
2692 (set_attr "unit" "i387,*")
2693 (set_attr "mode" "XF,SI")])
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2701 (define_insn "*pushxf_nointeger"
2702 [(set (match_operand:XF 0 "push_operand" "=X,X")
2703 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704 "optimize_function_for_size_p (cfun)"
2706 /* This insn should be already split before reg-stack. */
2709 [(set_attr "type" "multi")
2710 (set_attr "unit" "i387,*")
2711 (set_attr "mode" "XF,SI")])
2713 ;; %%% Kill this when call knows how to work this out.
2715 [(set (match_operand:XF 0 "push_operand" "")
2716 (match_operand:XF 1 "fp_register_operand" ""))]
2718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2726 (define_insn "*pushdf"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "DF,SI,DF")])
2738 ;; %%% Kill this when call knows how to work this out.
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2746 (define_insn "*pushsf_rex64"
2747 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{q}\t%q1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,DI,SF")])
2759 (define_insn "*pushsf"
2760 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2764 /* Anything else should be already split before reg-stack. */
2765 gcc_assert (which_alternative == 1);
2766 return "push{l}\t%1";
2768 [(set_attr "type" "multi,push,multi")
2769 (set_attr "unit" "i387,*,*")
2770 (set_attr "mode" "SF,SI,SF")])
2772 ;; %%% Kill this when call knows how to work this out.
2774 [(set (match_operand:SF 0 "push_operand" "")
2775 (match_operand:SF 1 "any_fp_register_operand" ""))]
2777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2785 && (operands[2] = find_constant_src (insn))"
2786 [(set (match_dup 0) (match_dup 2))])
2789 [(set (match_operand 0 "push_operand" "")
2790 (match_operand 1 "general_operand" ""))]
2792 && (GET_MODE (operands[0]) == TFmode
2793 || GET_MODE (operands[0]) == XFmode
2794 || GET_MODE (operands[0]) == DFmode)
2795 && !ANY_FP_REG_P (operands[1])"
2797 "ix86_split_long_move (operands); DONE;")
2799 ;; Floating point move instructions.
2801 (define_expand "movtf"
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "nonimmediate_operand" ""))]
2806 ix86_expand_move (TFmode, operands);
2810 (define_expand "mov<mode>"
2811 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812 (match_operand:X87MODEF 1 "general_operand" ""))]
2814 "ix86_expand_move (<MODE>mode, operands); DONE;")
2816 (define_insn "*movtf_internal"
2817 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (!can_create_pseudo_p ()
2822 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || (optimize_function_for_size_p (cfun)
2825 && standard_sse_constant_p (operands[1])
2826 && !memory_operand (operands[0], TFmode))
2827 || (!TARGET_MEMORY_MISMATCH_STALL
2828 && memory_operand (operands[0], TFmode)))"
2830 switch (which_alternative)
2834 /* Handle misaligned load/store since we
2835 don't have movmisaligntf pattern. */
2836 if (misaligned_operand (operands[0], TFmode)
2837 || misaligned_operand (operands[1], TFmode))
2839 if (get_attr_mode (insn) == MODE_V4SF)
2840 return "%vmovups\t{%1, %0|%0, %1}";
2842 return "%vmovdqu\t{%1, %0|%0, %1}";
2846 if (get_attr_mode (insn) == MODE_V4SF)
2847 return "%vmovaps\t{%1, %0|%0, %1}";
2849 return "%vmovdqa\t{%1, %0|%0, %1}";
2853 return standard_sse_constant_opcode (insn, operands[1]);
2863 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2866 (cond [(eq_attr "alternative" "0,2")
2868 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2870 (const_string "V4SF")
2871 (const_string "TI"))
2872 (eq_attr "alternative" "1")
2874 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2876 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2878 (const_string "V4SF")
2879 (const_string "TI"))]
2880 (const_string "DI")))])
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2886 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (!can_create_pseudo_p ()
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || (optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]) > 0
2892 && !memory_operand (operands[0], XFmode))
2893 || (!TARGET_MEMORY_MISMATCH_STALL
2894 && memory_operand (operands[0], XFmode)))"
2896 switch (which_alternative)
2900 return output_387_reg_move (insn, operands);
2903 return standard_80387_constant_opcode (operands[1]);
2913 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914 (set_attr "mode" "XF,XF,XF,SI,SI")])
2916 (define_insn "*movdf_internal_rex64"
2917 [(set (match_operand:DF 0 "nonimmediate_operand"
2918 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2919 (match_operand:DF 1 "general_operand"
2920 "fm,f,G,rm,r ,F ,F ,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2921 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922 && (!can_create_pseudo_p ()
2923 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || (optimize_function_for_size_p (cfun)
2926 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927 && standard_80387_constant_p (operands[1]) > 0)
2928 || (TARGET_SSE2 && TARGET_SSE_MATH
2929 && standard_sse_constant_p (operands[1]))))
2930 || memory_operand (operands[0], DFmode))"
2932 switch (which_alternative)
2936 return output_387_reg_move (insn, operands);
2939 return standard_80387_constant_opcode (operands[1]);
2943 return "mov{q}\t{%1, %0|%0, %1}";
2946 return "movabs{q}\t{%1, %0|%0, %1}";
2952 return standard_sse_constant_opcode (insn, operands[1]);
2957 switch (get_attr_mode (insn))
2960 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovapd\t{%1, %0|%0, %1}";
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2966 return "%vmovq\t{%1, %0|%0, %1}";
2968 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970 return "%vmovsd\t{%1, %0|%0, %1}";
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2981 /* Handle broken assemblers that require movd instead of movq. */
2982 return "%vmovd\t{%1, %0|%0, %1}";
2988 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2993 (const_string "*")))
2994 (set (attr "length_immediate")
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2998 (const_string "*")))
2999 (set (attr "prefix")
3000 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001 (const_string "orig")
3002 (const_string "maybe_vex")))
3003 (set (attr "prefix_data16")
3004 (if_then_else (eq_attr "mode" "V1DF")
3006 (const_string "*")))
3008 (cond [(eq_attr "alternative" "0,1,2")
3010 (eq_attr "alternative" "3,4,5,6,11,12")
3013 /* xorps is one byte shorter. */
3014 (eq_attr "alternative" "7")
3015 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3022 (const_string "V2DF"))
3024 /* For architectures resolving dependencies on
3025 whole SSE registers use APD move to break dependency
3026 chains, otherwise use short move to avoid extra work.
3028 movaps encodes one byte shorter. */
3029 (eq_attr "alternative" "8")
3031 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3033 (const_string "V4SF")
3034 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3036 (const_string "V2DF")
3038 (const_string "DF"))
3039 /* For architectures resolving dependencies on register
3040 parts we may avoid extra work to zero out upper part
3042 (eq_attr "alternative" "9")
3044 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3046 (const_string "V1DF")
3047 (const_string "DF"))
3049 (const_string "DF")))])
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3070 switch (which_alternative)
3074 return output_387_reg_move (insn, operands);
3077 return standard_80387_constant_opcode (operands[1]);
3084 return standard_sse_constant_opcode (insn, operands[1]);
3089 switch (get_attr_mode (insn))
3092 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "%vmovapd\t{%1, %0|%0, %1}";
3095 return "%vmovaps\t{%1, %0|%0, %1}";
3098 return "%vmovq\t{%1, %0|%0, %1}";
3100 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102 return "%vmovsd\t{%1, %0|%0, %1}";
3104 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3106 return "%vmovlps\t{%1, %d0|%d0, %1}";
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133 (eq_attr "alternative" "5,6")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146 (const_string "V2DF"))
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160 (const_string "V2DF")
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "7")
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3191 switch (which_alternative)
3195 return output_387_reg_move (insn, operands);
3198 return standard_80387_constant_opcode (operands[1]);
3202 return "mov{l}\t{%1, %0|%0, %1}";
3205 return standard_sse_constant_opcode (insn, operands[1]);
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3215 return "%vmovss\t{%1, %0|%0, %1}";
3221 return "movd\t{%1, %0|%0, %1}";
3224 return "movq\t{%1, %0|%0, %1}";
3228 return "%vmovd\t{%1, %0|%0, %1}";
3234 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235 (set (attr "prefix")
3236 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237 (const_string "maybe_vex")
3238 (const_string "orig")))
3240 (cond [(eq_attr "alternative" "3,4,9,10")
3242 (eq_attr "alternative" "5")
3244 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3246 (ne (symbol_ref "TARGET_SSE2")
3248 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3266 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3320 (neg:X87MODEF (match_dup 0)))]
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3328 operands[1] = CONST1_RTX (<MODE>mode);
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3340 "ix86_split_long_move (operands); DONE;")
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3349 if (STACK_TOP_P (operands[0]))
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3362 "TARGET_80387 || reload_completed"
3364 if (STACK_TOP_P (operands[0]))
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3372 ;; Zero extension instructions
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3381 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3389 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3392 mov\t{%k1, %k0|%k0, %k1}
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}
3397 %vmovd\t{%1, %0|%0, %1}"
3398 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3404 [(set (match_operand:DI 0 "memory_operand" "")
3405 (zero_extend:DI (match_dup 0)))]
3407 [(set (match_dup 4) (const_int 0))]
3408 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3414 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3415 (clobber (reg:CC FLAGS_REG))]
3421 movd\t{%1, %0|%0, %1}
3422 movd\t{%1, %0|%0, %1}
3423 %vmovd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}"
3425 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "!TARGET_64BIT && reload_completed
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_64BIT && reload_completed
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3457 (define_expand "zero_extendhisi2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3464 operands[1] = force_reg (HImode, operands[1]);
3465 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3470 (define_insn_and_split "zero_extendhisi2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r")
3472 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473 (clobber (reg:CC FLAGS_REG))]
3474 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3476 "&& reload_completed"
3477 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478 (clobber (reg:CC FLAGS_REG))])]
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "SI")])
3483 (define_insn "*zero_extendhisi2_movzwl"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486 "!TARGET_ZERO_EXTEND_WITH_AND
3487 || optimize_function_for_size_p (cfun)"
3488 "movz{wl|x}\t{%1, %0|%0, %1}"
3489 [(set_attr "type" "imovx")
3490 (set_attr "mode" "SI")])
3492 (define_expand "zero_extendqi<mode>2"
3494 [(set (match_operand:SWI24 0 "register_operand" "")
3495 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])])
3498 (define_insn "*zero_extendqi<mode>2_and"
3499 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "<MODE>")])
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3510 [(set (match_operand:SWI24 0 "register_operand" "")
3511 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512 (clobber (reg:CC FLAGS_REG))]
3514 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 && ANY_QI_REG_P (operands[0])
3516 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3520 operands[2] = gen_lowpart (QImode, operands[0]);
3521 ix86_expand_clear (operands[0]);
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "<MODE>")])
3533 ;; For the movzbl case strip only the clobber
3535 [(set (match_operand:SWI24 0 "register_operand" "")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537 (clobber (reg:CC FLAGS_REG))]
3539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3542 (zero_extend:SWI24 (match_dup 1)))])
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546 [(set (match_operand:SWI24 0 "register_operand" "=r")
3547 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3554 ;; Rest is handled by single and.
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC FLAGS_REG))])])
3564 ;; Sign extension instructions
3566 (define_expand "extendsidi2"
3567 [(set (match_operand:DI 0 "register_operand" "")
3568 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3573 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3578 (define_insn "*extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3584 movs{lq|x}\t{%1, %0|%0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "DI")
3587 (set_attr "prefix_0f" "0")
3588 (set_attr "modrm" "0,1")])
3590 (define_insn "extendsidi2_1"
3591 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3598 ;; Extend to memory case when source register does die.
3600 [(set (match_operand:DI 0 "memory_operand" "")
3601 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602 (clobber (reg:CC FLAGS_REG))
3603 (clobber (match_operand:SI 2 "register_operand" ""))]
3605 && dead_or_set_p (insn, operands[1])
3606 && !reg_mentioned_p (operands[1], operands[0]))"
3607 [(set (match_dup 3) (match_dup 1))
3608 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609 (clobber (reg:CC FLAGS_REG))])
3610 (set (match_dup 4) (match_dup 1))]
3611 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 ;; Extend to memory case when source register does not die.
3615 [(set (match_operand:DI 0 "memory_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_operand:SI 2 "register_operand" ""))]
3622 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3624 emit_move_insn (operands[3], operands[1]);
3626 /* Generate a cltd if possible and doing so it profitable. */
3627 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628 && true_regnum (operands[1]) == AX_REG
3629 && true_regnum (operands[2]) == DX_REG)
3631 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3635 emit_move_insn (operands[2], operands[1]);
3636 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3638 emit_move_insn (operands[4], operands[2]);
3642 ;; Extend to register case. Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3645 [(set (match_operand:DI 0 "register_operand" "")
3646 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647 (clobber (reg:CC FLAGS_REG))
3648 (clobber (match_scratch:SI 2 ""))]
3652 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3654 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[3], operands[1]);
3657 /* Generate a cltd if possible and doing so it profitable. */
3658 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659 && true_regnum (operands[3]) == AX_REG
3660 && true_regnum (operands[4]) == DX_REG)
3662 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3666 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667 emit_move_insn (operands[4], operands[1]);
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3673 (define_insn "extend<mode>di2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3676 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3678 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "DI")])
3682 (define_insn "extendhisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3687 switch (get_attr_prefix_0f (insn))
3690 return "{cwtl|cwde}";
3692 return "movs{wl|x}\t{%1, %0|%0, %1}";
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")
3697 (set (attr "prefix_0f")
3698 ;; movsx is short decodable while cwtl is vector decoded.
3699 (if_then_else (and (eq_attr "cpu" "!k6")
3700 (eq_attr "alternative" "0"))
3702 (const_string "1")))
3704 (if_then_else (eq_attr "prefix_0f" "0")
3706 (const_string "1")))])
3708 (define_insn "*extendhisi2_zext"
3709 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3712 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3715 switch (get_attr_prefix_0f (insn))
3718 return "{cwtl|cwde}";
3720 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3723 [(set_attr "type" "imovx")
3724 (set_attr "mode" "SI")
3725 (set (attr "prefix_0f")
3726 ;; movsx is short decodable while cwtl is vector decoded.
3727 (if_then_else (and (eq_attr "cpu" "!k6")
3728 (eq_attr "alternative" "0"))
3730 (const_string "1")))
3732 (if_then_else (eq_attr "prefix_0f" "0")
3734 (const_string "1")))])
3736 (define_insn "extendqisi2"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740 "movs{bl|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 (define_insn "*extendqisi2_zext"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3749 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3753 (define_insn "extendqihi2"
3754 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3758 switch (get_attr_prefix_0f (insn))
3761 return "{cbtw|cbw}";
3763 return "movs{bw|x}\t{%1, %0|%0, %1}";
3766 [(set_attr "type" "imovx")
3767 (set_attr "mode" "HI")
3768 (set (attr "prefix_0f")
3769 ;; movsx is short decodable while cwtl is vector decoded.
3770 (if_then_else (and (eq_attr "cpu" "!k6")
3771 (eq_attr "alternative" "0"))
3773 (const_string "1")))
3775 (if_then_else (eq_attr "prefix_0f" "0")
3777 (const_string "1")))])
3779 ;; Conversions between float and double.
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3786 [(set (match_operand:DF 0 "push_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3793 [(set (match_operand:XF 0 "push_operand" "")
3794 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3800 (define_expand "extendsfdf2"
3801 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3805 /* ??? Needed for compress_float_constant since all fp constants
3806 are TARGET_LEGITIMATE_CONSTANT_P. */
3807 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3809 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810 && standard_80387_constant_p (operands[1]) > 0)
3812 operands[1] = simplify_const_unary_operation
3813 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814 emit_move_insn_1 (operands[0], operands[1]);
3817 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3823 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3825 We do the conversion post reload to avoid producing of 128bit spills
3826 that might lead to ICE on 32bit target. The sequence unlikely combine
3829 [(set (match_operand:DF 0 "register_operand" "")
3831 (match_operand:SF 1 "nonimmediate_operand" "")))]
3832 "TARGET_USE_VECTOR_FP_CONVERTS
3833 && optimize_insn_for_speed_p ()
3834 && reload_completed && SSE_REG_P (operands[0])"
3839 (parallel [(const_int 0) (const_int 1)]))))]
3841 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844 Try to avoid move when unpacking can be done in source. */
3845 if (REG_P (operands[1]))
3847 /* If it is unsafe to overwrite upper half of source, we need
3848 to move to destination and unpack there. */
3849 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851 && true_regnum (operands[0]) != true_regnum (operands[1]))
3853 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854 emit_move_insn (tmp, operands[1]);
3857 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3862 emit_insn (gen_vec_setv4sf_0 (operands[3],
3863 CONST0_RTX (V4SFmode), operands[1]));
3866 (define_insn "*extendsfdf2_mixed"
3867 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3869 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3872 switch (which_alternative)
3876 return output_387_reg_move (insn, operands);
3879 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "prefix" "orig,orig,maybe_vex")
3887 (set_attr "mode" "SF,XF,DF")])
3889 (define_insn "*extendsfdf2_sse"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892 "TARGET_SSE2 && TARGET_SSE_MATH"
3893 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894 [(set_attr "type" "ssecvt")
3895 (set_attr "prefix" "maybe_vex")
3896 (set_attr "mode" "DF")])
3898 (define_insn "*extendsfdf2_i387"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3902 "* return output_387_reg_move (insn, operands);"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "SF,XF")])
3906 (define_expand "extend<mode>xf2"
3907 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3911 /* ??? Needed for compress_float_constant since all fp constants
3912 are TARGET_LEGITIMATE_CONSTANT_P. */
3913 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3915 if (standard_80387_constant_p (operands[1]) > 0)
3917 operands[1] = simplify_const_unary_operation
3918 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919 emit_move_insn_1 (operands[0], operands[1]);
3922 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3926 (define_insn "*extend<mode>xf2_i387"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3929 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>,XF")])
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3941 ;; Conversion from DFmode to SFmode.
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3951 else if (flag_unsafe_math_optimizations)
3955 enum ix86_stack_slot slot = (virtuals_instantiated
3958 rtx temp = assign_386_stack_local (SFmode, slot);
3959 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3966 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3968 We do the conversion post reload to avoid producing of 128bit spills
3969 that might lead to ICE on 32bit target. The sequence unlikely combine
3972 [(set (match_operand:SF 0 "register_operand" "")
3974 (match_operand:DF 1 "nonimmediate_operand" "")))]
3975 "TARGET_USE_VECTOR_FP_CONVERTS
3976 && optimize_insn_for_speed_p ()
3977 && reload_completed && SSE_REG_P (operands[0])"
3980 (float_truncate:V2SF
3984 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985 operands[3] = CONST0_RTX (V2SFmode);
3986 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987 /* Use movsd for loading from memory, unpcklpd for registers.
3988 Try to avoid move when unpacking can be done in source, or SSE3
3989 movddup is available. */
3990 if (REG_P (operands[1]))
3993 && true_regnum (operands[0]) != true_regnum (operands[1])
3994 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3997 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998 emit_move_insn (tmp, operands[1]);
4001 else if (!TARGET_SSE3)
4002 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4006 emit_insn (gen_sse2_loadlpd (operands[4],
4007 CONST0_RTX (V2DFmode), operands[1]));
4010 (define_expand "truncdfsf2_with_temp"
4011 [(parallel [(set (match_operand:SF 0 "" "")
4012 (float_truncate:SF (match_operand:DF 1 "" "")))
4013 (clobber (match_operand:SF 2 "" ""))])])
4015 (define_insn "*truncdfsf_fast_mixed"
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4018 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4019 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4021 switch (which_alternative)
4024 return output_387_reg_move (insn, operands);
4026 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4031 [(set_attr "type" "fmov,ssecvt")
4032 (set_attr "prefix" "orig,maybe_vex")
4033 (set_attr "mode" "SF")])
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4040 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041 "TARGET_SSE2 && TARGET_SSE_MATH"
4042 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043 [(set_attr "type" "ssecvt")
4044 (set_attr "prefix" "maybe_vex")
4045 (set_attr "mode" "SF")])
4047 (define_insn "*truncdfsf_fast_i387"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4050 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051 "TARGET_80387 && flag_unsafe_math_optimizations"
4052 "* return output_387_reg_move (insn, operands);"
4053 [(set_attr "type" "fmov")
4054 (set_attr "mode" "SF")])
4056 (define_insn "*truncdfsf_mixed"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4059 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4061 "TARGET_MIX_SSE_I387"
4063 switch (which_alternative)
4066 return output_387_reg_move (insn, operands);
4068 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4074 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "DF")])
4174 (define_insn "truncxf<mode>2_i387_noop"
4175 [(set (match_operand:MODEF 0 "register_operand" "=f")
4176 (float_truncate:MODEF
4177 (match_operand:XF 1 "register_operand" "f")))]
4178 "TARGET_80387 && flag_unsafe_math_optimizations"
4179 "* return output_387_reg_move (insn, operands);"
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "<MODE>")])
4183 (define_insn "*truncxf<mode>2_i387"
4184 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4193 [(set (match_operand:MODEF 0 "register_operand" "")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))])
4202 [(set (match_operand:MODEF 0 "memory_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4207 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4209 ;; Signed conversion to DImode.
4211 (define_expand "fix_truncxfdi2"
4212 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (fix:DI (match_operand:XF 1 "register_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))])]
4219 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4224 (define_expand "fix_trunc<mode>di2"
4225 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227 (clobber (reg:CC FLAGS_REG))])]
4228 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4231 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4233 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4236 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4238 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240 if (out != operands[0])
4241 emit_move_insn (operands[0], out);
4246 ;; Signed conversion to SImode.
4248 (define_expand "fix_truncxfsi2"
4249 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250 (fix:SI (match_operand:XF 1 "register_operand" "")))
4251 (clobber (reg:CC FLAGS_REG))])]
4256 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4261 (define_expand "fix_trunc<mode>si2"
4262 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264 (clobber (reg:CC FLAGS_REG))])]
4265 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4268 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4273 if (SSE_FLOAT_MODE_P (<MODE>mode))
4275 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277 if (out != operands[0])
4278 emit_move_insn (operands[0], out);
4283 ;; Signed conversion to HImode.
4285 (define_expand "fix_trunc<mode>hi2"
4286 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288 (clobber (reg:CC FLAGS_REG))])]
4290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4294 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4299 ;; Unsigned conversion to SImode.
4301 (define_expand "fixuns_trunc<mode>si2"
4303 [(set (match_operand:SI 0 "register_operand" "")
4305 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4307 (clobber (match_scratch:<ssevecmode> 3 ""))
4308 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4311 enum machine_mode mode = <MODE>mode;
4312 enum machine_mode vecmode = <ssevecmode>mode;
4313 REAL_VALUE_TYPE TWO31r;
4316 if (optimize_insn_for_size_p ())
4319 real_ldexp (&TWO31r, &dconst1, 31);
4320 two31 = const_double_from_real_value (TWO31r, mode);
4321 two31 = ix86_build_const_vector (vecmode, true, two31);
4322 operands[2] = force_reg (vecmode, two31);
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4328 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4330 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333 && optimize_function_for_speed_p (cfun)"
4335 "&& reload_completed"
4338 ix86_split_convert_uns_si_sse (operands);
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4346 (define_expand "fixuns_trunc<mode>hi2"
4348 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349 (set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (subreg:HI (match_dup 2) 0))]
4351 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352 "operands[2] = gen_reg_rtx (SImode);")
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356 [(set (match_operand:DI 0 "register_operand" "=r,r")
4357 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "sseicvt")
4362 (set_attr "prefix" "maybe_vex")
4363 (set_attr "prefix_rex" "1")
4364 (set_attr "mode" "<MODE>")
4365 (set_attr "athlon_decode" "double,vector")
4366 (set_attr "amdfam10_decode" "double,double")
4367 (set_attr "bdver1_decode" "double,double")])
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "prefix" "maybe_vex")
4377 (set_attr "mode" "<MODE>")
4378 (set_attr "athlon_decode" "double,vector")
4379 (set_attr "amdfam10_decode" "double,double")
4380 (set_attr "bdver1_decode" "double,double")])
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (match_operand:MODEF 1 "memory_operand" ""))
4386 (set (match_operand:SWI48x 2 "register_operand" "")
4387 (fix:SWI48x (match_dup 0)))]
4388 "TARGET_SHORTEN_X87_SSE
4389 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390 && peep2_reg_dead_p (2, operands[0])"
4391 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4393 ;; Avoid vector decoded forms of the instruction.
4395 [(match_scratch:DF 2 "Y2")
4396 (set (match_operand:SWI48x 0 "register_operand" "")
4397 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4403 [(match_scratch:SF 2 "x")
4404 (set (match_operand:SWI48x 0 "register_operand" "")
4405 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407 [(set (match_dup 2) (match_dup 1))
4408 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4418 && can_create_pseudo_p ()"
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, true);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4465 [(set (match_operand:SWI248x 0 "register_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4470 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))])
4475 [(set (match_operand:SWI248x 0 "memory_operand" "")
4476 (fix:SWI248x (match_operand 1 "register_operand" "")))
4477 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478 (clobber (match_scratch 3 ""))]
4480 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481 (clobber (match_dup 3))])])
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490 (fix:SWI248x (match_operand 1 "register_operand" "")))
4491 (clobber (reg:CC FLAGS_REG))]
4492 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && can_create_pseudo_p ()"
4501 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4503 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505 if (memory_operand (operands[0], VOIDmode))
4506 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507 operands[2], operands[3]));
4510 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512 operands[2], operands[3],
4517 [(set_attr "type" "fistp")
4518 (set_attr "i387_cw" "trunc")
4519 (set_attr "mode" "<MODE>")])
4521 (define_insn "fix_truncdi_i387"
4522 [(set (match_operand:DI 0 "memory_operand" "=m")
4523 (fix:DI (match_operand 1 "register_operand" "f")))
4524 (use (match_operand:HI 2 "memory_operand" "m"))
4525 (use (match_operand:HI 3 "memory_operand" "m"))
4526 (clobber (match_scratch:XF 4 "=&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530 "* return output_fix_trunc (insn, operands, false);"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4535 (define_insn "fix_truncdi_i387_with_temp"
4536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:DI (match_operand 1 "register_operand" "f,f")))
4538 (use (match_operand:HI 2 "memory_operand" "m,m"))
4539 (use (match_operand:HI 3 "memory_operand" "m,m"))
4540 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "DI")])
4551 [(set (match_operand:DI 0 "register_operand" "")
4552 (fix:DI (match_operand 1 "register_operand" "")))
4553 (use (match_operand:HI 2 "memory_operand" ""))
4554 (use (match_operand:HI 3 "memory_operand" ""))
4555 (clobber (match_operand:DI 4 "memory_operand" ""))
4556 (clobber (match_scratch 5 ""))]
4558 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4561 (clobber (match_dup 5))])
4562 (set (match_dup 0) (match_dup 4))])
4565 [(set (match_operand:DI 0 "memory_operand" "")
4566 (fix:DI (match_operand 1 "register_operand" "")))
4567 (use (match_operand:HI 2 "memory_operand" ""))
4568 (use (match_operand:HI 3 "memory_operand" ""))
4569 (clobber (match_operand:DI 4 "memory_operand" ""))
4570 (clobber (match_scratch 5 ""))]
4572 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4575 (clobber (match_dup 5))])])
4577 (define_insn "fix_trunc<mode>_i387"
4578 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 "* return output_fix_trunc (insn, operands, false);"
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593 (use (match_operand:HI 2 "memory_operand" "m,m"))
4594 (use (match_operand:HI 3 "memory_operand" "m,m"))
4595 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "<MODE>")])
4605 [(set (match_operand:SWI24 0 "register_operand" "")
4606 (fix:SWI24 (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4611 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4613 (use (match_dup 3))])
4614 (set (match_dup 0) (match_dup 4))])
4617 [(set (match_operand:SWI24 0 "memory_operand" "")
4618 (fix:SWI24 (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4623 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4625 (use (match_dup 3))])])
4627 (define_insn "x86_fnstcw_1"
4628 [(set (match_operand:HI 0 "memory_operand" "=m")
4629 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4632 [(set (attr "length")
4633 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634 (set_attr "mode" "HI")
4635 (set_attr "unit" "i387")
4636 (set_attr "bdver1_decode" "vector")])
4638 (define_insn "x86_fldcw_1"
4639 [(set (reg:HI FPCR_REG)
4640 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4643 [(set (attr "length")
4644 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645 (set_attr "mode" "HI")
4646 (set_attr "unit" "i387")
4647 (set_attr "athlon_decode" "vector")
4648 (set_attr "amdfam10_decode" "vector")
4649 (set_attr "bdver1_decode" "vector")])
4651 ;; Conversion between fixed point and floating point.
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4656 (define_expand "floathi<mode>2"
4657 [(set (match_operand:X87MODEF 0 "register_operand" "")
4658 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661 || TARGET_MIX_SSE_I387)")
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665 [(set (match_operand:X87MODEF 0 "register_operand" "")
4666 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)
4670 && can_create_pseudo_p ()"
4673 [(parallel [(set (match_dup 0)
4674 (float:X87MODEF (match_dup 1)))
4675 (clobber (match_dup 2))])]
4676 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684 || TARGET_MIX_SSE_I387)"
4686 [(set_attr "type" "fmov,multi")
4687 (set_attr "mode" "<MODE>")
4688 (set_attr "unit" "*,i387")
4689 (set_attr "fp_int_src" "true")])
4691 (define_insn "*floathi<mode>2_i387"
4692 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696 || TARGET_MIX_SSE_I387)"
4698 [(set_attr "type" "fmov")
4699 (set_attr "mode" "<MODE>")
4700 (set_attr "fp_int_src" "true")])
4703 [(set (match_operand:X87MODEF 0 "register_operand" "")
4704 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705 (clobber (match_operand:HI 2 "memory_operand" ""))]
4707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708 || TARGET_MIX_SSE_I387)
4709 && reload_completed"
4710 [(set (match_dup 2) (match_dup 1))
4711 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716 (clobber (match_operand:HI 2 "memory_operand" ""))]
4718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719 || TARGET_MIX_SSE_I387)
4720 && reload_completed"
4721 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724 [(set (match_operand:X87MODEF 0 "register_operand" "")
4726 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4728 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4731 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4735 rtx reg = gen_reg_rtx (XFmode);
4736 rtx (*insn)(rtx, rtx);
4738 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4740 if (<X87MODEF:MODE>mode == SFmode)
4741 insn = gen_truncxfsf2;
4742 else if (<X87MODEF:MODE>mode == DFmode)
4743 insn = gen_truncxfdf2;
4747 emit_insn (insn (operands[0], reg));
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "")
4755 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4757 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387))
4761 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763 && ((<SWI48x:MODE>mode == SImode
4764 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765 && optimize_function_for_speed_p (cfun)
4766 && flag_trapping_math)
4767 || !(TARGET_INTER_UNIT_CONVERSIONS
4768 || optimize_function_for_size_p (cfun)))))
4769 && can_create_pseudo_p ()"
4772 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773 (clobber (match_dup 2))])]
4775 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4777 /* Avoid store forwarding (partial memory) stall penalty
4778 by passing DImode value through XMM registers. */
4779 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781 && optimize_function_for_speed_p (cfun))
4783 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4793 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4798 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800 (set_attr "unit" "*,i387,*,*,*")
4801 (set_attr "athlon_decode" "*,*,double,direct,double")
4802 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803 (set_attr "bdver1_decode" "*,*,double,direct,double")
4804 (set_attr "fp_int_src" "true")])
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4814 [(set_attr "type" "fmov,sseicvt")
4815 (set_attr "mode" "<MODE>,<ssevecmode>")
4816 (set_attr "unit" "i387,*")
4817 (set_attr "athlon_decode" "*,direct")
4818 (set_attr "amdfam10_decode" "*,double")
4819 (set_attr "bdver1_decode" "*,direct")
4820 (set_attr "fp_int_src" "true")])
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4825 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4830 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831 (set_attr "mode" "<MODEF:MODE>")
4832 (set_attr "unit" "*,i387,*,*")
4833 (set_attr "athlon_decode" "*,*,double,direct")
4834 (set_attr "amdfam10_decode" "*,*,vector,double")
4835 (set_attr "bdver1_decode" "*,*,double,direct")
4836 (set_attr "fp_int_src" "true")])
4839 [(set (match_operand:MODEF 0 "register_operand" "")
4840 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844 && TARGET_INTER_UNIT_CONVERSIONS
4846 && (SSE_REG_P (operands[0])
4847 || (GET_CODE (operands[0]) == SUBREG
4848 && SSE_REG_P (operands[0])))"
4849 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4852 [(set (match_operand:MODEF 0 "register_operand" "")
4853 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4859 && (SSE_REG_P (operands[0])
4860 || (GET_CODE (operands[0]) == SUBREG
4861 && SSE_REG_P (operands[0])))"
4862 [(set (match_dup 2) (match_dup 1))
4863 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4868 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876 [(set_attr "type" "fmov,sseicvt,sseicvt")
4877 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878 (set_attr "mode" "<MODEF:MODE>")
4879 (set (attr "prefix_rex")
4881 (and (eq_attr "prefix" "maybe_vex")
4882 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4884 (const_string "*")))
4885 (set_attr "unit" "i387,*,*")
4886 (set_attr "athlon_decode" "*,double,direct")
4887 (set_attr "amdfam10_decode" "*,vector,double")
4888 (set_attr "bdver1_decode" "*,double,direct")
4889 (set_attr "fp_int_src" "true")])
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4894 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4900 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901 [(set_attr "type" "fmov,sseicvt")
4902 (set_attr "prefix" "orig,maybe_vex")
4903 (set_attr "mode" "<MODEF:MODE>")
4904 (set (attr "prefix_rex")
4906 (and (eq_attr "prefix" "maybe_vex")
4907 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4909 (const_string "*")))
4910 (set_attr "athlon_decode" "*,direct")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "bdver1_decode" "*,direct")
4913 (set_attr "fp_int_src" "true")])
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4918 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920 "TARGET_SSE2 && TARGET_SSE_MATH
4921 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4923 [(set_attr "type" "sseicvt")
4924 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925 (set_attr "athlon_decode" "double,direct,double")
4926 (set_attr "amdfam10_decode" "vector,double,double")
4927 (set_attr "bdver1_decode" "double,direct,double")
4928 (set_attr "fp_int_src" "true")])
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931 [(set (match_operand:MODEF 0 "register_operand" "=x")
4932 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933 "TARGET_SSE2 && TARGET_SSE_MATH
4934 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4936 [(set_attr "type" "sseicvt")
4937 (set_attr "mode" "<MODE>")
4938 (set_attr "athlon_decode" "direct")
4939 (set_attr "amdfam10_decode" "double")
4940 (set_attr "bdver1_decode" "direct")
4941 (set_attr "fp_int_src" "true")])
4944 [(set (match_operand:MODEF 0 "register_operand" "")
4945 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946 (clobber (match_operand:SI 2 "memory_operand" ""))]
4947 "TARGET_SSE2 && TARGET_SSE_MATH
4948 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (operands[0])))"
4955 rtx op1 = operands[1];
4957 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4959 if (GET_CODE (op1) == SUBREG)
4960 op1 = SUBREG_REG (op1);
4962 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[1]));
4968 /* We can ignore possible trapping value in the
4969 high part of SSE register for non-trapping math. */
4970 else if (SSE_REG_P (op1) && !flag_trapping_math)
4971 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4974 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975 emit_move_insn (operands[2], operands[1]);
4976 emit_insn (gen_sse2_loadld (operands[4],
4977 CONST0_RTX (V4SImode), operands[2]));
4980 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4985 [(set (match_operand:MODEF 0 "register_operand" "")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987 (clobber (match_operand:SI 2 "memory_operand" ""))]
4988 "TARGET_SSE2 && TARGET_SSE_MATH
4989 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4996 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4998 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000 emit_insn (gen_sse2_loadld (operands[4],
5001 CONST0_RTX (V4SImode), operands[1]));
5003 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5008 [(set (match_operand:MODEF 0 "register_operand" "")
5009 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5013 && (SSE_REG_P (operands[0])
5014 || (GET_CODE (operands[0]) == SUBREG
5015 && SSE_REG_P (operands[0])))"
5018 rtx op1 = operands[1];
5020 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5022 if (GET_CODE (op1) == SUBREG)
5023 op1 = SUBREG_REG (op1);
5025 if (GENERAL_REG_P (op1))
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 if (TARGET_INTER_UNIT_MOVES)
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5033 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5035 emit_insn (gen_sse2_loadld (operands[4],
5036 CONST0_RTX (V4SImode), operands[5]));
5037 ix86_free_from_memory (GET_MODE (operands[1]));
5040 /* We can ignore possible trapping value in the
5041 high part of SSE register for non-trapping math. */
5042 else if (SSE_REG_P (op1) && !flag_trapping_math)
5043 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5052 [(set (match_operand:MODEF 0 "register_operand" "")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (operands[0])))"
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5069 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5076 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5081 [(set_attr "type" "sseicvt")
5082 (set_attr "mode" "<MODEF:MODE>")
5083 (set_attr "athlon_decode" "double,direct")
5084 (set_attr "amdfam10_decode" "vector,double")
5085 (set_attr "bdver1_decode" "double,direct")
5086 (set_attr "fp_int_src" "true")])
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5091 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096 [(set_attr "type" "sseicvt")
5097 (set_attr "prefix" "maybe_vex")
5098 (set_attr "mode" "<MODEF:MODE>")
5099 (set (attr "prefix_rex")
5101 (and (eq_attr "prefix" "maybe_vex")
5102 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5104 (const_string "*")))
5105 (set_attr "athlon_decode" "double,direct")
5106 (set_attr "amdfam10_decode" "vector,double")
5107 (set_attr "bdver1_decode" "double,direct")
5108 (set_attr "fp_int_src" "true")])
5111 [(set (match_operand:MODEF 0 "register_operand" "")
5112 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (operands[0])))"
5121 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x")
5126 (match_operand:SWI48x 1 "memory_operand" "m")))]
5127 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "prefix" "maybe_vex")
5133 (set_attr "mode" "<MODEF:MODE>")
5134 (set (attr "prefix_rex")
5136 (and (eq_attr "prefix" "maybe_vex")
5137 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5139 (const_string "*")))
5140 (set_attr "athlon_decode" "direct")
5141 (set_attr "amdfam10_decode" "double")
5142 (set_attr "bdver1_decode" "direct")
5143 (set_attr "fp_int_src" "true")])
5146 [(set (match_operand:MODEF 0 "register_operand" "")
5147 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5156 [(set (match_dup 2) (match_dup 1))
5157 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5169 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5177 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5181 [(set_attr "type" "fmov,multi")
5182 (set_attr "mode" "<X87MODEF:MODE>")
5183 (set_attr "unit" "*,i387")
5184 (set_attr "fp_int_src" "true")])
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5189 (match_operand:SWI48x 1 "memory_operand" "m")))]
5191 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5193 [(set_attr "type" "fmov")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203 && reload_completed"
5204 [(set (match_dup 2) (match_dup 1))
5205 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5208 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213 && reload_completed"
5214 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers. */
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5222 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223 (clobber (match_scratch:V4SI 3 "=X,x"))
5224 (clobber (match_scratch:V4SI 4 "=X,x"))
5225 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5230 [(set_attr "type" "multi")
5231 (set_attr "mode" "<X87MODEF:MODE>")
5232 (set_attr "unit" "i387")
5233 (set_attr "fp_int_src" "true")])
5236 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238 (clobber (match_scratch:V4SI 3 ""))
5239 (clobber (match_scratch:V4SI 4 ""))
5240 (clobber (match_operand:DI 2 "memory_operand" ""))]
5241 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 3))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5248 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249 Assemble the 64-bit DImode value in an xmm register. */
5250 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 0)));
5252 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253 gen_rtx_SUBREG (SImode, operands[1], 4)));
5254 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5257 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5261 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263 (clobber (match_scratch:V4SI 3 ""))
5264 (clobber (match_scratch:V4SI 4 ""))
5265 (clobber (match_operand:DI 2 "memory_operand" ""))]
5266 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269 && reload_completed"
5270 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5278 (define_insn "*floatunssi<mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280 (unsigned_float:X87MODEF
5281 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283 (clobber (match_scratch:SI 3 "=X,x"))]
5285 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5288 [(set_attr "type" "multi")
5289 (set_attr "mode" "<MODE>")])
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (unsigned_float:X87MODEF
5294 (match_operand:SI 1 "register_operand" "")))
5295 (clobber (match_operand:DI 2 "memory_operand" ""))
5296 (clobber (match_scratch:SI 3 ""))]
5298 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 && reload_completed"
5301 [(set (match_dup 2) (match_dup 1))
5303 (float:X87MODEF (match_dup 2)))]
5304 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5307 [(set (match_operand:X87MODEF 0 "register_operand" "")
5308 (unsigned_float:X87MODEF
5309 (match_operand:SI 1 "memory_operand" "")))
5310 (clobber (match_operand:DI 2 "memory_operand" ""))
5311 (clobber (match_scratch:SI 3 ""))]
5313 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5315 && reload_completed"
5316 [(set (match_dup 2) (match_dup 3))
5318 (float:X87MODEF (match_dup 2)))]
5320 emit_move_insn (operands[3], operands[1]);
5321 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5324 (define_expand "floatunssi<mode>2"
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "nonimmediate_operand" "")))
5329 (clobber (match_dup 2))
5330 (clobber (match_scratch:SI 3 ""))])]
5332 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5334 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5338 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5343 enum ix86_stack_slot slot = (virtuals_instantiated
5346 operands[2] = assign_386_stack_local (DImode, slot);
5350 (define_expand "floatunsdisf2"
5351 [(use (match_operand:SF 0 "register_operand" ""))
5352 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353 "TARGET_64BIT && TARGET_SSE_MATH"
5354 "x86_emit_floatuns (operands); DONE;")
5356 (define_expand "floatunsdidf2"
5357 [(use (match_operand:DF 0 "register_operand" ""))
5358 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360 && TARGET_SSE2 && TARGET_SSE_MATH"
5363 x86_emit_floatuns (operands);
5365 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5371 (define_expand "add<mode>3"
5372 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374 (match_operand:SDWIM 2 "<general_operand>" "")))]
5376 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5381 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383 (clobber (reg:CC FLAGS_REG))]
5384 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5387 [(parallel [(set (reg:CC FLAGS_REG)
5388 (unspec:CC [(match_dup 1) (match_dup 2)]
5391 (plus:DWIH (match_dup 1) (match_dup 2)))])
5392 (parallel [(set (match_dup 3)
5396 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5398 (clobber (reg:CC FLAGS_REG))])]
5399 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5401 (define_insn "*add<mode>3_cc"
5402 [(set (reg:CC FLAGS_REG)
5404 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5407 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411 [(set_attr "type" "alu")
5412 (set_attr "mode" "<MODE>")])
5414 (define_insn "addqi3_cc"
5415 [(set (reg:CC FLAGS_REG)
5417 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:QI 2 "general_operand" "qn,qm")]
5420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421 (plus:QI (match_dup 1) (match_dup 2)))]
5422 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423 "add{b}\t{%2, %0|%0, %2}"
5424 [(set_attr "type" "alu")
5425 (set_attr "mode" "QI")])
5427 (define_insn "*lea_1"
5428 [(set (match_operand:P 0 "register_operand" "=r")
5429 (match_operand:P 1 "no_seg_address_operand" "p"))]
5431 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432 [(set_attr "type" "lea")
5433 (set_attr "mode" "<MODE>")])
5435 (define_insn "*lea_2"
5436 [(set (match_operand:SI 0 "register_operand" "=r")
5437 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5439 "lea{l}\t{%a1, %0|%0, %a1}"
5440 [(set_attr "type" "lea")
5441 (set_attr "mode" "SI")])
5443 (define_insn "*lea_2_zext"
5444 [(set (match_operand:DI 0 "register_operand" "=r")
5446 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5448 "lea{l}\t{%a1, %k0|%k0, %a1}"
5449 [(set_attr "type" "lea")
5450 (set_attr "mode" "SI")])
5452 (define_insn "*add<mode>_1"
5453 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5455 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5456 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5457 (clobber (reg:CC FLAGS_REG))]
5458 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5460 switch (get_attr_type (insn))
5466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5467 if (operands[2] == const1_rtx)
5468 return "inc{<imodesuffix>}\t%0";
5471 gcc_assert (operands[2] == constm1_rtx);
5472 return "dec{<imodesuffix>}\t%0";
5476 /* For most processors, ADD is faster than LEA. This alternative
5477 was added to use ADD as much as possible. */
5478 if (which_alternative == 2)
5481 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5485 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5486 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5488 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5492 (cond [(eq_attr "alternative" "3")
5493 (const_string "lea")
5494 (match_operand:SWI48 2 "incdec_operand" "")
5495 (const_string "incdec")
5497 (const_string "alu")))
5498 (set (attr "length_immediate")
5500 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5502 (const_string "*")))
5503 (set_attr "mode" "<MODE>")])
5505 ;; It may seem that nonimmediate operand is proper one for operand 1.
5506 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5507 ;; we take care in ix86_binary_operator_ok to not allow two memory
5508 ;; operands so proper swapping will be done in reload. This allow
5509 ;; patterns constructed from addsi_1 to match.
5511 (define_insn "*addsi_1_zext"
5512 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5514 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5515 (match_operand:SI 2 "general_operand" "g,0,li"))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5519 switch (get_attr_type (insn))
5525 if (operands[2] == const1_rtx)
5526 return "inc{l}\t%k0";
5529 gcc_assert (operands[2] == constm1_rtx);
5530 return "dec{l}\t%k0";
5534 /* For most processors, ADD is faster than LEA. This alternative
5535 was added to use ADD as much as possible. */
5536 if (which_alternative == 1)
5539 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5542 if (x86_maybe_negate_const_int (&operands[2], SImode))
5543 return "sub{l}\t{%2, %k0|%k0, %2}";
5545 return "add{l}\t{%2, %k0|%k0, %2}";
5549 (cond [(eq_attr "alternative" "2")
5550 (const_string "lea")
5551 (match_operand:SI 2 "incdec_operand" "")
5552 (const_string "incdec")
5554 (const_string "alu")))
5555 (set (attr "length_immediate")
5557 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5559 (const_string "*")))
5560 (set_attr "mode" "SI")])
5562 (define_insn "*addhi_1"
5563 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5564 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5565 (match_operand:HI 2 "general_operand" "rn,rm")))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_PARTIAL_REG_STALL
5568 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5570 switch (get_attr_type (insn))
5573 if (operands[2] == const1_rtx)
5574 return "inc{w}\t%0";
5577 gcc_assert (operands[2] == constm1_rtx);
5578 return "dec{w}\t%0";
5582 if (x86_maybe_negate_const_int (&operands[2], HImode))
5583 return "sub{w}\t{%2, %0|%0, %2}";
5585 return "add{w}\t{%2, %0|%0, %2}";
5589 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set (attr "length_immediate")
5594 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5596 (const_string "*")))
5597 (set_attr "mode" "HI")])
5599 (define_insn "*addhi_1_lea"
5600 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5601 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5602 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "!TARGET_PARTIAL_REG_STALL
5605 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5607 switch (get_attr_type (insn))
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{w}\t%0";
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{w}\t%0";
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], HImode))
5633 return "sub{w}\t{%2, %0|%0, %2}";
5635 return "add{w}\t{%2, %0|%0, %2}";
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:HI 2 "incdec_operand" "")
5642 (const_string "incdec")
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5649 (const_string "*")))
5650 (set_attr "mode" "HI,HI,HI,SI")])
5652 ;; %%% Potential partial reg stall on alternative 2. What to do?
5653 (define_insn "*addqi_1"
5654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5655 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5656 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5657 (clobber (reg:CC FLAGS_REG))]
5658 "TARGET_PARTIAL_REG_STALL
5659 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5661 int widen = (which_alternative == 2);
5662 switch (get_attr_type (insn))
5665 if (operands[2] == const1_rtx)
5666 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5674 if (x86_maybe_negate_const_int (&operands[2], QImode))
5677 return "sub{l}\t{%2, %k0|%k0, %2}";
5679 return "sub{b}\t{%2, %0|%0, %2}";
5682 return "add{l}\t{%k2, %k0|%k0, %k2}";
5684 return "add{b}\t{%2, %0|%0, %2}";
5688 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5689 (const_string "incdec")
5690 (const_string "alu")))
5691 (set (attr "length_immediate")
5693 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5695 (const_string "*")))
5696 (set_attr "mode" "QI,QI,SI")])
5698 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5699 (define_insn "*addqi_1_lea"
5700 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5701 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5702 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5703 (clobber (reg:CC FLAGS_REG))]
5704 "!TARGET_PARTIAL_REG_STALL
5705 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5707 int widen = (which_alternative == 3 || which_alternative == 4);
5709 switch (get_attr_type (insn))
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (operands[2] == const1_rtx)
5717 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5720 gcc_assert (operands[2] == constm1_rtx);
5721 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5725 /* For most processors, ADD is faster than LEA. These alternatives
5726 were added to use ADD as much as possible. */
5727 if (which_alternative == 2 || which_alternative == 4)
5730 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 if (x86_maybe_negate_const_int (&operands[2], QImode))
5737 return "sub{l}\t{%2, %k0|%k0, %2}";
5739 return "sub{b}\t{%2, %0|%0, %2}";
5742 return "add{l}\t{%k2, %k0|%k0, %k2}";
5744 return "add{b}\t{%2, %0|%0, %2}";
5748 (cond [(eq_attr "alternative" "5")
5749 (const_string "lea")
5750 (match_operand:QI 2 "incdec_operand" "")
5751 (const_string "incdec")
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5758 (const_string "*")))
5759 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5761 (define_insn "*addqi_1_slp"
5762 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5763 (plus:QI (match_dup 0)
5764 (match_operand:QI 1 "general_operand" "qn,qnm")))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5769 switch (get_attr_type (insn))
5772 if (operands[1] == const1_rtx)
5773 return "inc{b}\t%0";
5776 gcc_assert (operands[1] == constm1_rtx);
5777 return "dec{b}\t%0";
5781 if (x86_maybe_negate_const_int (&operands[1], QImode))
5782 return "sub{b}\t{%1, %0|%0, %1}";
5784 return "add{b}\t{%1, %0|%0, %1}";
5788 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5789 (const_string "incdec")
5790 (const_string "alu1")))
5791 (set (attr "memory")
5792 (if_then_else (match_operand 1 "memory_operand" "")
5793 (const_string "load")
5794 (const_string "none")))
5795 (set_attr "mode" "QI")])
5797 ;; Convert lea to the lea pattern to avoid flags dependency.
5799 [(set (match_operand 0 "register_operand" "")
5800 (plus (match_operand 1 "register_operand" "")
5801 (match_operand 2 "nonmemory_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5807 enum machine_mode mode = GET_MODE (operands[0]);
5809 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5810 may confuse gen_lowpart. */
5813 operands[1] = gen_lowpart (Pmode, operands[1]);
5814 operands[2] = gen_lowpart (Pmode, operands[2]);
5817 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5819 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5820 operands[0] = gen_lowpart (SImode, operands[0]);
5822 if (TARGET_64BIT && mode != Pmode)
5823 pat = gen_rtx_SUBREG (SImode, pat, 0);
5825 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5829 ;; Convert lea to the lea pattern to avoid flags dependency.
5830 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5831 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5833 [(set (match_operand:DI 0 "register_operand" "")
5834 (plus:DI (match_operand:DI 1 "register_operand" "")
5835 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 "TARGET_64BIT && reload_completed
5838 && true_regnum (operands[0]) != true_regnum (operands[1])"
5840 (plus:DI (match_dup 1) (match_dup 2)))])
5842 ;; Convert lea to the lea pattern to avoid flags dependency.
5844 [(set (match_operand:DI 0 "register_operand" "")
5846 (plus:SI (match_operand:SI 1 "register_operand" "")
5847 (match_operand:SI 2 "nonmemory_operand" ""))))
5848 (clobber (reg:CC FLAGS_REG))]
5849 "TARGET_64BIT && reload_completed
5850 && ix86_lea_for_add_ok (insn, operands)"
5852 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5854 operands[1] = gen_lowpart (DImode, operands[1]);
5855 operands[2] = gen_lowpart (DImode, operands[2]);
5858 (define_insn "*add<mode>_2"
5859 [(set (reg FLAGS_REG)
5862 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5863 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5865 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5866 (plus:SWI (match_dup 1) (match_dup 2)))]
5867 "ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{<imodesuffix>}\t%0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{<imodesuffix>}\t%0";
5882 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5883 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5885 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5889 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5890 (const_string "incdec")
5891 (const_string "alu")))
5892 (set (attr "length_immediate")
5894 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5896 (const_string "*")))
5897 (set_attr "mode" "<MODE>")])
5899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5900 (define_insn "*addsi_2_zext"
5901 [(set (reg FLAGS_REG)
5903 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5904 (match_operand:SI 2 "general_operand" "g"))
5906 (set (match_operand:DI 0 "register_operand" "=r")
5907 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5908 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5909 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5911 switch (get_attr_type (insn))
5914 if (operands[2] == const1_rtx)
5915 return "inc{l}\t%k0";
5918 gcc_assert (operands[2] == constm1_rtx);
5919 return "dec{l}\t%k0";
5923 if (x86_maybe_negate_const_int (&operands[2], SImode))
5924 return "sub{l}\t{%2, %k0|%k0, %2}";
5926 return "add{l}\t{%2, %k0|%k0, %2}";
5930 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5931 (const_string "incdec")
5932 (const_string "alu")))
5933 (set (attr "length_immediate")
5935 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5937 (const_string "*")))
5938 (set_attr "mode" "SI")])
5940 (define_insn "*add<mode>_3"
5941 [(set (reg FLAGS_REG)
5943 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5944 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5945 (clobber (match_scratch:SWI 0 "=<r>"))]
5946 "ix86_match_ccmode (insn, CCZmode)
5947 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5949 switch (get_attr_type (insn))
5952 if (operands[2] == const1_rtx)
5953 return "inc{<imodesuffix>}\t%0";
5956 gcc_assert (operands[2] == constm1_rtx);
5957 return "dec{<imodesuffix>}\t%0";
5961 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5962 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5964 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5968 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set (attr "length_immediate")
5973 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5975 (const_string "*")))
5976 (set_attr "mode" "<MODE>")])
5978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5979 (define_insn "*addsi_3_zext"
5980 [(set (reg FLAGS_REG)
5982 (neg:SI (match_operand:SI 2 "general_operand" "g"))
5983 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5984 (set (match_operand:DI 0 "register_operand" "=r")
5985 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5986 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5987 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == const1_rtx)
5993 return "inc{l}\t%k0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{l}\t%k0";
6001 if (x86_maybe_negate_const_int (&operands[2], SImode))
6002 return "sub{l}\t{%2, %k0|%k0, %2}";
6004 return "add{l}\t{%2, %k0|%k0, %2}";
6008 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set (attr "length_immediate")
6013 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6015 (const_string "*")))
6016 (set_attr "mode" "SI")])
6018 ; For comparisons against 1, -1 and 128, we may generate better code
6019 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6020 ; is matched then. We can't accept general immediate, because for
6021 ; case of overflows, the result is messed up.
6022 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6023 ; only for comparisons not depending on it.
6025 (define_insn "*adddi_4"
6026 [(set (reg FLAGS_REG)
6028 (match_operand:DI 1 "nonimmediate_operand" "0")
6029 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6030 (clobber (match_scratch:DI 0 "=rm"))]
6032 && ix86_match_ccmode (insn, CCGCmode)"
6034 switch (get_attr_type (insn))
6037 if (operands[2] == constm1_rtx)
6038 return "inc{q}\t%0";
6041 gcc_assert (operands[2] == const1_rtx);
6042 return "dec{q}\t%0";
6046 if (x86_maybe_negate_const_int (&operands[2], DImode))
6047 return "add{q}\t{%2, %0|%0, %2}";
6049 return "sub{q}\t{%2, %0|%0, %2}";
6053 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6054 (const_string "incdec")
6055 (const_string "alu")))
6056 (set (attr "length_immediate")
6058 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6060 (const_string "*")))
6061 (set_attr "mode" "DI")])
6063 ; For comparisons against 1, -1 and 128, we may generate better code
6064 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6065 ; is matched then. We can't accept general immediate, because for
6066 ; case of overflows, the result is messed up.
6067 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6068 ; only for comparisons not depending on it.
6070 (define_insn "*add<mode>_4"
6071 [(set (reg FLAGS_REG)
6073 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6074 (match_operand:SWI124 2 "const_int_operand" "n")))
6075 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6076 "ix86_match_ccmode (insn, CCGCmode)"
6078 switch (get_attr_type (insn))
6081 if (operands[2] == constm1_rtx)
6082 return "inc{<imodesuffix>}\t%0";
6085 gcc_assert (operands[2] == const1_rtx);
6086 return "dec{<imodesuffix>}\t%0";
6090 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6091 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6093 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6097 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6098 (const_string "incdec")
6099 (const_string "alu")))
6100 (set (attr "length_immediate")
6102 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6104 (const_string "*")))
6105 (set_attr "mode" "<MODE>")])
6107 (define_insn "*add<mode>_5"
6108 [(set (reg FLAGS_REG)
6111 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6112 (match_operand:SWI 2 "<general_operand>" "<g>"))
6114 (clobber (match_scratch:SWI 0 "=<r>"))]
6115 "ix86_match_ccmode (insn, CCGOCmode)
6116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6118 switch (get_attr_type (insn))
6121 if (operands[2] == const1_rtx)
6122 return "inc{<imodesuffix>}\t%0";
6125 gcc_assert (operands[2] == constm1_rtx);
6126 return "dec{<imodesuffix>}\t%0";
6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138 (const_string "incdec")
6139 (const_string "alu")))
6140 (set (attr "length_immediate")
6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144 (const_string "*")))
6145 (set_attr "mode" "<MODE>")])
6147 (define_insn "*addqi_ext_1_rex64"
6148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6153 (match_operand 1 "ext_register_operand" "0")
6156 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157 (clobber (reg:CC FLAGS_REG))]
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{b}\t%h0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{b}\t%h0";
6172 return "add{b}\t{%2, %h0|%h0, %2}";
6176 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "modrm" "1")
6180 (set_attr "mode" "QI")])
6182 (define_insn "addqi_ext_1"
6183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6188 (match_operand 1 "ext_register_operand" "0")
6191 (match_operand:QI 2 "general_operand" "Qmn")))
6192 (clobber (reg:CC FLAGS_REG))]
6195 switch (get_attr_type (insn))
6198 if (operands[2] == const1_rtx)
6199 return "inc{b}\t%h0";
6202 gcc_assert (operands[2] == constm1_rtx);
6203 return "dec{b}\t%h0";
6207 return "add{b}\t{%2, %h0|%h0, %2}";
6211 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set_attr "modrm" "1")
6215 (set_attr "mode" "QI")])
6217 (define_insn "*addqi_ext_2"
6218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6223 (match_operand 1 "ext_register_operand" "%0")
6227 (match_operand 2 "ext_register_operand" "Q")
6230 (clobber (reg:CC FLAGS_REG))]
6232 "add{b}\t{%h2, %h0|%h0, %h2}"
6233 [(set_attr "type" "alu")
6234 (set_attr "mode" "QI")])
6236 ;; The lea patterns for non-Pmodes needs to be matched by
6237 ;; several insns converted to real lea by splitters.
6239 (define_insn_and_split "*lea_general_1"
6240 [(set (match_operand 0 "register_operand" "=r")
6241 (plus (plus (match_operand 1 "index_register_operand" "l")
6242 (match_operand 2 "register_operand" "r"))
6243 (match_operand 3 "immediate_operand" "i")))]
6244 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6245 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6246 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6247 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6248 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6249 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6250 || GET_MODE (operands[3]) == VOIDmode)"
6252 "&& reload_completed"
6256 operands[0] = gen_lowpart (SImode, operands[0]);
6257 operands[1] = gen_lowpart (Pmode, operands[1]);
6258 operands[2] = gen_lowpart (Pmode, operands[2]);
6259 operands[3] = gen_lowpart (Pmode, operands[3]);
6260 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6262 if (Pmode != SImode)
6263 pat = gen_rtx_SUBREG (SImode, pat, 0);
6264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6267 [(set_attr "type" "lea")
6268 (set_attr "mode" "SI")])
6270 (define_insn_and_split "*lea_general_1_zext"
6271 [(set (match_operand:DI 0 "register_operand" "=r")
6274 (match_operand:SI 1 "index_register_operand" "l")
6275 (match_operand:SI 2 "register_operand" "r"))
6276 (match_operand:SI 3 "immediate_operand" "i"))))]
6279 "&& reload_completed"
6281 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6283 (match_dup 3)) 0)))]
6285 operands[1] = gen_lowpart (Pmode, operands[1]);
6286 operands[2] = gen_lowpart (Pmode, operands[2]);
6287 operands[3] = gen_lowpart (Pmode, operands[3]);
6289 [(set_attr "type" "lea")
6290 (set_attr "mode" "SI")])
6292 (define_insn_and_split "*lea_general_2"
6293 [(set (match_operand 0 "register_operand" "=r")
6294 (plus (mult (match_operand 1 "index_register_operand" "l")
6295 (match_operand 2 "const248_operand" "i"))
6296 (match_operand 3 "nonmemory_operand" "ri")))]
6297 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6298 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6299 && (!TARGET_PARTIAL_REG_STALL
6300 || GET_MODE (operands[0]) == SImode
6301 || optimize_function_for_size_p (cfun))
6302 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6303 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6304 || GET_MODE (operands[3]) == VOIDmode)"
6306 "&& reload_completed"
6310 operands[0] = gen_lowpart (SImode, operands[0]);
6311 operands[1] = gen_lowpart (Pmode, operands[1]);
6312 operands[3] = gen_lowpart (Pmode, operands[3]);
6313 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6315 if (Pmode != SImode)
6316 pat = gen_rtx_SUBREG (SImode, pat, 0);
6317 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6320 [(set_attr "type" "lea")
6321 (set_attr "mode" "SI")])
6323 (define_insn_and_split "*lea_general_2_zext"
6324 [(set (match_operand:DI 0 "register_operand" "=r")
6327 (match_operand:SI 1 "index_register_operand" "l")
6328 (match_operand:SI 2 "const248_operand" "n"))
6329 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6332 "&& reload_completed"
6334 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6336 (match_dup 3)) 0)))]
6338 operands[1] = gen_lowpart (Pmode, operands[1]);
6339 operands[3] = gen_lowpart (Pmode, operands[3]);
6341 [(set_attr "type" "lea")
6342 (set_attr "mode" "SI")])
6344 (define_insn_and_split "*lea_general_3"
6345 [(set (match_operand 0 "register_operand" "=r")
6346 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6347 (match_operand 2 "const248_operand" "i"))
6348 (match_operand 3 "register_operand" "r"))
6349 (match_operand 4 "immediate_operand" "i")))]
6350 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6351 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6352 && (!TARGET_PARTIAL_REG_STALL
6353 || GET_MODE (operands[0]) == SImode
6354 || optimize_function_for_size_p (cfun))
6355 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6356 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6358 "&& reload_completed"
6362 operands[0] = gen_lowpart (SImode, operands[0]);
6363 operands[1] = gen_lowpart (Pmode, operands[1]);
6364 operands[3] = gen_lowpart (Pmode, operands[3]);
6365 operands[4] = gen_lowpart (Pmode, operands[4]);
6366 pat = gen_rtx_PLUS (Pmode,
6367 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6371 if (Pmode != SImode)
6372 pat = gen_rtx_SUBREG (SImode, pat, 0);
6373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6376 [(set_attr "type" "lea")
6377 (set_attr "mode" "SI")])
6379 (define_insn_and_split "*lea_general_3_zext"
6380 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (match_operand:SI 1 "index_register_operand" "l")
6385 (match_operand:SI 2 "const248_operand" "n"))
6386 (match_operand:SI 3 "register_operand" "r"))
6387 (match_operand:SI 4 "immediate_operand" "i"))))]
6390 "&& reload_completed"
6392 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6395 (match_dup 4)) 0)))]
6397 operands[1] = gen_lowpart (Pmode, operands[1]);
6398 operands[3] = gen_lowpart (Pmode, operands[3]);
6399 operands[4] = gen_lowpart (Pmode, operands[4]);
6401 [(set_attr "type" "lea")
6402 (set_attr "mode" "SI")])
6404 (define_insn_and_split "*lea_general_4"
6405 [(set (match_operand:SWI 0 "register_operand" "=r")
6406 (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6407 (match_operand:SWI 2 "const_int_operand" "n"))
6408 (match_operand 3 "const_int_operand" "n")))]
6409 "(<MODE>mode == DImode
6410 || <MODE>mode == SImode
6411 || !TARGET_PARTIAL_REG_STALL
6412 || optimize_function_for_size_p (cfun))
6413 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6414 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6415 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6417 "&& reload_completed"
6421 if (<MODE>mode != DImode)
6422 operands[0] = gen_lowpart (SImode, operands[0]);
6423 operands[1] = gen_lowpart (Pmode, operands[1]);
6424 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425 pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6427 if (Pmode != SImode && <MODE>mode != DImode)
6428 pat = gen_rtx_SUBREG (SImode, pat, 0);
6429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6432 [(set_attr "type" "lea")
6434 (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6436 (const_string "DI")))])
6438 ;; Subtract instructions
6440 (define_expand "sub<mode>3"
6441 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6442 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6443 (match_operand:SDWIM 2 "<general_operand>" "")))]
6445 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6447 (define_insn_and_split "*sub<dwi>3_doubleword"
6448 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6450 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6451 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6456 [(parallel [(set (reg:CC FLAGS_REG)
6457 (compare:CC (match_dup 1) (match_dup 2)))
6459 (minus:DWIH (match_dup 1) (match_dup 2)))])
6460 (parallel [(set (match_dup 3)
6464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6469 (define_insn "*sub<mode>_1"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6476 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "mode" "<MODE>")])
6480 (define_insn "*subsi_1_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (match_operand:SI 2 "general_operand" "g"))))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6487 "sub{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "SI")])
6491 (define_insn "*subqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (minus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qm")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6498 "sub{b}\t{%1, %0|%0, %1}"
6499 [(set_attr "type" "alu1")
6500 (set_attr "mode" "QI")])
6502 (define_insn "*sub<mode>_2"
6503 [(set (reg FLAGS_REG)
6506 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6509 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (minus:SWI (match_dup 1) (match_dup 2)))]
6511 "ix86_match_ccmode (insn, CCGOCmode)
6512 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*subsi_2_zext"
6518 [(set (reg FLAGS_REG)
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "general_operand" "g"))
6523 (set (match_operand:DI 0 "register_operand" "=r")
6525 (minus:SI (match_dup 1)
6527 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6528 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %k0|%k0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6533 (define_insn "*sub<mode>_3"
6534 [(set (reg FLAGS_REG)
6535 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6538 (minus:SWI (match_dup 1) (match_dup 2)))]
6539 "ix86_match_ccmode (insn, CCmode)
6540 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6541 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "<MODE>")])
6545 (define_insn "*subsi_3_zext"
6546 [(set (reg FLAGS_REG)
6547 (compare (match_operand:SI 1 "register_operand" "0")
6548 (match_operand:SI 2 "general_operand" "g")))
6549 (set (match_operand:DI 0 "register_operand" "=r")
6551 (minus:SI (match_dup 1)
6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555 "sub{l}\t{%2, %1|%1, %2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "SI")])
6559 ;; Add with carry and subtract with borrow
6561 (define_expand "<plusminus_insn><mode>3_carry"
6563 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6565 (match_operand:SWI 1 "nonimmediate_operand" "")
6566 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6567 [(match_operand 3 "flags_reg_operand" "")
6569 (match_operand:SWI 2 "<general_operand>" ""))))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6573 (define_insn "*<plusminus_insn><mode>3_carry"
6574 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6578 (match_operator 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)])
6580 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "<MODE>")])
6589 (define_insn "*addsi3_carry_zext"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6593 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SI 2 "general_operand" "g")))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6604 (define_insn "*subsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (minus:SI (match_operand:SI 1 "register_operand" "0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "general_operand" "g")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6613 "sbb{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "SI")])
6618 ;; Overflow setting add and subtract instructions
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6633 (define_insn "*sub<mode>3_cconly_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6637 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6638 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6641 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6642 [(set_attr "type" "icmp")
6643 (set_attr "mode" "<MODE>")])
6645 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6646 [(set (reg:CCC FLAGS_REG)
6649 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6650 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6654 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6655 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "<MODE>")])
6659 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6660 [(set (reg:CCC FLAGS_REG)
6663 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6664 (match_operand:SI 2 "general_operand" "g"))
6666 (set (match_operand:DI 0 "register_operand" "=r")
6667 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6668 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6669 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6673 ;; The patterns that match these are at the end of this file.
6675 (define_expand "<plusminus_insn>xf3"
6676 [(set (match_operand:XF 0 "register_operand" "")
6678 (match_operand:XF 1 "register_operand" "")
6679 (match_operand:XF 2 "register_operand" "")))]
6682 (define_expand "<plusminus_insn><mode>3"
6683 [(set (match_operand:MODEF 0 "register_operand" "")
6685 (match_operand:MODEF 1 "register_operand" "")
6686 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6690 ;; Multiply instructions
6692 (define_expand "mul<mode>3"
6693 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6695 (match_operand:SWIM248 1 "register_operand" "")
6696 (match_operand:SWIM248 2 "<general_operand>" "")))
6697 (clobber (reg:CC FLAGS_REG))])])
6699 (define_expand "mulqi3"
6700 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6702 (match_operand:QI 1 "register_operand" "")
6703 (match_operand:QI 2 "nonimmediate_operand" "")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_QIMODE_MATH")
6708 ;; IMUL reg32/64, reg32/64, imm8 Direct
6709 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6710 ;; IMUL reg32/64, reg32/64, imm32 Direct
6711 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6712 ;; IMUL reg32/64, reg32/64 Direct
6713 ;; IMUL reg32/64, mem32/64 Direct
6715 ;; On BDVER1, all above IMULs use DirectPath
6717 (define_insn "*mul<mode>3_1"
6718 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6720 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6721 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6728 [(set_attr "type" "imul")
6729 (set_attr "prefix_0f" "0,0,1")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (eq_attr "alternative" "1")
6734 (const_string "vector")
6735 (and (eq_attr "alternative" "2")
6736 (match_operand 1 "memory_operand" ""))
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set (attr "amdfam10_decode")
6740 (cond [(and (eq_attr "alternative" "0,1")
6741 (match_operand 1 "memory_operand" ""))
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "<MODE>")])
6747 (define_insn "*mulsi3_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6750 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6752 (clobber (reg:CC FLAGS_REG))]
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "imul")
6760 (set_attr "prefix_0f" "0,0,1")
6761 (set (attr "athlon_decode")
6762 (cond [(eq_attr "cpu" "athlon")
6763 (const_string "vector")
6764 (eq_attr "alternative" "1")
6765 (const_string "vector")
6766 (and (eq_attr "alternative" "2")
6767 (match_operand 1 "memory_operand" ""))
6768 (const_string "vector")]
6769 (const_string "direct")))
6770 (set (attr "amdfam10_decode")
6771 (cond [(and (eq_attr "alternative" "0,1")
6772 (match_operand 1 "memory_operand" ""))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "SI")])
6779 ;; IMUL reg16, reg16, imm8 VectorPath
6780 ;; IMUL reg16, mem16, imm8 VectorPath
6781 ;; IMUL reg16, reg16, imm16 VectorPath
6782 ;; IMUL reg16, mem16, imm16 VectorPath
6783 ;; IMUL reg16, reg16 Direct
6784 ;; IMUL reg16, mem16 Direct
6786 ;; On BDVER1, all HI MULs use DoublePath
6788 (define_insn "*mulhi3_1"
6789 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6790 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:HI 2 "general_operand" "K,n,mr")))
6792 (clobber (reg:CC FLAGS_REG))]
6794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1,2")
6805 (const_string "vector")]
6806 (const_string "direct")))
6807 (set (attr "amdfam10_decode")
6808 (cond [(eq_attr "alternative" "0,1")
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "double")
6812 (set_attr "mode" "HI")])
6814 ;;On AMDFAM10 and BDVER1
6818 (define_insn "*mulqi3_1"
6819 [(set (match_operand:QI 0 "register_operand" "=a")
6820 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6821 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6822 (clobber (reg:CC FLAGS_REG))]
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 [(set_attr "type" "imul")
6827 (set_attr "length_immediate" "0")
6828 (set (attr "athlon_decode")
6829 (if_then_else (eq_attr "cpu" "athlon")
6830 (const_string "vector")
6831 (const_string "direct")))
6832 (set_attr "amdfam10_decode" "direct")
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "QI")])
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6840 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6842 (match_operand:DWIH 2 "register_operand" ""))))
6843 (clobber (reg:CC FLAGS_REG))])])
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6849 (match_operand:QI 1 "nonimmediate_operand" ""))
6851 (match_operand:QI 2 "register_operand" ""))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6855 (define_insn "*<u>mul<mode><dwi>3_1"
6856 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6859 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6861 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864 "<sgnprefix>mul{<imodesuffix>}\t%2"
6865 [(set_attr "type" "imul")
6866 (set_attr "length_immediate" "0")
6867 (set (attr "athlon_decode")
6868 (if_then_else (eq_attr "cpu" "athlon")
6869 (const_string "vector")
6870 (const_string "double")))
6871 (set_attr "amdfam10_decode" "double")
6872 (set_attr "bdver1_decode" "direct")
6873 (set_attr "mode" "<MODE>")])
6875 (define_insn "*<u>mulqihi3_1"
6876 [(set (match_operand:HI 0 "register_operand" "=a")
6879 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6881 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "<sgnprefix>mul{b}\t%2"
6886 [(set_attr "type" "imul")
6887 (set_attr "length_immediate" "0")
6888 (set (attr "athlon_decode")
6889 (if_then_else (eq_attr "cpu" "athlon")
6890 (const_string "vector")
6891 (const_string "direct")))
6892 (set_attr "amdfam10_decode" "direct")
6893 (set_attr "bdver1_decode" "direct")
6894 (set_attr "mode" "QI")])
6896 (define_expand "<s>mul<mode>3_highpart"
6897 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6902 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6904 (match_operand:SWI48 2 "register_operand" "")))
6906 (clobber (match_scratch:SWI48 3 ""))
6907 (clobber (reg:CC FLAGS_REG))])]
6909 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6911 (define_insn "*<s>muldi3_highpart_1"
6912 [(set (match_operand:DI 0 "register_operand" "=d")
6917 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6919 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6921 (clobber (match_scratch:DI 3 "=1"))
6922 (clobber (reg:CC FLAGS_REG))]
6924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6925 "<sgnprefix>mul{q}\t%2"
6926 [(set_attr "type" "imul")
6927 (set_attr "length_immediate" "0")
6928 (set (attr "athlon_decode")
6929 (if_then_else (eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (const_string "double")))
6932 (set_attr "amdfam10_decode" "double")
6933 (set_attr "bdver1_decode" "direct")
6934 (set_attr "mode" "DI")])
6936 (define_insn "*<s>mulsi3_highpart_1"
6937 [(set (match_operand:SI 0 "register_operand" "=d")
6942 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6944 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6946 (clobber (match_scratch:SI 3 "=1"))
6947 (clobber (reg:CC FLAGS_REG))]
6948 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949 "<sgnprefix>mul{l}\t%2"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "amdfam10_decode" "double")
6957 (set_attr "bdver1_decode" "direct")
6958 (set_attr "mode" "SI")])
6960 (define_insn "*<s>mulsi3_highpart_zext"
6961 [(set (match_operand:DI 0 "register_operand" "=d")
6962 (zero_extend:DI (truncate:SI
6964 (mult:DI (any_extend:DI
6965 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6967 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6969 (clobber (match_scratch:SI 3 "=1"))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{l}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "double")))
6980 (set_attr "amdfam10_decode" "double")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "SI")])
6984 ;; The patterns that match these are at the end of this file.
6986 (define_expand "mulxf3"
6987 [(set (match_operand:XF 0 "register_operand" "")
6988 (mult:XF (match_operand:XF 1 "register_operand" "")
6989 (match_operand:XF 2 "register_operand" "")))]
6992 (define_expand "mul<mode>3"
6993 [(set (match_operand:MODEF 0 "register_operand" "")
6994 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6995 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6996 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6997 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6999 ;; Divide instructions
7001 ;; The patterns that match these are at the end of this file.
7003 (define_expand "divxf3"
7004 [(set (match_operand:XF 0 "register_operand" "")
7005 (div:XF (match_operand:XF 1 "register_operand" "")
7006 (match_operand:XF 2 "register_operand" "")))]
7009 (define_expand "divdf3"
7010 [(set (match_operand:DF 0 "register_operand" "")
7011 (div:DF (match_operand:DF 1 "register_operand" "")
7012 (match_operand:DF 2 "nonimmediate_operand" "")))]
7013 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7014 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7016 (define_expand "divsf3"
7017 [(set (match_operand:SF 0 "register_operand" "")
7018 (div:SF (match_operand:SF 1 "register_operand" "")
7019 (match_operand:SF 2 "nonimmediate_operand" "")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7023 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7024 && flag_finite_math_only && !flag_trapping_math
7025 && flag_unsafe_math_optimizations)
7027 ix86_emit_swdivsf (operands[0], operands[1],
7028 operands[2], SFmode);
7033 ;; Divmod instructions.
7035 (define_expand "divmod<mode>4"
7036 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7038 (match_operand:SWIM248 1 "register_operand" "")
7039 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7040 (set (match_operand:SWIM248 3 "register_operand" "")
7041 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7042 (clobber (reg:CC FLAGS_REG))])])
7044 ;; Split with 8bit unsigned divide:
7045 ;; if (dividend an divisor are in [0-255])
7046 ;; use 8bit unsigned integer divide
7048 ;; use original integer divide
7050 [(set (match_operand:SWI48 0 "register_operand" "")
7051 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7052 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7053 (set (match_operand:SWI48 1 "register_operand" "")
7054 (mod:SWI48 (match_dup 2) (match_dup 3)))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "TARGET_USE_8BIT_IDIV
7057 && TARGET_QIMODE_MATH
7058 && can_create_pseudo_p ()
7059 && !optimize_insn_for_size_p ()"
7061 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7063 (define_insn_and_split "divmod<mode>4_1"
7064 [(set (match_operand:SWI48 0 "register_operand" "=a")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7066 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWI48 1 "register_operand" "=&d")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7070 (clobber (reg:CC FLAGS_REG))]
7074 [(parallel [(set (match_dup 1)
7075 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7076 (clobber (reg:CC FLAGS_REG))])
7077 (parallel [(set (match_dup 0)
7078 (div:SWI48 (match_dup 2) (match_dup 3)))
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7082 (clobber (reg:CC FLAGS_REG))])]
7084 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7086 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7087 operands[4] = operands[2];
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7098 (define_insn_and_split "*divmod<mode>4"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (clobber (reg:CC FLAGS_REG))]
7108 [(parallel [(set (match_dup 1)
7109 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7110 (clobber (reg:CC FLAGS_REG))])
7111 (parallel [(set (match_dup 0)
7112 (div:SWIM248 (match_dup 2) (match_dup 3)))
7114 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7116 (clobber (reg:CC FLAGS_REG))])]
7118 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7120 if (<MODE>mode != HImode
7121 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7122 operands[4] = operands[2];
7125 /* Avoid use of cltd in favor of a mov+shift. */
7126 emit_move_insn (operands[1], operands[2]);
7127 operands[4] = operands[1];
7130 [(set_attr "type" "multi")
7131 (set_attr "mode" "<MODE>")])
7133 (define_insn "*divmod<mode>4_noext"
7134 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7135 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7136 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7137 (set (match_operand:SWIM248 1 "register_operand" "=d")
7138 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7139 (use (match_operand:SWIM248 4 "register_operand" "1"))
7140 (clobber (reg:CC FLAGS_REG))]
7142 "idiv{<imodesuffix>}\t%3"
7143 [(set_attr "type" "idiv")
7144 (set_attr "mode" "<MODE>")])
7146 (define_expand "divmodqi4"
7147 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7149 (match_operand:QI 1 "register_operand" "")
7150 (match_operand:QI 2 "nonimmediate_operand" "")))
7151 (set (match_operand:QI 3 "register_operand" "")
7152 (mod:QI (match_dup 1) (match_dup 2)))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "TARGET_QIMODE_MATH"
7159 tmp0 = gen_reg_rtx (HImode);
7160 tmp1 = gen_reg_rtx (HImode);
7162 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7164 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7165 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7167 /* Extract remainder from AH. */
7168 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7169 insn = emit_move_insn (operands[3], tmp1);
7171 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7172 set_unique_reg_note (insn, REG_EQUAL, mod);
7174 /* Extract quotient from AL. */
7175 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7177 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7178 set_unique_reg_note (insn, REG_EQUAL, div);
7183 ;; Divide AX by r/m8, with result stored in
7186 ;; Change div/mod to HImode and extend the second argument to HImode
7187 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7188 ;; combine may fail.
7189 (define_insn "divmodhiqi3"
7190 [(set (match_operand:HI 0 "register_operand" "=a")
7195 (mod:HI (match_operand:HI 1 "register_operand" "0")
7197 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7201 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_QIMODE_MATH"
7205 [(set_attr "type" "idiv")
7206 (set_attr "mode" "QI")])
7208 (define_expand "udivmod<mode>4"
7209 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7211 (match_operand:SWIM248 1 "register_operand" "")
7212 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7213 (set (match_operand:SWIM248 3 "register_operand" "")
7214 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7215 (clobber (reg:CC FLAGS_REG))])])
7217 ;; Split with 8bit unsigned divide:
7218 ;; if (dividend an divisor are in [0-255])
7219 ;; use 8bit unsigned integer divide
7221 ;; use original integer divide
7223 [(set (match_operand:SWI48 0 "register_operand" "")
7224 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7225 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7226 (set (match_operand:SWI48 1 "register_operand" "")
7227 (umod:SWI48 (match_dup 2) (match_dup 3)))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_USE_8BIT_IDIV
7230 && TARGET_QIMODE_MATH
7231 && can_create_pseudo_p ()
7232 && !optimize_insn_for_size_p ()"
7234 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7236 (define_insn_and_split "udivmod<mode>4_1"
7237 [(set (match_operand:SWI48 0 "register_operand" "=a")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7240 (set (match_operand:SWI48 1 "register_operand" "=&d")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7251 (umod:SWI48 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7258 (define_insn_and_split "*udivmod<mode>4"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (clobber (reg:CC FLAGS_REG))]
7268 [(set (match_dup 1) (const_int 0))
7269 (parallel [(set (match_dup 0)
7270 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7272 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7274 (clobber (reg:CC FLAGS_REG))])]
7276 [(set_attr "type" "multi")
7277 (set_attr "mode" "<MODE>")])
7279 (define_insn "*udivmod<mode>4_noext"
7280 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7281 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7282 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7283 (set (match_operand:SWIM248 1 "register_operand" "=d")
7284 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7285 (use (match_operand:SWIM248 4 "register_operand" "1"))
7286 (clobber (reg:CC FLAGS_REG))]
7288 "div{<imodesuffix>}\t%3"
7289 [(set_attr "type" "idiv")
7290 (set_attr "mode" "<MODE>")])
7292 (define_expand "udivmodqi4"
7293 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (match_operand:QI 1 "register_operand" "")
7296 (match_operand:QI 2 "nonimmediate_operand" "")))
7297 (set (match_operand:QI 3 "register_operand" "")
7298 (umod:QI (match_dup 1) (match_dup 2)))
7299 (clobber (reg:CC FLAGS_REG))])]
7300 "TARGET_QIMODE_MATH"
7305 tmp0 = gen_reg_rtx (HImode);
7306 tmp1 = gen_reg_rtx (HImode);
7308 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7310 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7311 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7313 /* Extract remainder from AH. */
7314 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7315 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7316 insn = emit_move_insn (operands[3], tmp1);
7318 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7319 set_unique_reg_note (insn, REG_EQUAL, mod);
7321 /* Extract quotient from AL. */
7322 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7324 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7325 set_unique_reg_note (insn, REG_EQUAL, div);
7330 (define_insn "udivmodhiqi3"
7331 [(set (match_operand:HI 0 "register_operand" "=a")
7336 (mod:HI (match_operand:HI 1 "register_operand" "0")
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7342 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "TARGET_QIMODE_MATH"
7346 [(set_attr "type" "idiv")
7347 (set_attr "mode" "QI")])
7349 ;; We cannot use div/idiv for double division, because it causes
7350 ;; "division by zero" on the overflow and that's not what we expect
7351 ;; from truncate. Because true (non truncating) double division is
7352 ;; never generated, we can't create this insn anyway.
7355 ; [(set (match_operand:SI 0 "register_operand" "=a")
7357 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7359 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7360 ; (set (match_operand:SI 3 "register_operand" "=d")
7362 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7363 ; (clobber (reg:CC FLAGS_REG))]
7365 ; "div{l}\t{%2, %0|%0, %2}"
7366 ; [(set_attr "type" "idiv")])
7368 ;;- Logical AND instructions
7370 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7371 ;; Note that this excludes ah.
7373 (define_expand "testsi_ccno_1"
7374 [(set (reg:CCNO FLAGS_REG)
7376 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7377 (match_operand:SI 1 "nonmemory_operand" ""))
7380 (define_expand "testqi_ccz_1"
7381 [(set (reg:CCZ FLAGS_REG)
7382 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7383 (match_operand:QI 1 "nonmemory_operand" ""))
7386 (define_expand "testdi_ccno_1"
7387 [(set (reg:CCNO FLAGS_REG)
7389 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7390 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7392 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7394 (define_insn "*testdi_1"
7395 [(set (reg FLAGS_REG)
7398 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7399 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7404 test{l}\t{%k1, %k0|%k0, %k1}
7405 test{l}\t{%k1, %k0|%k0, %k1}
7406 test{q}\t{%1, %0|%0, %1}
7407 test{q}\t{%1, %0|%0, %1}
7408 test{q}\t{%1, %0|%0, %1}"
7409 [(set_attr "type" "test")
7410 (set_attr "modrm" "0,1,0,1,1")
7411 (set_attr "mode" "SI,SI,DI,DI,DI")])
7413 (define_insn "*testqi_1_maybe_si"
7414 [(set (reg FLAGS_REG)
7417 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7418 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7421 && ix86_match_ccmode (insn,
7422 CONST_INT_P (operands[1])
7423 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7425 if (which_alternative == 3)
7427 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7428 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7429 return "test{l}\t{%1, %k0|%k0, %1}";
7431 return "test{b}\t{%1, %0|%0, %1}";
7433 [(set_attr "type" "test")
7434 (set_attr "modrm" "0,1,1,1")
7435 (set_attr "mode" "QI,QI,QI,SI")
7436 (set_attr "pent_pair" "uv,np,uv,np")])
7438 (define_insn "*test<mode>_1"
7439 [(set (reg FLAGS_REG)
7442 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7443 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7445 "ix86_match_ccmode (insn, CCNOmode)
7446 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7447 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7448 [(set_attr "type" "test")
7449 (set_attr "modrm" "0,1,1")
7450 (set_attr "mode" "<MODE>")
7451 (set_attr "pent_pair" "uv,np,uv")])
7453 (define_expand "testqi_ext_ccno_0"
7454 [(set (reg:CCNO FLAGS_REG)
7458 (match_operand 0 "ext_register_operand" "")
7461 (match_operand 1 "const_int_operand" ""))
7464 (define_insn "*testqi_ext_0"
7465 [(set (reg FLAGS_REG)
7469 (match_operand 0 "ext_register_operand" "Q")
7472 (match_operand 1 "const_int_operand" "n"))
7474 "ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")
7478 (set_attr "length_immediate" "1")
7479 (set_attr "modrm" "1")
7480 (set_attr "pent_pair" "np")])
7482 (define_insn "*testqi_ext_1_rex64"
7483 [(set (reg FLAGS_REG)
7487 (match_operand 0 "ext_register_operand" "Q")
7491 (match_operand:QI 1 "register_operand" "Q")))
7493 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7494 "test{b}\t{%1, %h0|%h0, %1}"
7495 [(set_attr "type" "test")
7496 (set_attr "mode" "QI")])
7498 (define_insn "*testqi_ext_1"
7499 [(set (reg FLAGS_REG)
7503 (match_operand 0 "ext_register_operand" "Q")
7507 (match_operand:QI 1 "general_operand" "Qm")))
7509 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7510 "test{b}\t{%1, %h0|%h0, %1}"
7511 [(set_attr "type" "test")
7512 (set_attr "mode" "QI")])
7514 (define_insn "*testqi_ext_2"
7515 [(set (reg FLAGS_REG)
7519 (match_operand 0 "ext_register_operand" "Q")
7523 (match_operand 1 "ext_register_operand" "Q")
7527 "ix86_match_ccmode (insn, CCNOmode)"
7528 "test{b}\t{%h1, %h0|%h0, %h1}"
7529 [(set_attr "type" "test")
7530 (set_attr "mode" "QI")])
7532 (define_insn "*testqi_ext_3_rex64"
7533 [(set (reg FLAGS_REG)
7534 (compare (zero_extract:DI
7535 (match_operand 0 "nonimmediate_operand" "rm")
7536 (match_operand:DI 1 "const_int_operand" "")
7537 (match_operand:DI 2 "const_int_operand" ""))
7540 && ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 /* Ensure that resulting mask is zero or sign extended operand. */
7544 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7545 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7546 && INTVAL (operands[1]) > 32))
7547 && (GET_MODE (operands[0]) == SImode
7548 || GET_MODE (operands[0]) == DImode
7549 || GET_MODE (operands[0]) == HImode
7550 || GET_MODE (operands[0]) == QImode)"
7553 ;; Combine likes to form bit extractions for some tests. Humor it.
7554 (define_insn "*testqi_ext_3"
7555 [(set (reg FLAGS_REG)
7556 (compare (zero_extract:SI
7557 (match_operand 0 "nonimmediate_operand" "rm")
7558 (match_operand:SI 1 "const_int_operand" "")
7559 (match_operand:SI 2 "const_int_operand" ""))
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && INTVAL (operands[1]) > 0
7563 && INTVAL (operands[2]) >= 0
7564 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7565 && (GET_MODE (operands[0]) == SImode
7566 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7567 || GET_MODE (operands[0]) == HImode
7568 || GET_MODE (operands[0]) == QImode)"
7572 [(set (match_operand 0 "flags_reg_operand" "")
7573 (match_operator 1 "compare_operator"
7575 (match_operand 2 "nonimmediate_operand" "")
7576 (match_operand 3 "const_int_operand" "")
7577 (match_operand 4 "const_int_operand" ""))
7579 "ix86_match_ccmode (insn, CCNOmode)"
7580 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7582 rtx val = operands[2];
7583 HOST_WIDE_INT len = INTVAL (operands[3]);
7584 HOST_WIDE_INT pos = INTVAL (operands[4]);
7586 enum machine_mode mode, submode;
7588 mode = GET_MODE (val);
7591 /* ??? Combine likes to put non-volatile mem extractions in QImode
7592 no matter the size of the test. So find a mode that works. */
7593 if (! MEM_VOLATILE_P (val))
7595 mode = smallest_mode_for_size (pos + len, MODE_INT);
7596 val = adjust_address (val, mode, 0);
7599 else if (GET_CODE (val) == SUBREG
7600 && (submode = GET_MODE (SUBREG_REG (val)),
7601 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7602 && pos + len <= GET_MODE_BITSIZE (submode)
7603 && GET_MODE_CLASS (submode) == MODE_INT)
7605 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7607 val = SUBREG_REG (val);
7609 else if (mode == HImode && pos + len <= 8)
7611 /* Small HImode tests can be converted to QImode. */
7613 val = gen_lowpart (QImode, val);
7616 if (len == HOST_BITS_PER_WIDE_INT)
7619 mask = ((HOST_WIDE_INT)1 << len) - 1;
7622 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7625 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7626 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7627 ;; this is relatively important trick.
7628 ;; Do the conversion only post-reload to avoid limiting of the register class
7631 [(set (match_operand 0 "flags_reg_operand" "")
7632 (match_operator 1 "compare_operator"
7633 [(and (match_operand 2 "register_operand" "")
7634 (match_operand 3 "const_int_operand" ""))
7637 && QI_REG_P (operands[2])
7638 && GET_MODE (operands[2]) != QImode
7639 && ((ix86_match_ccmode (insn, CCZmode)
7640 && !(INTVAL (operands[3]) & ~(255 << 8)))
7641 || (ix86_match_ccmode (insn, CCNOmode)
7642 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7645 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7648 "operands[2] = gen_lowpart (SImode, operands[2]);
7649 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7652 [(set (match_operand 0 "flags_reg_operand" "")
7653 (match_operator 1 "compare_operator"
7654 [(and (match_operand 2 "nonimmediate_operand" "")
7655 (match_operand 3 "const_int_operand" ""))
7658 && GET_MODE (operands[2]) != QImode
7659 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7660 && ((ix86_match_ccmode (insn, CCZmode)
7661 && !(INTVAL (operands[3]) & ~255))
7662 || (ix86_match_ccmode (insn, CCNOmode)
7663 && !(INTVAL (operands[3]) & ~127)))"
7665 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7667 "operands[2] = gen_lowpart (QImode, operands[2]);
7668 operands[3] = gen_lowpart (QImode, operands[3]);")
7670 ;; %%% This used to optimize known byte-wide and operations to memory,
7671 ;; and sometimes to QImode registers. If this is considered useful,
7672 ;; it should be done with splitters.
7674 (define_expand "and<mode>3"
7675 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7676 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7677 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7679 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7681 (define_insn "*anddi_1"
7682 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7684 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7685 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7689 switch (get_attr_type (insn))
7693 enum machine_mode mode;
7695 gcc_assert (CONST_INT_P (operands[2]));
7696 if (INTVAL (operands[2]) == 0xff)
7700 gcc_assert (INTVAL (operands[2]) == 0xffff);
7704 operands[1] = gen_lowpart (mode, operands[1]);
7706 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7708 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7712 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7713 if (get_attr_mode (insn) == MODE_SI)
7714 return "and{l}\t{%k2, %k0|%k0, %k2}";
7716 return "and{q}\t{%2, %0|%0, %2}";
7719 [(set_attr "type" "alu,alu,alu,imovx")
7720 (set_attr "length_immediate" "*,*,*,0")
7721 (set (attr "prefix_rex")
7723 (and (eq_attr "type" "imovx")
7724 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7725 (match_operand 1 "ext_QIreg_operand" "")))
7727 (const_string "*")))
7728 (set_attr "mode" "SI,DI,DI,SI")])
7730 (define_insn "*andsi_1"
7731 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7732 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7733 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "ix86_binary_operator_ok (AND, SImode, operands)"
7737 switch (get_attr_type (insn))
7741 enum machine_mode mode;
7743 gcc_assert (CONST_INT_P (operands[2]));
7744 if (INTVAL (operands[2]) == 0xff)
7748 gcc_assert (INTVAL (operands[2]) == 0xffff);
7752 operands[1] = gen_lowpart (mode, operands[1]);
7754 return "movz{bl|x}\t{%1, %0|%0, %1}";
7756 return "movz{wl|x}\t{%1, %0|%0, %1}";
7760 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7761 return "and{l}\t{%2, %0|%0, %2}";
7764 [(set_attr "type" "alu,alu,imovx")
7765 (set (attr "prefix_rex")
7767 (and (eq_attr "type" "imovx")
7768 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7769 (match_operand 1 "ext_QIreg_operand" "")))
7771 (const_string "*")))
7772 (set_attr "length_immediate" "*,*,0")
7773 (set_attr "mode" "SI")])
7775 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7776 (define_insn "*andsi_1_zext"
7777 [(set (match_operand:DI 0 "register_operand" "=r")
7779 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7780 (match_operand:SI 2 "general_operand" "g"))))
7781 (clobber (reg:CC FLAGS_REG))]
7782 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7783 "and{l}\t{%2, %k0|%k0, %2}"
7784 [(set_attr "type" "alu")
7785 (set_attr "mode" "SI")])
7787 (define_insn "*andhi_1"
7788 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7789 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7790 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "ix86_binary_operator_ok (AND, HImode, operands)"
7794 switch (get_attr_type (insn))
7797 gcc_assert (CONST_INT_P (operands[2]));
7798 gcc_assert (INTVAL (operands[2]) == 0xff);
7799 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7804 return "and{w}\t{%2, %0|%0, %2}";
7807 [(set_attr "type" "alu,alu,imovx")
7808 (set_attr "length_immediate" "*,*,0")
7809 (set (attr "prefix_rex")
7811 (and (eq_attr "type" "imovx")
7812 (match_operand 1 "ext_QIreg_operand" ""))
7814 (const_string "*")))
7815 (set_attr "mode" "HI,HI,SI")])
7817 ;; %%% Potential partial reg stall on alternative 2. What to do?
7818 (define_insn "*andqi_1"
7819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7820 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7821 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7822 (clobber (reg:CC FLAGS_REG))]
7823 "ix86_binary_operator_ok (AND, QImode, operands)"
7825 and{b}\t{%2, %0|%0, %2}
7826 and{b}\t{%2, %0|%0, %2}
7827 and{l}\t{%k2, %k0|%k0, %k2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "QI,QI,SI")])
7831 (define_insn "*andqi_1_slp"
7832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7833 (and:QI (match_dup 0)
7834 (match_operand:QI 1 "general_operand" "qn,qmn")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7837 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7838 "and{b}\t{%1, %0|%0, %1}"
7839 [(set_attr "type" "alu1")
7840 (set_attr "mode" "QI")])
7843 [(set (match_operand 0 "register_operand" "")
7845 (const_int -65536)))
7846 (clobber (reg:CC FLAGS_REG))]
7847 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7848 || optimize_function_for_size_p (cfun)"
7849 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7850 "operands[1] = gen_lowpart (HImode, operands[0]);")
7853 [(set (match_operand 0 "ext_register_operand" "")
7856 (clobber (reg:CC FLAGS_REG))]
7857 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7858 && reload_completed"
7859 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7860 "operands[1] = gen_lowpart (QImode, operands[0]);")
7863 [(set (match_operand 0 "ext_register_operand" "")
7865 (const_int -65281)))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7868 && reload_completed"
7869 [(parallel [(set (zero_extract:SI (match_dup 0)
7873 (zero_extract:SI (match_dup 0)
7876 (zero_extract:SI (match_dup 0)
7879 (clobber (reg:CC FLAGS_REG))])]
7880 "operands[0] = gen_lowpart (SImode, operands[0]);")
7882 (define_insn "*anddi_2"
7883 [(set (reg FLAGS_REG)
7886 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7887 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7889 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7890 (and:DI (match_dup 1) (match_dup 2)))]
7891 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892 && ix86_binary_operator_ok (AND, DImode, operands)"
7894 and{l}\t{%k2, %k0|%k0, %k2}
7895 and{q}\t{%2, %0|%0, %2}
7896 and{q}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI,DI,DI")])
7900 (define_insn "*andqi_2_maybe_si"
7901 [(set (reg FLAGS_REG)
7903 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7904 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7906 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7907 (and:QI (match_dup 1) (match_dup 2)))]
7908 "ix86_binary_operator_ok (AND, QImode, operands)
7909 && ix86_match_ccmode (insn,
7910 CONST_INT_P (operands[2])
7911 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7913 if (which_alternative == 2)
7915 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7916 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7917 return "and{l}\t{%2, %k0|%k0, %2}";
7919 return "and{b}\t{%2, %0|%0, %2}";
7921 [(set_attr "type" "alu")
7922 (set_attr "mode" "QI,QI,SI")])
7924 (define_insn "*and<mode>_2"
7925 [(set (reg FLAGS_REG)
7926 (compare (and:SWI124
7927 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7928 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7930 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7931 (and:SWI124 (match_dup 1) (match_dup 2)))]
7932 "ix86_match_ccmode (insn, CCNOmode)
7933 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7934 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7935 [(set_attr "type" "alu")
7936 (set_attr "mode" "<MODE>")])
7938 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7939 (define_insn "*andsi_2_zext"
7940 [(set (reg FLAGS_REG)
7942 (match_operand:SI 1 "nonimmediate_operand" "%0")
7943 (match_operand:SI 2 "general_operand" "g"))
7945 (set (match_operand:DI 0 "register_operand" "=r")
7946 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7947 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7948 && ix86_binary_operator_ok (AND, SImode, operands)"
7949 "and{l}\t{%2, %k0|%k0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "SI")])
7953 (define_insn "*andqi_2_slp"
7954 [(set (reg FLAGS_REG)
7956 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7957 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7959 (set (strict_low_part (match_dup 0))
7960 (and:QI (match_dup 0) (match_dup 1)))]
7961 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7962 && ix86_match_ccmode (insn, CCNOmode)
7963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7964 "and{b}\t{%1, %0|%0, %1}"
7965 [(set_attr "type" "alu1")
7966 (set_attr "mode" "QI")])
7968 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7969 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7970 ;; for a QImode operand, which of course failed.
7971 (define_insn "andqi_ext_0"
7972 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7977 (match_operand 1 "ext_register_operand" "0")
7980 (match_operand 2 "const_int_operand" "n")))
7981 (clobber (reg:CC FLAGS_REG))]
7983 "and{b}\t{%2, %h0|%h0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "length_immediate" "1")
7986 (set_attr "modrm" "1")
7987 (set_attr "mode" "QI")])
7989 ;; Generated by peephole translating test to and. This shows up
7990 ;; often in fp comparisons.
7991 (define_insn "*andqi_ext_0_cc"
7992 [(set (reg FLAGS_REG)
7996 (match_operand 1 "ext_register_operand" "0")
7999 (match_operand 2 "const_int_operand" "n"))
8001 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8010 "ix86_match_ccmode (insn, CCNOmode)"
8011 "and{b}\t{%2, %h0|%h0, %2}"
8012 [(set_attr "type" "alu")
8013 (set_attr "length_immediate" "1")
8014 (set_attr "modrm" "1")
8015 (set_attr "mode" "QI")])
8017 (define_insn "*andqi_ext_1_rex64"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8023 (match_operand 1 "ext_register_operand" "0")
8027 (match_operand 2 "ext_register_operand" "Q"))))
8028 (clobber (reg:CC FLAGS_REG))]
8030 "and{b}\t{%2, %h0|%h0, %2}"
8031 [(set_attr "type" "alu")
8032 (set_attr "length_immediate" "0")
8033 (set_attr "mode" "QI")])
8035 (define_insn "*andqi_ext_1"
8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8041 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand:QI 2 "general_operand" "Qm"))))
8046 (clobber (reg:CC FLAGS_REG))]
8048 "and{b}\t{%2, %h0|%h0, %2}"
8049 [(set_attr "type" "alu")
8050 (set_attr "length_immediate" "0")
8051 (set_attr "mode" "QI")])
8053 (define_insn "*andqi_ext_2"
8054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8059 (match_operand 1 "ext_register_operand" "%0")
8063 (match_operand 2 "ext_register_operand" "Q")
8066 (clobber (reg:CC FLAGS_REG))]
8068 "and{b}\t{%h2, %h0|%h0, %h2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "length_immediate" "0")
8071 (set_attr "mode" "QI")])
8073 ;; Convert wide AND instructions with immediate operand to shorter QImode
8074 ;; equivalents when possible.
8075 ;; Don't do the splitting with memory operands, since it introduces risk
8076 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8077 ;; for size, but that can (should?) be handled by generic code instead.
8079 [(set (match_operand 0 "register_operand" "")
8080 (and (match_operand 1 "register_operand" "")
8081 (match_operand 2 "const_int_operand" "")))
8082 (clobber (reg:CC FLAGS_REG))]
8084 && QI_REG_P (operands[0])
8085 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086 && !(~INTVAL (operands[2]) & ~(255 << 8))
8087 && GET_MODE (operands[0]) != QImode"
8088 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8089 (and:SI (zero_extract:SI (match_dup 1)
8090 (const_int 8) (const_int 8))
8092 (clobber (reg:CC FLAGS_REG))])]
8093 "operands[0] = gen_lowpart (SImode, operands[0]);
8094 operands[1] = gen_lowpart (SImode, operands[1]);
8095 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8097 ;; Since AND can be encoded with sign extended immediate, this is only
8098 ;; profitable when 7th bit is not set.
8100 [(set (match_operand 0 "register_operand" "")
8101 (and (match_operand 1 "general_operand" "")
8102 (match_operand 2 "const_int_operand" "")))
8103 (clobber (reg:CC FLAGS_REG))]
8105 && ANY_QI_REG_P (operands[0])
8106 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8107 && !(~INTVAL (operands[2]) & ~255)
8108 && !(INTVAL (operands[2]) & 128)
8109 && GET_MODE (operands[0]) != QImode"
8110 [(parallel [(set (strict_low_part (match_dup 0))
8111 (and:QI (match_dup 1)
8113 (clobber (reg:CC FLAGS_REG))])]
8114 "operands[0] = gen_lowpart (QImode, operands[0]);
8115 operands[1] = gen_lowpart (QImode, operands[1]);
8116 operands[2] = gen_lowpart (QImode, operands[2]);")
8118 ;; Logical inclusive and exclusive OR instructions
8120 ;; %%% This used to optimize known byte-wide and operations to memory.
8121 ;; If this is considered useful, it should be done with splitters.
8123 (define_expand "<code><mode>3"
8124 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8125 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8126 (match_operand:SWIM 2 "<general_operand>" "")))]
8128 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8130 (define_insn "*<code><mode>_1"
8131 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8133 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8134 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8137 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "<MODE>")])
8141 ;; %%% Potential partial reg stall on alternative 2. What to do?
8142 (define_insn "*<code>qi_1"
8143 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8144 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8145 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8149 <logic>{b}\t{%2, %0|%0, %2}
8150 <logic>{b}\t{%2, %0|%0, %2}
8151 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "QI,QI,SI")])
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*<code>si_1_zext"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8159 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160 (match_operand:SI 2 "general_operand" "g"))))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8163 "<logic>{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8167 (define_insn "*<code>si_1_zext_imm"
8168 [(set (match_operand:DI 0 "register_operand" "=r")
8170 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8171 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8172 (clobber (reg:CC FLAGS_REG))]
8173 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8174 "<logic>{l}\t{%2, %k0|%k0, %2}"
8175 [(set_attr "type" "alu")
8176 (set_attr "mode" "SI")])
8178 (define_insn "*<code>qi_1_slp"
8179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8180 (any_or:QI (match_dup 0)
8181 (match_operand:QI 1 "general_operand" "qmn,qn")))
8182 (clobber (reg:CC FLAGS_REG))]
8183 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8184 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8185 "<logic>{b}\t{%1, %0|%0, %1}"
8186 [(set_attr "type" "alu1")
8187 (set_attr "mode" "QI")])
8189 (define_insn "*<code><mode>_2"
8190 [(set (reg FLAGS_REG)
8191 (compare (any_or:SWI
8192 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8193 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8195 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8196 (any_or:SWI (match_dup 1) (match_dup 2)))]
8197 "ix86_match_ccmode (insn, CCNOmode)
8198 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8199 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "<MODE>")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 ;; ??? Special case for immediate operand is missing - it is tricky.
8205 (define_insn "*<code>si_2_zext"
8206 [(set (reg FLAGS_REG)
8207 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "general_operand" "g"))
8210 (set (match_operand:DI 0 "register_operand" "=r")
8211 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8212 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214 "<logic>{l}\t{%2, %k0|%k0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "mode" "SI")])
8218 (define_insn "*<code>si_2_zext_imm"
8219 [(set (reg FLAGS_REG)
8221 (match_operand:SI 1 "nonimmediate_operand" "%0")
8222 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8224 (set (match_operand:DI 0 "register_operand" "=r")
8225 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8226 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228 "<logic>{l}\t{%2, %k0|%k0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "SI")])
8232 (define_insn "*<code>qi_2_slp"
8233 [(set (reg FLAGS_REG)
8234 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8235 (match_operand:QI 1 "general_operand" "qmn,qn"))
8237 (set (strict_low_part (match_dup 0))
8238 (any_or:QI (match_dup 0) (match_dup 1)))]
8239 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8240 && ix86_match_ccmode (insn, CCNOmode)
8241 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8242 "<logic>{b}\t{%1, %0|%0, %1}"
8243 [(set_attr "type" "alu1")
8244 (set_attr "mode" "QI")])
8246 (define_insn "*<code><mode>_3"
8247 [(set (reg FLAGS_REG)
8248 (compare (any_or:SWI
8249 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SWI 2 "<general_operand>" "<g>"))
8252 (clobber (match_scratch:SWI 0 "=<r>"))]
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8255 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "<MODE>")])
8259 (define_insn "*<code>qi_ext_0"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265 (match_operand 1 "ext_register_operand" "0")
8268 (match_operand 2 "const_int_operand" "n")))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8271 "<logic>{b}\t{%2, %h0|%h0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "length_immediate" "1")
8274 (set_attr "modrm" "1")
8275 (set_attr "mode" "QI")])
8277 (define_insn "*<code>qi_ext_1_rex64"
8278 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8283 (match_operand 1 "ext_register_operand" "0")
8287 (match_operand 2 "ext_register_operand" "Q"))))
8288 (clobber (reg:CC FLAGS_REG))]
8290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8291 "<logic>{b}\t{%2, %h0|%h0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "length_immediate" "0")
8294 (set_attr "mode" "QI")])
8296 (define_insn "*<code>qi_ext_1"
8297 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8302 (match_operand 1 "ext_register_operand" "0")
8306 (match_operand:QI 2 "general_operand" "Qm"))))
8307 (clobber (reg:CC FLAGS_REG))]
8309 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8310 "<logic>{b}\t{%2, %h0|%h0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "0")
8313 (set_attr "mode" "QI")])
8315 (define_insn "*<code>qi_ext_2"
8316 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8320 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8323 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8326 (clobber (reg:CC FLAGS_REG))]
8327 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8328 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "length_immediate" "0")
8331 (set_attr "mode" "QI")])
8334 [(set (match_operand 0 "register_operand" "")
8335 (any_or (match_operand 1 "register_operand" "")
8336 (match_operand 2 "const_int_operand" "")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 && QI_REG_P (operands[0])
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8341 && !(INTVAL (operands[2]) & ~(255 << 8))
8342 && GET_MODE (operands[0]) != QImode"
8343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8344 (any_or:SI (zero_extract:SI (match_dup 1)
8345 (const_int 8) (const_int 8))
8347 (clobber (reg:CC FLAGS_REG))])]
8348 "operands[0] = gen_lowpart (SImode, operands[0]);
8349 operands[1] = gen_lowpart (SImode, operands[1]);
8350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8352 ;; Since OR can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is set.
8355 [(set (match_operand 0 "register_operand" "")
8356 (any_or (match_operand 1 "general_operand" "")
8357 (match_operand 2 "const_int_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && ANY_QI_REG_P (operands[0])
8361 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8362 && !(INTVAL (operands[2]) & ~255)
8363 && (INTVAL (operands[2]) & 128)
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (strict_low_part (match_dup 0))
8366 (any_or:QI (match_dup 1)
8368 (clobber (reg:CC FLAGS_REG))])]
8369 "operands[0] = gen_lowpart (QImode, operands[0]);
8370 operands[1] = gen_lowpart (QImode, operands[1]);
8371 operands[2] = gen_lowpart (QImode, operands[2]);")
8373 (define_expand "xorqi_cc_ext_1"
8375 (set (reg:CCNO FLAGS_REG)
8379 (match_operand 1 "ext_register_operand" "")
8382 (match_operand:QI 2 "general_operand" ""))
8384 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8394 (define_insn "*xorqi_cc_ext_1_rex64"
8395 [(set (reg FLAGS_REG)
8399 (match_operand 1 "ext_register_operand" "0")
8402 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8404 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8414 "xor{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "modrm" "1")
8417 (set_attr "mode" "QI")])
8419 (define_insn "*xorqi_cc_ext_1"
8420 [(set (reg FLAGS_REG)
8424 (match_operand 1 "ext_register_operand" "0")
8427 (match_operand:QI 2 "general_operand" "qmn"))
8429 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8438 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8439 "xor{b}\t{%2, %h0|%h0, %2}"
8440 [(set_attr "type" "alu")
8441 (set_attr "modrm" "1")
8442 (set_attr "mode" "QI")])
8444 ;; Negation instructions
8446 (define_expand "neg<mode>2"
8447 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8448 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8450 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8452 (define_insn_and_split "*neg<dwi>2_doubleword"
8453 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8454 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8455 (clobber (reg:CC FLAGS_REG))]
8456 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8460 [(set (reg:CCZ FLAGS_REG)
8461 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8462 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8465 (plus:DWIH (match_dup 3)
8466 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8468 (clobber (reg:CC FLAGS_REG))])
8471 (neg:DWIH (match_dup 2)))
8472 (clobber (reg:CC FLAGS_REG))])]
8473 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8475 (define_insn "*neg<mode>2_1"
8476 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8477 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8480 "neg{<imodesuffix>}\t%0"
8481 [(set_attr "type" "negnot")
8482 (set_attr "mode" "<MODE>")])
8484 ;; Combine is quite creative about this pattern.
8485 (define_insn "*negsi2_1_zext"
8486 [(set (match_operand:DI 0 "register_operand" "=r")
8488 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8494 [(set_attr "type" "negnot")
8495 (set_attr "mode" "SI")])
8497 ;; The problem with neg is that it does not perform (compare x 0),
8498 ;; it really performs (compare 0 x), which leaves us with the zero
8499 ;; flag being the only useful item.
8501 (define_insn "*neg<mode>2_cmpz"
8502 [(set (reg:CCZ FLAGS_REG)
8504 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8507 (neg:SWI (match_dup 1)))]
8508 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8509 "neg{<imodesuffix>}\t%0"
8510 [(set_attr "type" "negnot")
8511 (set_attr "mode" "<MODE>")])
8513 (define_insn "*negsi2_cmpz_zext"
8514 [(set (reg:CCZ FLAGS_REG)
8518 (match_operand:DI 1 "register_operand" "0")
8522 (set (match_operand:DI 0 "register_operand" "=r")
8523 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8526 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8528 [(set_attr "type" "negnot")
8529 (set_attr "mode" "SI")])
8531 ;; Changing of sign for FP values is doable using integer unit too.
8533 (define_expand "<code><mode>2"
8534 [(set (match_operand:X87MODEF 0 "register_operand" "")
8535 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8536 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8537 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8539 (define_insn "*absneg<mode>2_mixed"
8540 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8541 (match_operator:MODEF 3 "absneg_operator"
8542 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8543 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8548 (define_insn "*absneg<mode>2_sse"
8549 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8550 (match_operator:MODEF 3 "absneg_operator"
8551 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8552 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8557 (define_insn "*absneg<mode>2_i387"
8558 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8559 (match_operator:X87MODEF 3 "absneg_operator"
8560 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8561 (use (match_operand 2 "" ""))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8566 (define_expand "<code>tf2"
8567 [(set (match_operand:TF 0 "register_operand" "")
8568 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8570 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8572 (define_insn "*absnegtf2_sse"
8573 [(set (match_operand:TF 0 "register_operand" "=x,x")
8574 (match_operator:TF 3 "absneg_operator"
8575 [(match_operand:TF 1 "register_operand" "0,x")]))
8576 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8577 (clobber (reg:CC FLAGS_REG))]
8581 ;; Splitters for fp abs and neg.
8584 [(set (match_operand 0 "fp_register_operand" "")
8585 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8586 (use (match_operand 2 "" ""))
8587 (clobber (reg:CC FLAGS_REG))]
8589 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8592 [(set (match_operand 0 "register_operand" "")
8593 (match_operator 3 "absneg_operator"
8594 [(match_operand 1 "register_operand" "")]))
8595 (use (match_operand 2 "nonimmediate_operand" ""))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "reload_completed && SSE_REG_P (operands[0])"
8598 [(set (match_dup 0) (match_dup 3))]
8600 enum machine_mode mode = GET_MODE (operands[0]);
8601 enum machine_mode vmode = GET_MODE (operands[2]);
8604 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8605 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8606 if (operands_match_p (operands[0], operands[2]))
8609 operands[1] = operands[2];
8612 if (GET_CODE (operands[3]) == ABS)
8613 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8615 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8620 [(set (match_operand:SF 0 "register_operand" "")
8621 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8622 (use (match_operand:V4SF 2 "" ""))
8623 (clobber (reg:CC FLAGS_REG))]
8625 [(parallel [(set (match_dup 0) (match_dup 1))
8626 (clobber (reg:CC FLAGS_REG))])]
8629 operands[0] = gen_lowpart (SImode, operands[0]);
8630 if (GET_CODE (operands[1]) == ABS)
8632 tmp = gen_int_mode (0x7fffffff, SImode);
8633 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8637 tmp = gen_int_mode (0x80000000, SImode);
8638 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8644 [(set (match_operand:DF 0 "register_operand" "")
8645 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8646 (use (match_operand 2 "" ""))
8647 (clobber (reg:CC FLAGS_REG))]
8649 [(parallel [(set (match_dup 0) (match_dup 1))
8650 (clobber (reg:CC FLAGS_REG))])]
8655 tmp = gen_lowpart (DImode, operands[0]);
8656 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8659 if (GET_CODE (operands[1]) == ABS)
8662 tmp = gen_rtx_NOT (DImode, tmp);
8666 operands[0] = gen_highpart (SImode, operands[0]);
8667 if (GET_CODE (operands[1]) == ABS)
8669 tmp = gen_int_mode (0x7fffffff, SImode);
8670 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8674 tmp = gen_int_mode (0x80000000, SImode);
8675 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8682 [(set (match_operand:XF 0 "register_operand" "")
8683 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8684 (use (match_operand 2 "" ""))
8685 (clobber (reg:CC FLAGS_REG))]
8687 [(parallel [(set (match_dup 0) (match_dup 1))
8688 (clobber (reg:CC FLAGS_REG))])]
8691 operands[0] = gen_rtx_REG (SImode,
8692 true_regnum (operands[0])
8693 + (TARGET_64BIT ? 1 : 2));
8694 if (GET_CODE (operands[1]) == ABS)
8696 tmp = GEN_INT (0x7fff);
8697 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8701 tmp = GEN_INT (0x8000);
8702 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8707 ;; Conditionalize these after reload. If they match before reload, we
8708 ;; lose the clobber and ability to use integer instructions.
8710 (define_insn "*<code><mode>2_1"
8711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8712 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8714 && (reload_completed
8715 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8716 "f<absneg_mnemonic>"
8717 [(set_attr "type" "fsgn")
8718 (set_attr "mode" "<MODE>")])
8720 (define_insn "*<code>extendsfdf2"
8721 [(set (match_operand:DF 0 "register_operand" "=f")
8722 (absneg:DF (float_extend:DF
8723 (match_operand:SF 1 "register_operand" "0"))))]
8724 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8725 "f<absneg_mnemonic>"
8726 [(set_attr "type" "fsgn")
8727 (set_attr "mode" "DF")])
8729 (define_insn "*<code>extendsfxf2"
8730 [(set (match_operand:XF 0 "register_operand" "=f")
8731 (absneg:XF (float_extend:XF
8732 (match_operand:SF 1 "register_operand" "0"))))]
8734 "f<absneg_mnemonic>"
8735 [(set_attr "type" "fsgn")
8736 (set_attr "mode" "XF")])
8738 (define_insn "*<code>extenddfxf2"
8739 [(set (match_operand:XF 0 "register_operand" "=f")
8740 (absneg:XF (float_extend:XF
8741 (match_operand:DF 1 "register_operand" "0"))))]
8743 "f<absneg_mnemonic>"
8744 [(set_attr "type" "fsgn")
8745 (set_attr "mode" "XF")])
8747 ;; Copysign instructions
8749 (define_mode_iterator CSGNMODE [SF DF TF])
8750 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8752 (define_expand "copysign<mode>3"
8753 [(match_operand:CSGNMODE 0 "register_operand" "")
8754 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8755 (match_operand:CSGNMODE 2 "register_operand" "")]
8756 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8757 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8758 "ix86_expand_copysign (operands); DONE;")
8760 (define_insn_and_split "copysign<mode>3_const"
8761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8763 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8764 (match_operand:CSGNMODE 2 "register_operand" "0")
8765 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8767 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8768 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8770 "&& reload_completed"
8772 "ix86_split_copysign_const (operands); DONE;")
8774 (define_insn "copysign<mode>3_var"
8775 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8777 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8778 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8779 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8780 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8782 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8783 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8784 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8788 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8790 [(match_operand:CSGNMODE 2 "register_operand" "")
8791 (match_operand:CSGNMODE 3 "register_operand" "")
8792 (match_operand:<CSGNVMODE> 4 "" "")
8793 (match_operand:<CSGNVMODE> 5 "" "")]
8795 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8796 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8798 && reload_completed"
8800 "ix86_split_copysign_var (operands); DONE;")
8802 ;; One complement instructions
8804 (define_expand "one_cmpl<mode>2"
8805 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8806 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8808 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8810 (define_insn "*one_cmpl<mode>2_1"
8811 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8812 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8813 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8814 "not{<imodesuffix>}\t%0"
8815 [(set_attr "type" "negnot")
8816 (set_attr "mode" "<MODE>")])
8818 ;; %%% Potential partial reg stall on alternative 1. What to do?
8819 (define_insn "*one_cmplqi2_1"
8820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8821 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8822 "ix86_unary_operator_ok (NOT, QImode, operands)"
8826 [(set_attr "type" "negnot")
8827 (set_attr "mode" "QI,SI")])
8829 ;; ??? Currently never generated - xor is used instead.
8830 (define_insn "*one_cmplsi2_1_zext"
8831 [(set (match_operand:DI 0 "register_operand" "=r")
8833 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8834 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8836 [(set_attr "type" "negnot")
8837 (set_attr "mode" "SI")])
8839 (define_insn "*one_cmpl<mode>2_2"
8840 [(set (reg FLAGS_REG)
8841 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8843 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8844 (not:SWI (match_dup 1)))]
8845 "ix86_match_ccmode (insn, CCNOmode)
8846 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8848 [(set_attr "type" "alu1")
8849 (set_attr "mode" "<MODE>")])
8852 [(set (match_operand 0 "flags_reg_operand" "")
8853 (match_operator 2 "compare_operator"
8854 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8856 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8857 (not:SWI (match_dup 3)))]
8858 "ix86_match_ccmode (insn, CCNOmode)"
8859 [(parallel [(set (match_dup 0)
8860 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8863 (xor:SWI (match_dup 3) (const_int -1)))])])
8865 ;; ??? Currently never generated - xor is used instead.
8866 (define_insn "*one_cmplsi2_2_zext"
8867 [(set (reg FLAGS_REG)
8868 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8870 (set (match_operand:DI 0 "register_operand" "=r")
8871 (zero_extend:DI (not:SI (match_dup 1))))]
8872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8873 && ix86_unary_operator_ok (NOT, SImode, operands)"
8875 [(set_attr "type" "alu1")
8876 (set_attr "mode" "SI")])
8879 [(set (match_operand 0 "flags_reg_operand" "")
8880 (match_operator 2 "compare_operator"
8881 [(not:SI (match_operand:SI 3 "register_operand" ""))
8883 (set (match_operand:DI 1 "register_operand" "")
8884 (zero_extend:DI (not:SI (match_dup 3))))]
8885 "ix86_match_ccmode (insn, CCNOmode)"
8886 [(parallel [(set (match_dup 0)
8887 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8890 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8892 ;; Shift instructions
8894 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8895 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8896 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8897 ;; from the assembler input.
8899 ;; This instruction shifts the target reg/mem as usual, but instead of
8900 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8901 ;; is a left shift double, bits are taken from the high order bits of
8902 ;; reg, else if the insn is a shift right double, bits are taken from the
8903 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8904 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8906 ;; Since sh[lr]d does not change the `reg' operand, that is done
8907 ;; separately, making all shifts emit pairs of shift double and normal
8908 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8909 ;; support a 63 bit shift, each shift where the count is in a reg expands
8910 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8912 ;; If the shift count is a constant, we need never emit more than one
8913 ;; shift pair, instead using moves and sign extension for counts greater
8916 (define_expand "ashl<mode>3"
8917 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8918 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8919 (match_operand:QI 2 "nonmemory_operand" "")))]
8921 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8923 (define_insn "*ashl<mode>3_doubleword"
8924 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8925 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8926 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8927 (clobber (reg:CC FLAGS_REG))]
8930 [(set_attr "type" "multi")])
8933 [(set (match_operand:DWI 0 "register_operand" "")
8934 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8935 (match_operand:QI 2 "nonmemory_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8939 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8941 ;; By default we don't ask for a scratch register, because when DWImode
8942 ;; values are manipulated, registers are already at a premium. But if
8943 ;; we have one handy, we won't turn it away.
8946 [(match_scratch:DWIH 3 "r")
8947 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8949 (match_operand:<DWI> 1 "nonmemory_operand" "")
8950 (match_operand:QI 2 "nonmemory_operand" "")))
8951 (clobber (reg:CC FLAGS_REG))])
8955 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8957 (define_insn "x86_64_shld"
8958 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8959 (ior:DI (ashift:DI (match_dup 0)
8960 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8961 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8962 (minus:QI (const_int 64) (match_dup 2)))))
8963 (clobber (reg:CC FLAGS_REG))]
8965 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8966 [(set_attr "type" "ishift")
8967 (set_attr "prefix_0f" "1")
8968 (set_attr "mode" "DI")
8969 (set_attr "athlon_decode" "vector")
8970 (set_attr "amdfam10_decode" "vector")
8971 (set_attr "bdver1_decode" "vector")])
8973 (define_insn "x86_shld"
8974 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8975 (ior:SI (ashift:SI (match_dup 0)
8976 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8977 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8978 (minus:QI (const_int 32) (match_dup 2)))))
8979 (clobber (reg:CC FLAGS_REG))]
8981 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8982 [(set_attr "type" "ishift")
8983 (set_attr "prefix_0f" "1")
8984 (set_attr "mode" "SI")
8985 (set_attr "pent_pair" "np")
8986 (set_attr "athlon_decode" "vector")
8987 (set_attr "amdfam10_decode" "vector")
8988 (set_attr "bdver1_decode" "vector")])
8990 (define_expand "x86_shift<mode>_adj_1"
8991 [(set (reg:CCZ FLAGS_REG)
8992 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8995 (set (match_operand:SWI48 0 "register_operand" "")
8996 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8997 (match_operand:SWI48 1 "register_operand" "")
9000 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9001 (match_operand:SWI48 3 "register_operand" "r")
9004 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9006 (define_expand "x86_shift<mode>_adj_2"
9007 [(use (match_operand:SWI48 0 "register_operand" ""))
9008 (use (match_operand:SWI48 1 "register_operand" ""))
9009 (use (match_operand:QI 2 "register_operand" ""))]
9012 rtx label = gen_label_rtx ();
9015 emit_insn (gen_testqi_ccz_1 (operands[2],
9016 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9018 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9019 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9020 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9021 gen_rtx_LABEL_REF (VOIDmode, label),
9023 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9024 JUMP_LABEL (tmp) = label;
9026 emit_move_insn (operands[0], operands[1]);
9027 ix86_expand_clear (operands[1]);
9030 LABEL_NUSES (label) = 1;
9035 ;; Avoid useless masking of count operand.
9036 (define_insn_and_split "*ashl<mode>3_mask"
9037 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9039 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9042 (match_operand:SI 2 "nonimmediate_operand" "c")
9043 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9046 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9047 == GET_MODE_BITSIZE (<MODE>mode)-1"
9050 [(parallel [(set (match_dup 0)
9051 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9052 (clobber (reg:CC FLAGS_REG))])]
9054 if (can_create_pseudo_p ())
9055 operands [2] = force_reg (SImode, operands[2]);
9057 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9059 [(set_attr "type" "ishift")
9060 (set_attr "mode" "<MODE>")])
9062 (define_insn "*ashl<mode>3_1"
9063 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9064 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9065 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9069 switch (get_attr_type (insn))
9075 gcc_assert (operands[2] == const1_rtx);
9076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9077 return "add{<imodesuffix>}\t%0, %0";
9080 if (operands[2] == const1_rtx
9081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9082 return "sal{<imodesuffix>}\t%0";
9084 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9088 (cond [(eq_attr "alternative" "1")
9089 (const_string "lea")
9090 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9092 (match_operand 0 "register_operand" ""))
9093 (match_operand 2 "const1_operand" ""))
9094 (const_string "alu")
9096 (const_string "ishift")))
9097 (set (attr "length_immediate")
9099 (ior (eq_attr "type" "alu")
9100 (and (eq_attr "type" "ishift")
9101 (and (match_operand 2 "const1_operand" "")
9102 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9105 (const_string "*")))
9106 (set_attr "mode" "<MODE>")])
9108 (define_insn "*ashlsi3_1_zext"
9109 [(set (match_operand:DI 0 "register_operand" "=r,r")
9111 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9112 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9116 switch (get_attr_type (insn))
9122 gcc_assert (operands[2] == const1_rtx);
9123 return "add{l}\t%k0, %k0";
9126 if (operands[2] == const1_rtx
9127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9128 return "sal{l}\t%k0";
9130 return "sal{l}\t{%2, %k0|%k0, %2}";
9134 (cond [(eq_attr "alternative" "1")
9135 (const_string "lea")
9136 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9138 (match_operand 2 "const1_operand" ""))
9139 (const_string "alu")
9141 (const_string "ishift")))
9142 (set (attr "length_immediate")
9144 (ior (eq_attr "type" "alu")
9145 (and (eq_attr "type" "ishift")
9146 (and (match_operand 2 "const1_operand" "")
9147 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9150 (const_string "*")))
9151 (set_attr "mode" "SI")])
9153 (define_insn "*ashlhi3_1"
9154 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9155 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9156 (match_operand:QI 2 "nonmemory_operand" "cI")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "TARGET_PARTIAL_REG_STALL
9159 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9161 switch (get_attr_type (insn))
9164 gcc_assert (operands[2] == const1_rtx);
9165 return "add{w}\t%0, %0";
9168 if (operands[2] == const1_rtx
9169 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9170 return "sal{w}\t%0";
9172 return "sal{w}\t{%2, %0|%0, %2}";
9176 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9178 (match_operand 0 "register_operand" ""))
9179 (match_operand 2 "const1_operand" ""))
9180 (const_string "alu")
9182 (const_string "ishift")))
9183 (set (attr "length_immediate")
9185 (ior (eq_attr "type" "alu")
9186 (and (eq_attr "type" "ishift")
9187 (and (match_operand 2 "const1_operand" "")
9188 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9191 (const_string "*")))
9192 (set_attr "mode" "HI")])
9194 (define_insn "*ashlhi3_1_lea"
9195 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9196 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9197 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9198 (clobber (reg:CC FLAGS_REG))]
9199 "!TARGET_PARTIAL_REG_STALL
9200 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9202 switch (get_attr_type (insn))
9208 gcc_assert (operands[2] == const1_rtx);
9209 return "add{w}\t%0, %0";
9212 if (operands[2] == const1_rtx
9213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9214 return "sal{w}\t%0";
9216 return "sal{w}\t{%2, %0|%0, %2}";
9220 (cond [(eq_attr "alternative" "1")
9221 (const_string "lea")
9222 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9224 (match_operand 0 "register_operand" ""))
9225 (match_operand 2 "const1_operand" ""))
9226 (const_string "alu")
9228 (const_string "ishift")))
9229 (set (attr "length_immediate")
9231 (ior (eq_attr "type" "alu")
9232 (and (eq_attr "type" "ishift")
9233 (and (match_operand 2 "const1_operand" "")
9234 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9237 (const_string "*")))
9238 (set_attr "mode" "HI,SI")])
9240 (define_insn "*ashlqi3_1"
9241 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9242 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9243 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "TARGET_PARTIAL_REG_STALL
9246 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9248 switch (get_attr_type (insn))
9251 gcc_assert (operands[2] == const1_rtx);
9252 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9253 return "add{l}\t%k0, %k0";
9255 return "add{b}\t%0, %0";
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9261 if (get_attr_mode (insn) == MODE_SI)
9262 return "sal{l}\t%k0";
9264 return "sal{b}\t%0";
9268 if (get_attr_mode (insn) == MODE_SI)
9269 return "sal{l}\t{%2, %k0|%k0, %2}";
9271 return "sal{b}\t{%2, %0|%0, %2}";
9276 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9278 (match_operand 0 "register_operand" ""))
9279 (match_operand 2 "const1_operand" ""))
9280 (const_string "alu")
9282 (const_string "ishift")))
9283 (set (attr "length_immediate")
9285 (ior (eq_attr "type" "alu")
9286 (and (eq_attr "type" "ishift")
9287 (and (match_operand 2 "const1_operand" "")
9288 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9291 (const_string "*")))
9292 (set_attr "mode" "QI,SI")])
9294 ;; %%% Potential partial reg stall on alternative 2. What to do?
9295 (define_insn "*ashlqi3_1_lea"
9296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9297 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9298 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "!TARGET_PARTIAL_REG_STALL
9301 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9303 switch (get_attr_type (insn))
9309 gcc_assert (operands[2] == const1_rtx);
9310 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9311 return "add{l}\t%k0, %k0";
9313 return "add{b}\t%0, %0";
9316 if (operands[2] == const1_rtx
9317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9319 if (get_attr_mode (insn) == MODE_SI)
9320 return "sal{l}\t%k0";
9322 return "sal{b}\t%0";
9326 if (get_attr_mode (insn) == MODE_SI)
9327 return "sal{l}\t{%2, %k0|%k0, %2}";
9329 return "sal{b}\t{%2, %0|%0, %2}";
9334 (cond [(eq_attr "alternative" "2")
9335 (const_string "lea")
9336 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9338 (match_operand 0 "register_operand" ""))
9339 (match_operand 2 "const1_operand" ""))
9340 (const_string "alu")
9342 (const_string "ishift")))
9343 (set (attr "length_immediate")
9345 (ior (eq_attr "type" "alu")
9346 (and (eq_attr "type" "ishift")
9347 (and (match_operand 2 "const1_operand" "")
9348 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9351 (const_string "*")))
9352 (set_attr "mode" "QI,SI,SI")])
9354 (define_insn "*ashlqi3_1_slp"
9355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9356 (ashift:QI (match_dup 0)
9357 (match_operand:QI 1 "nonmemory_operand" "cI")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "(optimize_function_for_size_p (cfun)
9360 || !TARGET_PARTIAL_FLAG_REG_STALL
9361 || (operands[1] == const1_rtx
9363 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9365 switch (get_attr_type (insn))
9368 gcc_assert (operands[1] == const1_rtx);
9369 return "add{b}\t%0, %0";
9372 if (operands[1] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 return "sal{b}\t%0";
9376 return "sal{b}\t{%1, %0|%0, %1}";
9380 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9382 (match_operand 0 "register_operand" ""))
9383 (match_operand 1 "const1_operand" ""))
9384 (const_string "alu")
9386 (const_string "ishift1")))
9387 (set (attr "length_immediate")
9389 (ior (eq_attr "type" "alu")
9390 (and (eq_attr "type" "ishift1")
9391 (and (match_operand 1 "const1_operand" "")
9392 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9395 (const_string "*")))
9396 (set_attr "mode" "QI")])
9398 ;; Convert lea to the lea pattern to avoid flags dependency.
9400 [(set (match_operand 0 "register_operand" "")
9401 (ashift (match_operand 1 "index_register_operand" "")
9402 (match_operand:QI 2 "const_int_operand" "")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 && true_regnum (operands[0]) != true_regnum (operands[1])"
9409 enum machine_mode mode = GET_MODE (operands[0]);
9412 operands[1] = gen_lowpart (Pmode, operands[1]);
9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9415 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9418 operands[0] = gen_lowpart (SImode, operands[0]);
9420 if (TARGET_64BIT && mode != Pmode)
9421 pat = gen_rtx_SUBREG (SImode, pat, 0);
9423 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9427 ;; Convert lea to the lea pattern to avoid flags dependency.
9429 [(set (match_operand:DI 0 "register_operand" "")
9431 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9432 (match_operand:QI 2 "const_int_operand" ""))))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "TARGET_64BIT && reload_completed
9435 && true_regnum (operands[0]) != true_regnum (operands[1])"
9437 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9439 operands[1] = gen_lowpart (DImode, operands[1]);
9440 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9443 ;; This pattern can't accept a variable shift count, since shifts by
9444 ;; zero don't affect the flags. We assume that shifts by constant
9445 ;; zero are optimized away.
9446 (define_insn "*ashl<mode>3_cmp"
9447 [(set (reg FLAGS_REG)
9449 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9450 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9452 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9453 (ashift:SWI (match_dup 1) (match_dup 2)))]
9454 "(optimize_function_for_size_p (cfun)
9455 || !TARGET_PARTIAL_FLAG_REG_STALL
9456 || (operands[2] == const1_rtx
9458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9459 && ix86_match_ccmode (insn, CCGOCmode)
9460 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9462 switch (get_attr_type (insn))
9465 gcc_assert (operands[2] == const1_rtx);
9466 return "add{<imodesuffix>}\t%0, %0";
9469 if (operands[2] == const1_rtx
9470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471 return "sal{<imodesuffix>}\t%0";
9473 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9477 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9479 (match_operand 0 "register_operand" ""))
9480 (match_operand 2 "const1_operand" ""))
9481 (const_string "alu")
9483 (const_string "ishift")))
9484 (set (attr "length_immediate")
9486 (ior (eq_attr "type" "alu")
9487 (and (eq_attr "type" "ishift")
9488 (and (match_operand 2 "const1_operand" "")
9489 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9492 (const_string "*")))
9493 (set_attr "mode" "<MODE>")])
9495 (define_insn "*ashlsi3_cmp_zext"
9496 [(set (reg FLAGS_REG)
9498 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9499 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9501 (set (match_operand:DI 0 "register_operand" "=r")
9502 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9504 && (optimize_function_for_size_p (cfun)
9505 || !TARGET_PARTIAL_FLAG_REG_STALL
9506 || (operands[2] == const1_rtx
9508 || TARGET_DOUBLE_WITH_ADD)))
9509 && ix86_match_ccmode (insn, CCGOCmode)
9510 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9512 switch (get_attr_type (insn))
9515 gcc_assert (operands[2] == const1_rtx);
9516 return "add{l}\t%k0, %k0";
9519 if (operands[2] == const1_rtx
9520 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521 return "sal{l}\t%k0";
9523 return "sal{l}\t{%2, %k0|%k0, %2}";
9527 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9529 (match_operand 2 "const1_operand" ""))
9530 (const_string "alu")
9532 (const_string "ishift")))
9533 (set (attr "length_immediate")
9535 (ior (eq_attr "type" "alu")
9536 (and (eq_attr "type" "ishift")
9537 (and (match_operand 2 "const1_operand" "")
9538 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9541 (const_string "*")))
9542 (set_attr "mode" "SI")])
9544 (define_insn "*ashl<mode>3_cconly"
9545 [(set (reg FLAGS_REG)
9547 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9548 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9550 (clobber (match_scratch:SWI 0 "=<r>"))]
9551 "(optimize_function_for_size_p (cfun)
9552 || !TARGET_PARTIAL_FLAG_REG_STALL
9553 || (operands[2] == const1_rtx
9555 || TARGET_DOUBLE_WITH_ADD)))
9556 && ix86_match_ccmode (insn, CCGOCmode)"
9558 switch (get_attr_type (insn))
9561 gcc_assert (operands[2] == const1_rtx);
9562 return "add{<imodesuffix>}\t%0, %0";
9565 if (operands[2] == const1_rtx
9566 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9567 return "sal{<imodesuffix>}\t%0";
9569 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9575 (match_operand 0 "register_operand" ""))
9576 (match_operand 2 "const1_operand" ""))
9577 (const_string "alu")
9579 (const_string "ishift")))
9580 (set (attr "length_immediate")
9582 (ior (eq_attr "type" "alu")
9583 (and (eq_attr "type" "ishift")
9584 (and (match_operand 2 "const1_operand" "")
9585 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9588 (const_string "*")))
9589 (set_attr "mode" "<MODE>")])
9591 ;; See comment above `ashl<mode>3' about how this works.
9593 (define_expand "<shiftrt_insn><mode>3"
9594 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9595 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9596 (match_operand:QI 2 "nonmemory_operand" "")))]
9598 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9600 ;; Avoid useless masking of count operand.
9601 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9602 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9604 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9607 (match_operand:SI 2 "nonimmediate_operand" "c")
9608 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9609 (clobber (reg:CC FLAGS_REG))]
9610 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9611 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9612 == GET_MODE_BITSIZE (<MODE>mode)-1"
9615 [(parallel [(set (match_dup 0)
9616 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9617 (clobber (reg:CC FLAGS_REG))])]
9619 if (can_create_pseudo_p ())
9620 operands [2] = force_reg (SImode, operands[2]);
9622 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9624 [(set_attr "type" "ishift")
9625 (set_attr "mode" "<MODE>")])
9627 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9628 [(set (match_operand:DWI 0 "register_operand" "=r")
9629 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9630 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9631 (clobber (reg:CC FLAGS_REG))]
9634 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9636 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9637 [(set_attr "type" "multi")])
9639 ;; By default we don't ask for a scratch register, because when DWImode
9640 ;; values are manipulated, registers are already at a premium. But if
9641 ;; we have one handy, we won't turn it away.
9644 [(match_scratch:DWIH 3 "r")
9645 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9647 (match_operand:<DWI> 1 "register_operand" "")
9648 (match_operand:QI 2 "nonmemory_operand" "")))
9649 (clobber (reg:CC FLAGS_REG))])
9653 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9655 (define_insn "x86_64_shrd"
9656 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9657 (ior:DI (ashiftrt:DI (match_dup 0)
9658 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9659 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9660 (minus:QI (const_int 64) (match_dup 2)))))
9661 (clobber (reg:CC FLAGS_REG))]
9663 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9664 [(set_attr "type" "ishift")
9665 (set_attr "prefix_0f" "1")
9666 (set_attr "mode" "DI")
9667 (set_attr "athlon_decode" "vector")
9668 (set_attr "amdfam10_decode" "vector")
9669 (set_attr "bdver1_decode" "vector")])
9671 (define_insn "x86_shrd"
9672 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9673 (ior:SI (ashiftrt:SI (match_dup 0)
9674 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9675 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9676 (minus:QI (const_int 32) (match_dup 2)))))
9677 (clobber (reg:CC FLAGS_REG))]
9679 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9680 [(set_attr "type" "ishift")
9681 (set_attr "prefix_0f" "1")
9682 (set_attr "mode" "SI")
9683 (set_attr "pent_pair" "np")
9684 (set_attr "athlon_decode" "vector")
9685 (set_attr "amdfam10_decode" "vector")
9686 (set_attr "bdver1_decode" "vector")])
9688 (define_insn "ashrdi3_cvt"
9689 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9690 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9691 (match_operand:QI 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "TARGET_64BIT && INTVAL (operands[2]) == 63
9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9698 sar{q}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "imovx,ishift")
9700 (set_attr "prefix_0f" "0,*")
9701 (set_attr "length_immediate" "0,*")
9702 (set_attr "modrm" "0,1")
9703 (set_attr "mode" "DI")])
9705 (define_insn "ashrsi3_cvt"
9706 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9707 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9708 (match_operand:QI 2 "const_int_operand" "")))
9709 (clobber (reg:CC FLAGS_REG))]
9710 "INTVAL (operands[2]) == 31
9711 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9712 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9715 sar{l}\t{%2, %0|%0, %2}"
9716 [(set_attr "type" "imovx,ishift")
9717 (set_attr "prefix_0f" "0,*")
9718 (set_attr "length_immediate" "0,*")
9719 (set_attr "modrm" "0,1")
9720 (set_attr "mode" "SI")])
9722 (define_insn "*ashrsi3_cvt_zext"
9723 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9725 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9726 (match_operand:QI 2 "const_int_operand" ""))))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "TARGET_64BIT && INTVAL (operands[2]) == 31
9729 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9730 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9733 sar{l}\t{%2, %k0|%k0, %2}"
9734 [(set_attr "type" "imovx,ishift")
9735 (set_attr "prefix_0f" "0,*")
9736 (set_attr "length_immediate" "0,*")
9737 (set_attr "modrm" "0,1")
9738 (set_attr "mode" "SI")])
9740 (define_expand "x86_shift<mode>_adj_3"
9741 [(use (match_operand:SWI48 0 "register_operand" ""))
9742 (use (match_operand:SWI48 1 "register_operand" ""))
9743 (use (match_operand:QI 2 "register_operand" ""))]
9746 rtx label = gen_label_rtx ();
9749 emit_insn (gen_testqi_ccz_1 (operands[2],
9750 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9752 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9753 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9754 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9755 gen_rtx_LABEL_REF (VOIDmode, label),
9757 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9758 JUMP_LABEL (tmp) = label;
9760 emit_move_insn (operands[0], operands[1]);
9761 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9762 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9764 LABEL_NUSES (label) = 1;
9769 (define_insn "*<shiftrt_insn><mode>3_1"
9770 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9771 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9772 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shiftrt>{<imodesuffix>}\t%0";
9780 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9782 [(set_attr "type" "ishift")
9783 (set (attr "length_immediate")
9785 (and (match_operand 2 "const1_operand" "")
9786 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9789 (const_string "*")))
9790 (set_attr "mode" "<MODE>")])
9792 (define_insn "*<shiftrt_insn>si3_1_zext"
9793 [(set (match_operand:DI 0 "register_operand" "=r")
9795 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9796 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9800 if (operands[2] == const1_rtx
9801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9802 return "<shiftrt>{l}\t%k0";
9804 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9806 [(set_attr "type" "ishift")
9807 (set (attr "length_immediate")
9809 (and (match_operand 2 "const1_operand" "")
9810 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9813 (const_string "*")))
9814 (set_attr "mode" "SI")])
9816 (define_insn "*<shiftrt_insn>qi3_1_slp"
9817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9818 (any_shiftrt:QI (match_dup 0)
9819 (match_operand:QI 1 "nonmemory_operand" "cI")))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "(optimize_function_for_size_p (cfun)
9822 || !TARGET_PARTIAL_REG_STALL
9823 || (operands[1] == const1_rtx
9826 if (operands[1] == const1_rtx
9827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9828 return "<shiftrt>{b}\t%0";
9830 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9832 [(set_attr "type" "ishift1")
9833 (set (attr "length_immediate")
9835 (and (match_operand 1 "const1_operand" "")
9836 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9839 (const_string "*")))
9840 (set_attr "mode" "QI")])
9842 ;; This pattern can't accept a variable shift count, since shifts by
9843 ;; zero don't affect the flags. We assume that shifts by constant
9844 ;; zero are optimized away.
9845 (define_insn "*<shiftrt_insn><mode>3_cmp"
9846 [(set (reg FLAGS_REG)
9849 (match_operand:SWI 1 "nonimmediate_operand" "0")
9850 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9853 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9854 "(optimize_function_for_size_p (cfun)
9855 || !TARGET_PARTIAL_FLAG_REG_STALL
9856 || (operands[2] == const1_rtx
9858 && ix86_match_ccmode (insn, CCGOCmode)
9859 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9861 if (operands[2] == const1_rtx
9862 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9863 return "<shiftrt>{<imodesuffix>}\t%0";
9865 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9867 [(set_attr "type" "ishift")
9868 (set (attr "length_immediate")
9870 (and (match_operand 2 "const1_operand" "")
9871 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9874 (const_string "*")))
9875 (set_attr "mode" "<MODE>")])
9877 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9878 [(set (reg FLAGS_REG)
9880 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9881 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9883 (set (match_operand:DI 0 "register_operand" "=r")
9884 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9886 && (optimize_function_for_size_p (cfun)
9887 || !TARGET_PARTIAL_FLAG_REG_STALL
9888 || (operands[2] == const1_rtx
9890 && ix86_match_ccmode (insn, CCGOCmode)
9891 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "<shiftrt>{l}\t%k0";
9897 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9899 [(set_attr "type" "ishift")
9900 (set (attr "length_immediate")
9902 (and (match_operand 2 "const1_operand" "")
9903 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9906 (const_string "*")))
9907 (set_attr "mode" "SI")])
9909 (define_insn "*<shiftrt_insn><mode>3_cconly"
9910 [(set (reg FLAGS_REG)
9913 (match_operand:SWI 1 "register_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916 (clobber (match_scratch:SWI 0 "=<r>"))]
9917 "(optimize_function_for_size_p (cfun)
9918 || !TARGET_PARTIAL_FLAG_REG_STALL
9919 || (operands[2] == const1_rtx
9921 && ix86_match_ccmode (insn, CCGOCmode)"
9923 if (operands[2] == const1_rtx
9924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925 return "<shiftrt>{<imodesuffix>}\t%0";
9927 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9929 [(set_attr "type" "ishift")
9930 (set (attr "length_immediate")
9932 (and (match_operand 2 "const1_operand" "")
9933 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9936 (const_string "*")))
9937 (set_attr "mode" "<MODE>")])
9939 ;; Rotate instructions
9941 (define_expand "<rotate_insn>ti3"
9942 [(set (match_operand:TI 0 "register_operand" "")
9943 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9944 (match_operand:QI 2 "nonmemory_operand" "")))]
9947 if (const_1_to_63_operand (operands[2], VOIDmode))
9948 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9949 (operands[0], operands[1], operands[2]));
9956 (define_expand "<rotate_insn>di3"
9957 [(set (match_operand:DI 0 "shiftdi_operand" "")
9958 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9959 (match_operand:QI 2 "nonmemory_operand" "")))]
9963 ix86_expand_binary_operator (<CODE>, DImode, operands);
9964 else if (const_1_to_31_operand (operands[2], VOIDmode))
9965 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9966 (operands[0], operands[1], operands[2]));
9973 (define_expand "<rotate_insn><mode>3"
9974 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9975 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9976 (match_operand:QI 2 "nonmemory_operand" "")))]
9978 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9980 ;; Avoid useless masking of count operand.
9981 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9982 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9984 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9987 (match_operand:SI 2 "nonimmediate_operand" "c")
9988 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9991 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9992 == GET_MODE_BITSIZE (<MODE>mode)-1"
9995 [(parallel [(set (match_dup 0)
9996 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9997 (clobber (reg:CC FLAGS_REG))])]
9999 if (can_create_pseudo_p ())
10000 operands [2] = force_reg (SImode, operands[2]);
10002 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10004 [(set_attr "type" "rotate")
10005 (set_attr "mode" "<MODE>")])
10007 ;; Implement rotation using two double-precision
10008 ;; shift instructions and a scratch register.
10010 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10011 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10012 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10013 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10014 (clobber (reg:CC FLAGS_REG))
10015 (clobber (match_scratch:DWIH 3 "=&r"))]
10019 [(set (match_dup 3) (match_dup 4))
10021 [(set (match_dup 4)
10022 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10023 (lshiftrt:DWIH (match_dup 5)
10024 (minus:QI (match_dup 6) (match_dup 2)))))
10025 (clobber (reg:CC FLAGS_REG))])
10027 [(set (match_dup 5)
10028 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10029 (lshiftrt:DWIH (match_dup 3)
10030 (minus:QI (match_dup 6) (match_dup 2)))))
10031 (clobber (reg:CC FLAGS_REG))])]
10033 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10035 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10038 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10039 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10040 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10041 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10042 (clobber (reg:CC FLAGS_REG))
10043 (clobber (match_scratch:DWIH 3 "=&r"))]
10047 [(set (match_dup 3) (match_dup 4))
10049 [(set (match_dup 4)
10050 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10051 (ashift:DWIH (match_dup 5)
10052 (minus:QI (match_dup 6) (match_dup 2)))))
10053 (clobber (reg:CC FLAGS_REG))])
10055 [(set (match_dup 5)
10056 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10057 (ashift:DWIH (match_dup 3)
10058 (minus:QI (match_dup 6) (match_dup 2)))))
10059 (clobber (reg:CC FLAGS_REG))])]
10061 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10063 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10066 (define_insn "*<rotate_insn><mode>3_1"
10067 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10068 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10069 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10073 if (operands[2] == const1_rtx
10074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10075 return "<rotate>{<imodesuffix>}\t%0";
10077 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10079 [(set_attr "type" "rotate")
10080 (set (attr "length_immediate")
10082 (and (match_operand 2 "const1_operand" "")
10083 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10086 (const_string "*")))
10087 (set_attr "mode" "<MODE>")])
10089 (define_insn "*<rotate_insn>si3_1_zext"
10090 [(set (match_operand:DI 0 "register_operand" "=r")
10092 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10093 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10097 if (operands[2] == const1_rtx
10098 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10099 return "<rotate>{l}\t%k0";
10101 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10103 [(set_attr "type" "rotate")
10104 (set (attr "length_immediate")
10106 (and (match_operand 2 "const1_operand" "")
10107 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10110 (const_string "*")))
10111 (set_attr "mode" "SI")])
10113 (define_insn "*<rotate_insn>qi3_1_slp"
10114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10115 (any_rotate:QI (match_dup 0)
10116 (match_operand:QI 1 "nonmemory_operand" "cI")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_REG_STALL
10120 || (operands[1] == const1_rtx
10121 && TARGET_SHIFT1))"
10123 if (operands[1] == const1_rtx
10124 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10125 return "<rotate>{b}\t%0";
10127 return "<rotate>{b}\t{%1, %0|%0, %1}";
10129 [(set_attr "type" "rotate1")
10130 (set (attr "length_immediate")
10132 (and (match_operand 1 "const1_operand" "")
10133 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10136 (const_string "*")))
10137 (set_attr "mode" "QI")])
10140 [(set (match_operand:HI 0 "register_operand" "")
10141 (any_rotate:HI (match_dup 0) (const_int 8)))
10142 (clobber (reg:CC FLAGS_REG))]
10144 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10145 [(parallel [(set (strict_low_part (match_dup 0))
10146 (bswap:HI (match_dup 0)))
10147 (clobber (reg:CC FLAGS_REG))])])
10149 ;; Bit set / bit test instructions
10151 (define_expand "extv"
10152 [(set (match_operand:SI 0 "register_operand" "")
10153 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10154 (match_operand:SI 2 "const8_operand" "")
10155 (match_operand:SI 3 "const8_operand" "")))]
10158 /* Handle extractions from %ah et al. */
10159 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10162 /* From mips.md: extract_bit_field doesn't verify that our source
10163 matches the predicate, so check it again here. */
10164 if (! ext_register_operand (operands[1], VOIDmode))
10168 (define_expand "extzv"
10169 [(set (match_operand:SI 0 "register_operand" "")
10170 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10171 (match_operand:SI 2 "const8_operand" "")
10172 (match_operand:SI 3 "const8_operand" "")))]
10175 /* Handle extractions from %ah et al. */
10176 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10179 /* From mips.md: extract_bit_field doesn't verify that our source
10180 matches the predicate, so check it again here. */
10181 if (! ext_register_operand (operands[1], VOIDmode))
10185 (define_expand "insv"
10186 [(set (zero_extract (match_operand 0 "register_operand" "")
10187 (match_operand 1 "const_int_operand" "")
10188 (match_operand 2 "const_int_operand" ""))
10189 (match_operand 3 "register_operand" ""))]
10192 rtx (*gen_mov_insv_1) (rtx, rtx);
10194 if (ix86_expand_pinsr (operands))
10197 /* Handle insertions to %ah et al. */
10198 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10201 /* From mips.md: insert_bit_field doesn't verify that our source
10202 matches the predicate, so check it again here. */
10203 if (! ext_register_operand (operands[0], VOIDmode))
10206 gen_mov_insv_1 = (TARGET_64BIT
10207 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10209 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10213 ;; %%% bts, btr, btc, bt.
10214 ;; In general these instructions are *slow* when applied to memory,
10215 ;; since they enforce atomic operation. When applied to registers,
10216 ;; it depends on the cpu implementation. They're never faster than
10217 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10218 ;; no point. But in 64-bit, we can't hold the relevant immediates
10219 ;; within the instruction itself, so operating on bits in the high
10220 ;; 32-bits of a register becomes easier.
10222 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10223 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10224 ;; negdf respectively, so they can never be disabled entirely.
10226 (define_insn "*btsq"
10227 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10229 (match_operand:DI 1 "const_0_to_63_operand" ""))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10233 "bts{q}\t{%1, %0|%0, %1}"
10234 [(set_attr "type" "alu1")
10235 (set_attr "prefix_0f" "1")
10236 (set_attr "mode" "DI")])
10238 (define_insn "*btrq"
10239 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10241 (match_operand:DI 1 "const_0_to_63_operand" ""))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10245 "btr{q}\t{%1, %0|%0, %1}"
10246 [(set_attr "type" "alu1")
10247 (set_attr "prefix_0f" "1")
10248 (set_attr "mode" "DI")])
10250 (define_insn "*btcq"
10251 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10253 (match_operand:DI 1 "const_0_to_63_operand" ""))
10254 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10255 (clobber (reg:CC FLAGS_REG))]
10256 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10257 "btc{q}\t{%1, %0|%0, %1}"
10258 [(set_attr "type" "alu1")
10259 (set_attr "prefix_0f" "1")
10260 (set_attr "mode" "DI")])
10262 ;; Allow Nocona to avoid these instructions if a register is available.
10265 [(match_scratch:DI 2 "r")
10266 (parallel [(set (zero_extract:DI
10267 (match_operand:DI 0 "register_operand" "")
10269 (match_operand:DI 1 "const_0_to_63_operand" ""))
10271 (clobber (reg:CC FLAGS_REG))])]
10272 "TARGET_64BIT && !TARGET_USE_BT"
10275 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10278 if (HOST_BITS_PER_WIDE_INT >= 64)
10279 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10280 else if (i < HOST_BITS_PER_WIDE_INT)
10281 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10283 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10285 op1 = immed_double_const (lo, hi, DImode);
10288 emit_move_insn (operands[2], op1);
10292 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10297 [(match_scratch:DI 2 "r")
10298 (parallel [(set (zero_extract:DI
10299 (match_operand:DI 0 "register_operand" "")
10301 (match_operand:DI 1 "const_0_to_63_operand" ""))
10303 (clobber (reg:CC FLAGS_REG))])]
10304 "TARGET_64BIT && !TARGET_USE_BT"
10307 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10310 if (HOST_BITS_PER_WIDE_INT >= 64)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 else if (i < HOST_BITS_PER_WIDE_INT)
10313 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10315 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10317 op1 = immed_double_const (~lo, ~hi, DImode);
10320 emit_move_insn (operands[2], op1);
10324 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10329 [(match_scratch:DI 2 "r")
10330 (parallel [(set (zero_extract:DI
10331 (match_operand:DI 0 "register_operand" "")
10333 (match_operand:DI 1 "const_0_to_63_operand" ""))
10334 (not:DI (zero_extract:DI
10335 (match_dup 0) (const_int 1) (match_dup 1))))
10336 (clobber (reg:CC FLAGS_REG))])]
10337 "TARGET_64BIT && !TARGET_USE_BT"
10340 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10343 if (HOST_BITS_PER_WIDE_INT >= 64)
10344 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10345 else if (i < HOST_BITS_PER_WIDE_INT)
10346 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10348 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10350 op1 = immed_double_const (lo, hi, DImode);
10353 emit_move_insn (operands[2], op1);
10357 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10361 (define_insn "*bt<mode>"
10362 [(set (reg:CCC FLAGS_REG)
10364 (zero_extract:SWI48
10365 (match_operand:SWI48 0 "register_operand" "r")
10367 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10369 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10370 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10371 [(set_attr "type" "alu1")
10372 (set_attr "prefix_0f" "1")
10373 (set_attr "mode" "<MODE>")])
10375 ;; Store-flag instructions.
10377 ;; For all sCOND expanders, also expand the compare or test insn that
10378 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10380 (define_insn_and_split "*setcc_di_1"
10381 [(set (match_operand:DI 0 "register_operand" "=q")
10382 (match_operator:DI 1 "ix86_comparison_operator"
10383 [(reg FLAGS_REG) (const_int 0)]))]
10384 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10386 "&& reload_completed"
10387 [(set (match_dup 2) (match_dup 1))
10388 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10390 PUT_MODE (operands[1], QImode);
10391 operands[2] = gen_lowpart (QImode, operands[0]);
10394 (define_insn_and_split "*setcc_si_1_and"
10395 [(set (match_operand:SI 0 "register_operand" "=q")
10396 (match_operator:SI 1 "ix86_comparison_operator"
10397 [(reg FLAGS_REG) (const_int 0)]))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "!TARGET_PARTIAL_REG_STALL
10400 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10402 "&& reload_completed"
10403 [(set (match_dup 2) (match_dup 1))
10404 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10405 (clobber (reg:CC FLAGS_REG))])]
10407 PUT_MODE (operands[1], QImode);
10408 operands[2] = gen_lowpart (QImode, operands[0]);
10411 (define_insn_and_split "*setcc_si_1_movzbl"
10412 [(set (match_operand:SI 0 "register_operand" "=q")
10413 (match_operator:SI 1 "ix86_comparison_operator"
10414 [(reg FLAGS_REG) (const_int 0)]))]
10415 "!TARGET_PARTIAL_REG_STALL
10416 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10418 "&& reload_completed"
10419 [(set (match_dup 2) (match_dup 1))
10420 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10422 PUT_MODE (operands[1], QImode);
10423 operands[2] = gen_lowpart (QImode, operands[0]);
10426 (define_insn "*setcc_qi"
10427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10428 (match_operator:QI 1 "ix86_comparison_operator"
10429 [(reg FLAGS_REG) (const_int 0)]))]
10432 [(set_attr "type" "setcc")
10433 (set_attr "mode" "QI")])
10435 (define_insn "*setcc_qi_slp"
10436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10437 (match_operator:QI 1 "ix86_comparison_operator"
10438 [(reg FLAGS_REG) (const_int 0)]))]
10441 [(set_attr "type" "setcc")
10442 (set_attr "mode" "QI")])
10444 ;; In general it is not safe to assume too much about CCmode registers,
10445 ;; so simplify-rtx stops when it sees a second one. Under certain
10446 ;; conditions this is safe on x86, so help combine not create
10453 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10454 (ne:QI (match_operator 1 "ix86_comparison_operator"
10455 [(reg FLAGS_REG) (const_int 0)])
10458 [(set (match_dup 0) (match_dup 1))]
10459 "PUT_MODE (operands[1], QImode);")
10462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10463 (ne:QI (match_operator 1 "ix86_comparison_operator"
10464 [(reg FLAGS_REG) (const_int 0)])
10467 [(set (match_dup 0) (match_dup 1))]
10468 "PUT_MODE (operands[1], QImode);")
10471 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10472 (eq:QI (match_operator 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)])
10476 [(set (match_dup 0) (match_dup 1))]
10478 rtx new_op1 = copy_rtx (operands[1]);
10479 operands[1] = new_op1;
10480 PUT_MODE (new_op1, QImode);
10481 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10482 GET_MODE (XEXP (new_op1, 0))));
10484 /* Make sure that (a) the CCmode we have for the flags is strong
10485 enough for the reversed compare or (b) we have a valid FP compare. */
10486 if (! ix86_comparison_operator (new_op1, VOIDmode))
10491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10492 (eq:QI (match_operator 1 "ix86_comparison_operator"
10493 [(reg FLAGS_REG) (const_int 0)])
10496 [(set (match_dup 0) (match_dup 1))]
10498 rtx new_op1 = copy_rtx (operands[1]);
10499 operands[1] = new_op1;
10500 PUT_MODE (new_op1, QImode);
10501 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10502 GET_MODE (XEXP (new_op1, 0))));
10504 /* Make sure that (a) the CCmode we have for the flags is strong
10505 enough for the reversed compare or (b) we have a valid FP compare. */
10506 if (! ix86_comparison_operator (new_op1, VOIDmode))
10510 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10511 ;; subsequent logical operations are used to imitate conditional moves.
10512 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10515 (define_insn "setcc_<mode>_sse"
10516 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10517 (match_operator:MODEF 3 "sse_comparison_operator"
10518 [(match_operand:MODEF 1 "register_operand" "0,x")
10519 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10520 "SSE_FLOAT_MODE_P (<MODE>mode)"
10522 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10523 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10524 [(set_attr "isa" "noavx,avx")
10525 (set_attr "type" "ssecmp")
10526 (set_attr "length_immediate" "1")
10527 (set_attr "prefix" "orig,vex")
10528 (set_attr "mode" "<MODE>")])
10530 ;; Basic conditional jump instructions.
10531 ;; We ignore the overflow flag for signed branch instructions.
10533 (define_insn "*jcc_1"
10535 (if_then_else (match_operator 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)])
10537 (label_ref (match_operand 0 "" ""))
10541 [(set_attr "type" "ibr")
10542 (set_attr "modrm" "0")
10543 (set (attr "length")
10544 (if_then_else (and (ge (minus (match_dup 0) (pc))
10546 (lt (minus (match_dup 0) (pc))
10551 (define_insn "*jcc_2"
10553 (if_then_else (match_operator 1 "ix86_comparison_operator"
10554 [(reg FLAGS_REG) (const_int 0)])
10556 (label_ref (match_operand 0 "" ""))))]
10559 [(set_attr "type" "ibr")
10560 (set_attr "modrm" "0")
10561 (set (attr "length")
10562 (if_then_else (and (ge (minus (match_dup 0) (pc))
10564 (lt (minus (match_dup 0) (pc))
10569 ;; In general it is not safe to assume too much about CCmode registers,
10570 ;; so simplify-rtx stops when it sees a second one. Under certain
10571 ;; conditions this is safe on x86, so help combine not create
10579 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10580 [(reg FLAGS_REG) (const_int 0)])
10582 (label_ref (match_operand 1 "" ""))
10586 (if_then_else (match_dup 0)
10587 (label_ref (match_dup 1))
10589 "PUT_MODE (operands[0], VOIDmode);")
10593 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)])
10596 (label_ref (match_operand 1 "" ""))
10600 (if_then_else (match_dup 0)
10601 (label_ref (match_dup 1))
10604 rtx new_op0 = copy_rtx (operands[0]);
10605 operands[0] = new_op0;
10606 PUT_MODE (new_op0, VOIDmode);
10607 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10608 GET_MODE (XEXP (new_op0, 0))));
10610 /* Make sure that (a) the CCmode we have for the flags is strong
10611 enough for the reversed compare or (b) we have a valid FP compare. */
10612 if (! ix86_comparison_operator (new_op0, VOIDmode))
10616 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10617 ;; pass generates from shift insn with QImode operand. Actually, the mode
10618 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10619 ;; appropriate modulo of the bit offset value.
10621 (define_insn_and_split "*jcc_bt<mode>"
10623 (if_then_else (match_operator 0 "bt_comparison_operator"
10624 [(zero_extract:SWI48
10625 (match_operand:SWI48 1 "register_operand" "r")
10628 (match_operand:QI 2 "register_operand" "r")))
10630 (label_ref (match_operand 3 "" ""))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10636 [(set (reg:CCC FLAGS_REG)
10638 (zero_extract:SWI48
10644 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10645 (label_ref (match_dup 3))
10648 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10650 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10653 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10654 ;; also for DImode, this is what combine produces.
10655 (define_insn_and_split "*jcc_bt<mode>_mask"
10657 (if_then_else (match_operator 0 "bt_comparison_operator"
10658 [(zero_extract:SWI48
10659 (match_operand:SWI48 1 "register_operand" "r")
10662 (match_operand:SI 2 "register_operand" "r")
10663 (match_operand:SI 3 "const_int_operand" "n")))])
10664 (label_ref (match_operand 4 "" ""))
10666 (clobber (reg:CC FLAGS_REG))]
10667 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10668 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10669 == GET_MODE_BITSIZE (<MODE>mode)-1"
10672 [(set (reg:CCC FLAGS_REG)
10674 (zero_extract:SWI48
10680 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10681 (label_ref (match_dup 4))
10684 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10686 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10689 (define_insn_and_split "*jcc_btsi_1"
10691 (if_then_else (match_operator 0 "bt_comparison_operator"
10694 (match_operand:SI 1 "register_operand" "r")
10695 (match_operand:QI 2 "register_operand" "r"))
10698 (label_ref (match_operand 3 "" ""))
10700 (clobber (reg:CC FLAGS_REG))]
10701 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10704 [(set (reg:CCC FLAGS_REG)
10712 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10713 (label_ref (match_dup 3))
10716 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10718 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10721 ;; avoid useless masking of bit offset operand
10722 (define_insn_and_split "*jcc_btsi_mask_1"
10725 (match_operator 0 "bt_comparison_operator"
10728 (match_operand:SI 1 "register_operand" "r")
10731 (match_operand:SI 2 "register_operand" "r")
10732 (match_operand:SI 3 "const_int_operand" "n")) 0))
10735 (label_ref (match_operand 4 "" ""))
10737 (clobber (reg:CC FLAGS_REG))]
10738 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10739 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10742 [(set (reg:CCC FLAGS_REG)
10750 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10751 (label_ref (match_dup 4))
10753 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10755 ;; Define combination compare-and-branch fp compare instructions to help
10758 (define_insn "*fp_jcc_1_387"
10760 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10761 [(match_operand 1 "register_operand" "f")
10762 (match_operand 2 "nonimmediate_operand" "fm")])
10763 (label_ref (match_operand 3 "" ""))
10765 (clobber (reg:CCFP FPSR_REG))
10766 (clobber (reg:CCFP FLAGS_REG))
10767 (clobber (match_scratch:HI 4 "=a"))]
10769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10771 && SELECT_CC_MODE (GET_CODE (operands[0]),
10772 operands[1], operands[2]) == CCFPmode
10776 (define_insn "*fp_jcc_1r_387"
10778 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10779 [(match_operand 1 "register_operand" "f")
10780 (match_operand 2 "nonimmediate_operand" "fm")])
10782 (label_ref (match_operand 3 "" ""))))
10783 (clobber (reg:CCFP FPSR_REG))
10784 (clobber (reg:CCFP FLAGS_REG))
10785 (clobber (match_scratch:HI 4 "=a"))]
10787 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10789 && SELECT_CC_MODE (GET_CODE (operands[0]),
10790 operands[1], operands[2]) == CCFPmode
10794 (define_insn "*fp_jcc_2_387"
10796 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10797 [(match_operand 1 "register_operand" "f")
10798 (match_operand 2 "register_operand" "f")])
10799 (label_ref (match_operand 3 "" ""))
10801 (clobber (reg:CCFP FPSR_REG))
10802 (clobber (reg:CCFP FLAGS_REG))
10803 (clobber (match_scratch:HI 4 "=a"))]
10804 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10809 (define_insn "*fp_jcc_2r_387"
10811 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10812 [(match_operand 1 "register_operand" "f")
10813 (match_operand 2 "register_operand" "f")])
10815 (label_ref (match_operand 3 "" ""))))
10816 (clobber (reg:CCFP FPSR_REG))
10817 (clobber (reg:CCFP FLAGS_REG))
10818 (clobber (match_scratch:HI 4 "=a"))]
10819 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10820 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10824 (define_insn "*fp_jcc_3_387"
10826 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10827 [(match_operand 1 "register_operand" "f")
10828 (match_operand 2 "const0_operand" "")])
10829 (label_ref (match_operand 3 "" ""))
10831 (clobber (reg:CCFP FPSR_REG))
10832 (clobber (reg:CCFP FLAGS_REG))
10833 (clobber (match_scratch:HI 4 "=a"))]
10834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10836 && SELECT_CC_MODE (GET_CODE (operands[0]),
10837 operands[1], operands[2]) == CCFPmode
10843 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10844 [(match_operand 1 "register_operand" "")
10845 (match_operand 2 "nonimmediate_operand" "")])
10846 (match_operand 3 "" "")
10847 (match_operand 4 "" "")))
10848 (clobber (reg:CCFP FPSR_REG))
10849 (clobber (reg:CCFP FLAGS_REG))]
10853 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10854 operands[3], operands[4], NULL_RTX, NULL_RTX);
10860 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10861 [(match_operand 1 "register_operand" "")
10862 (match_operand 2 "general_operand" "")])
10863 (match_operand 3 "" "")
10864 (match_operand 4 "" "")))
10865 (clobber (reg:CCFP FPSR_REG))
10866 (clobber (reg:CCFP FLAGS_REG))
10867 (clobber (match_scratch:HI 5 "=a"))]
10871 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10872 operands[3], operands[4], operands[5], NULL_RTX);
10876 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10877 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10878 ;; with a precedence over other operators and is always put in the first
10879 ;; place. Swap condition and operands to match ficom instruction.
10881 (define_insn "*fp_jcc_4_<mode>_387"
10884 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10885 [(match_operator 1 "float_operator"
10886 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10887 (match_operand 3 "register_operand" "f,f")])
10888 (label_ref (match_operand 4 "" ""))
10890 (clobber (reg:CCFP FPSR_REG))
10891 (clobber (reg:CCFP FLAGS_REG))
10892 (clobber (match_scratch:HI 5 "=a,a"))]
10893 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10894 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10895 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10896 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10903 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10904 [(match_operator 1 "float_operator"
10905 [(match_operand:SWI24 2 "memory_operand" "")])
10906 (match_operand 3 "register_operand" "")])
10907 (match_operand 4 "" "")
10908 (match_operand 5 "" "")))
10909 (clobber (reg:CCFP FPSR_REG))
10910 (clobber (reg:CCFP FLAGS_REG))
10911 (clobber (match_scratch:HI 6 "=a"))]
10915 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10917 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10918 operands[3], operands[7],
10919 operands[4], operands[5], operands[6], NULL_RTX);
10923 ;; %%% Kill this when reload knows how to do it.
10927 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10928 [(match_operator 1 "float_operator"
10929 [(match_operand:SWI24 2 "register_operand" "")])
10930 (match_operand 3 "register_operand" "")])
10931 (match_operand 4 "" "")
10932 (match_operand 5 "" "")))
10933 (clobber (reg:CCFP FPSR_REG))
10934 (clobber (reg:CCFP FLAGS_REG))
10935 (clobber (match_scratch:HI 6 "=a"))]
10939 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10940 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10942 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10943 operands[3], operands[7],
10944 operands[4], operands[5], operands[6], operands[2]);
10948 ;; Unconditional and other jump instructions
10950 (define_insn "jump"
10952 (label_ref (match_operand 0 "" "")))]
10955 [(set_attr "type" "ibr")
10956 (set (attr "length")
10957 (if_then_else (and (ge (minus (match_dup 0) (pc))
10959 (lt (minus (match_dup 0) (pc))
10963 (set_attr "modrm" "0")])
10965 (define_expand "indirect_jump"
10966 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10970 (define_insn "*indirect_jump"
10971 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10974 [(set_attr "type" "ibr")
10975 (set_attr "length_immediate" "0")])
10977 (define_expand "tablejump"
10978 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10979 (use (label_ref (match_operand 1 "" "")))])]
10982 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10983 relative. Convert the relative address to an absolute address. */
10987 enum rtx_code code;
10989 /* We can't use @GOTOFF for text labels on VxWorks;
10990 see gotoff_operand. */
10991 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10995 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10997 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11001 op1 = pic_offset_table_rtx;
11006 op0 = pic_offset_table_rtx;
11010 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11015 (define_insn "*tablejump_1"
11016 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11017 (use (label_ref (match_operand 1 "" "")))]
11020 [(set_attr "type" "ibr")
11021 (set_attr "length_immediate" "0")])
11023 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11026 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11027 (set (match_operand:QI 1 "register_operand" "")
11028 (match_operator:QI 2 "ix86_comparison_operator"
11029 [(reg FLAGS_REG) (const_int 0)]))
11030 (set (match_operand 3 "q_regs_operand" "")
11031 (zero_extend (match_dup 1)))]
11032 "(peep2_reg_dead_p (3, operands[1])
11033 || operands_match_p (operands[1], operands[3]))
11034 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11035 [(set (match_dup 4) (match_dup 0))
11036 (set (strict_low_part (match_dup 5))
11039 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11040 operands[5] = gen_lowpart (QImode, operands[3]);
11041 ix86_expand_clear (operands[3]);
11044 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11047 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11048 (set (match_operand:QI 1 "register_operand" "")
11049 (match_operator:QI 2 "ix86_comparison_operator"
11050 [(reg FLAGS_REG) (const_int 0)]))
11051 (parallel [(set (match_operand 3 "q_regs_operand" "")
11052 (zero_extend (match_dup 1)))
11053 (clobber (reg:CC FLAGS_REG))])]
11054 "(peep2_reg_dead_p (3, operands[1])
11055 || operands_match_p (operands[1], operands[3]))
11056 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11057 [(set (match_dup 4) (match_dup 0))
11058 (set (strict_low_part (match_dup 5))
11061 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11062 operands[5] = gen_lowpart (QImode, operands[3]);
11063 ix86_expand_clear (operands[3]);
11066 ;; Call instructions.
11068 ;; The predicates normally associated with named expanders are not properly
11069 ;; checked for calls. This is a bug in the generic code, but it isn't that
11070 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11072 ;; P6 processors will jump to the address after the decrement when %esp
11073 ;; is used as a call operand, so they will execute return address as a code.
11074 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11076 ;; Register constraint for call instruction.
11077 (define_mode_attr c [(SI "l") (DI "r")])
11079 ;; Call subroutine returning no value.
11081 (define_expand "call"
11082 [(call (match_operand:QI 0 "" "")
11083 (match_operand 1 "" ""))
11084 (use (match_operand 2 "" ""))]
11087 ix86_expand_call (NULL, operands[0], operands[1],
11088 operands[2], NULL, false);
11092 (define_expand "sibcall"
11093 [(call (match_operand:QI 0 "" "")
11094 (match_operand 1 "" ""))
11095 (use (match_operand 2 "" ""))]
11098 ix86_expand_call (NULL, operands[0], operands[1],
11099 operands[2], NULL, true);
11103 (define_insn_and_split "*call_vzeroupper"
11104 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11105 (match_operand 1 "" ""))
11106 (unspec [(match_operand 2 "const_int_operand" "")]
11107 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11108 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11110 "&& reload_completed"
11112 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11113 [(set_attr "type" "call")])
11115 (define_insn "*call"
11116 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11117 (match_operand 1 "" ""))]
11118 "!SIBLING_CALL_P (insn)"
11119 "* return ix86_output_call_insn (insn, operands[0]);"
11120 [(set_attr "type" "call")])
11122 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11124 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11125 (match_operand 1 "" ""))
11126 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11127 (clobber (reg:TI XMM6_REG))
11128 (clobber (reg:TI XMM7_REG))
11129 (clobber (reg:TI XMM8_REG))
11130 (clobber (reg:TI XMM9_REG))
11131 (clobber (reg:TI XMM10_REG))
11132 (clobber (reg:TI XMM11_REG))
11133 (clobber (reg:TI XMM12_REG))
11134 (clobber (reg:TI XMM13_REG))
11135 (clobber (reg:TI XMM14_REG))
11136 (clobber (reg:TI XMM15_REG))
11137 (clobber (reg:DI SI_REG))
11138 (clobber (reg:DI DI_REG))])
11139 (unspec [(match_operand 2 "const_int_operand" "")]
11140 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11141 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11143 "&& reload_completed"
11145 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11146 [(set_attr "type" "call")])
11148 (define_insn "*call_rex64_ms_sysv"
11149 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11150 (match_operand 1 "" ""))
11151 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11152 (clobber (reg:TI XMM6_REG))
11153 (clobber (reg:TI XMM7_REG))
11154 (clobber (reg:TI XMM8_REG))
11155 (clobber (reg:TI XMM9_REG))
11156 (clobber (reg:TI XMM10_REG))
11157 (clobber (reg:TI XMM11_REG))
11158 (clobber (reg:TI XMM12_REG))
11159 (clobber (reg:TI XMM13_REG))
11160 (clobber (reg:TI XMM14_REG))
11161 (clobber (reg:TI XMM15_REG))
11162 (clobber (reg:DI SI_REG))
11163 (clobber (reg:DI DI_REG))]
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_vzeroupper"
11169 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11170 (match_operand 1 "" ""))
11171 (unspec [(match_operand 2 "const_int_operand" "")]
11172 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11173 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11175 "&& reload_completed"
11177 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11178 [(set_attr "type" "call")])
11180 (define_insn "*sibcall"
11181 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11182 (match_operand 1 "" ""))]
11183 "SIBLING_CALL_P (insn)"
11184 "* return ix86_output_call_insn (insn, operands[0]);"
11185 [(set_attr "type" "call")])
11187 (define_expand "call_pop"
11188 [(parallel [(call (match_operand:QI 0 "" "")
11189 (match_operand:SI 1 "" ""))
11190 (set (reg:SI SP_REG)
11191 (plus:SI (reg:SI SP_REG)
11192 (match_operand:SI 3 "" "")))])]
11195 ix86_expand_call (NULL, operands[0], operands[1],
11196 operands[2], operands[3], false);
11200 (define_insn_and_split "*call_pop_vzeroupper"
11202 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11203 (match_operand:SI 1 "" ""))
11204 (set (reg:SI SP_REG)
11205 (plus:SI (reg:SI SP_REG)
11206 (match_operand:SI 2 "immediate_operand" "i")))])
11207 (unspec [(match_operand 3 "const_int_operand" "")]
11208 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11209 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11211 "&& reload_completed"
11213 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11214 [(set_attr "type" "call")])
11216 (define_insn "*call_pop"
11217 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11218 (match_operand 1 "" ""))
11219 (set (reg:SI SP_REG)
11220 (plus:SI (reg:SI SP_REG)
11221 (match_operand:SI 2 "immediate_operand" "i")))]
11222 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11223 "* return ix86_output_call_insn (insn, operands[0]);"
11224 [(set_attr "type" "call")])
11226 (define_insn_and_split "*sibcall_pop_vzeroupper"
11228 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11229 (match_operand 1 "" ""))
11230 (set (reg:SI SP_REG)
11231 (plus:SI (reg:SI SP_REG)
11232 (match_operand:SI 2 "immediate_operand" "i")))])
11233 (unspec [(match_operand 3 "const_int_operand" "")]
11234 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11235 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11237 "&& reload_completed"
11239 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11240 [(set_attr "type" "call")])
11242 (define_insn "*sibcall_pop"
11243 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11244 (match_operand 1 "" ""))
11245 (set (reg:SI SP_REG)
11246 (plus:SI (reg:SI SP_REG)
11247 (match_operand:SI 2 "immediate_operand" "i")))]
11248 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11249 "* return ix86_output_call_insn (insn, operands[0]);"
11250 [(set_attr "type" "call")])
11252 ;; Call subroutine, returning value in operand 0
11254 (define_expand "call_value"
11255 [(set (match_operand 0 "" "")
11256 (call (match_operand:QI 1 "" "")
11257 (match_operand 2 "" "")))
11258 (use (match_operand 3 "" ""))]
11261 ix86_expand_call (operands[0], operands[1], operands[2],
11262 operands[3], NULL, false);
11266 (define_expand "sibcall_value"
11267 [(set (match_operand 0 "" "")
11268 (call (match_operand:QI 1 "" "")
11269 (match_operand 2 "" "")))
11270 (use (match_operand 3 "" ""))]
11273 ix86_expand_call (operands[0], operands[1], operands[2],
11274 operands[3], NULL, true);
11278 (define_insn_and_split "*call_value_vzeroupper"
11279 [(set (match_operand 0 "" "")
11280 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11281 (match_operand 2 "" "")))
11282 (unspec [(match_operand 3 "const_int_operand" "")]
11283 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11284 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11286 "&& reload_completed"
11288 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11289 [(set_attr "type" "callv")])
11291 (define_insn "*call_value"
11292 [(set (match_operand 0 "" "")
11293 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11294 (match_operand 2 "" "")))]
11295 "!SIBLING_CALL_P (insn)"
11296 "* return ix86_output_call_insn (insn, operands[1]);"
11297 [(set_attr "type" "callv")])
11299 (define_insn_and_split "*sibcall_value_vzeroupper"
11300 [(set (match_operand 0 "" "")
11301 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11302 (match_operand 2 "" "")))
11303 (unspec [(match_operand 3 "const_int_operand" "")]
11304 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11305 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11307 "&& reload_completed"
11309 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11310 [(set_attr "type" "callv")])
11312 (define_insn "*sibcall_value"
11313 [(set (match_operand 0 "" "")
11314 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11315 (match_operand 2 "" "")))]
11316 "SIBLING_CALL_P (insn)"
11317 "* return ix86_output_call_insn (insn, operands[1]);"
11318 [(set_attr "type" "callv")])
11320 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11322 [(set (match_operand 0 "" "")
11323 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11324 (match_operand 2 "" "")))
11325 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11326 (clobber (reg:TI XMM6_REG))
11327 (clobber (reg:TI XMM7_REG))
11328 (clobber (reg:TI XMM8_REG))
11329 (clobber (reg:TI XMM9_REG))
11330 (clobber (reg:TI XMM10_REG))
11331 (clobber (reg:TI XMM11_REG))
11332 (clobber (reg:TI XMM12_REG))
11333 (clobber (reg:TI XMM13_REG))
11334 (clobber (reg:TI XMM14_REG))
11335 (clobber (reg:TI XMM15_REG))
11336 (clobber (reg:DI SI_REG))
11337 (clobber (reg:DI DI_REG))])
11338 (unspec [(match_operand 3 "const_int_operand" "")]
11339 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11340 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11342 "&& reload_completed"
11344 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11345 [(set_attr "type" "callv")])
11347 (define_insn "*call_value_rex64_ms_sysv"
11348 [(set (match_operand 0 "" "")
11349 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11350 (match_operand 2 "" "")))
11351 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11352 (clobber (reg:TI XMM6_REG))
11353 (clobber (reg:TI XMM7_REG))
11354 (clobber (reg:TI XMM8_REG))
11355 (clobber (reg:TI XMM9_REG))
11356 (clobber (reg:TI XMM10_REG))
11357 (clobber (reg:TI XMM11_REG))
11358 (clobber (reg:TI XMM12_REG))
11359 (clobber (reg:TI XMM13_REG))
11360 (clobber (reg:TI XMM14_REG))
11361 (clobber (reg:TI XMM15_REG))
11362 (clobber (reg:DI SI_REG))
11363 (clobber (reg:DI DI_REG))]
11364 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11365 "* return ix86_output_call_insn (insn, operands[1]);"
11366 [(set_attr "type" "callv")])
11368 (define_expand "call_value_pop"
11369 [(parallel [(set (match_operand 0 "" "")
11370 (call (match_operand:QI 1 "" "")
11371 (match_operand:SI 2 "" "")))
11372 (set (reg:SI SP_REG)
11373 (plus:SI (reg:SI SP_REG)
11374 (match_operand:SI 4 "" "")))])]
11377 ix86_expand_call (operands[0], operands[1], operands[2],
11378 operands[3], operands[4], false);
11382 (define_insn_and_split "*call_value_pop_vzeroupper"
11384 [(set (match_operand 0 "" "")
11385 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11386 (match_operand 2 "" "")))
11387 (set (reg:SI SP_REG)
11388 (plus:SI (reg:SI SP_REG)
11389 (match_operand:SI 3 "immediate_operand" "i")))])
11390 (unspec [(match_operand 4 "const_int_operand" "")]
11391 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11392 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11394 "&& reload_completed"
11396 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11397 [(set_attr "type" "callv")])
11399 (define_insn "*call_value_pop"
11400 [(set (match_operand 0 "" "")
11401 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11402 (match_operand 2 "" "")))
11403 (set (reg:SI SP_REG)
11404 (plus:SI (reg:SI SP_REG)
11405 (match_operand:SI 3 "immediate_operand" "i")))]
11406 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11407 "* return ix86_output_call_insn (insn, operands[1]);"
11408 [(set_attr "type" "callv")])
11410 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11412 [(set (match_operand 0 "" "")
11413 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11414 (match_operand 2 "" "")))
11415 (set (reg:SI SP_REG)
11416 (plus:SI (reg:SI SP_REG)
11417 (match_operand:SI 3 "immediate_operand" "i")))])
11418 (unspec [(match_operand 4 "const_int_operand" "")]
11419 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11420 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11422 "&& reload_completed"
11424 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11425 [(set_attr "type" "callv")])
11427 (define_insn "*sibcall_value_pop"
11428 [(set (match_operand 0 "" "")
11429 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11430 (match_operand 2 "" "")))
11431 (set (reg:SI SP_REG)
11432 (plus:SI (reg:SI SP_REG)
11433 (match_operand:SI 3 "immediate_operand" "i")))]
11434 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11435 "* return ix86_output_call_insn (insn, operands[1]);"
11436 [(set_attr "type" "callv")])
11438 ;; Call subroutine returning any type.
11440 (define_expand "untyped_call"
11441 [(parallel [(call (match_operand 0 "" "")
11443 (match_operand 1 "" "")
11444 (match_operand 2 "" "")])]
11449 /* In order to give reg-stack an easier job in validating two
11450 coprocessor registers as containing a possible return value,
11451 simply pretend the untyped call returns a complex long double
11454 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11455 and should have the default ABI. */
11457 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11458 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11459 operands[0], const0_rtx,
11460 GEN_INT ((TARGET_64BIT
11461 ? (ix86_abi == SYSV_ABI
11462 ? X86_64_SSE_REGPARM_MAX
11463 : X86_64_MS_SSE_REGPARM_MAX)
11464 : X86_32_SSE_REGPARM_MAX)
11468 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11470 rtx set = XVECEXP (operands[2], 0, i);
11471 emit_move_insn (SET_DEST (set), SET_SRC (set));
11474 /* The optimizer does not know that the call sets the function value
11475 registers we stored in the result block. We avoid problems by
11476 claiming that all hard registers are used and clobbered at this
11478 emit_insn (gen_blockage ());
11483 ;; Prologue and epilogue instructions
11485 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11486 ;; all of memory. This blocks insns from being moved across this point.
11488 (define_insn "blockage"
11489 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11492 [(set_attr "length" "0")])
11494 ;; Do not schedule instructions accessing memory across this point.
11496 (define_expand "memory_blockage"
11497 [(set (match_dup 0)
11498 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11501 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11502 MEM_VOLATILE_P (operands[0]) = 1;
11505 (define_insn "*memory_blockage"
11506 [(set (match_operand:BLK 0 "" "")
11507 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11510 [(set_attr "length" "0")])
11512 ;; As USE insns aren't meaningful after reload, this is used instead
11513 ;; to prevent deleting instructions setting registers for PIC code
11514 (define_insn "prologue_use"
11515 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11518 [(set_attr "length" "0")])
11520 ;; Insn emitted into the body of a function to return from a function.
11521 ;; This is only done if the function's epilogue is known to be simple.
11522 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11524 (define_expand "return"
11526 "ix86_can_use_return_insn_p ()"
11528 if (crtl->args.pops_args)
11530 rtx popc = GEN_INT (crtl->args.pops_args);
11531 emit_jump_insn (gen_return_pop_internal (popc));
11536 (define_insn "return_internal"
11540 [(set_attr "length" "1")
11541 (set_attr "atom_unit" "jeu")
11542 (set_attr "length_immediate" "0")
11543 (set_attr "modrm" "0")])
11545 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11546 ;; instruction Athlon and K8 have.
11548 (define_insn "return_internal_long"
11550 (unspec [(const_int 0)] UNSPEC_REP)]
11553 [(set_attr "length" "2")
11554 (set_attr "atom_unit" "jeu")
11555 (set_attr "length_immediate" "0")
11556 (set_attr "prefix_rep" "1")
11557 (set_attr "modrm" "0")])
11559 (define_insn "return_pop_internal"
11561 (use (match_operand:SI 0 "const_int_operand" ""))]
11564 [(set_attr "length" "3")
11565 (set_attr "atom_unit" "jeu")
11566 (set_attr "length_immediate" "2")
11567 (set_attr "modrm" "0")])
11569 (define_insn "return_indirect_internal"
11571 (use (match_operand:SI 0 "register_operand" "r"))]
11574 [(set_attr "type" "ibr")
11575 (set_attr "length_immediate" "0")])
11581 [(set_attr "length" "1")
11582 (set_attr "length_immediate" "0")
11583 (set_attr "modrm" "0")])
11585 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11586 (define_insn "nops"
11587 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11591 int num = INTVAL (operands[0]);
11593 gcc_assert (num >= 1 && num <= 8);
11596 fputs ("\tnop\n", asm_out_file);
11600 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11601 (set_attr "length_immediate" "0")
11602 (set_attr "modrm" "0")])
11604 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11605 ;; branch prediction penalty for the third jump in a 16-byte
11609 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11612 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11613 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11615 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11616 The align insn is used to avoid 3 jump instructions in the row to improve
11617 branch prediction and the benefits hardly outweigh the cost of extra 8
11618 nops on the average inserted by full alignment pseudo operation. */
11622 [(set_attr "length" "16")])
11624 (define_expand "prologue"
11627 "ix86_expand_prologue (); DONE;")
11629 (define_insn "set_got"
11630 [(set (match_operand:SI 0 "register_operand" "=r")
11631 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11632 (clobber (reg:CC FLAGS_REG))]
11634 "* return output_set_got (operands[0], NULL_RTX);"
11635 [(set_attr "type" "multi")
11636 (set_attr "length" "12")])
11638 (define_insn "set_got_labelled"
11639 [(set (match_operand:SI 0 "register_operand" "=r")
11640 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11642 (clobber (reg:CC FLAGS_REG))]
11644 "* return output_set_got (operands[0], operands[1]);"
11645 [(set_attr "type" "multi")
11646 (set_attr "length" "12")])
11648 (define_insn "set_got_rex64"
11649 [(set (match_operand:DI 0 "register_operand" "=r")
11650 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11652 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11653 [(set_attr "type" "lea")
11654 (set_attr "length_address" "4")
11655 (set_attr "mode" "DI")])
11657 (define_insn "set_rip_rex64"
11658 [(set (match_operand:DI 0 "register_operand" "=r")
11659 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11661 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11662 [(set_attr "type" "lea")
11663 (set_attr "length_address" "4")
11664 (set_attr "mode" "DI")])
11666 (define_insn "set_got_offset_rex64"
11667 [(set (match_operand:DI 0 "register_operand" "=r")
11669 [(label_ref (match_operand 1 "" ""))]
11670 UNSPEC_SET_GOT_OFFSET))]
11672 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11673 [(set_attr "type" "imov")
11674 (set_attr "length_immediate" "0")
11675 (set_attr "length_address" "8")
11676 (set_attr "mode" "DI")])
11678 (define_expand "epilogue"
11681 "ix86_expand_epilogue (1); DONE;")
11683 (define_expand "sibcall_epilogue"
11686 "ix86_expand_epilogue (0); DONE;")
11688 (define_expand "eh_return"
11689 [(use (match_operand 0 "register_operand" ""))]
11692 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11694 /* Tricky bit: we write the address of the handler to which we will
11695 be returning into someone else's stack frame, one word below the
11696 stack address we wish to restore. */
11697 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11698 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11699 tmp = gen_rtx_MEM (Pmode, tmp);
11700 emit_move_insn (tmp, ra);
11702 emit_jump_insn (gen_eh_return_internal ());
11707 (define_insn_and_split "eh_return_internal"
11711 "epilogue_completed"
11713 "ix86_expand_epilogue (2); DONE;")
11715 (define_insn "leave"
11716 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11717 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11718 (clobber (mem:BLK (scratch)))]
11721 [(set_attr "type" "leave")])
11723 (define_insn "leave_rex64"
11724 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11725 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11726 (clobber (mem:BLK (scratch)))]
11729 [(set_attr "type" "leave")])
11731 ;; Handle -fsplit-stack.
11733 (define_expand "split_stack_prologue"
11737 ix86_expand_split_stack_prologue ();
11741 ;; In order to support the call/return predictor, we use a return
11742 ;; instruction which the middle-end doesn't see.
11743 (define_insn "split_stack_return"
11744 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11745 UNSPECV_SPLIT_STACK_RETURN)]
11748 if (operands[0] == const0_rtx)
11753 [(set_attr "atom_unit" "jeu")
11754 (set_attr "modrm" "0")
11755 (set (attr "length")
11756 (if_then_else (match_operand:SI 0 "const0_operand" "")
11759 (set (attr "length_immediate")
11760 (if_then_else (match_operand:SI 0 "const0_operand" "")
11764 ;; If there are operand 0 bytes available on the stack, jump to
11767 (define_expand "split_stack_space_check"
11768 [(set (pc) (if_then_else
11769 (ltu (minus (reg SP_REG)
11770 (match_operand 0 "register_operand" ""))
11771 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11772 (label_ref (match_operand 1 "" ""))
11776 rtx reg, size, limit;
11778 reg = gen_reg_rtx (Pmode);
11779 size = force_reg (Pmode, operands[0]);
11780 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11781 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11782 UNSPEC_STACK_CHECK);
11783 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11784 ix86_expand_branch (GEU, reg, limit, operands[1]);
11789 ;; Bit manipulation instructions.
11791 (define_expand "ffs<mode>2"
11792 [(set (match_dup 2) (const_int -1))
11793 (parallel [(set (reg:CCZ FLAGS_REG)
11795 (match_operand:SWI48 1 "nonimmediate_operand" "")
11797 (set (match_operand:SWI48 0 "register_operand" "")
11798 (ctz:SWI48 (match_dup 1)))])
11799 (set (match_dup 0) (if_then_else:SWI48
11800 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11803 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11804 (clobber (reg:CC FLAGS_REG))])]
11807 if (<MODE>mode == SImode && !TARGET_CMOVE)
11809 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11812 operands[2] = gen_reg_rtx (<MODE>mode);
11815 (define_insn_and_split "ffssi2_no_cmove"
11816 [(set (match_operand:SI 0 "register_operand" "=r")
11817 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11818 (clobber (match_scratch:SI 2 "=&q"))
11819 (clobber (reg:CC FLAGS_REG))]
11822 "&& reload_completed"
11823 [(parallel [(set (reg:CCZ FLAGS_REG)
11824 (compare:CCZ (match_dup 1) (const_int 0)))
11825 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11826 (set (strict_low_part (match_dup 3))
11827 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11828 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11829 (clobber (reg:CC FLAGS_REG))])
11830 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11831 (clobber (reg:CC FLAGS_REG))])
11832 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11833 (clobber (reg:CC FLAGS_REG))])]
11835 operands[3] = gen_lowpart (QImode, operands[2]);
11836 ix86_expand_clear (operands[2]);
11839 (define_insn "*ffs<mode>_1"
11840 [(set (reg:CCZ FLAGS_REG)
11841 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11843 (set (match_operand:SWI48 0 "register_operand" "=r")
11844 (ctz:SWI48 (match_dup 1)))]
11846 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11847 [(set_attr "type" "alu1")
11848 (set_attr "prefix_0f" "1")
11849 (set_attr "mode" "<MODE>")])
11851 (define_insn "ctz<mode>2"
11852 [(set (match_operand:SWI248 0 "register_operand" "=r")
11853 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11854 (clobber (reg:CC FLAGS_REG))]
11858 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11860 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11862 [(set_attr "type" "alu1")
11863 (set_attr "prefix_0f" "1")
11864 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11865 (set_attr "mode" "<MODE>")])
11867 (define_expand "clz<mode>2"
11869 [(set (match_operand:SWI248 0 "register_operand" "")
11872 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11873 (clobber (reg:CC FLAGS_REG))])
11875 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11876 (clobber (reg:CC FLAGS_REG))])]
11881 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11884 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11887 (define_insn "clz<mode>2_abm"
11888 [(set (match_operand:SWI248 0 "register_operand" "=r")
11889 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11890 (clobber (reg:CC FLAGS_REG))]
11891 "TARGET_ABM || TARGET_BMI"
11892 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11893 [(set_attr "prefix_rep" "1")
11894 (set_attr "type" "bitmanip")
11895 (set_attr "mode" "<MODE>")])
11897 ;; BMI instructions.
11898 (define_insn "*bmi_andn_<mode>"
11899 [(set (match_operand:SWI48 0 "register_operand" "=r")
11902 (match_operand:SWI48 1 "register_operand" "r"))
11903 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11904 (clobber (reg:CC FLAGS_REG))]
11906 "andn\t{%2, %1, %0|%0, %1, %2}"
11907 [(set_attr "type" "bitmanip")
11908 (set_attr "mode" "<MODE>")])
11910 (define_insn "bmi_bextr_<mode>"
11911 [(set (match_operand:SWI48 0 "register_operand" "=r")
11912 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11913 (match_operand:SWI48 2 "register_operand" "r")]
11915 (clobber (reg:CC FLAGS_REG))]
11917 "bextr\t{%2, %1, %0|%0, %1, %2}"
11918 [(set_attr "type" "bitmanip")
11919 (set_attr "mode" "<MODE>")])
11921 (define_insn "*bmi_blsi_<mode>"
11922 [(set (match_operand:SWI48 0 "register_operand" "=r")
11925 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11927 (clobber (reg:CC FLAGS_REG))]
11929 "blsi\t{%1, %0|%0, %1}"
11930 [(set_attr "type" "bitmanip")
11931 (set_attr "mode" "<MODE>")])
11933 (define_insn "*bmi_blsmsk_<mode>"
11934 [(set (match_operand:SWI48 0 "register_operand" "=r")
11937 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11940 (clobber (reg:CC FLAGS_REG))]
11942 "blsmsk\t{%1, %0|%0, %1}"
11943 [(set_attr "type" "bitmanip")
11944 (set_attr "mode" "<MODE>")])
11946 (define_insn "*bmi_blsr_<mode>"
11947 [(set (match_operand:SWI48 0 "register_operand" "=r")
11950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11953 (clobber (reg:CC FLAGS_REG))]
11955 "blsr\t{%1, %0|%0, %1}"
11956 [(set_attr "type" "bitmanip")
11957 (set_attr "mode" "<MODE>")])
11959 ;; TBM instructions.
11960 (define_insn "tbm_bextri_<mode>"
11961 [(set (match_operand:SWI48 0 "register_operand" "=r")
11962 (zero_extract:SWI48
11963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11964 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11965 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11966 (clobber (reg:CC FLAGS_REG))]
11969 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11970 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11972 [(set_attr "type" "bitmanip")
11973 (set_attr "mode" "<MODE>")])
11975 (define_insn "*tbm_blcfill_<mode>"
11976 [(set (match_operand:SWI48 0 "register_operand" "=r")
11979 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11982 (clobber (reg:CC FLAGS_REG))]
11984 "blcfill\t{%1, %0|%0, %1}"
11985 [(set_attr "type" "bitmanip")
11986 (set_attr "mode" "<MODE>")])
11988 (define_insn "*tbm_blci_<mode>"
11989 [(set (match_operand:SWI48 0 "register_operand" "=r")
11993 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11996 (clobber (reg:CC FLAGS_REG))]
11998 "blci\t{%1, %0|%0, %1}"
11999 [(set_attr "type" "bitmanip")
12000 (set_attr "mode" "<MODE>")])
12002 (define_insn "*tbm_blcic_<mode>"
12003 [(set (match_operand:SWI48 0 "register_operand" "=r")
12006 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12010 (clobber (reg:CC FLAGS_REG))]
12012 "blcic\t{%1, %0|%0, %1}"
12013 [(set_attr "type" "bitmanip")
12014 (set_attr "mode" "<MODE>")])
12016 (define_insn "*tbm_blcmsk_<mode>"
12017 [(set (match_operand:SWI48 0 "register_operand" "=r")
12020 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12023 (clobber (reg:CC FLAGS_REG))]
12025 "blcmsk\t{%1, %0|%0, %1}"
12026 [(set_attr "type" "bitmanip")
12027 (set_attr "mode" "<MODE>")])
12029 (define_insn "*tbm_blcs_<mode>"
12030 [(set (match_operand:SWI48 0 "register_operand" "=r")
12033 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12036 (clobber (reg:CC FLAGS_REG))]
12038 "blcs\t{%1, %0|%0, %1}"
12039 [(set_attr "type" "bitmanip")
12040 (set_attr "mode" "<MODE>")])
12042 (define_insn "*tbm_blsfill_<mode>"
12043 [(set (match_operand:SWI48 0 "register_operand" "=r")
12046 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12049 (clobber (reg:CC FLAGS_REG))]
12051 "blsfill\t{%1, %0|%0, %1}"
12052 [(set_attr "type" "bitmanip")
12053 (set_attr "mode" "<MODE>")])
12055 (define_insn "*tbm_blsic_<mode>"
12056 [(set (match_operand:SWI48 0 "register_operand" "=r")
12059 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12063 (clobber (reg:CC FLAGS_REG))]
12065 "blsic\t{%1, %0|%0, %1}"
12066 [(set_attr "type" "bitmanip")
12067 (set_attr "mode" "<MODE>")])
12069 (define_insn "*tbm_t1mskc_<mode>"
12070 [(set (match_operand:SWI48 0 "register_operand" "=r")
12073 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12077 (clobber (reg:CC FLAGS_REG))]
12079 "t1mskc\t{%1, %0|%0, %1}"
12080 [(set_attr "type" "bitmanip")
12081 (set_attr "mode" "<MODE>")])
12083 (define_insn "*tbm_tzmsk_<mode>"
12084 [(set (match_operand:SWI48 0 "register_operand" "=r")
12087 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12091 (clobber (reg:CC FLAGS_REG))]
12093 "tzmsk\t{%1, %0|%0, %1}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "bsr_rex64"
12098 [(set (match_operand:DI 0 "register_operand" "=r")
12099 (minus:DI (const_int 63)
12100 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12101 (clobber (reg:CC FLAGS_REG))]
12103 "bsr{q}\t{%1, %0|%0, %1}"
12104 [(set_attr "type" "alu1")
12105 (set_attr "prefix_0f" "1")
12106 (set_attr "mode" "DI")])
12109 [(set (match_operand:SI 0 "register_operand" "=r")
12110 (minus:SI (const_int 31)
12111 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12112 (clobber (reg:CC FLAGS_REG))]
12114 "bsr{l}\t{%1, %0|%0, %1}"
12115 [(set_attr "type" "alu1")
12116 (set_attr "prefix_0f" "1")
12117 (set_attr "mode" "SI")])
12119 (define_insn "*bsrhi"
12120 [(set (match_operand:HI 0 "register_operand" "=r")
12121 (minus:HI (const_int 15)
12122 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12123 (clobber (reg:CC FLAGS_REG))]
12125 "bsr{w}\t{%1, %0|%0, %1}"
12126 [(set_attr "type" "alu1")
12127 (set_attr "prefix_0f" "1")
12128 (set_attr "mode" "HI")])
12130 (define_insn "popcount<mode>2"
12131 [(set (match_operand:SWI248 0 "register_operand" "=r")
12133 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12134 (clobber (reg:CC FLAGS_REG))]
12138 return "popcnt\t{%1, %0|%0, %1}";
12140 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12143 [(set_attr "prefix_rep" "1")
12144 (set_attr "type" "bitmanip")
12145 (set_attr "mode" "<MODE>")])
12147 (define_insn "*popcount<mode>2_cmp"
12148 [(set (reg FLAGS_REG)
12151 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12153 (set (match_operand:SWI248 0 "register_operand" "=r")
12154 (popcount:SWI248 (match_dup 1)))]
12155 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12158 return "popcnt\t{%1, %0|%0, %1}";
12160 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12163 [(set_attr "prefix_rep" "1")
12164 (set_attr "type" "bitmanip")
12165 (set_attr "mode" "<MODE>")])
12167 (define_insn "*popcountsi2_cmp_zext"
12168 [(set (reg FLAGS_REG)
12170 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12172 (set (match_operand:DI 0 "register_operand" "=r")
12173 (zero_extend:DI(popcount:SI (match_dup 1))))]
12174 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12177 return "popcnt\t{%1, %0|%0, %1}";
12179 return "popcnt{l}\t{%1, %0|%0, %1}";
12182 [(set_attr "prefix_rep" "1")
12183 (set_attr "type" "bitmanip")
12184 (set_attr "mode" "SI")])
12186 (define_expand "bswap<mode>2"
12187 [(set (match_operand:SWI48 0 "register_operand" "")
12188 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12191 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12193 rtx x = operands[0];
12195 emit_move_insn (x, operands[1]);
12196 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12197 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12198 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12203 (define_insn "*bswap<mode>2_movbe"
12204 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12205 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12207 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12210 movbe\t{%1, %0|%0, %1}
12211 movbe\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "bitmanip,imov,imov")
12213 (set_attr "modrm" "0,1,1")
12214 (set_attr "prefix_0f" "*,1,1")
12215 (set_attr "prefix_extra" "*,1,1")
12216 (set_attr "mode" "<MODE>")])
12218 (define_insn "*bswap<mode>2_1"
12219 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12223 [(set_attr "type" "bitmanip")
12224 (set_attr "modrm" "0")
12225 (set_attr "mode" "<MODE>")])
12227 (define_insn "*bswaphi_lowpart_1"
12228 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12229 (bswap:HI (match_dup 0)))
12230 (clobber (reg:CC FLAGS_REG))]
12231 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12233 xchg{b}\t{%h0, %b0|%b0, %h0}
12234 rol{w}\t{$8, %0|%0, 8}"
12235 [(set_attr "length" "2,4")
12236 (set_attr "mode" "QI,HI")])
12238 (define_insn "bswaphi_lowpart"
12239 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12240 (bswap:HI (match_dup 0)))
12241 (clobber (reg:CC FLAGS_REG))]
12243 "rol{w}\t{$8, %0|%0, 8}"
12244 [(set_attr "length" "4")
12245 (set_attr "mode" "HI")])
12247 (define_expand "paritydi2"
12248 [(set (match_operand:DI 0 "register_operand" "")
12249 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12252 rtx scratch = gen_reg_rtx (QImode);
12255 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12256 NULL_RTX, operands[1]));
12258 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12259 gen_rtx_REG (CCmode, FLAGS_REG),
12261 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12264 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12267 rtx tmp = gen_reg_rtx (SImode);
12269 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12270 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12275 (define_expand "paritysi2"
12276 [(set (match_operand:SI 0 "register_operand" "")
12277 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12280 rtx scratch = gen_reg_rtx (QImode);
12283 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12285 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12286 gen_rtx_REG (CCmode, FLAGS_REG),
12288 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12290 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12294 (define_insn_and_split "paritydi2_cmp"
12295 [(set (reg:CC FLAGS_REG)
12296 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12298 (clobber (match_scratch:DI 0 "=r"))
12299 (clobber (match_scratch:SI 1 "=&r"))
12300 (clobber (match_scratch:HI 2 "=Q"))]
12303 "&& reload_completed"
12305 [(set (match_dup 1)
12306 (xor:SI (match_dup 1) (match_dup 4)))
12307 (clobber (reg:CC FLAGS_REG))])
12309 [(set (reg:CC FLAGS_REG)
12310 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12311 (clobber (match_dup 1))
12312 (clobber (match_dup 2))])]
12314 operands[4] = gen_lowpart (SImode, operands[3]);
12318 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12319 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12322 operands[1] = gen_highpart (SImode, operands[3]);
12325 (define_insn_and_split "paritysi2_cmp"
12326 [(set (reg:CC FLAGS_REG)
12327 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12329 (clobber (match_scratch:SI 0 "=r"))
12330 (clobber (match_scratch:HI 1 "=&Q"))]
12333 "&& reload_completed"
12335 [(set (match_dup 1)
12336 (xor:HI (match_dup 1) (match_dup 3)))
12337 (clobber (reg:CC FLAGS_REG))])
12339 [(set (reg:CC FLAGS_REG)
12340 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12341 (clobber (match_dup 1))])]
12343 operands[3] = gen_lowpart (HImode, operands[2]);
12345 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12346 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12349 (define_insn "*parityhi2_cmp"
12350 [(set (reg:CC FLAGS_REG)
12351 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12353 (clobber (match_scratch:HI 0 "=Q"))]
12355 "xor{b}\t{%h0, %b0|%b0, %h0}"
12356 [(set_attr "length" "2")
12357 (set_attr "mode" "HI")])
12359 ;; Thread-local storage patterns for ELF.
12361 ;; Note that these code sequences must appear exactly as shown
12362 ;; in order to allow linker relaxation.
12364 (define_insn "*tls_global_dynamic_32_gnu"
12365 [(set (match_operand:SI 0 "register_operand" "=a")
12367 [(match_operand:SI 1 "register_operand" "b")
12368 (match_operand:SI 2 "tls_symbolic_operand" "")
12369 (match_operand:SI 3 "constant_call_address_operand" "z")]
12371 (clobber (match_scratch:SI 4 "=d"))
12372 (clobber (match_scratch:SI 5 "=c"))
12373 (clobber (reg:CC FLAGS_REG))]
12374 "!TARGET_64BIT && TARGET_GNU_TLS"
12377 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12378 if (TARGET_SUN_TLS)
12379 #ifdef HAVE_AS_IX86_TLSGDPLT
12380 return "call\t%a2@tlsgdplt";
12382 return "call\t%p3@plt";
12384 return "call\t%P3";
12386 [(set_attr "type" "multi")
12387 (set_attr "length" "12")])
12389 (define_expand "tls_global_dynamic_32"
12391 [(set (match_operand:SI 0 "register_operand" "")
12392 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12393 (match_operand:SI 1 "tls_symbolic_operand" "")
12394 (match_operand:SI 3 "constant_call_address_operand" "")]
12396 (clobber (match_scratch:SI 4 ""))
12397 (clobber (match_scratch:SI 5 ""))
12398 (clobber (reg:CC FLAGS_REG))])])
12400 (define_insn "*tls_global_dynamic_64"
12401 [(set (match_operand:DI 0 "register_operand" "=a")
12403 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12404 (match_operand:DI 3 "" "")))
12405 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12409 fputs (ASM_BYTE "0x66\n", asm_out_file);
12411 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12412 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12413 fputs ("\trex64\n", asm_out_file);
12414 if (TARGET_SUN_TLS)
12415 return "call\t%p2@plt";
12416 return "call\t%P2";
12418 [(set_attr "type" "multi")
12419 (set_attr "length" "16")])
12421 (define_expand "tls_global_dynamic_64"
12423 [(set (match_operand:DI 0 "register_operand" "")
12425 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12427 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12430 (define_insn "*tls_local_dynamic_base_32_gnu"
12431 [(set (match_operand:SI 0 "register_operand" "=a")
12433 [(match_operand:SI 1 "register_operand" "b")
12434 (match_operand:SI 2 "constant_call_address_operand" "z")]
12435 UNSPEC_TLS_LD_BASE))
12436 (clobber (match_scratch:SI 3 "=d"))
12437 (clobber (match_scratch:SI 4 "=c"))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "!TARGET_64BIT && TARGET_GNU_TLS"
12442 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12443 if (TARGET_SUN_TLS)
12444 #ifdef HAVE_AS_IX86_TLSLDMPLT
12445 return "call\t%&@tlsldmplt";
12447 return "call\t%p2@plt";
12449 return "call\t%P2";
12451 [(set_attr "type" "multi")
12452 (set_attr "length" "11")])
12454 (define_expand "tls_local_dynamic_base_32"
12456 [(set (match_operand:SI 0 "register_operand" "")
12458 [(match_operand:SI 1 "register_operand" "")
12459 (match_operand:SI 2 "constant_call_address_operand" "")]
12460 UNSPEC_TLS_LD_BASE))
12461 (clobber (match_scratch:SI 3 ""))
12462 (clobber (match_scratch:SI 4 ""))
12463 (clobber (reg:CC FLAGS_REG))])])
12465 (define_insn "*tls_local_dynamic_base_64"
12466 [(set (match_operand:DI 0 "register_operand" "=a")
12468 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12469 (match_operand:DI 2 "" "")))
12470 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12474 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12475 if (TARGET_SUN_TLS)
12476 return "call\t%p1@plt";
12477 return "call\t%P1";
12479 [(set_attr "type" "multi")
12480 (set_attr "length" "12")])
12482 (define_expand "tls_local_dynamic_base_64"
12484 [(set (match_operand:DI 0 "register_operand" "")
12486 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12488 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12490 ;; Local dynamic of a single variable is a lose. Show combine how
12491 ;; to convert that back to global dynamic.
12493 (define_insn_and_split "*tls_local_dynamic_32_once"
12494 [(set (match_operand:SI 0 "register_operand" "=a")
12496 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12497 (match_operand:SI 2 "constant_call_address_operand" "z")]
12498 UNSPEC_TLS_LD_BASE)
12499 (const:SI (unspec:SI
12500 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12502 (clobber (match_scratch:SI 4 "=d"))
12503 (clobber (match_scratch:SI 5 "=c"))
12504 (clobber (reg:CC FLAGS_REG))]
12509 [(set (match_dup 0)
12510 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12512 (clobber (match_dup 4))
12513 (clobber (match_dup 5))
12514 (clobber (reg:CC FLAGS_REG))])])
12516 ;; Segment register for the thread base ptr load
12517 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12519 ;; Load and add the thread base pointer from %<tp_seg>:0.
12520 (define_insn "*load_tp_<mode>"
12521 [(set (match_operand:P 0 "register_operand" "=r")
12522 (unspec:P [(const_int 0)] UNSPEC_TP))]
12524 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12525 [(set_attr "type" "imov")
12526 (set_attr "modrm" "0")
12527 (set_attr "length" "7")
12528 (set_attr "memory" "load")
12529 (set_attr "imm_disp" "false")])
12531 (define_insn "*add_tp_<mode>"
12532 [(set (match_operand:P 0 "register_operand" "=r")
12533 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12534 (match_operand:P 1 "register_operand" "0")))
12535 (clobber (reg:CC FLAGS_REG))]
12537 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12538 [(set_attr "type" "alu")
12539 (set_attr "modrm" "0")
12540 (set_attr "length" "7")
12541 (set_attr "memory" "load")
12542 (set_attr "imm_disp" "false")])
12544 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12545 ;; %rax as destination of the initial executable code sequence.
12546 (define_insn "tls_initial_exec_64_sun"
12547 [(set (match_operand:DI 0 "register_operand" "=a")
12549 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12550 UNSPEC_TLS_IE_SUN))
12551 (clobber (reg:CC FLAGS_REG))]
12552 "TARGET_64BIT && TARGET_SUN_TLS"
12555 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12556 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12558 [(set_attr "type" "multi")])
12560 ;; GNU2 TLS patterns can be split.
12562 (define_expand "tls_dynamic_gnu2_32"
12563 [(set (match_dup 3)
12564 (plus:SI (match_operand:SI 2 "register_operand" "")
12566 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12569 [(set (match_operand:SI 0 "register_operand" "")
12570 (unspec:SI [(match_dup 1) (match_dup 3)
12571 (match_dup 2) (reg:SI SP_REG)]
12573 (clobber (reg:CC FLAGS_REG))])]
12574 "!TARGET_64BIT && TARGET_GNU2_TLS"
12576 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12577 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12580 (define_insn "*tls_dynamic_lea_32"
12581 [(set (match_operand:SI 0 "register_operand" "=r")
12582 (plus:SI (match_operand:SI 1 "register_operand" "b")
12584 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12585 UNSPEC_TLSDESC))))]
12586 "!TARGET_64BIT && TARGET_GNU2_TLS"
12587 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12588 [(set_attr "type" "lea")
12589 (set_attr "mode" "SI")
12590 (set_attr "length" "6")
12591 (set_attr "length_address" "4")])
12593 (define_insn "*tls_dynamic_call_32"
12594 [(set (match_operand:SI 0 "register_operand" "=a")
12595 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12596 (match_operand:SI 2 "register_operand" "0")
12597 ;; we have to make sure %ebx still points to the GOT
12598 (match_operand:SI 3 "register_operand" "b")
12601 (clobber (reg:CC FLAGS_REG))]
12602 "!TARGET_64BIT && TARGET_GNU2_TLS"
12603 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12604 [(set_attr "type" "call")
12605 (set_attr "length" "2")
12606 (set_attr "length_address" "0")])
12608 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12609 [(set (match_operand:SI 0 "register_operand" "=&a")
12611 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12612 (match_operand:SI 4 "" "")
12613 (match_operand:SI 2 "register_operand" "b")
12616 (const:SI (unspec:SI
12617 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12619 (clobber (reg:CC FLAGS_REG))]
12620 "!TARGET_64BIT && TARGET_GNU2_TLS"
12623 [(set (match_dup 0) (match_dup 5))]
12625 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12626 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12629 (define_expand "tls_dynamic_gnu2_64"
12630 [(set (match_dup 2)
12631 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12634 [(set (match_operand:DI 0 "register_operand" "")
12635 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12637 (clobber (reg:CC FLAGS_REG))])]
12638 "TARGET_64BIT && TARGET_GNU2_TLS"
12640 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12641 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12644 (define_insn "*tls_dynamic_lea_64"
12645 [(set (match_operand:DI 0 "register_operand" "=r")
12646 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12648 "TARGET_64BIT && TARGET_GNU2_TLS"
12649 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12650 [(set_attr "type" "lea")
12651 (set_attr "mode" "DI")
12652 (set_attr "length" "7")
12653 (set_attr "length_address" "4")])
12655 (define_insn "*tls_dynamic_call_64"
12656 [(set (match_operand:DI 0 "register_operand" "=a")
12657 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12658 (match_operand:DI 2 "register_operand" "0")
12661 (clobber (reg:CC FLAGS_REG))]
12662 "TARGET_64BIT && TARGET_GNU2_TLS"
12663 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12664 [(set_attr "type" "call")
12665 (set_attr "length" "2")
12666 (set_attr "length_address" "0")])
12668 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12669 [(set (match_operand:DI 0 "register_operand" "=&a")
12671 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12672 (match_operand:DI 3 "" "")
12675 (const:DI (unspec:DI
12676 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12678 (clobber (reg:CC FLAGS_REG))]
12679 "TARGET_64BIT && TARGET_GNU2_TLS"
12682 [(set (match_dup 0) (match_dup 4))]
12684 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12685 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12688 ;; These patterns match the binary 387 instructions for addM3, subM3,
12689 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12690 ;; SFmode. The first is the normal insn, the second the same insn but
12691 ;; with one operand a conversion, and the third the same insn but with
12692 ;; the other operand a conversion. The conversion may be SFmode or
12693 ;; SImode if the target mode DFmode, but only SImode if the target mode
12696 ;; Gcc is slightly more smart about handling normal two address instructions
12697 ;; so use special patterns for add and mull.
12699 (define_insn "*fop_<mode>_comm_mixed"
12700 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12701 (match_operator:MODEF 3 "binary_fp_operator"
12702 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12703 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12704 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12705 && COMMUTATIVE_ARITH_P (operands[3])
12706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12707 "* return output_387_binary_op (insn, operands);"
12708 [(set (attr "type")
12709 (if_then_else (eq_attr "alternative" "1,2")
12710 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12711 (const_string "ssemul")
12712 (const_string "sseadd"))
12713 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12714 (const_string "fmul")
12715 (const_string "fop"))))
12716 (set_attr "isa" "*,noavx,avx")
12717 (set_attr "prefix" "orig,orig,vex")
12718 (set_attr "mode" "<MODE>")])
12720 (define_insn "*fop_<mode>_comm_sse"
12721 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12722 (match_operator:MODEF 3 "binary_fp_operator"
12723 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12724 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12725 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12726 && COMMUTATIVE_ARITH_P (operands[3])
12727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12728 "* return output_387_binary_op (insn, operands);"
12729 [(set (attr "type")
12730 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12731 (const_string "ssemul")
12732 (const_string "sseadd")))
12733 (set_attr "isa" "noavx,avx")
12734 (set_attr "prefix" "orig,vex")
12735 (set_attr "mode" "<MODE>")])
12737 (define_insn "*fop_<mode>_comm_i387"
12738 [(set (match_operand:MODEF 0 "register_operand" "=f")
12739 (match_operator:MODEF 3 "binary_fp_operator"
12740 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12741 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12742 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12743 && COMMUTATIVE_ARITH_P (operands[3])
12744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745 "* return output_387_binary_op (insn, operands);"
12746 [(set (attr "type")
12747 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12748 (const_string "fmul")
12749 (const_string "fop")))
12750 (set_attr "mode" "<MODE>")])
12752 (define_insn "*fop_<mode>_1_mixed"
12753 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12754 (match_operator:MODEF 3 "binary_fp_operator"
12755 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12756 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12757 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12758 && !COMMUTATIVE_ARITH_P (operands[3])
12759 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12760 "* return output_387_binary_op (insn, operands);"
12761 [(set (attr "type")
12762 (cond [(and (eq_attr "alternative" "2,3")
12763 (match_operand:MODEF 3 "mult_operator" ""))
12764 (const_string "ssemul")
12765 (and (eq_attr "alternative" "2,3")
12766 (match_operand:MODEF 3 "div_operator" ""))
12767 (const_string "ssediv")
12768 (eq_attr "alternative" "2,3")
12769 (const_string "sseadd")
12770 (match_operand:MODEF 3 "mult_operator" "")
12771 (const_string "fmul")
12772 (match_operand:MODEF 3 "div_operator" "")
12773 (const_string "fdiv")
12775 (const_string "fop")))
12776 (set_attr "isa" "*,*,noavx,avx")
12777 (set_attr "prefix" "orig,orig,orig,vex")
12778 (set_attr "mode" "<MODE>")])
12780 (define_insn "*rcpsf2_sse"
12781 [(set (match_operand:SF 0 "register_operand" "=x")
12782 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12785 "%vrcpss\t{%1, %d0|%d0, %1}"
12786 [(set_attr "type" "sse")
12787 (set_attr "atom_sse_attr" "rcp")
12788 (set_attr "prefix" "maybe_vex")
12789 (set_attr "mode" "SF")])
12791 (define_insn "*fop_<mode>_1_sse"
12792 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12793 (match_operator:MODEF 3 "binary_fp_operator"
12794 [(match_operand:MODEF 1 "register_operand" "0,x")
12795 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12796 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12797 && !COMMUTATIVE_ARITH_P (operands[3])"
12798 "* return output_387_binary_op (insn, operands);"
12799 [(set (attr "type")
12800 (cond [(match_operand:MODEF 3 "mult_operator" "")
12801 (const_string "ssemul")
12802 (match_operand:MODEF 3 "div_operator" "")
12803 (const_string "ssediv")
12805 (const_string "sseadd")))
12806 (set_attr "isa" "noavx,avx")
12807 (set_attr "prefix" "orig,vex")
12808 (set_attr "mode" "<MODE>")])
12810 ;; This pattern is not fully shadowed by the pattern above.
12811 (define_insn "*fop_<mode>_1_i387"
12812 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12813 (match_operator:MODEF 3 "binary_fp_operator"
12814 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12815 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12816 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12817 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12818 && !COMMUTATIVE_ARITH_P (operands[3])
12819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12820 "* return output_387_binary_op (insn, operands);"
12821 [(set (attr "type")
12822 (cond [(match_operand:MODEF 3 "mult_operator" "")
12823 (const_string "fmul")
12824 (match_operand:MODEF 3 "div_operator" "")
12825 (const_string "fdiv")
12827 (const_string "fop")))
12828 (set_attr "mode" "<MODE>")])
12830 ;; ??? Add SSE splitters for these!
12831 (define_insn "*fop_<MODEF:mode>_2_i387"
12832 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12833 (match_operator:MODEF 3 "binary_fp_operator"
12835 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12836 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12837 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12838 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12839 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12840 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12841 [(set (attr "type")
12842 (cond [(match_operand:MODEF 3 "mult_operator" "")
12843 (const_string "fmul")
12844 (match_operand:MODEF 3 "div_operator" "")
12845 (const_string "fdiv")
12847 (const_string "fop")))
12848 (set_attr "fp_int_src" "true")
12849 (set_attr "mode" "<SWI24:MODE>")])
12851 (define_insn "*fop_<MODEF:mode>_3_i387"
12852 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12853 (match_operator:MODEF 3 "binary_fp_operator"
12854 [(match_operand:MODEF 1 "register_operand" "0,0")
12856 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12857 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12858 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12859 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12860 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12861 [(set (attr "type")
12862 (cond [(match_operand:MODEF 3 "mult_operator" "")
12863 (const_string "fmul")
12864 (match_operand:MODEF 3 "div_operator" "")
12865 (const_string "fdiv")
12867 (const_string "fop")))
12868 (set_attr "fp_int_src" "true")
12869 (set_attr "mode" "<MODE>")])
12871 (define_insn "*fop_df_4_i387"
12872 [(set (match_operand:DF 0 "register_operand" "=f,f")
12873 (match_operator:DF 3 "binary_fp_operator"
12875 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12876 (match_operand:DF 2 "register_operand" "0,f")]))]
12877 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12878 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12879 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12880 "* return output_387_binary_op (insn, operands);"
12881 [(set (attr "type")
12882 (cond [(match_operand:DF 3 "mult_operator" "")
12883 (const_string "fmul")
12884 (match_operand:DF 3 "div_operator" "")
12885 (const_string "fdiv")
12887 (const_string "fop")))
12888 (set_attr "mode" "SF")])
12890 (define_insn "*fop_df_5_i387"
12891 [(set (match_operand:DF 0 "register_operand" "=f,f")
12892 (match_operator:DF 3 "binary_fp_operator"
12893 [(match_operand:DF 1 "register_operand" "0,f")
12895 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12896 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12897 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12898 "* return output_387_binary_op (insn, operands);"
12899 [(set (attr "type")
12900 (cond [(match_operand:DF 3 "mult_operator" "")
12901 (const_string "fmul")
12902 (match_operand:DF 3 "div_operator" "")
12903 (const_string "fdiv")
12905 (const_string "fop")))
12906 (set_attr "mode" "SF")])
12908 (define_insn "*fop_df_6_i387"
12909 [(set (match_operand:DF 0 "register_operand" "=f,f")
12910 (match_operator:DF 3 "binary_fp_operator"
12912 (match_operand:SF 1 "register_operand" "0,f"))
12914 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12915 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12916 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12917 "* return output_387_binary_op (insn, operands);"
12918 [(set (attr "type")
12919 (cond [(match_operand:DF 3 "mult_operator" "")
12920 (const_string "fmul")
12921 (match_operand:DF 3 "div_operator" "")
12922 (const_string "fdiv")
12924 (const_string "fop")))
12925 (set_attr "mode" "SF")])
12927 (define_insn "*fop_xf_comm_i387"
12928 [(set (match_operand:XF 0 "register_operand" "=f")
12929 (match_operator:XF 3 "binary_fp_operator"
12930 [(match_operand:XF 1 "register_operand" "%0")
12931 (match_operand:XF 2 "register_operand" "f")]))]
12933 && COMMUTATIVE_ARITH_P (operands[3])"
12934 "* return output_387_binary_op (insn, operands);"
12935 [(set (attr "type")
12936 (if_then_else (match_operand:XF 3 "mult_operator" "")
12937 (const_string "fmul")
12938 (const_string "fop")))
12939 (set_attr "mode" "XF")])
12941 (define_insn "*fop_xf_1_i387"
12942 [(set (match_operand:XF 0 "register_operand" "=f,f")
12943 (match_operator:XF 3 "binary_fp_operator"
12944 [(match_operand:XF 1 "register_operand" "0,f")
12945 (match_operand:XF 2 "register_operand" "f,0")]))]
12947 && !COMMUTATIVE_ARITH_P (operands[3])"
12948 "* return output_387_binary_op (insn, operands);"
12949 [(set (attr "type")
12950 (cond [(match_operand:XF 3 "mult_operator" "")
12951 (const_string "fmul")
12952 (match_operand:XF 3 "div_operator" "")
12953 (const_string "fdiv")
12955 (const_string "fop")))
12956 (set_attr "mode" "XF")])
12958 (define_insn "*fop_xf_2_i387"
12959 [(set (match_operand:XF 0 "register_operand" "=f,f")
12960 (match_operator:XF 3 "binary_fp_operator"
12962 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12963 (match_operand:XF 2 "register_operand" "0,0")]))]
12964 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12965 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12966 [(set (attr "type")
12967 (cond [(match_operand:XF 3 "mult_operator" "")
12968 (const_string "fmul")
12969 (match_operand:XF 3 "div_operator" "")
12970 (const_string "fdiv")
12972 (const_string "fop")))
12973 (set_attr "fp_int_src" "true")
12974 (set_attr "mode" "<MODE>")])
12976 (define_insn "*fop_xf_3_i387"
12977 [(set (match_operand:XF 0 "register_operand" "=f,f")
12978 (match_operator:XF 3 "binary_fp_operator"
12979 [(match_operand:XF 1 "register_operand" "0,0")
12981 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12982 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12983 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12984 [(set (attr "type")
12985 (cond [(match_operand:XF 3 "mult_operator" "")
12986 (const_string "fmul")
12987 (match_operand:XF 3 "div_operator" "")
12988 (const_string "fdiv")
12990 (const_string "fop")))
12991 (set_attr "fp_int_src" "true")
12992 (set_attr "mode" "<MODE>")])
12994 (define_insn "*fop_xf_4_i387"
12995 [(set (match_operand:XF 0 "register_operand" "=f,f")
12996 (match_operator:XF 3 "binary_fp_operator"
12998 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12999 (match_operand:XF 2 "register_operand" "0,f")]))]
13001 "* return output_387_binary_op (insn, operands);"
13002 [(set (attr "type")
13003 (cond [(match_operand:XF 3 "mult_operator" "")
13004 (const_string "fmul")
13005 (match_operand:XF 3 "div_operator" "")
13006 (const_string "fdiv")
13008 (const_string "fop")))
13009 (set_attr "mode" "<MODE>")])
13011 (define_insn "*fop_xf_5_i387"
13012 [(set (match_operand:XF 0 "register_operand" "=f,f")
13013 (match_operator:XF 3 "binary_fp_operator"
13014 [(match_operand:XF 1 "register_operand" "0,f")
13016 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13018 "* return output_387_binary_op (insn, operands);"
13019 [(set (attr "type")
13020 (cond [(match_operand:XF 3 "mult_operator" "")
13021 (const_string "fmul")
13022 (match_operand:XF 3 "div_operator" "")
13023 (const_string "fdiv")
13025 (const_string "fop")))
13026 (set_attr "mode" "<MODE>")])
13028 (define_insn "*fop_xf_6_i387"
13029 [(set (match_operand:XF 0 "register_operand" "=f,f")
13030 (match_operator:XF 3 "binary_fp_operator"
13032 (match_operand:MODEF 1 "register_operand" "0,f"))
13034 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13036 "* return output_387_binary_op (insn, operands);"
13037 [(set (attr "type")
13038 (cond [(match_operand:XF 3 "mult_operator" "")
13039 (const_string "fmul")
13040 (match_operand:XF 3 "div_operator" "")
13041 (const_string "fdiv")
13043 (const_string "fop")))
13044 (set_attr "mode" "<MODE>")])
13047 [(set (match_operand 0 "register_operand" "")
13048 (match_operator 3 "binary_fp_operator"
13049 [(float (match_operand:SWI24 1 "register_operand" ""))
13050 (match_operand 2 "register_operand" "")]))]
13052 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13053 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13056 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13057 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13058 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13059 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13060 GET_MODE (operands[3]),
13063 ix86_free_from_memory (GET_MODE (operands[1]));
13068 [(set (match_operand 0 "register_operand" "")
13069 (match_operator 3 "binary_fp_operator"
13070 [(match_operand 1 "register_operand" "")
13071 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13073 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13074 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13077 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13078 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13079 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13080 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13081 GET_MODE (operands[3]),
13084 ix86_free_from_memory (GET_MODE (operands[2]));
13088 ;; FPU special functions.
13090 ;; This pattern implements a no-op XFmode truncation for
13091 ;; all fancy i386 XFmode math functions.
13093 (define_insn "truncxf<mode>2_i387_noop_unspec"
13094 [(set (match_operand:MODEF 0 "register_operand" "=f")
13095 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13096 UNSPEC_TRUNC_NOOP))]
13097 "TARGET_USE_FANCY_MATH_387"
13098 "* return output_387_reg_move (insn, operands);"
13099 [(set_attr "type" "fmov")
13100 (set_attr "mode" "<MODE>")])
13102 (define_insn "sqrtxf2"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13104 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13105 "TARGET_USE_FANCY_MATH_387"
13107 [(set_attr "type" "fpspc")
13108 (set_attr "mode" "XF")
13109 (set_attr "athlon_decode" "direct")
13110 (set_attr "amdfam10_decode" "direct")
13111 (set_attr "bdver1_decode" "direct")])
13113 (define_insn "sqrt_extend<mode>xf2_i387"
13114 [(set (match_operand:XF 0 "register_operand" "=f")
13117 (match_operand:MODEF 1 "register_operand" "0"))))]
13118 "TARGET_USE_FANCY_MATH_387"
13120 [(set_attr "type" "fpspc")
13121 (set_attr "mode" "XF")
13122 (set_attr "athlon_decode" "direct")
13123 (set_attr "amdfam10_decode" "direct")
13124 (set_attr "bdver1_decode" "direct")])
13126 (define_insn "*rsqrtsf2_sse"
13127 [(set (match_operand:SF 0 "register_operand" "=x")
13128 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13131 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13132 [(set_attr "type" "sse")
13133 (set_attr "atom_sse_attr" "rcp")
13134 (set_attr "prefix" "maybe_vex")
13135 (set_attr "mode" "SF")])
13137 (define_expand "rsqrtsf2"
13138 [(set (match_operand:SF 0 "register_operand" "")
13139 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13143 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13147 (define_insn "*sqrt<mode>2_sse"
13148 [(set (match_operand:MODEF 0 "register_operand" "=x")
13150 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13151 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13152 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13153 [(set_attr "type" "sse")
13154 (set_attr "atom_sse_attr" "sqrt")
13155 (set_attr "prefix" "maybe_vex")
13156 (set_attr "mode" "<MODE>")
13157 (set_attr "athlon_decode" "*")
13158 (set_attr "amdfam10_decode" "*")
13159 (set_attr "bdver1_decode" "*")])
13161 (define_expand "sqrt<mode>2"
13162 [(set (match_operand:MODEF 0 "register_operand" "")
13164 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13165 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13166 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13168 if (<MODE>mode == SFmode
13169 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13170 && flag_finite_math_only && !flag_trapping_math
13171 && flag_unsafe_math_optimizations)
13173 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13177 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13179 rtx op0 = gen_reg_rtx (XFmode);
13180 rtx op1 = force_reg (<MODE>mode, operands[1]);
13182 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13183 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13188 (define_insn "fpremxf4_i387"
13189 [(set (match_operand:XF 0 "register_operand" "=f")
13190 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13191 (match_operand:XF 3 "register_operand" "1")]
13193 (set (match_operand:XF 1 "register_operand" "=u")
13194 (unspec:XF [(match_dup 2) (match_dup 3)]
13196 (set (reg:CCFP FPSR_REG)
13197 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13199 "TARGET_USE_FANCY_MATH_387"
13201 [(set_attr "type" "fpspc")
13202 (set_attr "mode" "XF")])
13204 (define_expand "fmodxf3"
13205 [(use (match_operand:XF 0 "register_operand" ""))
13206 (use (match_operand:XF 1 "general_operand" ""))
13207 (use (match_operand:XF 2 "general_operand" ""))]
13208 "TARGET_USE_FANCY_MATH_387"
13210 rtx label = gen_label_rtx ();
13212 rtx op1 = gen_reg_rtx (XFmode);
13213 rtx op2 = gen_reg_rtx (XFmode);
13215 emit_move_insn (op2, operands[2]);
13216 emit_move_insn (op1, operands[1]);
13218 emit_label (label);
13219 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13220 ix86_emit_fp_unordered_jump (label);
13221 LABEL_NUSES (label) = 1;
13223 emit_move_insn (operands[0], op1);
13227 (define_expand "fmod<mode>3"
13228 [(use (match_operand:MODEF 0 "register_operand" ""))
13229 (use (match_operand:MODEF 1 "general_operand" ""))
13230 (use (match_operand:MODEF 2 "general_operand" ""))]
13231 "TARGET_USE_FANCY_MATH_387"
13233 rtx (*gen_truncxf) (rtx, rtx);
13235 rtx label = gen_label_rtx ();
13237 rtx op1 = gen_reg_rtx (XFmode);
13238 rtx op2 = gen_reg_rtx (XFmode);
13240 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13243 emit_label (label);
13244 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13245 ix86_emit_fp_unordered_jump (label);
13246 LABEL_NUSES (label) = 1;
13248 /* Truncate the result properly for strict SSE math. */
13249 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13250 && !TARGET_MIX_SSE_I387)
13251 gen_truncxf = gen_truncxf<mode>2;
13253 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13255 emit_insn (gen_truncxf (operands[0], op1));
13259 (define_insn "fprem1xf4_i387"
13260 [(set (match_operand:XF 0 "register_operand" "=f")
13261 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13262 (match_operand:XF 3 "register_operand" "1")]
13264 (set (match_operand:XF 1 "register_operand" "=u")
13265 (unspec:XF [(match_dup 2) (match_dup 3)]
13267 (set (reg:CCFP FPSR_REG)
13268 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13270 "TARGET_USE_FANCY_MATH_387"
13272 [(set_attr "type" "fpspc")
13273 (set_attr "mode" "XF")])
13275 (define_expand "remainderxf3"
13276 [(use (match_operand:XF 0 "register_operand" ""))
13277 (use (match_operand:XF 1 "general_operand" ""))
13278 (use (match_operand:XF 2 "general_operand" ""))]
13279 "TARGET_USE_FANCY_MATH_387"
13281 rtx label = gen_label_rtx ();
13283 rtx op1 = gen_reg_rtx (XFmode);
13284 rtx op2 = gen_reg_rtx (XFmode);
13286 emit_move_insn (op2, operands[2]);
13287 emit_move_insn (op1, operands[1]);
13289 emit_label (label);
13290 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13291 ix86_emit_fp_unordered_jump (label);
13292 LABEL_NUSES (label) = 1;
13294 emit_move_insn (operands[0], op1);
13298 (define_expand "remainder<mode>3"
13299 [(use (match_operand:MODEF 0 "register_operand" ""))
13300 (use (match_operand:MODEF 1 "general_operand" ""))
13301 (use (match_operand:MODEF 2 "general_operand" ""))]
13302 "TARGET_USE_FANCY_MATH_387"
13304 rtx (*gen_truncxf) (rtx, rtx);
13306 rtx label = gen_label_rtx ();
13308 rtx op1 = gen_reg_rtx (XFmode);
13309 rtx op2 = gen_reg_rtx (XFmode);
13311 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13314 emit_label (label);
13316 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13317 ix86_emit_fp_unordered_jump (label);
13318 LABEL_NUSES (label) = 1;
13320 /* Truncate the result properly for strict SSE math. */
13321 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13322 && !TARGET_MIX_SSE_I387)
13323 gen_truncxf = gen_truncxf<mode>2;
13325 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13327 emit_insn (gen_truncxf (operands[0], op1));
13331 (define_insn "*sinxf2_i387"
13332 [(set (match_operand:XF 0 "register_operand" "=f")
13333 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13334 "TARGET_USE_FANCY_MATH_387
13335 && flag_unsafe_math_optimizations"
13337 [(set_attr "type" "fpspc")
13338 (set_attr "mode" "XF")])
13340 (define_insn "*sin_extend<mode>xf2_i387"
13341 [(set (match_operand:XF 0 "register_operand" "=f")
13342 (unspec:XF [(float_extend:XF
13343 (match_operand:MODEF 1 "register_operand" "0"))]
13345 "TARGET_USE_FANCY_MATH_387
13346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13347 || TARGET_MIX_SSE_I387)
13348 && flag_unsafe_math_optimizations"
13350 [(set_attr "type" "fpspc")
13351 (set_attr "mode" "XF")])
13353 (define_insn "*cosxf2_i387"
13354 [(set (match_operand:XF 0 "register_operand" "=f")
13355 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13356 "TARGET_USE_FANCY_MATH_387
13357 && flag_unsafe_math_optimizations"
13359 [(set_attr "type" "fpspc")
13360 (set_attr "mode" "XF")])
13362 (define_insn "*cos_extend<mode>xf2_i387"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13364 (unspec:XF [(float_extend:XF
13365 (match_operand:MODEF 1 "register_operand" "0"))]
13367 "TARGET_USE_FANCY_MATH_387
13368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13369 || TARGET_MIX_SSE_I387)
13370 && flag_unsafe_math_optimizations"
13372 [(set_attr "type" "fpspc")
13373 (set_attr "mode" "XF")])
13375 ;; When sincos pattern is defined, sin and cos builtin functions will be
13376 ;; expanded to sincos pattern with one of its outputs left unused.
13377 ;; CSE pass will figure out if two sincos patterns can be combined,
13378 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13379 ;; depending on the unused output.
13381 (define_insn "sincosxf3"
13382 [(set (match_operand:XF 0 "register_operand" "=f")
13383 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13384 UNSPEC_SINCOS_COS))
13385 (set (match_operand:XF 1 "register_operand" "=u")
13386 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13387 "TARGET_USE_FANCY_MATH_387
13388 && flag_unsafe_math_optimizations"
13390 [(set_attr "type" "fpspc")
13391 (set_attr "mode" "XF")])
13394 [(set (match_operand:XF 0 "register_operand" "")
13395 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13396 UNSPEC_SINCOS_COS))
13397 (set (match_operand:XF 1 "register_operand" "")
13398 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13399 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13400 && can_create_pseudo_p ()"
13401 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13404 [(set (match_operand:XF 0 "register_operand" "")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13406 UNSPEC_SINCOS_COS))
13407 (set (match_operand:XF 1 "register_operand" "")
13408 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13409 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13410 && can_create_pseudo_p ()"
13411 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13413 (define_insn "sincos_extend<mode>xf3_i387"
13414 [(set (match_operand:XF 0 "register_operand" "=f")
13415 (unspec:XF [(float_extend:XF
13416 (match_operand:MODEF 2 "register_operand" "0"))]
13417 UNSPEC_SINCOS_COS))
13418 (set (match_operand:XF 1 "register_operand" "=u")
13419 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13420 "TARGET_USE_FANCY_MATH_387
13421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13422 || TARGET_MIX_SSE_I387)
13423 && flag_unsafe_math_optimizations"
13425 [(set_attr "type" "fpspc")
13426 (set_attr "mode" "XF")])
13429 [(set (match_operand:XF 0 "register_operand" "")
13430 (unspec:XF [(float_extend:XF
13431 (match_operand:MODEF 2 "register_operand" ""))]
13432 UNSPEC_SINCOS_COS))
13433 (set (match_operand:XF 1 "register_operand" "")
13434 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13435 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13436 && can_create_pseudo_p ()"
13437 [(set (match_dup 1)
13438 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13441 [(set (match_operand:XF 0 "register_operand" "")
13442 (unspec:XF [(float_extend:XF
13443 (match_operand:MODEF 2 "register_operand" ""))]
13444 UNSPEC_SINCOS_COS))
13445 (set (match_operand:XF 1 "register_operand" "")
13446 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13447 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13448 && can_create_pseudo_p ()"
13449 [(set (match_dup 0)
13450 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13452 (define_expand "sincos<mode>3"
13453 [(use (match_operand:MODEF 0 "register_operand" ""))
13454 (use (match_operand:MODEF 1 "register_operand" ""))
13455 (use (match_operand:MODEF 2 "register_operand" ""))]
13456 "TARGET_USE_FANCY_MATH_387
13457 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13458 || TARGET_MIX_SSE_I387)
13459 && flag_unsafe_math_optimizations"
13461 rtx op0 = gen_reg_rtx (XFmode);
13462 rtx op1 = gen_reg_rtx (XFmode);
13464 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13465 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13470 (define_insn "fptanxf4_i387"
13471 [(set (match_operand:XF 0 "register_operand" "=f")
13472 (match_operand:XF 3 "const_double_operand" "F"))
13473 (set (match_operand:XF 1 "register_operand" "=u")
13474 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13476 "TARGET_USE_FANCY_MATH_387
13477 && flag_unsafe_math_optimizations
13478 && standard_80387_constant_p (operands[3]) == 2"
13480 [(set_attr "type" "fpspc")
13481 (set_attr "mode" "XF")])
13483 (define_insn "fptan_extend<mode>xf4_i387"
13484 [(set (match_operand:MODEF 0 "register_operand" "=f")
13485 (match_operand:MODEF 3 "const_double_operand" "F"))
13486 (set (match_operand:XF 1 "register_operand" "=u")
13487 (unspec:XF [(float_extend:XF
13488 (match_operand:MODEF 2 "register_operand" "0"))]
13490 "TARGET_USE_FANCY_MATH_387
13491 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13492 || TARGET_MIX_SSE_I387)
13493 && flag_unsafe_math_optimizations
13494 && standard_80387_constant_p (operands[3]) == 2"
13496 [(set_attr "type" "fpspc")
13497 (set_attr "mode" "XF")])
13499 (define_expand "tanxf2"
13500 [(use (match_operand:XF 0 "register_operand" ""))
13501 (use (match_operand:XF 1 "register_operand" ""))]
13502 "TARGET_USE_FANCY_MATH_387
13503 && flag_unsafe_math_optimizations"
13505 rtx one = gen_reg_rtx (XFmode);
13506 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13508 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13512 (define_expand "tan<mode>2"
13513 [(use (match_operand:MODEF 0 "register_operand" ""))
13514 (use (match_operand:MODEF 1 "register_operand" ""))]
13515 "TARGET_USE_FANCY_MATH_387
13516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13517 || TARGET_MIX_SSE_I387)
13518 && flag_unsafe_math_optimizations"
13520 rtx op0 = gen_reg_rtx (XFmode);
13522 rtx one = gen_reg_rtx (<MODE>mode);
13523 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13525 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13526 operands[1], op2));
13527 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13531 (define_insn "*fpatanxf3_i387"
13532 [(set (match_operand:XF 0 "register_operand" "=f")
13533 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13534 (match_operand:XF 2 "register_operand" "u")]
13536 (clobber (match_scratch:XF 3 "=2"))]
13537 "TARGET_USE_FANCY_MATH_387
13538 && flag_unsafe_math_optimizations"
13540 [(set_attr "type" "fpspc")
13541 (set_attr "mode" "XF")])
13543 (define_insn "fpatan_extend<mode>xf3_i387"
13544 [(set (match_operand:XF 0 "register_operand" "=f")
13545 (unspec:XF [(float_extend:XF
13546 (match_operand:MODEF 1 "register_operand" "0"))
13548 (match_operand:MODEF 2 "register_operand" "u"))]
13550 (clobber (match_scratch:XF 3 "=2"))]
13551 "TARGET_USE_FANCY_MATH_387
13552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13553 || TARGET_MIX_SSE_I387)
13554 && flag_unsafe_math_optimizations"
13556 [(set_attr "type" "fpspc")
13557 (set_attr "mode" "XF")])
13559 (define_expand "atan2xf3"
13560 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13561 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13562 (match_operand:XF 1 "register_operand" "")]
13564 (clobber (match_scratch:XF 3 ""))])]
13565 "TARGET_USE_FANCY_MATH_387
13566 && flag_unsafe_math_optimizations")
13568 (define_expand "atan2<mode>3"
13569 [(use (match_operand:MODEF 0 "register_operand" ""))
13570 (use (match_operand:MODEF 1 "register_operand" ""))
13571 (use (match_operand:MODEF 2 "register_operand" ""))]
13572 "TARGET_USE_FANCY_MATH_387
13573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13574 || TARGET_MIX_SSE_I387)
13575 && flag_unsafe_math_optimizations"
13577 rtx op0 = gen_reg_rtx (XFmode);
13579 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13580 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13584 (define_expand "atanxf2"
13585 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13586 (unspec:XF [(match_dup 2)
13587 (match_operand:XF 1 "register_operand" "")]
13589 (clobber (match_scratch:XF 3 ""))])]
13590 "TARGET_USE_FANCY_MATH_387
13591 && flag_unsafe_math_optimizations"
13593 operands[2] = gen_reg_rtx (XFmode);
13594 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13597 (define_expand "atan<mode>2"
13598 [(use (match_operand:MODEF 0 "register_operand" ""))
13599 (use (match_operand:MODEF 1 "register_operand" ""))]
13600 "TARGET_USE_FANCY_MATH_387
13601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602 || TARGET_MIX_SSE_I387)
13603 && flag_unsafe_math_optimizations"
13605 rtx op0 = gen_reg_rtx (XFmode);
13607 rtx op2 = gen_reg_rtx (<MODE>mode);
13608 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13610 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13611 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13615 (define_expand "asinxf2"
13616 [(set (match_dup 2)
13617 (mult:XF (match_operand:XF 1 "register_operand" "")
13619 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13620 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13621 (parallel [(set (match_operand:XF 0 "register_operand" "")
13622 (unspec:XF [(match_dup 5) (match_dup 1)]
13624 (clobber (match_scratch:XF 6 ""))])]
13625 "TARGET_USE_FANCY_MATH_387
13626 && flag_unsafe_math_optimizations"
13630 if (optimize_insn_for_size_p ())
13633 for (i = 2; i < 6; i++)
13634 operands[i] = gen_reg_rtx (XFmode);
13636 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13639 (define_expand "asin<mode>2"
13640 [(use (match_operand:MODEF 0 "register_operand" ""))
13641 (use (match_operand:MODEF 1 "general_operand" ""))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644 || TARGET_MIX_SSE_I387)
13645 && flag_unsafe_math_optimizations"
13647 rtx op0 = gen_reg_rtx (XFmode);
13648 rtx op1 = gen_reg_rtx (XFmode);
13650 if (optimize_insn_for_size_p ())
13653 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13654 emit_insn (gen_asinxf2 (op0, op1));
13655 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13659 (define_expand "acosxf2"
13660 [(set (match_dup 2)
13661 (mult:XF (match_operand:XF 1 "register_operand" "")
13663 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13664 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13665 (parallel [(set (match_operand:XF 0 "register_operand" "")
13666 (unspec:XF [(match_dup 1) (match_dup 5)]
13668 (clobber (match_scratch:XF 6 ""))])]
13669 "TARGET_USE_FANCY_MATH_387
13670 && flag_unsafe_math_optimizations"
13674 if (optimize_insn_for_size_p ())
13677 for (i = 2; i < 6; i++)
13678 operands[i] = gen_reg_rtx (XFmode);
13680 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13683 (define_expand "acos<mode>2"
13684 [(use (match_operand:MODEF 0 "register_operand" ""))
13685 (use (match_operand:MODEF 1 "general_operand" ""))]
13686 "TARGET_USE_FANCY_MATH_387
13687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13688 || TARGET_MIX_SSE_I387)
13689 && flag_unsafe_math_optimizations"
13691 rtx op0 = gen_reg_rtx (XFmode);
13692 rtx op1 = gen_reg_rtx (XFmode);
13694 if (optimize_insn_for_size_p ())
13697 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13698 emit_insn (gen_acosxf2 (op0, op1));
13699 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13703 (define_insn "fyl2xxf3_i387"
13704 [(set (match_operand:XF 0 "register_operand" "=f")
13705 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13706 (match_operand:XF 2 "register_operand" "u")]
13708 (clobber (match_scratch:XF 3 "=2"))]
13709 "TARGET_USE_FANCY_MATH_387
13710 && flag_unsafe_math_optimizations"
13712 [(set_attr "type" "fpspc")
13713 (set_attr "mode" "XF")])
13715 (define_insn "fyl2x_extend<mode>xf3_i387"
13716 [(set (match_operand:XF 0 "register_operand" "=f")
13717 (unspec:XF [(float_extend:XF
13718 (match_operand:MODEF 1 "register_operand" "0"))
13719 (match_operand:XF 2 "register_operand" "u")]
13721 (clobber (match_scratch:XF 3 "=2"))]
13722 "TARGET_USE_FANCY_MATH_387
13723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13724 || TARGET_MIX_SSE_I387)
13725 && flag_unsafe_math_optimizations"
13727 [(set_attr "type" "fpspc")
13728 (set_attr "mode" "XF")])
13730 (define_expand "logxf2"
13731 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13732 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13733 (match_dup 2)] UNSPEC_FYL2X))
13734 (clobber (match_scratch:XF 3 ""))])]
13735 "TARGET_USE_FANCY_MATH_387
13736 && flag_unsafe_math_optimizations"
13738 operands[2] = gen_reg_rtx (XFmode);
13739 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13742 (define_expand "log<mode>2"
13743 [(use (match_operand:MODEF 0 "register_operand" ""))
13744 (use (match_operand:MODEF 1 "register_operand" ""))]
13745 "TARGET_USE_FANCY_MATH_387
13746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13747 || TARGET_MIX_SSE_I387)
13748 && flag_unsafe_math_optimizations"
13750 rtx op0 = gen_reg_rtx (XFmode);
13752 rtx op2 = gen_reg_rtx (XFmode);
13753 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13755 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13756 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13760 (define_expand "log10xf2"
13761 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13762 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13763 (match_dup 2)] UNSPEC_FYL2X))
13764 (clobber (match_scratch:XF 3 ""))])]
13765 "TARGET_USE_FANCY_MATH_387
13766 && flag_unsafe_math_optimizations"
13768 operands[2] = gen_reg_rtx (XFmode);
13769 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13772 (define_expand "log10<mode>2"
13773 [(use (match_operand:MODEF 0 "register_operand" ""))
13774 (use (match_operand:MODEF 1 "register_operand" ""))]
13775 "TARGET_USE_FANCY_MATH_387
13776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13777 || TARGET_MIX_SSE_I387)
13778 && flag_unsafe_math_optimizations"
13780 rtx op0 = gen_reg_rtx (XFmode);
13782 rtx op2 = gen_reg_rtx (XFmode);
13783 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13785 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13790 (define_expand "log2xf2"
13791 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13792 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13793 (match_dup 2)] UNSPEC_FYL2X))
13794 (clobber (match_scratch:XF 3 ""))])]
13795 "TARGET_USE_FANCY_MATH_387
13796 && flag_unsafe_math_optimizations"
13798 operands[2] = gen_reg_rtx (XFmode);
13799 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13802 (define_expand "log2<mode>2"
13803 [(use (match_operand:MODEF 0 "register_operand" ""))
13804 (use (match_operand:MODEF 1 "register_operand" ""))]
13805 "TARGET_USE_FANCY_MATH_387
13806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13807 || TARGET_MIX_SSE_I387)
13808 && flag_unsafe_math_optimizations"
13810 rtx op0 = gen_reg_rtx (XFmode);
13812 rtx op2 = gen_reg_rtx (XFmode);
13813 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13815 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13816 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13820 (define_insn "fyl2xp1xf3_i387"
13821 [(set (match_operand:XF 0 "register_operand" "=f")
13822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13823 (match_operand:XF 2 "register_operand" "u")]
13825 (clobber (match_scratch:XF 3 "=2"))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && flag_unsafe_math_optimizations"
13829 [(set_attr "type" "fpspc")
13830 (set_attr "mode" "XF")])
13832 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13833 [(set (match_operand:XF 0 "register_operand" "=f")
13834 (unspec:XF [(float_extend:XF
13835 (match_operand:MODEF 1 "register_operand" "0"))
13836 (match_operand:XF 2 "register_operand" "u")]
13838 (clobber (match_scratch:XF 3 "=2"))]
13839 "TARGET_USE_FANCY_MATH_387
13840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841 || TARGET_MIX_SSE_I387)
13842 && flag_unsafe_math_optimizations"
13844 [(set_attr "type" "fpspc")
13845 (set_attr "mode" "XF")])
13847 (define_expand "log1pxf2"
13848 [(use (match_operand:XF 0 "register_operand" ""))
13849 (use (match_operand:XF 1 "register_operand" ""))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && flag_unsafe_math_optimizations"
13853 if (optimize_insn_for_size_p ())
13856 ix86_emit_i387_log1p (operands[0], operands[1]);
13860 (define_expand "log1p<mode>2"
13861 [(use (match_operand:MODEF 0 "register_operand" ""))
13862 (use (match_operand:MODEF 1 "register_operand" ""))]
13863 "TARGET_USE_FANCY_MATH_387
13864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13865 || TARGET_MIX_SSE_I387)
13866 && flag_unsafe_math_optimizations"
13870 if (optimize_insn_for_size_p ())
13873 op0 = gen_reg_rtx (XFmode);
13875 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13877 ix86_emit_i387_log1p (op0, operands[1]);
13878 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13882 (define_insn "fxtractxf3_i387"
13883 [(set (match_operand:XF 0 "register_operand" "=f")
13884 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13885 UNSPEC_XTRACT_FRACT))
13886 (set (match_operand:XF 1 "register_operand" "=u")
13887 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13888 "TARGET_USE_FANCY_MATH_387
13889 && flag_unsafe_math_optimizations"
13891 [(set_attr "type" "fpspc")
13892 (set_attr "mode" "XF")])
13894 (define_insn "fxtract_extend<mode>xf3_i387"
13895 [(set (match_operand:XF 0 "register_operand" "=f")
13896 (unspec:XF [(float_extend:XF
13897 (match_operand:MODEF 2 "register_operand" "0"))]
13898 UNSPEC_XTRACT_FRACT))
13899 (set (match_operand:XF 1 "register_operand" "=u")
13900 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13906 [(set_attr "type" "fpspc")
13907 (set_attr "mode" "XF")])
13909 (define_expand "logbxf2"
13910 [(parallel [(set (match_dup 2)
13911 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13912 UNSPEC_XTRACT_FRACT))
13913 (set (match_operand:XF 0 "register_operand" "")
13914 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13915 "TARGET_USE_FANCY_MATH_387
13916 && flag_unsafe_math_optimizations"
13917 "operands[2] = gen_reg_rtx (XFmode);")
13919 (define_expand "logb<mode>2"
13920 [(use (match_operand:MODEF 0 "register_operand" ""))
13921 (use (match_operand:MODEF 1 "register_operand" ""))]
13922 "TARGET_USE_FANCY_MATH_387
13923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13924 || TARGET_MIX_SSE_I387)
13925 && flag_unsafe_math_optimizations"
13927 rtx op0 = gen_reg_rtx (XFmode);
13928 rtx op1 = gen_reg_rtx (XFmode);
13930 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13935 (define_expand "ilogbxf2"
13936 [(use (match_operand:SI 0 "register_operand" ""))
13937 (use (match_operand:XF 1 "register_operand" ""))]
13938 "TARGET_USE_FANCY_MATH_387
13939 && flag_unsafe_math_optimizations"
13943 if (optimize_insn_for_size_p ())
13946 op0 = gen_reg_rtx (XFmode);
13947 op1 = gen_reg_rtx (XFmode);
13949 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13950 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13954 (define_expand "ilogb<mode>2"
13955 [(use (match_operand:SI 0 "register_operand" ""))
13956 (use (match_operand:MODEF 1 "register_operand" ""))]
13957 "TARGET_USE_FANCY_MATH_387
13958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959 || TARGET_MIX_SSE_I387)
13960 && flag_unsafe_math_optimizations"
13964 if (optimize_insn_for_size_p ())
13967 op0 = gen_reg_rtx (XFmode);
13968 op1 = gen_reg_rtx (XFmode);
13970 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13971 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13975 (define_insn "*f2xm1xf2_i387"
13976 [(set (match_operand:XF 0 "register_operand" "=f")
13977 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13979 "TARGET_USE_FANCY_MATH_387
13980 && flag_unsafe_math_optimizations"
13982 [(set_attr "type" "fpspc")
13983 (set_attr "mode" "XF")])
13985 (define_insn "*fscalexf4_i387"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13988 (match_operand:XF 3 "register_operand" "1")]
13989 UNSPEC_FSCALE_FRACT))
13990 (set (match_operand:XF 1 "register_operand" "=u")
13991 (unspec:XF [(match_dup 2) (match_dup 3)]
13992 UNSPEC_FSCALE_EXP))]
13993 "TARGET_USE_FANCY_MATH_387
13994 && flag_unsafe_math_optimizations"
13996 [(set_attr "type" "fpspc")
13997 (set_attr "mode" "XF")])
13999 (define_expand "expNcorexf3"
14000 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14001 (match_operand:XF 2 "register_operand" "")))
14002 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14003 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14004 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14005 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14006 (parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_dup 8) (match_dup 4)]
14008 UNSPEC_FSCALE_FRACT))
14010 (unspec:XF [(match_dup 8) (match_dup 4)]
14011 UNSPEC_FSCALE_EXP))])]
14012 "TARGET_USE_FANCY_MATH_387
14013 && flag_unsafe_math_optimizations"
14017 if (optimize_insn_for_size_p ())
14020 for (i = 3; i < 10; i++)
14021 operands[i] = gen_reg_rtx (XFmode);
14023 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14026 (define_expand "expxf2"
14027 [(use (match_operand:XF 0 "register_operand" ""))
14028 (use (match_operand:XF 1 "register_operand" ""))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && flag_unsafe_math_optimizations"
14034 if (optimize_insn_for_size_p ())
14037 op2 = gen_reg_rtx (XFmode);
14038 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14040 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14044 (define_expand "exp<mode>2"
14045 [(use (match_operand:MODEF 0 "register_operand" ""))
14046 (use (match_operand:MODEF 1 "general_operand" ""))]
14047 "TARGET_USE_FANCY_MATH_387
14048 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14049 || TARGET_MIX_SSE_I387)
14050 && flag_unsafe_math_optimizations"
14054 if (optimize_insn_for_size_p ())
14057 op0 = gen_reg_rtx (XFmode);
14058 op1 = gen_reg_rtx (XFmode);
14060 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14061 emit_insn (gen_expxf2 (op0, op1));
14062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 (define_expand "exp10xf2"
14067 [(use (match_operand:XF 0 "register_operand" ""))
14068 (use (match_operand:XF 1 "register_operand" ""))]
14069 "TARGET_USE_FANCY_MATH_387
14070 && flag_unsafe_math_optimizations"
14074 if (optimize_insn_for_size_p ())
14077 op2 = gen_reg_rtx (XFmode);
14078 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14080 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14084 (define_expand "exp10<mode>2"
14085 [(use (match_operand:MODEF 0 "register_operand" ""))
14086 (use (match_operand:MODEF 1 "general_operand" ""))]
14087 "TARGET_USE_FANCY_MATH_387
14088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14089 || TARGET_MIX_SSE_I387)
14090 && flag_unsafe_math_optimizations"
14094 if (optimize_insn_for_size_p ())
14097 op0 = gen_reg_rtx (XFmode);
14098 op1 = gen_reg_rtx (XFmode);
14100 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14101 emit_insn (gen_exp10xf2 (op0, op1));
14102 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14106 (define_expand "exp2xf2"
14107 [(use (match_operand:XF 0 "register_operand" ""))
14108 (use (match_operand:XF 1 "register_operand" ""))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations"
14114 if (optimize_insn_for_size_p ())
14117 op2 = gen_reg_rtx (XFmode);
14118 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14120 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14124 (define_expand "exp2<mode>2"
14125 [(use (match_operand:MODEF 0 "register_operand" ""))
14126 (use (match_operand:MODEF 1 "general_operand" ""))]
14127 "TARGET_USE_FANCY_MATH_387
14128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14129 || TARGET_MIX_SSE_I387)
14130 && flag_unsafe_math_optimizations"
14134 if (optimize_insn_for_size_p ())
14137 op0 = gen_reg_rtx (XFmode);
14138 op1 = gen_reg_rtx (XFmode);
14140 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14141 emit_insn (gen_exp2xf2 (op0, op1));
14142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14146 (define_expand "expm1xf2"
14147 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14149 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14150 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14151 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14152 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14153 (parallel [(set (match_dup 7)
14154 (unspec:XF [(match_dup 6) (match_dup 4)]
14155 UNSPEC_FSCALE_FRACT))
14157 (unspec:XF [(match_dup 6) (match_dup 4)]
14158 UNSPEC_FSCALE_EXP))])
14159 (parallel [(set (match_dup 10)
14160 (unspec:XF [(match_dup 9) (match_dup 8)]
14161 UNSPEC_FSCALE_FRACT))
14162 (set (match_dup 11)
14163 (unspec:XF [(match_dup 9) (match_dup 8)]
14164 UNSPEC_FSCALE_EXP))])
14165 (set (match_dup 12) (minus:XF (match_dup 10)
14166 (float_extend:XF (match_dup 13))))
14167 (set (match_operand:XF 0 "register_operand" "")
14168 (plus:XF (match_dup 12) (match_dup 7)))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && flag_unsafe_math_optimizations"
14174 if (optimize_insn_for_size_p ())
14177 for (i = 2; i < 13; i++)
14178 operands[i] = gen_reg_rtx (XFmode);
14181 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14183 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14186 (define_expand "expm1<mode>2"
14187 [(use (match_operand:MODEF 0 "register_operand" ""))
14188 (use (match_operand:MODEF 1 "general_operand" ""))]
14189 "TARGET_USE_FANCY_MATH_387
14190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191 || TARGET_MIX_SSE_I387)
14192 && flag_unsafe_math_optimizations"
14196 if (optimize_insn_for_size_p ())
14199 op0 = gen_reg_rtx (XFmode);
14200 op1 = gen_reg_rtx (XFmode);
14202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14203 emit_insn (gen_expm1xf2 (op0, op1));
14204 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14208 (define_expand "ldexpxf3"
14209 [(set (match_dup 3)
14210 (float:XF (match_operand:SI 2 "register_operand" "")))
14211 (parallel [(set (match_operand:XF 0 " register_operand" "")
14212 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14214 UNSPEC_FSCALE_FRACT))
14216 (unspec:XF [(match_dup 1) (match_dup 3)]
14217 UNSPEC_FSCALE_EXP))])]
14218 "TARGET_USE_FANCY_MATH_387
14219 && flag_unsafe_math_optimizations"
14221 if (optimize_insn_for_size_p ())
14224 operands[3] = gen_reg_rtx (XFmode);
14225 operands[4] = gen_reg_rtx (XFmode);
14228 (define_expand "ldexp<mode>3"
14229 [(use (match_operand:MODEF 0 "register_operand" ""))
14230 (use (match_operand:MODEF 1 "general_operand" ""))
14231 (use (match_operand:SI 2 "register_operand" ""))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14234 || TARGET_MIX_SSE_I387)
14235 && flag_unsafe_math_optimizations"
14239 if (optimize_insn_for_size_p ())
14242 op0 = gen_reg_rtx (XFmode);
14243 op1 = gen_reg_rtx (XFmode);
14245 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14246 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14247 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14251 (define_expand "scalbxf3"
14252 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14253 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14254 (match_operand:XF 2 "register_operand" "")]
14255 UNSPEC_FSCALE_FRACT))
14257 (unspec:XF [(match_dup 1) (match_dup 2)]
14258 UNSPEC_FSCALE_EXP))])]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14262 if (optimize_insn_for_size_p ())
14265 operands[3] = gen_reg_rtx (XFmode);
14268 (define_expand "scalb<mode>3"
14269 [(use (match_operand:MODEF 0 "register_operand" ""))
14270 (use (match_operand:MODEF 1 "general_operand" ""))
14271 (use (match_operand:MODEF 2 "general_operand" ""))]
14272 "TARGET_USE_FANCY_MATH_387
14273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14274 || TARGET_MIX_SSE_I387)
14275 && flag_unsafe_math_optimizations"
14279 if (optimize_insn_for_size_p ())
14282 op0 = gen_reg_rtx (XFmode);
14283 op1 = gen_reg_rtx (XFmode);
14284 op2 = gen_reg_rtx (XFmode);
14286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14288 emit_insn (gen_scalbxf3 (op0, op1, op2));
14289 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14293 (define_expand "significandxf2"
14294 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14295 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14296 UNSPEC_XTRACT_FRACT))
14298 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14299 "TARGET_USE_FANCY_MATH_387
14300 && flag_unsafe_math_optimizations"
14301 "operands[2] = gen_reg_rtx (XFmode);")
14303 (define_expand "significand<mode>2"
14304 [(use (match_operand:MODEF 0 "register_operand" ""))
14305 (use (match_operand:MODEF 1 "register_operand" ""))]
14306 "TARGET_USE_FANCY_MATH_387
14307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14308 || TARGET_MIX_SSE_I387)
14309 && flag_unsafe_math_optimizations"
14311 rtx op0 = gen_reg_rtx (XFmode);
14312 rtx op1 = gen_reg_rtx (XFmode);
14314 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14315 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14320 (define_insn "sse4_1_round<mode>2"
14321 [(set (match_operand:MODEF 0 "register_operand" "=x")
14322 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14323 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14326 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14327 [(set_attr "type" "ssecvt")
14328 (set_attr "prefix_extra" "1")
14329 (set_attr "prefix" "maybe_vex")
14330 (set_attr "mode" "<MODE>")])
14332 (define_insn "rintxf2"
14333 [(set (match_operand:XF 0 "register_operand" "=f")
14334 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14336 "TARGET_USE_FANCY_MATH_387
14337 && flag_unsafe_math_optimizations"
14339 [(set_attr "type" "fpspc")
14340 (set_attr "mode" "XF")])
14342 (define_expand "rint<mode>2"
14343 [(use (match_operand:MODEF 0 "register_operand" ""))
14344 (use (match_operand:MODEF 1 "register_operand" ""))]
14345 "(TARGET_USE_FANCY_MATH_387
14346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14347 || TARGET_MIX_SSE_I387)
14348 && flag_unsafe_math_optimizations)
14349 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14350 && !flag_trapping_math)"
14352 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14353 && !flag_trapping_math)
14355 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14358 emit_insn (gen_sse4_1_round<mode>2
14359 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14361 ix86_expand_rint (operand0, operand1);
14365 rtx op0 = gen_reg_rtx (XFmode);
14366 rtx op1 = gen_reg_rtx (XFmode);
14368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14369 emit_insn (gen_rintxf2 (op0, op1));
14371 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14376 (define_expand "round<mode>2"
14377 [(match_operand:MODEF 0 "register_operand" "")
14378 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14380 && !flag_trapping_math && !flag_rounding_math"
14382 if (optimize_insn_for_size_p ())
14384 if (TARGET_64BIT || (<MODE>mode != DFmode))
14385 ix86_expand_round (operand0, operand1);
14387 ix86_expand_rounddf_32 (operand0, operand1);
14391 (define_insn_and_split "*fistdi2_1"
14392 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14393 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14395 "TARGET_USE_FANCY_MATH_387
14396 && can_create_pseudo_p ()"
14401 if (memory_operand (operands[0], VOIDmode))
14402 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14405 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14406 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14411 [(set_attr "type" "fpspc")
14412 (set_attr "mode" "DI")])
14414 (define_insn "fistdi2"
14415 [(set (match_operand:DI 0 "memory_operand" "=m")
14416 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14418 (clobber (match_scratch:XF 2 "=&1f"))]
14419 "TARGET_USE_FANCY_MATH_387"
14420 "* return output_fix_trunc (insn, operands, false);"
14421 [(set_attr "type" "fpspc")
14422 (set_attr "mode" "DI")])
14424 (define_insn "fistdi2_with_temp"
14425 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14426 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14428 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14429 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14430 "TARGET_USE_FANCY_MATH_387"
14432 [(set_attr "type" "fpspc")
14433 (set_attr "mode" "DI")])
14436 [(set (match_operand:DI 0 "register_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 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14443 (clobber (match_dup 3))])
14444 (set (match_dup 0) (match_dup 2))])
14447 [(set (match_operand:DI 0 "memory_operand" "")
14448 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14450 (clobber (match_operand:DI 2 "memory_operand" ""))
14451 (clobber (match_scratch 3 ""))]
14453 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14454 (clobber (match_dup 3))])])
14456 (define_insn_and_split "*fist<mode>2_1"
14457 [(set (match_operand:SWI24 0 "register_operand" "")
14458 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14460 "TARGET_USE_FANCY_MATH_387
14461 && can_create_pseudo_p ()"
14466 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14467 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14471 [(set_attr "type" "fpspc")
14472 (set_attr "mode" "<MODE>")])
14474 (define_insn "fist<mode>2"
14475 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14476 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14478 "TARGET_USE_FANCY_MATH_387"
14479 "* return output_fix_trunc (insn, operands, false);"
14480 [(set_attr "type" "fpspc")
14481 (set_attr "mode" "<MODE>")])
14483 (define_insn "fist<mode>2_with_temp"
14484 [(set (match_operand:SWI24 0 "register_operand" "=r")
14485 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14487 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14488 "TARGET_USE_FANCY_MATH_387"
14490 [(set_attr "type" "fpspc")
14491 (set_attr "mode" "<MODE>")])
14494 [(set (match_operand:SWI24 0 "register_operand" "")
14495 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14497 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14499 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14500 (set (match_dup 0) (match_dup 2))])
14503 [(set (match_operand:SWI24 0 "memory_operand" "")
14504 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14506 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14508 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14510 (define_expand "lrintxf<mode>2"
14511 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14512 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14514 "TARGET_USE_FANCY_MATH_387")
14516 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14517 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14518 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14519 UNSPEC_FIX_NOTRUNC))]
14520 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14521 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14523 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14524 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14525 (match_operand:MODEF 1 "register_operand" "")]
14526 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14527 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14528 && !flag_trapping_math && !flag_rounding_math"
14530 if (optimize_insn_for_size_p ())
14532 ix86_expand_lround (operand0, operand1);
14536 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14537 (define_insn_and_split "frndintxf2_floor"
14538 [(set (match_operand:XF 0 "register_operand" "")
14539 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14540 UNSPEC_FRNDINT_FLOOR))
14541 (clobber (reg:CC FLAGS_REG))]
14542 "TARGET_USE_FANCY_MATH_387
14543 && flag_unsafe_math_optimizations
14544 && can_create_pseudo_p ()"
14549 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14551 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14552 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14554 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14555 operands[2], operands[3]));
14558 [(set_attr "type" "frndint")
14559 (set_attr "i387_cw" "floor")
14560 (set_attr "mode" "XF")])
14562 (define_insn "frndintxf2_floor_i387"
14563 [(set (match_operand:XF 0 "register_operand" "=f")
14564 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14565 UNSPEC_FRNDINT_FLOOR))
14566 (use (match_operand:HI 2 "memory_operand" "m"))
14567 (use (match_operand:HI 3 "memory_operand" "m"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14570 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14571 [(set_attr "type" "frndint")
14572 (set_attr "i387_cw" "floor")
14573 (set_attr "mode" "XF")])
14575 (define_expand "floorxf2"
14576 [(use (match_operand:XF 0 "register_operand" ""))
14577 (use (match_operand:XF 1 "register_operand" ""))]
14578 "TARGET_USE_FANCY_MATH_387
14579 && flag_unsafe_math_optimizations"
14581 if (optimize_insn_for_size_p ())
14583 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14587 (define_expand "floor<mode>2"
14588 [(use (match_operand:MODEF 0 "register_operand" ""))
14589 (use (match_operand:MODEF 1 "register_operand" ""))]
14590 "(TARGET_USE_FANCY_MATH_387
14591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592 || TARGET_MIX_SSE_I387)
14593 && flag_unsafe_math_optimizations)
14594 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14595 && !flag_trapping_math)"
14597 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14598 && !flag_trapping_math
14599 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14601 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14604 emit_insn (gen_sse4_1_round<mode>2
14605 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14606 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14607 ix86_expand_floorceil (operand0, operand1, true);
14609 ix86_expand_floorceildf_32 (operand0, operand1, true);
14615 if (optimize_insn_for_size_p ())
14618 op0 = gen_reg_rtx (XFmode);
14619 op1 = gen_reg_rtx (XFmode);
14620 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14621 emit_insn (gen_frndintxf2_floor (op0, op1));
14623 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14628 (define_insn_and_split "*fist<mode>2_floor_1"
14629 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14630 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14631 UNSPEC_FIST_FLOOR))
14632 (clobber (reg:CC FLAGS_REG))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && flag_unsafe_math_optimizations
14635 && can_create_pseudo_p ()"
14640 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14644 if (memory_operand (operands[0], VOIDmode))
14645 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14646 operands[2], operands[3]));
14649 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14650 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14651 operands[2], operands[3],
14656 [(set_attr "type" "fistp")
14657 (set_attr "i387_cw" "floor")
14658 (set_attr "mode" "<MODE>")])
14660 (define_insn "fistdi2_floor"
14661 [(set (match_operand:DI 0 "memory_operand" "=m")
14662 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14663 UNSPEC_FIST_FLOOR))
14664 (use (match_operand:HI 2 "memory_operand" "m"))
14665 (use (match_operand:HI 3 "memory_operand" "m"))
14666 (clobber (match_scratch:XF 4 "=&1f"))]
14667 "TARGET_USE_FANCY_MATH_387
14668 && flag_unsafe_math_optimizations"
14669 "* return output_fix_trunc (insn, operands, false);"
14670 [(set_attr "type" "fistp")
14671 (set_attr "i387_cw" "floor")
14672 (set_attr "mode" "DI")])
14674 (define_insn "fistdi2_floor_with_temp"
14675 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14677 UNSPEC_FIST_FLOOR))
14678 (use (match_operand:HI 2 "memory_operand" "m,m"))
14679 (use (match_operand:HI 3 "memory_operand" "m,m"))
14680 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14681 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && flag_unsafe_math_optimizations"
14685 [(set_attr "type" "fistp")
14686 (set_attr "i387_cw" "floor")
14687 (set_attr "mode" "DI")])
14690 [(set (match_operand:DI 0 "register_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692 UNSPEC_FIST_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" ""))
14694 (use (match_operand:HI 3 "memory_operand" ""))
14695 (clobber (match_operand:DI 4 "memory_operand" ""))
14696 (clobber (match_scratch 5 ""))]
14698 [(parallel [(set (match_dup 4)
14699 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14700 (use (match_dup 2))
14701 (use (match_dup 3))
14702 (clobber (match_dup 5))])
14703 (set (match_dup 0) (match_dup 4))])
14706 [(set (match_operand:DI 0 "memory_operand" "")
14707 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14708 UNSPEC_FIST_FLOOR))
14709 (use (match_operand:HI 2 "memory_operand" ""))
14710 (use (match_operand:HI 3 "memory_operand" ""))
14711 (clobber (match_operand:DI 4 "memory_operand" ""))
14712 (clobber (match_scratch 5 ""))]
14714 [(parallel [(set (match_dup 0)
14715 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14716 (use (match_dup 2))
14717 (use (match_dup 3))
14718 (clobber (match_dup 5))])])
14720 (define_insn "fist<mode>2_floor"
14721 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14722 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14723 UNSPEC_FIST_FLOOR))
14724 (use (match_operand:HI 2 "memory_operand" "m"))
14725 (use (match_operand:HI 3 "memory_operand" "m"))]
14726 "TARGET_USE_FANCY_MATH_387
14727 && flag_unsafe_math_optimizations"
14728 "* return output_fix_trunc (insn, operands, false);"
14729 [(set_attr "type" "fistp")
14730 (set_attr "i387_cw" "floor")
14731 (set_attr "mode" "<MODE>")])
14733 (define_insn "fist<mode>2_floor_with_temp"
14734 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14735 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14736 UNSPEC_FIST_FLOOR))
14737 (use (match_operand:HI 2 "memory_operand" "m,m"))
14738 (use (match_operand:HI 3 "memory_operand" "m,m"))
14739 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14740 "TARGET_USE_FANCY_MATH_387
14741 && flag_unsafe_math_optimizations"
14743 [(set_attr "type" "fistp")
14744 (set_attr "i387_cw" "floor")
14745 (set_attr "mode" "<MODE>")])
14748 [(set (match_operand:SWI24 0 "register_operand" "")
14749 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14750 UNSPEC_FIST_FLOOR))
14751 (use (match_operand:HI 2 "memory_operand" ""))
14752 (use (match_operand:HI 3 "memory_operand" ""))
14753 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14755 [(parallel [(set (match_dup 4)
14756 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14757 (use (match_dup 2))
14758 (use (match_dup 3))])
14759 (set (match_dup 0) (match_dup 4))])
14762 [(set (match_operand:SWI24 0 "memory_operand" "")
14763 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14764 UNSPEC_FIST_FLOOR))
14765 (use (match_operand:HI 2 "memory_operand" ""))
14766 (use (match_operand:HI 3 "memory_operand" ""))
14767 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14769 [(parallel [(set (match_dup 0)
14770 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14771 (use (match_dup 2))
14772 (use (match_dup 3))])])
14774 (define_expand "lfloorxf<mode>2"
14775 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14776 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14777 UNSPEC_FIST_FLOOR))
14778 (clobber (reg:CC FLAGS_REG))])]
14779 "TARGET_USE_FANCY_MATH_387
14780 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14781 && flag_unsafe_math_optimizations")
14783 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14784 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14785 (match_operand:MODEF 1 "register_operand" "")]
14786 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14787 && !flag_trapping_math"
14789 if (TARGET_64BIT && optimize_insn_for_size_p ())
14791 ix86_expand_lfloorceil (operand0, operand1, true);
14795 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14796 (define_insn_and_split "frndintxf2_ceil"
14797 [(set (match_operand:XF 0 "register_operand" "")
14798 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14799 UNSPEC_FRNDINT_CEIL))
14800 (clobber (reg:CC FLAGS_REG))]
14801 "TARGET_USE_FANCY_MATH_387
14802 && flag_unsafe_math_optimizations
14803 && can_create_pseudo_p ()"
14808 ix86_optimize_mode_switching[I387_CEIL] = 1;
14810 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14811 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14813 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14814 operands[2], operands[3]));
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "ceil")
14819 (set_attr "mode" "XF")])
14821 (define_insn "frndintxf2_ceil_i387"
14822 [(set (match_operand:XF 0 "register_operand" "=f")
14823 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14824 UNSPEC_FRNDINT_CEIL))
14825 (use (match_operand:HI 2 "memory_operand" "m"))
14826 (use (match_operand:HI 3 "memory_operand" "m"))]
14827 "TARGET_USE_FANCY_MATH_387
14828 && flag_unsafe_math_optimizations"
14829 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14830 [(set_attr "type" "frndint")
14831 (set_attr "i387_cw" "ceil")
14832 (set_attr "mode" "XF")])
14834 (define_expand "ceilxf2"
14835 [(use (match_operand:XF 0 "register_operand" ""))
14836 (use (match_operand:XF 1 "register_operand" ""))]
14837 "TARGET_USE_FANCY_MATH_387
14838 && flag_unsafe_math_optimizations"
14840 if (optimize_insn_for_size_p ())
14842 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14846 (define_expand "ceil<mode>2"
14847 [(use (match_operand:MODEF 0 "register_operand" ""))
14848 (use (match_operand:MODEF 1 "register_operand" ""))]
14849 "(TARGET_USE_FANCY_MATH_387
14850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14851 || TARGET_MIX_SSE_I387)
14852 && flag_unsafe_math_optimizations)
14853 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14854 && !flag_trapping_math)"
14856 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14857 && !flag_trapping_math
14858 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14861 emit_insn (gen_sse4_1_round<mode>2
14862 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14863 else if (optimize_insn_for_size_p ())
14865 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14866 ix86_expand_floorceil (operand0, operand1, false);
14868 ix86_expand_floorceildf_32 (operand0, operand1, false);
14874 if (optimize_insn_for_size_p ())
14877 op0 = gen_reg_rtx (XFmode);
14878 op1 = gen_reg_rtx (XFmode);
14879 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14880 emit_insn (gen_frndintxf2_ceil (op0, op1));
14882 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14887 (define_insn_and_split "*fist<mode>2_ceil_1"
14888 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14889 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14891 (clobber (reg:CC FLAGS_REG))]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations
14894 && can_create_pseudo_p ()"
14899 ix86_optimize_mode_switching[I387_CEIL] = 1;
14901 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14902 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14903 if (memory_operand (operands[0], VOIDmode))
14904 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14905 operands[2], operands[3]));
14908 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14909 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14910 operands[2], operands[3],
14915 [(set_attr "type" "fistp")
14916 (set_attr "i387_cw" "ceil")
14917 (set_attr "mode" "<MODE>")])
14919 (define_insn "fistdi2_ceil"
14920 [(set (match_operand:DI 0 "memory_operand" "=m")
14921 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14923 (use (match_operand:HI 2 "memory_operand" "m"))
14924 (use (match_operand:HI 3 "memory_operand" "m"))
14925 (clobber (match_scratch:XF 4 "=&1f"))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && flag_unsafe_math_optimizations"
14928 "* return output_fix_trunc (insn, operands, false);"
14929 [(set_attr "type" "fistp")
14930 (set_attr "i387_cw" "ceil")
14931 (set_attr "mode" "DI")])
14933 (define_insn "fistdi2_ceil_with_temp"
14934 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14935 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14937 (use (match_operand:HI 2 "memory_operand" "m,m"))
14938 (use (match_operand:HI 3 "memory_operand" "m,m"))
14939 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14940 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14941 "TARGET_USE_FANCY_MATH_387
14942 && flag_unsafe_math_optimizations"
14944 [(set_attr "type" "fistp")
14945 (set_attr "i387_cw" "ceil")
14946 (set_attr "mode" "DI")])
14949 [(set (match_operand:DI 0 "register_operand" "")
14950 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14952 (use (match_operand:HI 2 "memory_operand" ""))
14953 (use (match_operand:HI 3 "memory_operand" ""))
14954 (clobber (match_operand:DI 4 "memory_operand" ""))
14955 (clobber (match_scratch 5 ""))]
14957 [(parallel [(set (match_dup 4)
14958 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14959 (use (match_dup 2))
14960 (use (match_dup 3))
14961 (clobber (match_dup 5))])
14962 (set (match_dup 0) (match_dup 4))])
14965 [(set (match_operand:DI 0 "memory_operand" "")
14966 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14968 (use (match_operand:HI 2 "memory_operand" ""))
14969 (use (match_operand:HI 3 "memory_operand" ""))
14970 (clobber (match_operand:DI 4 "memory_operand" ""))
14971 (clobber (match_scratch 5 ""))]
14973 [(parallel [(set (match_dup 0)
14974 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14975 (use (match_dup 2))
14976 (use (match_dup 3))
14977 (clobber (match_dup 5))])])
14979 (define_insn "fist<mode>2_ceil"
14980 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14981 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14983 (use (match_operand:HI 2 "memory_operand" "m"))
14984 (use (match_operand:HI 3 "memory_operand" "m"))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations"
14987 "* return output_fix_trunc (insn, operands, false);"
14988 [(set_attr "type" "fistp")
14989 (set_attr "i387_cw" "ceil")
14990 (set_attr "mode" "<MODE>")])
14992 (define_insn "fist<mode>2_ceil_with_temp"
14993 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14994 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14996 (use (match_operand:HI 2 "memory_operand" "m,m"))
14997 (use (match_operand:HI 3 "memory_operand" "m,m"))
14998 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14999 "TARGET_USE_FANCY_MATH_387
15000 && flag_unsafe_math_optimizations"
15002 [(set_attr "type" "fistp")
15003 (set_attr "i387_cw" "ceil")
15004 (set_attr "mode" "<MODE>")])
15007 [(set (match_operand:SWI24 0 "register_operand" "")
15008 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15010 (use (match_operand:HI 2 "memory_operand" ""))
15011 (use (match_operand:HI 3 "memory_operand" ""))
15012 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15014 [(parallel [(set (match_dup 4)
15015 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15016 (use (match_dup 2))
15017 (use (match_dup 3))])
15018 (set (match_dup 0) (match_dup 4))])
15021 [(set (match_operand:SWI24 0 "memory_operand" "")
15022 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15024 (use (match_operand:HI 2 "memory_operand" ""))
15025 (use (match_operand:HI 3 "memory_operand" ""))
15026 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15028 [(parallel [(set (match_dup 0)
15029 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15030 (use (match_dup 2))
15031 (use (match_dup 3))])])
15033 (define_expand "lceilxf<mode>2"
15034 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15035 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15037 (clobber (reg:CC FLAGS_REG))])]
15038 "TARGET_USE_FANCY_MATH_387
15039 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15040 && flag_unsafe_math_optimizations")
15042 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15043 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15044 (match_operand:MODEF 1 "register_operand" "")]
15045 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15046 && !flag_trapping_math"
15048 ix86_expand_lfloorceil (operand0, operand1, false);
15052 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15053 (define_insn_and_split "frndintxf2_trunc"
15054 [(set (match_operand:XF 0 "register_operand" "")
15055 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15056 UNSPEC_FRNDINT_TRUNC))
15057 (clobber (reg:CC FLAGS_REG))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && flag_unsafe_math_optimizations
15060 && can_create_pseudo_p ()"
15065 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15067 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15068 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15070 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15071 operands[2], operands[3]));
15074 [(set_attr "type" "frndint")
15075 (set_attr "i387_cw" "trunc")
15076 (set_attr "mode" "XF")])
15078 (define_insn "frndintxf2_trunc_i387"
15079 [(set (match_operand:XF 0 "register_operand" "=f")
15080 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15081 UNSPEC_FRNDINT_TRUNC))
15082 (use (match_operand:HI 2 "memory_operand" "m"))
15083 (use (match_operand:HI 3 "memory_operand" "m"))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations"
15086 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15087 [(set_attr "type" "frndint")
15088 (set_attr "i387_cw" "trunc")
15089 (set_attr "mode" "XF")])
15091 (define_expand "btruncxf2"
15092 [(use (match_operand:XF 0 "register_operand" ""))
15093 (use (match_operand:XF 1 "register_operand" ""))]
15094 "TARGET_USE_FANCY_MATH_387
15095 && flag_unsafe_math_optimizations"
15097 if (optimize_insn_for_size_p ())
15099 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15103 (define_expand "btrunc<mode>2"
15104 [(use (match_operand:MODEF 0 "register_operand" ""))
15105 (use (match_operand:MODEF 1 "register_operand" ""))]
15106 "(TARGET_USE_FANCY_MATH_387
15107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15108 || TARGET_MIX_SSE_I387)
15109 && flag_unsafe_math_optimizations)
15110 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15111 && !flag_trapping_math)"
15113 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15114 && !flag_trapping_math
15115 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15118 emit_insn (gen_sse4_1_round<mode>2
15119 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15120 else if (optimize_insn_for_size_p ())
15122 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15123 ix86_expand_trunc (operand0, operand1);
15125 ix86_expand_truncdf_32 (operand0, operand1);
15131 if (optimize_insn_for_size_p ())
15134 op0 = gen_reg_rtx (XFmode);
15135 op1 = gen_reg_rtx (XFmode);
15136 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15137 emit_insn (gen_frndintxf2_trunc (op0, op1));
15139 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15144 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15145 (define_insn_and_split "frndintxf2_mask_pm"
15146 [(set (match_operand:XF 0 "register_operand" "")
15147 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15148 UNSPEC_FRNDINT_MASK_PM))
15149 (clobber (reg:CC FLAGS_REG))]
15150 "TARGET_USE_FANCY_MATH_387
15151 && flag_unsafe_math_optimizations
15152 && can_create_pseudo_p ()"
15157 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15159 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15160 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15162 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15163 operands[2], operands[3]));
15166 [(set_attr "type" "frndint")
15167 (set_attr "i387_cw" "mask_pm")
15168 (set_attr "mode" "XF")])
15170 (define_insn "frndintxf2_mask_pm_i387"
15171 [(set (match_operand:XF 0 "register_operand" "=f")
15172 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15173 UNSPEC_FRNDINT_MASK_PM))
15174 (use (match_operand:HI 2 "memory_operand" "m"))
15175 (use (match_operand:HI 3 "memory_operand" "m"))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15178 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15179 [(set_attr "type" "frndint")
15180 (set_attr "i387_cw" "mask_pm")
15181 (set_attr "mode" "XF")])
15183 (define_expand "nearbyintxf2"
15184 [(use (match_operand:XF 0 "register_operand" ""))
15185 (use (match_operand:XF 1 "register_operand" ""))]
15186 "TARGET_USE_FANCY_MATH_387
15187 && flag_unsafe_math_optimizations"
15189 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15193 (define_expand "nearbyint<mode>2"
15194 [(use (match_operand:MODEF 0 "register_operand" ""))
15195 (use (match_operand:MODEF 1 "register_operand" ""))]
15196 "TARGET_USE_FANCY_MATH_387
15197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15198 || TARGET_MIX_SSE_I387)
15199 && flag_unsafe_math_optimizations"
15201 rtx op0 = gen_reg_rtx (XFmode);
15202 rtx op1 = gen_reg_rtx (XFmode);
15204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15205 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15211 (define_insn "fxam<mode>2_i387"
15212 [(set (match_operand:HI 0 "register_operand" "=a")
15214 [(match_operand:X87MODEF 1 "register_operand" "f")]
15216 "TARGET_USE_FANCY_MATH_387"
15217 "fxam\n\tfnstsw\t%0"
15218 [(set_attr "type" "multi")
15219 (set_attr "length" "4")
15220 (set_attr "unit" "i387")
15221 (set_attr "mode" "<MODE>")])
15223 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15224 [(set (match_operand:HI 0 "register_operand" "")
15226 [(match_operand:MODEF 1 "memory_operand" "")]
15228 "TARGET_USE_FANCY_MATH_387
15229 && can_create_pseudo_p ()"
15232 [(set (match_dup 2)(match_dup 1))
15234 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15236 operands[2] = gen_reg_rtx (<MODE>mode);
15238 MEM_VOLATILE_P (operands[1]) = 1;
15240 [(set_attr "type" "multi")
15241 (set_attr "unit" "i387")
15242 (set_attr "mode" "<MODE>")])
15244 (define_expand "isinfxf2"
15245 [(use (match_operand:SI 0 "register_operand" ""))
15246 (use (match_operand:XF 1 "register_operand" ""))]
15247 "TARGET_USE_FANCY_MATH_387
15248 && TARGET_C99_FUNCTIONS"
15250 rtx mask = GEN_INT (0x45);
15251 rtx val = GEN_INT (0x05);
15255 rtx scratch = gen_reg_rtx (HImode);
15256 rtx res = gen_reg_rtx (QImode);
15258 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15260 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15261 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15262 cond = gen_rtx_fmt_ee (EQ, QImode,
15263 gen_rtx_REG (CCmode, FLAGS_REG),
15265 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15266 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15270 (define_expand "isinf<mode>2"
15271 [(use (match_operand:SI 0 "register_operand" ""))
15272 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15273 "TARGET_USE_FANCY_MATH_387
15274 && TARGET_C99_FUNCTIONS
15275 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15277 rtx mask = GEN_INT (0x45);
15278 rtx val = GEN_INT (0x05);
15282 rtx scratch = gen_reg_rtx (HImode);
15283 rtx res = gen_reg_rtx (QImode);
15285 /* Remove excess precision by forcing value through memory. */
15286 if (memory_operand (operands[1], VOIDmode))
15287 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15290 enum ix86_stack_slot slot = (virtuals_instantiated
15293 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15295 emit_move_insn (temp, operands[1]);
15296 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15299 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15300 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15301 cond = gen_rtx_fmt_ee (EQ, QImode,
15302 gen_rtx_REG (CCmode, FLAGS_REG),
15304 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15305 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15309 (define_expand "signbitxf2"
15310 [(use (match_operand:SI 0 "register_operand" ""))
15311 (use (match_operand:XF 1 "register_operand" ""))]
15312 "TARGET_USE_FANCY_MATH_387"
15314 rtx scratch = gen_reg_rtx (HImode);
15316 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15317 emit_insn (gen_andsi3 (operands[0],
15318 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15322 (define_insn "movmsk_df"
15323 [(set (match_operand:SI 0 "register_operand" "=r")
15325 [(match_operand:DF 1 "register_operand" "x")]
15327 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15328 "%vmovmskpd\t{%1, %0|%0, %1}"
15329 [(set_attr "type" "ssemov")
15330 (set_attr "prefix" "maybe_vex")
15331 (set_attr "mode" "DF")])
15333 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15334 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15335 (define_expand "signbitdf2"
15336 [(use (match_operand:SI 0 "register_operand" ""))
15337 (use (match_operand:DF 1 "register_operand" ""))]
15338 "TARGET_USE_FANCY_MATH_387
15339 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15341 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15343 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15344 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15348 rtx scratch = gen_reg_rtx (HImode);
15350 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15351 emit_insn (gen_andsi3 (operands[0],
15352 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15357 (define_expand "signbitsf2"
15358 [(use (match_operand:SI 0 "register_operand" ""))
15359 (use (match_operand:SF 1 "register_operand" ""))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15363 rtx scratch = gen_reg_rtx (HImode);
15365 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15366 emit_insn (gen_andsi3 (operands[0],
15367 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15371 ;; Block operation instructions
15374 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15377 [(set_attr "length" "1")
15378 (set_attr "length_immediate" "0")
15379 (set_attr "modrm" "0")])
15381 (define_expand "movmem<mode>"
15382 [(use (match_operand:BLK 0 "memory_operand" ""))
15383 (use (match_operand:BLK 1 "memory_operand" ""))
15384 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15385 (use (match_operand:SWI48 3 "const_int_operand" ""))
15386 (use (match_operand:SI 4 "const_int_operand" ""))
15387 (use (match_operand:SI 5 "const_int_operand" ""))]
15390 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15391 operands[4], operands[5]))
15397 ;; Most CPUs don't like single string operations
15398 ;; Handle this case here to simplify previous expander.
15400 (define_expand "strmov"
15401 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15402 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15403 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15404 (clobber (reg:CC FLAGS_REG))])
15405 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15406 (clobber (reg:CC FLAGS_REG))])]
15409 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15411 /* If .md ever supports :P for Pmode, these can be directly
15412 in the pattern above. */
15413 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15414 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15416 /* Can't use this if the user has appropriated esi or edi. */
15417 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15418 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15420 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15421 operands[2], operands[3],
15422 operands[5], operands[6]));
15426 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15429 (define_expand "strmov_singleop"
15430 [(parallel [(set (match_operand 1 "memory_operand" "")
15431 (match_operand 3 "memory_operand" ""))
15432 (set (match_operand 0 "register_operand" "")
15433 (match_operand 4 "" ""))
15434 (set (match_operand 2 "register_operand" "")
15435 (match_operand 5 "" ""))])]
15437 "ix86_current_function_needs_cld = 1;")
15439 (define_insn "*strmovdi_rex_1"
15440 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15441 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15442 (set (match_operand:DI 0 "register_operand" "=D")
15443 (plus:DI (match_dup 2)
15445 (set (match_operand:DI 1 "register_operand" "=S")
15446 (plus:DI (match_dup 3)
15450 [(set_attr "type" "str")
15451 (set_attr "memory" "both")
15452 (set_attr "mode" "DI")])
15454 (define_insn "*strmovsi_1"
15455 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15456 (mem:SI (match_operand:P 3 "register_operand" "1")))
15457 (set (match_operand:P 0 "register_operand" "=D")
15458 (plus:P (match_dup 2)
15460 (set (match_operand:P 1 "register_operand" "=S")
15461 (plus:P (match_dup 3)
15465 [(set_attr "type" "str")
15466 (set_attr "memory" "both")
15467 (set_attr "mode" "SI")])
15469 (define_insn "*strmovhi_1"
15470 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15471 (mem:HI (match_operand:P 3 "register_operand" "1")))
15472 (set (match_operand:P 0 "register_operand" "=D")
15473 (plus:P (match_dup 2)
15475 (set (match_operand:P 1 "register_operand" "=S")
15476 (plus:P (match_dup 3)
15480 [(set_attr "type" "str")
15481 (set_attr "memory" "both")
15482 (set_attr "mode" "HI")])
15484 (define_insn "*strmovqi_1"
15485 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15486 (mem:QI (match_operand:P 3 "register_operand" "1")))
15487 (set (match_operand:P 0 "register_operand" "=D")
15488 (plus:P (match_dup 2)
15490 (set (match_operand:P 1 "register_operand" "=S")
15491 (plus:P (match_dup 3)
15495 [(set_attr "type" "str")
15496 (set_attr "memory" "both")
15497 (set (attr "prefix_rex")
15499 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15501 (const_string "*")))
15502 (set_attr "mode" "QI")])
15504 (define_expand "rep_mov"
15505 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15506 (set (match_operand 0 "register_operand" "")
15507 (match_operand 5 "" ""))
15508 (set (match_operand 2 "register_operand" "")
15509 (match_operand 6 "" ""))
15510 (set (match_operand 1 "memory_operand" "")
15511 (match_operand 3 "memory_operand" ""))
15512 (use (match_dup 4))])]
15514 "ix86_current_function_needs_cld = 1;")
15516 (define_insn "*rep_movdi_rex64"
15517 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15518 (set (match_operand:DI 0 "register_operand" "=D")
15519 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15521 (match_operand:DI 3 "register_operand" "0")))
15522 (set (match_operand:DI 1 "register_operand" "=S")
15523 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15524 (match_operand:DI 4 "register_operand" "1")))
15525 (set (mem:BLK (match_dup 3))
15526 (mem:BLK (match_dup 4)))
15527 (use (match_dup 5))]
15530 [(set_attr "type" "str")
15531 (set_attr "prefix_rep" "1")
15532 (set_attr "memory" "both")
15533 (set_attr "mode" "DI")])
15535 (define_insn "*rep_movsi"
15536 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15537 (set (match_operand:P 0 "register_operand" "=D")
15538 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15540 (match_operand:P 3 "register_operand" "0")))
15541 (set (match_operand:P 1 "register_operand" "=S")
15542 (plus:P (ashift:P (match_dup 5) (const_int 2))
15543 (match_operand:P 4 "register_operand" "1")))
15544 (set (mem:BLK (match_dup 3))
15545 (mem:BLK (match_dup 4)))
15546 (use (match_dup 5))]
15548 "rep{%;} movs{l|d}"
15549 [(set_attr "type" "str")
15550 (set_attr "prefix_rep" "1")
15551 (set_attr "memory" "both")
15552 (set_attr "mode" "SI")])
15554 (define_insn "*rep_movqi"
15555 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15556 (set (match_operand:P 0 "register_operand" "=D")
15557 (plus:P (match_operand:P 3 "register_operand" "0")
15558 (match_operand:P 5 "register_operand" "2")))
15559 (set (match_operand:P 1 "register_operand" "=S")
15560 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15561 (set (mem:BLK (match_dup 3))
15562 (mem:BLK (match_dup 4)))
15563 (use (match_dup 5))]
15566 [(set_attr "type" "str")
15567 (set_attr "prefix_rep" "1")
15568 (set_attr "memory" "both")
15569 (set_attr "mode" "QI")])
15571 (define_expand "setmem<mode>"
15572 [(use (match_operand:BLK 0 "memory_operand" ""))
15573 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15574 (use (match_operand:QI 2 "nonmemory_operand" ""))
15575 (use (match_operand 3 "const_int_operand" ""))
15576 (use (match_operand:SI 4 "const_int_operand" ""))
15577 (use (match_operand:SI 5 "const_int_operand" ""))]
15580 if (ix86_expand_setmem (operands[0], operands[1],
15581 operands[2], operands[3],
15582 operands[4], operands[5]))
15588 ;; Most CPUs don't like single string operations
15589 ;; Handle this case here to simplify previous expander.
15591 (define_expand "strset"
15592 [(set (match_operand 1 "memory_operand" "")
15593 (match_operand 2 "register_operand" ""))
15594 (parallel [(set (match_operand 0 "register_operand" "")
15596 (clobber (reg:CC FLAGS_REG))])]
15599 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15600 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15602 /* If .md ever supports :P for Pmode, this can be directly
15603 in the pattern above. */
15604 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15605 GEN_INT (GET_MODE_SIZE (GET_MODE
15607 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15609 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15615 (define_expand "strset_singleop"
15616 [(parallel [(set (match_operand 1 "memory_operand" "")
15617 (match_operand 2 "register_operand" ""))
15618 (set (match_operand 0 "register_operand" "")
15619 (match_operand 3 "" ""))])]
15621 "ix86_current_function_needs_cld = 1;")
15623 (define_insn "*strsetdi_rex_1"
15624 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15625 (match_operand:DI 2 "register_operand" "a"))
15626 (set (match_operand:DI 0 "register_operand" "=D")
15627 (plus:DI (match_dup 1)
15631 [(set_attr "type" "str")
15632 (set_attr "memory" "store")
15633 (set_attr "mode" "DI")])
15635 (define_insn "*strsetsi_1"
15636 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15637 (match_operand:SI 2 "register_operand" "a"))
15638 (set (match_operand:P 0 "register_operand" "=D")
15639 (plus:P (match_dup 1)
15643 [(set_attr "type" "str")
15644 (set_attr "memory" "store")
15645 (set_attr "mode" "SI")])
15647 (define_insn "*strsethi_1"
15648 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15649 (match_operand:HI 2 "register_operand" "a"))
15650 (set (match_operand:P 0 "register_operand" "=D")
15651 (plus:P (match_dup 1)
15655 [(set_attr "type" "str")
15656 (set_attr "memory" "store")
15657 (set_attr "mode" "HI")])
15659 (define_insn "*strsetqi_1"
15660 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15661 (match_operand:QI 2 "register_operand" "a"))
15662 (set (match_operand:P 0 "register_operand" "=D")
15663 (plus:P (match_dup 1)
15667 [(set_attr "type" "str")
15668 (set_attr "memory" "store")
15669 (set (attr "prefix_rex")
15671 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15673 (const_string "*")))
15674 (set_attr "mode" "QI")])
15676 (define_expand "rep_stos"
15677 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15678 (set (match_operand 0 "register_operand" "")
15679 (match_operand 4 "" ""))
15680 (set (match_operand 2 "memory_operand" "") (const_int 0))
15681 (use (match_operand 3 "register_operand" ""))
15682 (use (match_dup 1))])]
15684 "ix86_current_function_needs_cld = 1;")
15686 (define_insn "*rep_stosdi_rex64"
15687 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15688 (set (match_operand:DI 0 "register_operand" "=D")
15689 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15691 (match_operand:DI 3 "register_operand" "0")))
15692 (set (mem:BLK (match_dup 3))
15694 (use (match_operand:DI 2 "register_operand" "a"))
15695 (use (match_dup 4))]
15698 [(set_attr "type" "str")
15699 (set_attr "prefix_rep" "1")
15700 (set_attr "memory" "store")
15701 (set_attr "mode" "DI")])
15703 (define_insn "*rep_stossi"
15704 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15705 (set (match_operand:P 0 "register_operand" "=D")
15706 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15708 (match_operand:P 3 "register_operand" "0")))
15709 (set (mem:BLK (match_dup 3))
15711 (use (match_operand:SI 2 "register_operand" "a"))
15712 (use (match_dup 4))]
15714 "rep{%;} stos{l|d}"
15715 [(set_attr "type" "str")
15716 (set_attr "prefix_rep" "1")
15717 (set_attr "memory" "store")
15718 (set_attr "mode" "SI")])
15720 (define_insn "*rep_stosqi"
15721 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15722 (set (match_operand:P 0 "register_operand" "=D")
15723 (plus:P (match_operand:P 3 "register_operand" "0")
15724 (match_operand:P 4 "register_operand" "1")))
15725 (set (mem:BLK (match_dup 3))
15727 (use (match_operand:QI 2 "register_operand" "a"))
15728 (use (match_dup 4))]
15731 [(set_attr "type" "str")
15732 (set_attr "prefix_rep" "1")
15733 (set_attr "memory" "store")
15734 (set (attr "prefix_rex")
15736 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15738 (const_string "*")))
15739 (set_attr "mode" "QI")])
15741 (define_expand "cmpstrnsi"
15742 [(set (match_operand:SI 0 "register_operand" "")
15743 (compare:SI (match_operand:BLK 1 "general_operand" "")
15744 (match_operand:BLK 2 "general_operand" "")))
15745 (use (match_operand 3 "general_operand" ""))
15746 (use (match_operand 4 "immediate_operand" ""))]
15749 rtx addr1, addr2, out, outlow, count, countreg, align;
15751 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15754 /* Can't use this if the user has appropriated esi or edi. */
15755 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15760 out = gen_reg_rtx (SImode);
15762 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15763 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15764 if (addr1 != XEXP (operands[1], 0))
15765 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15766 if (addr2 != XEXP (operands[2], 0))
15767 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15769 count = operands[3];
15770 countreg = ix86_zero_extend_to_Pmode (count);
15772 /* %%% Iff we are testing strict equality, we can use known alignment
15773 to good advantage. This may be possible with combine, particularly
15774 once cc0 is dead. */
15775 align = operands[4];
15777 if (CONST_INT_P (count))
15779 if (INTVAL (count) == 0)
15781 emit_move_insn (operands[0], const0_rtx);
15784 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15785 operands[1], operands[2]));
15789 rtx (*gen_cmp) (rtx, rtx);
15791 gen_cmp = (TARGET_64BIT
15792 ? gen_cmpdi_1 : gen_cmpsi_1);
15794 emit_insn (gen_cmp (countreg, countreg));
15795 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15796 operands[1], operands[2]));
15799 outlow = gen_lowpart (QImode, out);
15800 emit_insn (gen_cmpintqi (outlow));
15801 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15803 if (operands[0] != out)
15804 emit_move_insn (operands[0], out);
15809 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15811 (define_expand "cmpintqi"
15812 [(set (match_dup 1)
15813 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15815 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15816 (parallel [(set (match_operand:QI 0 "register_operand" "")
15817 (minus:QI (match_dup 1)
15819 (clobber (reg:CC FLAGS_REG))])]
15822 operands[1] = gen_reg_rtx (QImode);
15823 operands[2] = gen_reg_rtx (QImode);
15826 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15827 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15829 (define_expand "cmpstrnqi_nz_1"
15830 [(parallel [(set (reg:CC FLAGS_REG)
15831 (compare:CC (match_operand 4 "memory_operand" "")
15832 (match_operand 5 "memory_operand" "")))
15833 (use (match_operand 2 "register_operand" ""))
15834 (use (match_operand:SI 3 "immediate_operand" ""))
15835 (clobber (match_operand 0 "register_operand" ""))
15836 (clobber (match_operand 1 "register_operand" ""))
15837 (clobber (match_dup 2))])]
15839 "ix86_current_function_needs_cld = 1;")
15841 (define_insn "*cmpstrnqi_nz_1"
15842 [(set (reg:CC FLAGS_REG)
15843 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15844 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15845 (use (match_operand:P 6 "register_operand" "2"))
15846 (use (match_operand:SI 3 "immediate_operand" "i"))
15847 (clobber (match_operand:P 0 "register_operand" "=S"))
15848 (clobber (match_operand:P 1 "register_operand" "=D"))
15849 (clobber (match_operand:P 2 "register_operand" "=c"))]
15852 [(set_attr "type" "str")
15853 (set_attr "mode" "QI")
15854 (set (attr "prefix_rex")
15856 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15858 (const_string "*")))
15859 (set_attr "prefix_rep" "1")])
15861 ;; The same, but the count is not known to not be zero.
15863 (define_expand "cmpstrnqi_1"
15864 [(parallel [(set (reg:CC FLAGS_REG)
15865 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15867 (compare:CC (match_operand 4 "memory_operand" "")
15868 (match_operand 5 "memory_operand" ""))
15870 (use (match_operand:SI 3 "immediate_operand" ""))
15871 (use (reg:CC FLAGS_REG))
15872 (clobber (match_operand 0 "register_operand" ""))
15873 (clobber (match_operand 1 "register_operand" ""))
15874 (clobber (match_dup 2))])]
15876 "ix86_current_function_needs_cld = 1;")
15878 (define_insn "*cmpstrnqi_1"
15879 [(set (reg:CC FLAGS_REG)
15880 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15882 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15883 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15885 (use (match_operand:SI 3 "immediate_operand" "i"))
15886 (use (reg:CC FLAGS_REG))
15887 (clobber (match_operand:P 0 "register_operand" "=S"))
15888 (clobber (match_operand:P 1 "register_operand" "=D"))
15889 (clobber (match_operand:P 2 "register_operand" "=c"))]
15892 [(set_attr "type" "str")
15893 (set_attr "mode" "QI")
15894 (set (attr "prefix_rex")
15896 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15898 (const_string "*")))
15899 (set_attr "prefix_rep" "1")])
15901 (define_expand "strlen<mode>"
15902 [(set (match_operand:SWI48x 0 "register_operand" "")
15903 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15904 (match_operand:QI 2 "immediate_operand" "")
15905 (match_operand 3 "immediate_operand" "")]
15909 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15915 (define_expand "strlenqi_1"
15916 [(parallel [(set (match_operand 0 "register_operand" "")
15917 (match_operand 2 "" ""))
15918 (clobber (match_operand 1 "register_operand" ""))
15919 (clobber (reg:CC FLAGS_REG))])]
15921 "ix86_current_function_needs_cld = 1;")
15923 (define_insn "*strlenqi_1"
15924 [(set (match_operand:P 0 "register_operand" "=&c")
15925 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15926 (match_operand:QI 2 "register_operand" "a")
15927 (match_operand:P 3 "immediate_operand" "i")
15928 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15929 (clobber (match_operand:P 1 "register_operand" "=D"))
15930 (clobber (reg:CC FLAGS_REG))]
15933 [(set_attr "type" "str")
15934 (set_attr "mode" "QI")
15935 (set (attr "prefix_rex")
15937 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15939 (const_string "*")))
15940 (set_attr "prefix_rep" "1")])
15942 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15943 ;; handled in combine, but it is not currently up to the task.
15944 ;; When used for their truth value, the cmpstrn* expanders generate
15953 ;; The intermediate three instructions are unnecessary.
15955 ;; This one handles cmpstrn*_nz_1...
15958 (set (reg:CC FLAGS_REG)
15959 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15960 (mem:BLK (match_operand 5 "register_operand" ""))))
15961 (use (match_operand 6 "register_operand" ""))
15962 (use (match_operand:SI 3 "immediate_operand" ""))
15963 (clobber (match_operand 0 "register_operand" ""))
15964 (clobber (match_operand 1 "register_operand" ""))
15965 (clobber (match_operand 2 "register_operand" ""))])
15966 (set (match_operand:QI 7 "register_operand" "")
15967 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15968 (set (match_operand:QI 8 "register_operand" "")
15969 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15970 (set (reg FLAGS_REG)
15971 (compare (match_dup 7) (match_dup 8)))
15973 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15975 (set (reg:CC FLAGS_REG)
15976 (compare:CC (mem:BLK (match_dup 4))
15977 (mem:BLK (match_dup 5))))
15978 (use (match_dup 6))
15979 (use (match_dup 3))
15980 (clobber (match_dup 0))
15981 (clobber (match_dup 1))
15982 (clobber (match_dup 2))])])
15984 ;; ...and this one handles cmpstrn*_1.
15987 (set (reg:CC FLAGS_REG)
15988 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15990 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15991 (mem:BLK (match_operand 5 "register_operand" "")))
15993 (use (match_operand:SI 3 "immediate_operand" ""))
15994 (use (reg:CC FLAGS_REG))
15995 (clobber (match_operand 0 "register_operand" ""))
15996 (clobber (match_operand 1 "register_operand" ""))
15997 (clobber (match_operand 2 "register_operand" ""))])
15998 (set (match_operand:QI 7 "register_operand" "")
15999 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16000 (set (match_operand:QI 8 "register_operand" "")
16001 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16002 (set (reg FLAGS_REG)
16003 (compare (match_dup 7) (match_dup 8)))
16005 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16007 (set (reg:CC FLAGS_REG)
16008 (if_then_else:CC (ne (match_dup 6)
16010 (compare:CC (mem:BLK (match_dup 4))
16011 (mem:BLK (match_dup 5)))
16013 (use (match_dup 3))
16014 (use (reg:CC FLAGS_REG))
16015 (clobber (match_dup 0))
16016 (clobber (match_dup 1))
16017 (clobber (match_dup 2))])])
16019 ;; Conditional move instructions.
16021 (define_expand "mov<mode>cc"
16022 [(set (match_operand:SWIM 0 "register_operand" "")
16023 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16024 (match_operand:SWIM 2 "general_operand" "")
16025 (match_operand:SWIM 3 "general_operand" "")))]
16027 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16029 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16030 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16031 ;; So just document what we're doing explicitly.
16033 (define_expand "x86_mov<mode>cc_0_m1"
16035 [(set (match_operand:SWI48 0 "register_operand" "")
16036 (if_then_else:SWI48
16037 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16038 [(match_operand 1 "flags_reg_operand" "")
16042 (clobber (reg:CC FLAGS_REG))])])
16044 (define_insn "*x86_mov<mode>cc_0_m1"
16045 [(set (match_operand:SWI48 0 "register_operand" "=r")
16046 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16047 [(reg FLAGS_REG) (const_int 0)])
16050 (clobber (reg:CC FLAGS_REG))]
16052 "sbb{<imodesuffix>}\t%0, %0"
16053 ; Since we don't have the proper number of operands for an alu insn,
16054 ; fill in all the blanks.
16055 [(set_attr "type" "alu")
16056 (set_attr "use_carry" "1")
16057 (set_attr "pent_pair" "pu")
16058 (set_attr "memory" "none")
16059 (set_attr "imm_disp" "false")
16060 (set_attr "mode" "<MODE>")
16061 (set_attr "length_immediate" "0")])
16063 (define_insn "*x86_mov<mode>cc_0_m1_se"
16064 [(set (match_operand:SWI48 0 "register_operand" "=r")
16065 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16066 [(reg FLAGS_REG) (const_int 0)])
16069 (clobber (reg:CC FLAGS_REG))]
16071 "sbb{<imodesuffix>}\t%0, %0"
16072 [(set_attr "type" "alu")
16073 (set_attr "use_carry" "1")
16074 (set_attr "pent_pair" "pu")
16075 (set_attr "memory" "none")
16076 (set_attr "imm_disp" "false")
16077 (set_attr "mode" "<MODE>")
16078 (set_attr "length_immediate" "0")])
16080 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16081 [(set (match_operand:SWI48 0 "register_operand" "=r")
16082 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16083 [(reg FLAGS_REG) (const_int 0)])))]
16085 "sbb{<imodesuffix>}\t%0, %0"
16086 [(set_attr "type" "alu")
16087 (set_attr "use_carry" "1")
16088 (set_attr "pent_pair" "pu")
16089 (set_attr "memory" "none")
16090 (set_attr "imm_disp" "false")
16091 (set_attr "mode" "<MODE>")
16092 (set_attr "length_immediate" "0")])
16094 (define_insn "*mov<mode>cc_noc"
16095 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16096 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16097 [(reg FLAGS_REG) (const_int 0)])
16098 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16099 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16100 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16102 cmov%O2%C1\t{%2, %0|%0, %2}
16103 cmov%O2%c1\t{%3, %0|%0, %3}"
16104 [(set_attr "type" "icmov")
16105 (set_attr "mode" "<MODE>")])
16107 (define_insn_and_split "*movqicc_noc"
16108 [(set (match_operand:QI 0 "register_operand" "=r,r")
16109 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16110 [(match_operand 4 "flags_reg_operand" "")
16112 (match_operand:QI 2 "register_operand" "r,0")
16113 (match_operand:QI 3 "register_operand" "0,r")))]
16114 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16116 "&& reload_completed"
16117 [(set (match_dup 0)
16118 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16121 "operands[0] = gen_lowpart (SImode, operands[0]);
16122 operands[2] = gen_lowpart (SImode, operands[2]);
16123 operands[3] = gen_lowpart (SImode, operands[3]);"
16124 [(set_attr "type" "icmov")
16125 (set_attr "mode" "SI")])
16127 (define_expand "mov<mode>cc"
16128 [(set (match_operand:X87MODEF 0 "register_operand" "")
16129 (if_then_else:X87MODEF
16130 (match_operand 1 "ix86_fp_comparison_operator" "")
16131 (match_operand:X87MODEF 2 "register_operand" "")
16132 (match_operand:X87MODEF 3 "register_operand" "")))]
16133 "(TARGET_80387 && TARGET_CMOVE)
16134 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16135 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16137 (define_insn "*movxfcc_1"
16138 [(set (match_operand:XF 0 "register_operand" "=f,f")
16139 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16140 [(reg FLAGS_REG) (const_int 0)])
16141 (match_operand:XF 2 "register_operand" "f,0")
16142 (match_operand:XF 3 "register_operand" "0,f")))]
16143 "TARGET_80387 && TARGET_CMOVE"
16145 fcmov%F1\t{%2, %0|%0, %2}
16146 fcmov%f1\t{%3, %0|%0, %3}"
16147 [(set_attr "type" "fcmov")
16148 (set_attr "mode" "XF")])
16150 (define_insn "*movdfcc_1_rex64"
16151 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16152 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16153 [(reg FLAGS_REG) (const_int 0)])
16154 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16155 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16156 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16157 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16159 fcmov%F1\t{%2, %0|%0, %2}
16160 fcmov%f1\t{%3, %0|%0, %3}
16161 cmov%O2%C1\t{%2, %0|%0, %2}
16162 cmov%O2%c1\t{%3, %0|%0, %3}"
16163 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16164 (set_attr "mode" "DF,DF,DI,DI")])
16166 (define_insn "*movdfcc_1"
16167 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16168 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16169 [(reg FLAGS_REG) (const_int 0)])
16170 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16171 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16172 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16173 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16175 fcmov%F1\t{%2, %0|%0, %2}
16176 fcmov%f1\t{%3, %0|%0, %3}
16179 [(set_attr "type" "fcmov,fcmov,multi,multi")
16180 (set_attr "mode" "DF,DF,DI,DI")])
16183 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16184 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16185 [(match_operand 4 "flags_reg_operand" "")
16187 (match_operand:DF 2 "nonimmediate_operand" "")
16188 (match_operand:DF 3 "nonimmediate_operand" "")))]
16189 "!TARGET_64BIT && reload_completed"
16190 [(set (match_dup 2)
16191 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16195 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16199 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16200 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16203 (define_insn "*movsfcc_1_387"
16204 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16205 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16206 [(reg FLAGS_REG) (const_int 0)])
16207 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16208 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16209 "TARGET_80387 && TARGET_CMOVE
16210 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16212 fcmov%F1\t{%2, %0|%0, %2}
16213 fcmov%f1\t{%3, %0|%0, %3}
16214 cmov%O2%C1\t{%2, %0|%0, %2}
16215 cmov%O2%c1\t{%3, %0|%0, %3}"
16216 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16217 (set_attr "mode" "SF,SF,SI,SI")])
16219 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16220 ;; the scalar versions to have only XMM registers as operands.
16222 ;; XOP conditional move
16223 (define_insn "*xop_pcmov_<mode>"
16224 [(set (match_operand:MODEF 0 "register_operand" "=x")
16225 (if_then_else:MODEF
16226 (match_operand:MODEF 1 "register_operand" "x")
16227 (match_operand:MODEF 2 "register_operand" "x")
16228 (match_operand:MODEF 3 "register_operand" "x")))]
16230 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16231 [(set_attr "type" "sse4arg")])
16233 ;; These versions of the min/max patterns are intentionally ignorant of
16234 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16235 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16236 ;; are undefined in this condition, we're certain this is correct.
16238 (define_insn "<code><mode>3"
16239 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16241 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16242 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16243 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16245 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16246 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16247 [(set_attr "isa" "noavx,avx")
16248 (set_attr "prefix" "orig,vex")
16249 (set_attr "type" "sseadd")
16250 (set_attr "mode" "<MODE>")])
16252 ;; These versions of the min/max patterns implement exactly the operations
16253 ;; min = (op1 < op2 ? op1 : op2)
16254 ;; max = (!(op1 < op2) ? op1 : op2)
16255 ;; Their operands are not commutative, and thus they may be used in the
16256 ;; presence of -0.0 and NaN.
16258 (define_insn "*ieee_smin<mode>3"
16259 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16261 [(match_operand:MODEF 1 "register_operand" "0,x")
16262 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16264 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16266 min<ssemodesuffix>\t{%2, %0|%0, %2}
16267 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16268 [(set_attr "isa" "noavx,avx")
16269 (set_attr "prefix" "orig,vex")
16270 (set_attr "type" "sseadd")
16271 (set_attr "mode" "<MODE>")])
16273 (define_insn "*ieee_smax<mode>3"
16274 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16276 [(match_operand:MODEF 1 "register_operand" "0,x")
16277 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16279 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16281 max<ssemodesuffix>\t{%2, %0|%0, %2}
16282 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16283 [(set_attr "isa" "noavx,avx")
16284 (set_attr "prefix" "orig,vex")
16285 (set_attr "type" "sseadd")
16286 (set_attr "mode" "<MODE>")])
16288 ;; Make two stack loads independent:
16290 ;; fld %st(0) -> fld bb
16291 ;; fmul bb fmul %st(1), %st
16293 ;; Actually we only match the last two instructions for simplicity.
16295 [(set (match_operand 0 "fp_register_operand" "")
16296 (match_operand 1 "fp_register_operand" ""))
16298 (match_operator 2 "binary_fp_operator"
16300 (match_operand 3 "memory_operand" "")]))]
16301 "REGNO (operands[0]) != REGNO (operands[1])"
16302 [(set (match_dup 0) (match_dup 3))
16303 (set (match_dup 0) (match_dup 4))]
16305 ;; The % modifier is not operational anymore in peephole2's, so we have to
16306 ;; swap the operands manually in the case of addition and multiplication.
16307 "if (COMMUTATIVE_ARITH_P (operands[2]))
16308 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16309 GET_MODE (operands[2]),
16310 operands[0], operands[1]);
16312 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16313 GET_MODE (operands[2]),
16314 operands[1], operands[0]);")
16316 ;; Conditional addition patterns
16317 (define_expand "add<mode>cc"
16318 [(match_operand:SWI 0 "register_operand" "")
16319 (match_operand 1 "ordered_comparison_operator" "")
16320 (match_operand:SWI 2 "register_operand" "")
16321 (match_operand:SWI 3 "const_int_operand" "")]
16323 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16325 ;; Misc patterns (?)
16327 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16328 ;; Otherwise there will be nothing to keep
16330 ;; [(set (reg ebp) (reg esp))]
16331 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16332 ;; (clobber (eflags)]
16333 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16335 ;; in proper program order.
16337 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16338 [(set (match_operand:P 0 "register_operand" "=r,r")
16339 (plus:P (match_operand:P 1 "register_operand" "0,r")
16340 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16341 (clobber (reg:CC FLAGS_REG))
16342 (clobber (mem:BLK (scratch)))]
16345 switch (get_attr_type (insn))
16348 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16351 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16352 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16353 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16355 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16358 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16359 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16362 [(set (attr "type")
16363 (cond [(and (eq_attr "alternative" "0")
16364 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16365 (const_string "alu")
16366 (match_operand:<MODE> 2 "const0_operand" "")
16367 (const_string "imov")
16369 (const_string "lea")))
16370 (set (attr "length_immediate")
16371 (cond [(eq_attr "type" "imov")
16373 (and (eq_attr "type" "alu")
16374 (match_operand 2 "const128_operand" ""))
16377 (const_string "*")))
16378 (set_attr "mode" "<MODE>")])
16380 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16381 [(set (match_operand:P 0 "register_operand" "=r")
16382 (minus:P (match_operand:P 1 "register_operand" "0")
16383 (match_operand:P 2 "register_operand" "r")))
16384 (clobber (reg:CC FLAGS_REG))
16385 (clobber (mem:BLK (scratch)))]
16387 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16388 [(set_attr "type" "alu")
16389 (set_attr "mode" "<MODE>")])
16391 (define_insn "allocate_stack_worker_probe_<mode>"
16392 [(set (match_operand:P 0 "register_operand" "=a")
16393 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16394 UNSPECV_STACK_PROBE))
16395 (clobber (reg:CC FLAGS_REG))]
16396 "ix86_target_stack_probe ()"
16397 "call\t___chkstk_ms"
16398 [(set_attr "type" "multi")
16399 (set_attr "length" "5")])
16401 (define_expand "allocate_stack"
16402 [(match_operand 0 "register_operand" "")
16403 (match_operand 1 "general_operand" "")]
16404 "ix86_target_stack_probe ()"
16408 #ifndef CHECK_STACK_LIMIT
16409 #define CHECK_STACK_LIMIT 0
16412 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16413 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16415 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16416 stack_pointer_rtx, 0, OPTAB_DIRECT);
16417 if (x != stack_pointer_rtx)
16418 emit_move_insn (stack_pointer_rtx, x);
16422 x = copy_to_mode_reg (Pmode, operands[1]);
16424 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16426 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16427 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16428 stack_pointer_rtx, 0, OPTAB_DIRECT);
16429 if (x != stack_pointer_rtx)
16430 emit_move_insn (stack_pointer_rtx, x);
16433 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16437 ;; Use IOR for stack probes, this is shorter.
16438 (define_expand "probe_stack"
16439 [(match_operand 0 "memory_operand" "")]
16442 rtx (*gen_ior3) (rtx, rtx, rtx);
16444 gen_ior3 = (GET_MODE (operands[0]) == DImode
16445 ? gen_iordi3 : gen_iorsi3);
16447 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16451 (define_insn "adjust_stack_and_probe<mode>"
16452 [(set (match_operand:P 0 "register_operand" "=r")
16453 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16454 UNSPECV_PROBE_STACK_RANGE))
16455 (set (reg:P SP_REG)
16456 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16457 (clobber (reg:CC FLAGS_REG))
16458 (clobber (mem:BLK (scratch)))]
16460 "* return output_adjust_stack_and_probe (operands[0]);"
16461 [(set_attr "type" "multi")])
16463 (define_insn "probe_stack_range<mode>"
16464 [(set (match_operand:P 0 "register_operand" "=r")
16465 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16466 (match_operand:P 2 "const_int_operand" "n")]
16467 UNSPECV_PROBE_STACK_RANGE))
16468 (clobber (reg:CC FLAGS_REG))]
16470 "* return output_probe_stack_range (operands[0], operands[2]);"
16471 [(set_attr "type" "multi")])
16473 (define_expand "builtin_setjmp_receiver"
16474 [(label_ref (match_operand 0 "" ""))]
16475 "!TARGET_64BIT && flag_pic"
16481 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16482 rtx label_rtx = gen_label_rtx ();
16483 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16484 xops[0] = xops[1] = picreg;
16485 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16486 ix86_expand_binary_operator (MINUS, SImode, xops);
16490 emit_insn (gen_set_got (pic_offset_table_rtx));
16494 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16497 [(set (match_operand 0 "register_operand" "")
16498 (match_operator 3 "promotable_binary_operator"
16499 [(match_operand 1 "register_operand" "")
16500 (match_operand 2 "aligned_operand" "")]))
16501 (clobber (reg:CC FLAGS_REG))]
16502 "! TARGET_PARTIAL_REG_STALL && reload_completed
16503 && ((GET_MODE (operands[0]) == HImode
16504 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16505 /* ??? next two lines just !satisfies_constraint_K (...) */
16506 || !CONST_INT_P (operands[2])
16507 || satisfies_constraint_K (operands[2])))
16508 || (GET_MODE (operands[0]) == QImode
16509 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16510 [(parallel [(set (match_dup 0)
16511 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16512 (clobber (reg:CC FLAGS_REG))])]
16513 "operands[0] = gen_lowpart (SImode, operands[0]);
16514 operands[1] = gen_lowpart (SImode, operands[1]);
16515 if (GET_CODE (operands[3]) != ASHIFT)
16516 operands[2] = gen_lowpart (SImode, operands[2]);
16517 PUT_MODE (operands[3], SImode);")
16519 ; Promote the QImode tests, as i386 has encoding of the AND
16520 ; instruction with 32-bit sign-extended immediate and thus the
16521 ; instruction size is unchanged, except in the %eax case for
16522 ; which it is increased by one byte, hence the ! optimize_size.
16524 [(set (match_operand 0 "flags_reg_operand" "")
16525 (match_operator 2 "compare_operator"
16526 [(and (match_operand 3 "aligned_operand" "")
16527 (match_operand 4 "const_int_operand" ""))
16529 (set (match_operand 1 "register_operand" "")
16530 (and (match_dup 3) (match_dup 4)))]
16531 "! TARGET_PARTIAL_REG_STALL && reload_completed
16532 && optimize_insn_for_speed_p ()
16533 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16534 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16535 /* Ensure that the operand will remain sign-extended immediate. */
16536 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16537 [(parallel [(set (match_dup 0)
16538 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16541 (and:SI (match_dup 3) (match_dup 4)))])]
16544 = gen_int_mode (INTVAL (operands[4])
16545 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16546 operands[1] = gen_lowpart (SImode, operands[1]);
16547 operands[3] = gen_lowpart (SImode, operands[3]);
16550 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16551 ; the TEST instruction with 32-bit sign-extended immediate and thus
16552 ; the instruction size would at least double, which is not what we
16553 ; want even with ! optimize_size.
16555 [(set (match_operand 0 "flags_reg_operand" "")
16556 (match_operator 1 "compare_operator"
16557 [(and (match_operand:HI 2 "aligned_operand" "")
16558 (match_operand:HI 3 "const_int_operand" ""))
16560 "! TARGET_PARTIAL_REG_STALL && reload_completed
16561 && ! TARGET_FAST_PREFIX
16562 && optimize_insn_for_speed_p ()
16563 /* Ensure that the operand will remain sign-extended immediate. */
16564 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16565 [(set (match_dup 0)
16566 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16570 = gen_int_mode (INTVAL (operands[3])
16571 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16572 operands[2] = gen_lowpart (SImode, operands[2]);
16576 [(set (match_operand 0 "register_operand" "")
16577 (neg (match_operand 1 "register_operand" "")))
16578 (clobber (reg:CC FLAGS_REG))]
16579 "! TARGET_PARTIAL_REG_STALL && reload_completed
16580 && (GET_MODE (operands[0]) == HImode
16581 || (GET_MODE (operands[0]) == QImode
16582 && (TARGET_PROMOTE_QImode
16583 || optimize_insn_for_size_p ())))"
16584 [(parallel [(set (match_dup 0)
16585 (neg:SI (match_dup 1)))
16586 (clobber (reg:CC FLAGS_REG))])]
16587 "operands[0] = gen_lowpart (SImode, operands[0]);
16588 operands[1] = gen_lowpart (SImode, operands[1]);")
16591 [(set (match_operand 0 "register_operand" "")
16592 (not (match_operand 1 "register_operand" "")))]
16593 "! TARGET_PARTIAL_REG_STALL && reload_completed
16594 && (GET_MODE (operands[0]) == HImode
16595 || (GET_MODE (operands[0]) == QImode
16596 && (TARGET_PROMOTE_QImode
16597 || optimize_insn_for_size_p ())))"
16598 [(set (match_dup 0)
16599 (not:SI (match_dup 1)))]
16600 "operands[0] = gen_lowpart (SImode, operands[0]);
16601 operands[1] = gen_lowpart (SImode, operands[1]);")
16604 [(set (match_operand 0 "register_operand" "")
16605 (if_then_else (match_operator 1 "ordered_comparison_operator"
16606 [(reg FLAGS_REG) (const_int 0)])
16607 (match_operand 2 "register_operand" "")
16608 (match_operand 3 "register_operand" "")))]
16609 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16610 && (GET_MODE (operands[0]) == HImode
16611 || (GET_MODE (operands[0]) == QImode
16612 && (TARGET_PROMOTE_QImode
16613 || optimize_insn_for_size_p ())))"
16614 [(set (match_dup 0)
16615 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16616 "operands[0] = gen_lowpart (SImode, operands[0]);
16617 operands[2] = gen_lowpart (SImode, operands[2]);
16618 operands[3] = gen_lowpart (SImode, operands[3]);")
16620 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16621 ;; transform a complex memory operation into two memory to register operations.
16623 ;; Don't push memory operands
16625 [(set (match_operand:SWI 0 "push_operand" "")
16626 (match_operand:SWI 1 "memory_operand" ""))
16627 (match_scratch:SWI 2 "<r>")]
16628 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16629 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16630 [(set (match_dup 2) (match_dup 1))
16631 (set (match_dup 0) (match_dup 2))])
16633 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16636 [(set (match_operand:SF 0 "push_operand" "")
16637 (match_operand:SF 1 "memory_operand" ""))
16638 (match_scratch:SF 2 "r")]
16639 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16640 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16641 [(set (match_dup 2) (match_dup 1))
16642 (set (match_dup 0) (match_dup 2))])
16644 ;; Don't move an immediate directly to memory when the instruction
16647 [(match_scratch:SWI124 1 "<r>")
16648 (set (match_operand:SWI124 0 "memory_operand" "")
16650 "optimize_insn_for_speed_p ()
16651 && !TARGET_USE_MOV0
16652 && TARGET_SPLIT_LONG_MOVES
16653 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16654 && peep2_regno_dead_p (0, FLAGS_REG)"
16655 [(parallel [(set (match_dup 2) (const_int 0))
16656 (clobber (reg:CC FLAGS_REG))])
16657 (set (match_dup 0) (match_dup 1))]
16658 "operands[2] = gen_lowpart (SImode, operands[1]);")
16661 [(match_scratch:SWI124 2 "<r>")
16662 (set (match_operand:SWI124 0 "memory_operand" "")
16663 (match_operand:SWI124 1 "immediate_operand" ""))]
16664 "optimize_insn_for_speed_p ()
16665 && TARGET_SPLIT_LONG_MOVES
16666 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16667 [(set (match_dup 2) (match_dup 1))
16668 (set (match_dup 0) (match_dup 2))])
16670 ;; Don't compare memory with zero, load and use a test instead.
16672 [(set (match_operand 0 "flags_reg_operand" "")
16673 (match_operator 1 "compare_operator"
16674 [(match_operand:SI 2 "memory_operand" "")
16676 (match_scratch:SI 3 "r")]
16677 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16678 [(set (match_dup 3) (match_dup 2))
16679 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16681 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16682 ;; Don't split NOTs with a displacement operand, because resulting XOR
16683 ;; will not be pairable anyway.
16685 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16686 ;; represented using a modRM byte. The XOR replacement is long decoded,
16687 ;; so this split helps here as well.
16689 ;; Note: Can't do this as a regular split because we can't get proper
16690 ;; lifetime information then.
16693 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16694 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16695 "optimize_insn_for_speed_p ()
16696 && ((TARGET_NOT_UNPAIRABLE
16697 && (!MEM_P (operands[0])
16698 || !memory_displacement_operand (operands[0], <MODE>mode)))
16699 || (TARGET_NOT_VECTORMODE
16700 && long_memory_operand (operands[0], <MODE>mode)))
16701 && peep2_regno_dead_p (0, FLAGS_REG)"
16702 [(parallel [(set (match_dup 0)
16703 (xor:SWI124 (match_dup 1) (const_int -1)))
16704 (clobber (reg:CC FLAGS_REG))])])
16706 ;; Non pairable "test imm, reg" instructions can be translated to
16707 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16708 ;; byte opcode instead of two, have a short form for byte operands),
16709 ;; so do it for other CPUs as well. Given that the value was dead,
16710 ;; this should not create any new dependencies. Pass on the sub-word
16711 ;; versions if we're concerned about partial register stalls.
16714 [(set (match_operand 0 "flags_reg_operand" "")
16715 (match_operator 1 "compare_operator"
16716 [(and:SI (match_operand:SI 2 "register_operand" "")
16717 (match_operand:SI 3 "immediate_operand" ""))
16719 "ix86_match_ccmode (insn, CCNOmode)
16720 && (true_regnum (operands[2]) != AX_REG
16721 || satisfies_constraint_K (operands[3]))
16722 && peep2_reg_dead_p (1, operands[2])"
16724 [(set (match_dup 0)
16725 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16728 (and:SI (match_dup 2) (match_dup 3)))])])
16730 ;; We don't need to handle HImode case, because it will be promoted to SImode
16731 ;; on ! TARGET_PARTIAL_REG_STALL
16734 [(set (match_operand 0 "flags_reg_operand" "")
16735 (match_operator 1 "compare_operator"
16736 [(and:QI (match_operand:QI 2 "register_operand" "")
16737 (match_operand:QI 3 "immediate_operand" ""))
16739 "! TARGET_PARTIAL_REG_STALL
16740 && ix86_match_ccmode (insn, CCNOmode)
16741 && true_regnum (operands[2]) != AX_REG
16742 && peep2_reg_dead_p (1, operands[2])"
16744 [(set (match_dup 0)
16745 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16748 (and:QI (match_dup 2) (match_dup 3)))])])
16751 [(set (match_operand 0 "flags_reg_operand" "")
16752 (match_operator 1 "compare_operator"
16755 (match_operand 2 "ext_register_operand" "")
16758 (match_operand 3 "const_int_operand" ""))
16760 "! TARGET_PARTIAL_REG_STALL
16761 && ix86_match_ccmode (insn, CCNOmode)
16762 && true_regnum (operands[2]) != AX_REG
16763 && peep2_reg_dead_p (1, operands[2])"
16764 [(parallel [(set (match_dup 0)
16773 (set (zero_extract:SI (match_dup 2)
16781 (match_dup 3)))])])
16783 ;; Don't do logical operations with memory inputs.
16785 [(match_scratch:SI 2 "r")
16786 (parallel [(set (match_operand:SI 0 "register_operand" "")
16787 (match_operator:SI 3 "arith_or_logical_operator"
16789 (match_operand:SI 1 "memory_operand" "")]))
16790 (clobber (reg:CC FLAGS_REG))])]
16791 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16792 [(set (match_dup 2) (match_dup 1))
16793 (parallel [(set (match_dup 0)
16794 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16795 (clobber (reg:CC FLAGS_REG))])])
16798 [(match_scratch:SI 2 "r")
16799 (parallel [(set (match_operand:SI 0 "register_operand" "")
16800 (match_operator:SI 3 "arith_or_logical_operator"
16801 [(match_operand:SI 1 "memory_operand" "")
16803 (clobber (reg:CC FLAGS_REG))])]
16804 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16805 [(set (match_dup 2) (match_dup 1))
16806 (parallel [(set (match_dup 0)
16807 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16808 (clobber (reg:CC FLAGS_REG))])])
16810 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16811 ;; refers to the destination of the load!
16814 [(set (match_operand:SI 0 "register_operand" "")
16815 (match_operand:SI 1 "register_operand" ""))
16816 (parallel [(set (match_dup 0)
16817 (match_operator:SI 3 "commutative_operator"
16819 (match_operand:SI 2 "memory_operand" "")]))
16820 (clobber (reg:CC FLAGS_REG))])]
16821 "REGNO (operands[0]) != REGNO (operands[1])
16822 && GENERAL_REGNO_P (REGNO (operands[0]))
16823 && GENERAL_REGNO_P (REGNO (operands[1]))"
16824 [(set (match_dup 0) (match_dup 4))
16825 (parallel [(set (match_dup 0)
16826 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16831 [(set (match_operand 0 "register_operand" "")
16832 (match_operand 1 "register_operand" ""))
16834 (match_operator 3 "commutative_operator"
16836 (match_operand 2 "memory_operand" "")]))]
16837 "REGNO (operands[0]) != REGNO (operands[1])
16838 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16839 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16840 [(set (match_dup 0) (match_dup 2))
16842 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16844 ; Don't do logical operations with memory outputs
16846 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16847 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16848 ; the same decoder scheduling characteristics as the original.
16851 [(match_scratch:SI 2 "r")
16852 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16853 (match_operator:SI 3 "arith_or_logical_operator"
16855 (match_operand:SI 1 "nonmemory_operand" "")]))
16856 (clobber (reg:CC FLAGS_REG))])]
16857 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16858 /* Do not split stack checking probes. */
16859 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16860 [(set (match_dup 2) (match_dup 0))
16861 (parallel [(set (match_dup 2)
16862 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16863 (clobber (reg:CC FLAGS_REG))])
16864 (set (match_dup 0) (match_dup 2))])
16867 [(match_scratch:SI 2 "r")
16868 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16869 (match_operator:SI 3 "arith_or_logical_operator"
16870 [(match_operand:SI 1 "nonmemory_operand" "")
16872 (clobber (reg:CC FLAGS_REG))])]
16873 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16874 /* Do not split stack checking probes. */
16875 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16876 [(set (match_dup 2) (match_dup 0))
16877 (parallel [(set (match_dup 2)
16878 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16879 (clobber (reg:CC FLAGS_REG))])
16880 (set (match_dup 0) (match_dup 2))])
16882 ;; Attempt to use arith or logical operations with memory outputs with
16883 ;; setting of flags.
16885 [(set (match_operand:SWI 0 "register_operand" "")
16886 (match_operand:SWI 1 "memory_operand" ""))
16887 (parallel [(set (match_dup 0)
16888 (match_operator:SWI 3 "plusminuslogic_operator"
16890 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16891 (clobber (reg:CC FLAGS_REG))])
16892 (set (match_dup 1) (match_dup 0))
16893 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16894 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16895 && peep2_reg_dead_p (4, operands[0])
16896 && !reg_overlap_mentioned_p (operands[0], operands[1])
16897 && ix86_match_ccmode (peep2_next_insn (3),
16898 (GET_CODE (operands[3]) == PLUS
16899 || GET_CODE (operands[3]) == MINUS)
16900 ? CCGOCmode : CCNOmode)"
16901 [(parallel [(set (match_dup 4) (match_dup 5))
16902 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16903 (match_dup 2)]))])]
16904 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16905 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16906 copy_rtx (operands[1]),
16907 copy_rtx (operands[2]));
16908 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16909 operands[5], const0_rtx);")
16912 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16913 (match_operator:SWI 2 "plusminuslogic_operator"
16915 (match_operand:SWI 1 "memory_operand" "")]))
16916 (clobber (reg:CC FLAGS_REG))])
16917 (set (match_dup 1) (match_dup 0))
16918 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16919 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16920 && GET_CODE (operands[2]) != MINUS
16921 && peep2_reg_dead_p (3, operands[0])
16922 && !reg_overlap_mentioned_p (operands[0], operands[1])
16923 && ix86_match_ccmode (peep2_next_insn (2),
16924 GET_CODE (operands[2]) == PLUS
16925 ? CCGOCmode : CCNOmode)"
16926 [(parallel [(set (match_dup 3) (match_dup 4))
16927 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16928 (match_dup 0)]))])]
16929 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16930 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16931 copy_rtx (operands[1]),
16932 copy_rtx (operands[0]));
16933 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16934 operands[4], const0_rtx);")
16937 [(set (match_operand:SWI12 0 "register_operand" "")
16938 (match_operand:SWI12 1 "memory_operand" ""))
16939 (parallel [(set (match_operand:SI 4 "register_operand" "")
16940 (match_operator:SI 3 "plusminuslogic_operator"
16942 (match_operand:SI 2 "nonmemory_operand" "")]))
16943 (clobber (reg:CC FLAGS_REG))])
16944 (set (match_dup 1) (match_dup 0))
16945 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16946 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16947 && REG_P (operands[0]) && REG_P (operands[4])
16948 && REGNO (operands[0]) == REGNO (operands[4])
16949 && peep2_reg_dead_p (4, operands[0])
16950 && !reg_overlap_mentioned_p (operands[0], operands[1])
16951 && ix86_match_ccmode (peep2_next_insn (3),
16952 (GET_CODE (operands[3]) == PLUS
16953 || GET_CODE (operands[3]) == MINUS)
16954 ? CCGOCmode : CCNOmode)"
16955 [(parallel [(set (match_dup 4) (match_dup 5))
16956 (set (match_dup 1) (match_dup 6))])]
16957 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16958 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16959 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16960 copy_rtx (operands[1]), operands[2]);
16961 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16962 operands[5], const0_rtx);
16963 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16964 copy_rtx (operands[1]),
16965 copy_rtx (operands[2]));")
16967 ;; Attempt to always use XOR for zeroing registers.
16969 [(set (match_operand 0 "register_operand" "")
16970 (match_operand 1 "const0_operand" ""))]
16971 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16972 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16973 && GENERAL_REG_P (operands[0])
16974 && peep2_regno_dead_p (0, FLAGS_REG)"
16975 [(parallel [(set (match_dup 0) (const_int 0))
16976 (clobber (reg:CC FLAGS_REG))])]
16977 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16980 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16982 "(GET_MODE (operands[0]) == QImode
16983 || GET_MODE (operands[0]) == HImode)
16984 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16985 && peep2_regno_dead_p (0, FLAGS_REG)"
16986 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16987 (clobber (reg:CC FLAGS_REG))])])
16989 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16991 [(set (match_operand:SWI248 0 "register_operand" "")
16993 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16994 && peep2_regno_dead_p (0, FLAGS_REG)"
16995 [(parallel [(set (match_dup 0) (const_int -1))
16996 (clobber (reg:CC FLAGS_REG))])]
16998 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16999 operands[0] = gen_lowpart (SImode, operands[0]);
17002 ;; Attempt to convert simple lea to add/shift.
17003 ;; These can be created by move expanders.
17006 [(set (match_operand:SWI48 0 "register_operand" "")
17007 (plus:SWI48 (match_dup 0)
17008 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17009 "peep2_regno_dead_p (0, FLAGS_REG)"
17010 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17011 (clobber (reg:CC FLAGS_REG))])])
17014 [(set (match_operand:SI 0 "register_operand" "")
17015 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17016 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17018 && peep2_regno_dead_p (0, FLAGS_REG)
17019 && REGNO (operands[0]) == REGNO (operands[1])"
17020 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17021 (clobber (reg:CC FLAGS_REG))])]
17022 "operands[2] = gen_lowpart (SImode, operands[2]);")
17025 [(set (match_operand:SWI48 0 "register_operand" "")
17026 (mult:SWI48 (match_dup 0)
17027 (match_operand:SWI48 1 "const_int_operand" "")))]
17028 "exact_log2 (INTVAL (operands[1])) >= 0
17029 && peep2_regno_dead_p (0, FLAGS_REG)"
17030 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17031 (clobber (reg:CC FLAGS_REG))])]
17032 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17035 [(set (match_operand:SI 0 "register_operand" "")
17036 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17037 (match_operand:DI 2 "const_int_operand" "")) 0))]
17039 && exact_log2 (INTVAL (operands[2])) >= 0
17040 && REGNO (operands[0]) == REGNO (operands[1])
17041 && peep2_regno_dead_p (0, FLAGS_REG)"
17042 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17043 (clobber (reg:CC FLAGS_REG))])]
17044 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17046 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17047 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17048 ;; On many CPUs it is also faster, since special hardware to avoid esp
17049 ;; dependencies is present.
17051 ;; While some of these conversions may be done using splitters, we use
17052 ;; peepholes in order to allow combine_stack_adjustments pass to see
17053 ;; nonobfuscated RTL.
17055 ;; Convert prologue esp subtractions to push.
17056 ;; We need register to push. In order to keep verify_flow_info happy we have
17058 ;; - use scratch and clobber it in order to avoid dependencies
17059 ;; - use already live register
17060 ;; We can't use the second way right now, since there is no reliable way how to
17061 ;; verify that given register is live. First choice will also most likely in
17062 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17063 ;; call clobbered registers are dead. We may want to use base pointer as an
17064 ;; alternative when no register is available later.
17067 [(match_scratch:P 1 "r")
17068 (parallel [(set (reg:P SP_REG)
17069 (plus:P (reg:P SP_REG)
17070 (match_operand:P 0 "const_int_operand" "")))
17071 (clobber (reg:CC FLAGS_REG))
17072 (clobber (mem:BLK (scratch)))])]
17073 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17074 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17075 [(clobber (match_dup 1))
17076 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17077 (clobber (mem:BLK (scratch)))])])
17080 [(match_scratch:P 1 "r")
17081 (parallel [(set (reg:P SP_REG)
17082 (plus:P (reg:P SP_REG)
17083 (match_operand:P 0 "const_int_operand" "")))
17084 (clobber (reg:CC FLAGS_REG))
17085 (clobber (mem:BLK (scratch)))])]
17086 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17087 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17088 [(clobber (match_dup 1))
17089 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17090 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17091 (clobber (mem:BLK (scratch)))])])
17093 ;; Convert esp subtractions to push.
17095 [(match_scratch:P 1 "r")
17096 (parallel [(set (reg:P SP_REG)
17097 (plus:P (reg:P SP_REG)
17098 (match_operand:P 0 "const_int_operand" "")))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17101 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17102 [(clobber (match_dup 1))
17103 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17106 [(match_scratch:P 1 "r")
17107 (parallel [(set (reg:P SP_REG)
17108 (plus:P (reg:P SP_REG)
17109 (match_operand:P 0 "const_int_operand" "")))
17110 (clobber (reg:CC FLAGS_REG))])]
17111 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17112 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17113 [(clobber (match_dup 1))
17114 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17115 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17117 ;; Convert epilogue deallocator to pop.
17119 [(match_scratch:P 1 "r")
17120 (parallel [(set (reg:P SP_REG)
17121 (plus:P (reg:P SP_REG)
17122 (match_operand:P 0 "const_int_operand" "")))
17123 (clobber (reg:CC FLAGS_REG))
17124 (clobber (mem:BLK (scratch)))])]
17125 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17126 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17127 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17128 (clobber (mem:BLK (scratch)))])])
17130 ;; Two pops case is tricky, since pop causes dependency
17131 ;; on destination register. We use two registers if available.
17133 [(match_scratch:P 1 "r")
17134 (match_scratch:P 2 "r")
17135 (parallel [(set (reg:P SP_REG)
17136 (plus:P (reg:P SP_REG)
17137 (match_operand:P 0 "const_int_operand" "")))
17138 (clobber (reg:CC FLAGS_REG))
17139 (clobber (mem:BLK (scratch)))])]
17140 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17141 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17142 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17143 (clobber (mem:BLK (scratch)))])
17144 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17147 [(match_scratch:P 1 "r")
17148 (parallel [(set (reg:P SP_REG)
17149 (plus:P (reg:P SP_REG)
17150 (match_operand:P 0 "const_int_operand" "")))
17151 (clobber (reg:CC FLAGS_REG))
17152 (clobber (mem:BLK (scratch)))])]
17153 "optimize_insn_for_size_p ()
17154 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17155 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17156 (clobber (mem:BLK (scratch)))])
17157 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17159 ;; Convert esp additions to pop.
17161 [(match_scratch:P 1 "r")
17162 (parallel [(set (reg:P SP_REG)
17163 (plus:P (reg:P SP_REG)
17164 (match_operand:P 0 "const_int_operand" "")))
17165 (clobber (reg:CC FLAGS_REG))])]
17166 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17167 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17169 ;; Two pops case is tricky, since pop causes dependency
17170 ;; on destination register. We use two registers if available.
17172 [(match_scratch:P 1 "r")
17173 (match_scratch:P 2 "r")
17174 (parallel [(set (reg:P SP_REG)
17175 (plus:P (reg:P SP_REG)
17176 (match_operand:P 0 "const_int_operand" "")))
17177 (clobber (reg:CC FLAGS_REG))])]
17178 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17179 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17180 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17183 [(match_scratch:P 1 "r")
17184 (parallel [(set (reg:P SP_REG)
17185 (plus:P (reg:P SP_REG)
17186 (match_operand:P 0 "const_int_operand" "")))
17187 (clobber (reg:CC FLAGS_REG))])]
17188 "optimize_insn_for_size_p ()
17189 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17190 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17191 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17193 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17194 ;; required and register dies. Similarly for 128 to -128.
17196 [(set (match_operand 0 "flags_reg_operand" "")
17197 (match_operator 1 "compare_operator"
17198 [(match_operand 2 "register_operand" "")
17199 (match_operand 3 "const_int_operand" "")]))]
17200 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17201 && incdec_operand (operands[3], GET_MODE (operands[3])))
17202 || (!TARGET_FUSE_CMP_AND_BRANCH
17203 && INTVAL (operands[3]) == 128))
17204 && ix86_match_ccmode (insn, CCGCmode)
17205 && peep2_reg_dead_p (1, operands[2])"
17206 [(parallel [(set (match_dup 0)
17207 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17208 (clobber (match_dup 2))])])
17210 ;; Convert imul by three, five and nine into lea
17213 [(set (match_operand:SWI48 0 "register_operand" "")
17214 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17215 (match_operand:SWI48 2 "const359_operand" "")))
17216 (clobber (reg:CC FLAGS_REG))])]
17217 "!TARGET_PARTIAL_REG_STALL
17218 || <MODE>mode == SImode
17219 || optimize_function_for_size_p (cfun)"
17220 [(set (match_dup 0)
17221 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17223 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17227 [(set (match_operand:SWI48 0 "register_operand" "")
17228 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17229 (match_operand:SWI48 2 "const359_operand" "")))
17230 (clobber (reg:CC FLAGS_REG))])]
17231 "optimize_insn_for_speed_p ()
17232 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17233 [(set (match_dup 0) (match_dup 1))
17235 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17237 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17239 ;; imul $32bit_imm, mem, reg is vector decoded, while
17240 ;; imul $32bit_imm, reg, reg is direct decoded.
17242 [(match_scratch:SWI48 3 "r")
17243 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17244 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17245 (match_operand:SWI48 2 "immediate_operand" "")))
17246 (clobber (reg:CC FLAGS_REG))])]
17247 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17248 && !satisfies_constraint_K (operands[2])"
17249 [(set (match_dup 3) (match_dup 1))
17250 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17251 (clobber (reg:CC FLAGS_REG))])])
17254 [(match_scratch:SI 3 "r")
17255 (parallel [(set (match_operand:DI 0 "register_operand" "")
17257 (mult:SI (match_operand:SI 1 "memory_operand" "")
17258 (match_operand:SI 2 "immediate_operand" ""))))
17259 (clobber (reg:CC FLAGS_REG))])]
17261 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17262 && !satisfies_constraint_K (operands[2])"
17263 [(set (match_dup 3) (match_dup 1))
17264 (parallel [(set (match_dup 0)
17265 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17266 (clobber (reg:CC FLAGS_REG))])])
17268 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17269 ;; Convert it into imul reg, reg
17270 ;; It would be better to force assembler to encode instruction using long
17271 ;; immediate, but there is apparently no way to do so.
17273 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17275 (match_operand:SWI248 1 "nonimmediate_operand" "")
17276 (match_operand:SWI248 2 "const_int_operand" "")))
17277 (clobber (reg:CC FLAGS_REG))])
17278 (match_scratch:SWI248 3 "r")]
17279 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17280 && satisfies_constraint_K (operands[2])"
17281 [(set (match_dup 3) (match_dup 2))
17282 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17283 (clobber (reg:CC FLAGS_REG))])]
17285 if (!rtx_equal_p (operands[0], operands[1]))
17286 emit_move_insn (operands[0], operands[1]);
17289 ;; After splitting up read-modify operations, array accesses with memory
17290 ;; operands might end up in form:
17292 ;; movl 4(%esp), %edx
17294 ;; instead of pre-splitting:
17296 ;; addl 4(%esp), %eax
17298 ;; movl 4(%esp), %edx
17299 ;; leal (%edx,%eax,4), %eax
17302 [(match_scratch:P 5 "r")
17303 (parallel [(set (match_operand 0 "register_operand" "")
17304 (ashift (match_operand 1 "register_operand" "")
17305 (match_operand 2 "const_int_operand" "")))
17306 (clobber (reg:CC FLAGS_REG))])
17307 (parallel [(set (match_operand 3 "register_operand" "")
17308 (plus (match_dup 0)
17309 (match_operand 4 "x86_64_general_operand" "")))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17312 /* Validate MODE for lea. */
17313 && ((!TARGET_PARTIAL_REG_STALL
17314 && (GET_MODE (operands[0]) == QImode
17315 || GET_MODE (operands[0]) == HImode))
17316 || GET_MODE (operands[0]) == SImode
17317 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17318 && (rtx_equal_p (operands[0], operands[3])
17319 || peep2_reg_dead_p (2, operands[0]))
17320 /* We reorder load and the shift. */
17321 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17322 [(set (match_dup 5) (match_dup 4))
17323 (set (match_dup 0) (match_dup 1))]
17325 enum machine_mode op1mode = GET_MODE (operands[1]);
17326 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17327 int scale = 1 << INTVAL (operands[2]);
17328 rtx index = gen_lowpart (Pmode, operands[1]);
17329 rtx base = gen_lowpart (Pmode, operands[5]);
17330 rtx dest = gen_lowpart (mode, operands[3]);
17332 operands[1] = gen_rtx_PLUS (Pmode, base,
17333 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17334 operands[5] = base;
17336 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17337 if (op1mode != Pmode)
17338 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17339 operands[0] = dest;
17342 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17343 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17344 ;; caught for use by garbage collectors and the like. Using an insn that
17345 ;; maps to SIGILL makes it more likely the program will rightfully die.
17346 ;; Keeping with tradition, "6" is in honor of #UD.
17347 (define_insn "trap"
17348 [(trap_if (const_int 1) (const_int 6))]
17350 { return ASM_SHORT "0x0b0f"; }
17351 [(set_attr "length" "2")])
17353 (define_expand "prefetch"
17354 [(prefetch (match_operand 0 "address_operand" "")
17355 (match_operand:SI 1 "const_int_operand" "")
17356 (match_operand:SI 2 "const_int_operand" ""))]
17357 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17359 int rw = INTVAL (operands[1]);
17360 int locality = INTVAL (operands[2]);
17362 gcc_assert (rw == 0 || rw == 1);
17363 gcc_assert (locality >= 0 && locality <= 3);
17364 gcc_assert (GET_MODE (operands[0]) == Pmode
17365 || GET_MODE (operands[0]) == VOIDmode);
17367 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17368 supported by SSE counterpart or the SSE prefetch is not available
17369 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17371 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17372 operands[2] = GEN_INT (3);
17374 operands[1] = const0_rtx;
17377 (define_insn "*prefetch_sse_<mode>"
17378 [(prefetch (match_operand:P 0 "address_operand" "p")
17380 (match_operand:SI 1 "const_int_operand" ""))]
17381 "TARGET_PREFETCH_SSE"
17383 static const char * const patterns[4] = {
17384 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17387 int locality = INTVAL (operands[1]);
17388 gcc_assert (locality >= 0 && locality <= 3);
17390 return patterns[locality];
17392 [(set_attr "type" "sse")
17393 (set_attr "atom_sse_attr" "prefetch")
17394 (set (attr "length_address")
17395 (symbol_ref "memory_address_length (operands[0])"))
17396 (set_attr "memory" "none")])
17398 (define_insn "*prefetch_3dnow_<mode>"
17399 [(prefetch (match_operand:P 0 "address_operand" "p")
17400 (match_operand:SI 1 "const_int_operand" "n")
17404 if (INTVAL (operands[1]) == 0)
17405 return "prefetch\t%a0";
17407 return "prefetchw\t%a0";
17409 [(set_attr "type" "mmx")
17410 (set (attr "length_address")
17411 (symbol_ref "memory_address_length (operands[0])"))
17412 (set_attr "memory" "none")])
17414 (define_expand "stack_protect_set"
17415 [(match_operand 0 "memory_operand" "")
17416 (match_operand 1 "memory_operand" "")]
17419 rtx (*insn)(rtx, rtx);
17421 #ifdef TARGET_THREAD_SSP_OFFSET
17422 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17423 insn = (TARGET_64BIT
17424 ? gen_stack_tls_protect_set_di
17425 : gen_stack_tls_protect_set_si);
17427 insn = (TARGET_64BIT
17428 ? gen_stack_protect_set_di
17429 : gen_stack_protect_set_si);
17432 emit_insn (insn (operands[0], operands[1]));
17436 (define_insn "stack_protect_set_<mode>"
17437 [(set (match_operand:P 0 "memory_operand" "=m")
17438 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17439 (set (match_scratch:P 2 "=&r") (const_int 0))
17440 (clobber (reg:CC FLAGS_REG))]
17442 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17443 [(set_attr "type" "multi")])
17445 (define_insn "stack_tls_protect_set_<mode>"
17446 [(set (match_operand:P 0 "memory_operand" "=m")
17447 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17448 UNSPEC_SP_TLS_SET))
17449 (set (match_scratch:P 2 "=&r") (const_int 0))
17450 (clobber (reg:CC FLAGS_REG))]
17452 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17453 [(set_attr "type" "multi")])
17455 (define_expand "stack_protect_test"
17456 [(match_operand 0 "memory_operand" "")
17457 (match_operand 1 "memory_operand" "")
17458 (match_operand 2 "" "")]
17461 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17463 rtx (*insn)(rtx, rtx, rtx);
17465 #ifdef TARGET_THREAD_SSP_OFFSET
17466 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17467 insn = (TARGET_64BIT
17468 ? gen_stack_tls_protect_test_di
17469 : gen_stack_tls_protect_test_si);
17471 insn = (TARGET_64BIT
17472 ? gen_stack_protect_test_di
17473 : gen_stack_protect_test_si);
17476 emit_insn (insn (flags, operands[0], operands[1]));
17478 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17479 flags, const0_rtx, operands[2]));
17483 (define_insn "stack_protect_test_<mode>"
17484 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17485 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17486 (match_operand:P 2 "memory_operand" "m")]
17488 (clobber (match_scratch:P 3 "=&r"))]
17490 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17491 [(set_attr "type" "multi")])
17493 (define_insn "stack_tls_protect_test_<mode>"
17494 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17495 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17496 (match_operand:P 2 "const_int_operand" "i")]
17497 UNSPEC_SP_TLS_TEST))
17498 (clobber (match_scratch:P 3 "=r"))]
17500 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17501 [(set_attr "type" "multi")])
17503 (define_insn "sse4_2_crc32<mode>"
17504 [(set (match_operand:SI 0 "register_operand" "=r")
17506 [(match_operand:SI 1 "register_operand" "0")
17507 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17509 "TARGET_SSE4_2 || TARGET_CRC32"
17510 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17511 [(set_attr "type" "sselog1")
17512 (set_attr "prefix_rep" "1")
17513 (set_attr "prefix_extra" "1")
17514 (set (attr "prefix_data16")
17515 (if_then_else (match_operand:HI 2 "" "")
17517 (const_string "*")))
17518 (set (attr "prefix_rex")
17519 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17521 (const_string "*")))
17522 (set_attr "mode" "SI")])
17524 (define_insn "sse4_2_crc32di"
17525 [(set (match_operand:DI 0 "register_operand" "=r")
17527 [(match_operand:DI 1 "register_operand" "0")
17528 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17530 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17531 "crc32{q}\t{%2, %0|%0, %2}"
17532 [(set_attr "type" "sselog1")
17533 (set_attr "prefix_rep" "1")
17534 (set_attr "prefix_extra" "1")
17535 (set_attr "mode" "DI")])
17537 (define_expand "rdpmc"
17538 [(match_operand:DI 0 "register_operand" "")
17539 (match_operand:SI 1 "register_operand" "")]
17542 rtx reg = gen_reg_rtx (DImode);
17545 /* Force operand 1 into ECX. */
17546 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17547 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17548 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17553 rtvec vec = rtvec_alloc (2);
17554 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17555 rtx upper = gen_reg_rtx (DImode);
17556 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17557 gen_rtvec (1, const0_rtx),
17559 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17560 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17562 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17563 NULL, 1, OPTAB_DIRECT);
17564 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17568 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17569 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17573 (define_insn "*rdpmc"
17574 [(set (match_operand:DI 0 "register_operand" "=A")
17575 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17579 [(set_attr "type" "other")
17580 (set_attr "length" "2")])
17582 (define_insn "*rdpmc_rex64"
17583 [(set (match_operand:DI 0 "register_operand" "=a")
17584 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17586 (set (match_operand:DI 1 "register_operand" "=d")
17587 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17590 [(set_attr "type" "other")
17591 (set_attr "length" "2")])
17593 (define_expand "rdtsc"
17594 [(set (match_operand:DI 0 "register_operand" "")
17595 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17600 rtvec vec = rtvec_alloc (2);
17601 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17602 rtx upper = gen_reg_rtx (DImode);
17603 rtx lower = gen_reg_rtx (DImode);
17604 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17605 gen_rtvec (1, const0_rtx),
17607 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17608 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17610 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17611 NULL, 1, OPTAB_DIRECT);
17612 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17614 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17619 (define_insn "*rdtsc"
17620 [(set (match_operand:DI 0 "register_operand" "=A")
17621 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17624 [(set_attr "type" "other")
17625 (set_attr "length" "2")])
17627 (define_insn "*rdtsc_rex64"
17628 [(set (match_operand:DI 0 "register_operand" "=a")
17629 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17630 (set (match_operand:DI 1 "register_operand" "=d")
17631 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17634 [(set_attr "type" "other")
17635 (set_attr "length" "2")])
17637 (define_expand "rdtscp"
17638 [(match_operand:DI 0 "register_operand" "")
17639 (match_operand:SI 1 "memory_operand" "")]
17642 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17643 gen_rtvec (1, const0_rtx),
17645 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17646 gen_rtvec (1, const0_rtx),
17648 rtx reg = gen_reg_rtx (DImode);
17649 rtx tmp = gen_reg_rtx (SImode);
17653 rtvec vec = rtvec_alloc (3);
17654 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17655 rtx upper = gen_reg_rtx (DImode);
17656 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17657 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17658 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17660 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17661 NULL, 1, OPTAB_DIRECT);
17662 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17667 rtvec vec = rtvec_alloc (2);
17668 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17669 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17670 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17673 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17674 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17678 (define_insn "*rdtscp"
17679 [(set (match_operand:DI 0 "register_operand" "=A")
17680 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17681 (set (match_operand:SI 1 "register_operand" "=c")
17682 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17685 [(set_attr "type" "other")
17686 (set_attr "length" "3")])
17688 (define_insn "*rdtscp_rex64"
17689 [(set (match_operand:DI 0 "register_operand" "=a")
17690 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17691 (set (match_operand:DI 1 "register_operand" "=d")
17692 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17693 (set (match_operand:SI 2 "register_operand" "=c")
17694 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17697 [(set_attr "type" "other")
17698 (set_attr "length" "3")])
17700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17702 ;; LWP instructions
17704 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17706 (define_expand "lwp_llwpcb"
17707 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17708 UNSPECV_LLWP_INTRINSIC)]
17711 (define_insn "*lwp_llwpcb<mode>1"
17712 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17713 UNSPECV_LLWP_INTRINSIC)]
17716 [(set_attr "type" "lwp")
17717 (set_attr "mode" "<MODE>")
17718 (set_attr "length" "5")])
17720 (define_expand "lwp_slwpcb"
17721 [(set (match_operand 0 "register_operand" "=r")
17722 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17727 insn = (TARGET_64BIT
17729 : gen_lwp_slwpcbsi);
17731 emit_insn (insn (operands[0]));
17735 (define_insn "lwp_slwpcb<mode>"
17736 [(set (match_operand:P 0 "register_operand" "=r")
17737 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17740 [(set_attr "type" "lwp")
17741 (set_attr "mode" "<MODE>")
17742 (set_attr "length" "5")])
17744 (define_expand "lwp_lwpval<mode>3"
17745 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17746 (match_operand:SI 2 "nonimmediate_operand" "rm")
17747 (match_operand:SI 3 "const_int_operand" "i")]
17748 UNSPECV_LWPVAL_INTRINSIC)]
17750 "/* Avoid unused variable warning. */
17753 (define_insn "*lwp_lwpval<mode>3_1"
17754 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17755 (match_operand:SI 1 "nonimmediate_operand" "rm")
17756 (match_operand:SI 2 "const_int_operand" "i")]
17757 UNSPECV_LWPVAL_INTRINSIC)]
17759 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17760 [(set_attr "type" "lwp")
17761 (set_attr "mode" "<MODE>")
17762 (set (attr "length")
17763 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17765 (define_expand "lwp_lwpins<mode>3"
17766 [(set (reg:CCC FLAGS_REG)
17767 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17768 (match_operand:SI 2 "nonimmediate_operand" "rm")
17769 (match_operand:SI 3 "const_int_operand" "i")]
17770 UNSPECV_LWPINS_INTRINSIC))
17771 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17772 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17775 (define_insn "*lwp_lwpins<mode>3_1"
17776 [(set (reg:CCC FLAGS_REG)
17777 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17778 (match_operand:SI 1 "nonimmediate_operand" "rm")
17779 (match_operand:SI 2 "const_int_operand" "i")]
17780 UNSPECV_LWPINS_INTRINSIC))]
17782 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17783 [(set_attr "type" "lwp")
17784 (set_attr "mode" "<MODE>")
17785 (set (attr "length")
17786 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17788 (define_insn "rdfsbase<mode>"
17789 [(set (match_operand:SWI48 0 "register_operand" "=r")
17790 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17791 "TARGET_64BIT && TARGET_FSGSBASE"
17793 [(set_attr "type" "other")
17794 (set_attr "prefix_extra" "2")])
17796 (define_insn "rdgsbase<mode>"
17797 [(set (match_operand:SWI48 0 "register_operand" "=r")
17798 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17799 "TARGET_64BIT && TARGET_FSGSBASE"
17801 [(set_attr "type" "other")
17802 (set_attr "prefix_extra" "2")])
17804 (define_insn "wrfsbase<mode>"
17805 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17807 "TARGET_64BIT && TARGET_FSGSBASE"
17809 [(set_attr "type" "other")
17810 (set_attr "prefix_extra" "2")])
17812 (define_insn "wrgsbase<mode>"
17813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17815 "TARGET_64BIT && TARGET_FSGSBASE"
17817 [(set_attr "type" "other")
17818 (set_attr "prefix_extra" "2")])
17820 (define_insn "rdrand<mode>_1"
17821 [(set (match_operand:SWI248 0 "register_operand" "=r")
17822 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17823 (set (reg:CCC FLAGS_REG)
17824 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17827 [(set_attr "type" "other")
17828 (set_attr "prefix_extra" "1")])
17830 (define_expand "pause"
17831 [(set (match_dup 0)
17832 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17835 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17836 MEM_VOLATILE_P (operands[0]) = 1;
17839 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17840 ;; They have the same encoding.
17841 (define_insn "*pause"
17842 [(set (match_operand:BLK 0 "" "")
17843 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17846 [(set_attr "length" "2")
17847 (set_attr "memory" "unknown")])
17851 (include "sync.md")