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,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 "base")))
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) && TARGET_INTER_UNIT_MOVES)
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028 emit_insn (gen_sse2_loadld (operands[4],
5029 CONST0_RTX (V4SImode), operands[1]));
5031 /* We can ignore possible trapping value in the
5032 high part of SSE register for non-trapping math. */
5033 else if (SSE_REG_P (op1) && !flag_trapping_math)
5034 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5038 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (operands[0])))"
5053 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5057 emit_insn (gen_sse2_loadld (operands[4],
5058 CONST0_RTX (V4SImode), operands[1]));
5060 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5064 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5065 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5067 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5068 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5069 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5070 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5072 [(set_attr "type" "sseicvt")
5073 (set_attr "mode" "<MODEF:MODE>")
5074 (set_attr "athlon_decode" "double,direct")
5075 (set_attr "amdfam10_decode" "vector,double")
5076 (set_attr "bdver1_decode" "double,direct")
5077 (set_attr "fp_int_src" "true")])
5079 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5080 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5082 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5083 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5084 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5085 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5086 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5087 [(set_attr "type" "sseicvt")
5088 (set_attr "prefix" "maybe_vex")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set (attr "prefix_rex")
5092 (and (eq_attr "prefix" "maybe_vex")
5093 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5095 (const_string "*")))
5096 (set_attr "athlon_decode" "double,direct")
5097 (set_attr "amdfam10_decode" "vector,double")
5098 (set_attr "bdver1_decode" "double,direct")
5099 (set_attr "fp_int_src" "true")])
5102 [(set (match_operand:MODEF 0 "register_operand" "")
5103 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5104 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5105 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5106 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5107 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5109 && (SSE_REG_P (operands[0])
5110 || (GET_CODE (operands[0]) == SUBREG
5111 && SSE_REG_P (operands[0])))"
5112 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5114 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5115 [(set (match_operand:MODEF 0 "register_operand" "=x")
5117 (match_operand:SWI48x 1 "memory_operand" "m")))]
5118 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5119 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5122 [(set_attr "type" "sseicvt")
5123 (set_attr "prefix" "maybe_vex")
5124 (set_attr "mode" "<MODEF:MODE>")
5125 (set (attr "prefix_rex")
5127 (and (eq_attr "prefix" "maybe_vex")
5128 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5130 (const_string "*")))
5131 (set_attr "athlon_decode" "direct")
5132 (set_attr "amdfam10_decode" "double")
5133 (set_attr "bdver1_decode" "direct")
5134 (set_attr "fp_int_src" "true")])
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5139 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5140 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5144 && (SSE_REG_P (operands[0])
5145 || (GET_CODE (operands[0]) == SUBREG
5146 && SSE_REG_P (operands[0])))"
5147 [(set (match_dup 2) (match_dup 1))
5148 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5151 [(set (match_operand:MODEF 0 "register_operand" "")
5152 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5153 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5154 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5155 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157 && (SSE_REG_P (operands[0])
5158 || (GET_CODE (operands[0]) == SUBREG
5159 && SSE_REG_P (operands[0])))"
5160 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5162 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5163 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5165 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5166 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5168 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5172 [(set_attr "type" "fmov,multi")
5173 (set_attr "mode" "<X87MODEF:MODE>")
5174 (set_attr "unit" "*,i387")
5175 (set_attr "fp_int_src" "true")])
5177 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5178 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5180 (match_operand:SWI48x 1 "memory_operand" "m")))]
5182 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5184 [(set_attr "type" "fmov")
5185 (set_attr "mode" "<X87MODEF:MODE>")
5186 (set_attr "fp_int_src" "true")])
5189 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5190 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5191 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5193 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5194 && reload_completed"
5195 [(set (match_dup 2) (match_dup 1))
5196 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5199 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5200 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5201 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5204 && reload_completed"
5205 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5207 ;; Avoid store forwarding (partial memory) stall penalty
5208 ;; by passing DImode value through XMM registers. */
5210 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5211 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5213 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5214 (clobber (match_scratch:V4SI 3 "=X,x"))
5215 (clobber (match_scratch:V4SI 4 "=X,x"))
5216 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5217 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5218 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5219 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5221 [(set_attr "type" "multi")
5222 (set_attr "mode" "<X87MODEF:MODE>")
5223 (set_attr "unit" "i387")
5224 (set_attr "fp_int_src" "true")])
5227 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5228 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5229 (clobber (match_scratch:V4SI 3 ""))
5230 (clobber (match_scratch:V4SI 4 ""))
5231 (clobber (match_operand:DI 2 "memory_operand" ""))]
5232 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5233 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5234 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5235 && reload_completed"
5236 [(set (match_dup 2) (match_dup 3))
5237 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5239 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5240 Assemble the 64-bit DImode value in an xmm register. */
5241 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5242 gen_rtx_SUBREG (SImode, operands[1], 0)));
5243 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5244 gen_rtx_SUBREG (SImode, operands[1], 4)));
5245 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5248 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5252 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5253 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5254 (clobber (match_scratch:V4SI 3 ""))
5255 (clobber (match_scratch:V4SI 4 ""))
5256 (clobber (match_operand:DI 2 "memory_operand" ""))]
5257 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5258 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5259 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5260 && reload_completed"
5261 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5263 ;; Avoid store forwarding (partial memory) stall penalty by extending
5264 ;; SImode value to DImode through XMM register instead of pushing two
5265 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5266 ;; targets benefit from this optimization. Also note that fild
5267 ;; loads from memory only.
5269 (define_insn "*floatunssi<mode>2_1"
5270 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5271 (unsigned_float:X87MODEF
5272 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5273 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5274 (clobber (match_scratch:SI 3 "=X,x"))]
5276 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5279 [(set_attr "type" "multi")
5280 (set_attr "mode" "<MODE>")])
5283 [(set (match_operand:X87MODEF 0 "register_operand" "")
5284 (unsigned_float:X87MODEF
5285 (match_operand:SI 1 "register_operand" "")))
5286 (clobber (match_operand:DI 2 "memory_operand" ""))
5287 (clobber (match_scratch:SI 3 ""))]
5289 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5291 && reload_completed"
5292 [(set (match_dup 2) (match_dup 1))
5294 (float:X87MODEF (match_dup 2)))]
5295 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5298 [(set (match_operand:X87MODEF 0 "register_operand" "")
5299 (unsigned_float:X87MODEF
5300 (match_operand:SI 1 "memory_operand" "")))
5301 (clobber (match_operand:DI 2 "memory_operand" ""))
5302 (clobber (match_scratch:SI 3 ""))]
5304 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5306 && reload_completed"
5307 [(set (match_dup 2) (match_dup 3))
5309 (float:X87MODEF (match_dup 2)))]
5311 emit_move_insn (operands[3], operands[1]);
5312 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5315 (define_expand "floatunssi<mode>2"
5317 [(set (match_operand:X87MODEF 0 "register_operand" "")
5318 (unsigned_float:X87MODEF
5319 (match_operand:SI 1 "nonimmediate_operand" "")))
5320 (clobber (match_dup 2))
5321 (clobber (match_scratch:SI 3 ""))])]
5323 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5327 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5329 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5334 enum ix86_stack_slot slot = (virtuals_instantiated
5337 operands[2] = assign_386_stack_local (DImode, slot);
5341 (define_expand "floatunsdisf2"
5342 [(use (match_operand:SF 0 "register_operand" ""))
5343 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5344 "TARGET_64BIT && TARGET_SSE_MATH"
5345 "x86_emit_floatuns (operands); DONE;")
5347 (define_expand "floatunsdidf2"
5348 [(use (match_operand:DF 0 "register_operand" ""))
5349 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5350 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5351 && TARGET_SSE2 && TARGET_SSE_MATH"
5354 x86_emit_floatuns (operands);
5356 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5362 (define_expand "add<mode>3"
5363 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5364 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5365 (match_operand:SDWIM 2 "<general_operand>" "")))]
5367 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5369 (define_insn_and_split "*add<dwi>3_doubleword"
5370 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5372 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5373 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5374 (clobber (reg:CC FLAGS_REG))]
5375 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5378 [(parallel [(set (reg:CC FLAGS_REG)
5379 (unspec:CC [(match_dup 1) (match_dup 2)]
5382 (plus:DWIH (match_dup 1) (match_dup 2)))])
5383 (parallel [(set (match_dup 3)
5387 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5389 (clobber (reg:CC FLAGS_REG))])]
5390 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5392 (define_insn "*add<mode>3_cc"
5393 [(set (reg:CC FLAGS_REG)
5395 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5396 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5398 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5399 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5400 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5401 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5402 [(set_attr "type" "alu")
5403 (set_attr "mode" "<MODE>")])
5405 (define_insn "addqi3_cc"
5406 [(set (reg:CC FLAGS_REG)
5408 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5409 (match_operand:QI 2 "general_operand" "qn,qm")]
5411 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5412 (plus:QI (match_dup 1) (match_dup 2)))]
5413 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5414 "add{b}\t{%2, %0|%0, %2}"
5415 [(set_attr "type" "alu")
5416 (set_attr "mode" "QI")])
5418 (define_insn "*lea_1"
5419 [(set (match_operand:P 0 "register_operand" "=r")
5420 (match_operand:P 1 "no_seg_address_operand" "p"))]
5422 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5423 [(set_attr "type" "lea")
5424 (set_attr "mode" "<MODE>")])
5426 (define_insn "*lea_2"
5427 [(set (match_operand:SI 0 "register_operand" "=r")
5428 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5430 "lea{l}\t{%a1, %0|%0, %a1}"
5431 [(set_attr "type" "lea")
5432 (set_attr "mode" "SI")])
5434 (define_insn "*lea_2_zext"
5435 [(set (match_operand:DI 0 "register_operand" "=r")
5437 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5439 "lea{l}\t{%a1, %k0|%k0, %a1}"
5440 [(set_attr "type" "lea")
5441 (set_attr "mode" "SI")])
5443 (define_insn "*add<mode>_1"
5444 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5446 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5447 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5448 (clobber (reg:CC FLAGS_REG))]
5449 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5451 switch (get_attr_type (insn))
5457 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458 if (operands[2] == const1_rtx)
5459 return "inc{<imodesuffix>}\t%0";
5462 gcc_assert (operands[2] == constm1_rtx);
5463 return "dec{<imodesuffix>}\t%0";
5467 /* For most processors, ADD is faster than LEA. This alternative
5468 was added to use ADD as much as possible. */
5469 if (which_alternative == 2)
5472 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5477 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5479 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5483 (cond [(eq_attr "alternative" "3")
5484 (const_string "lea")
5485 (match_operand:SWI48 2 "incdec_operand" "")
5486 (const_string "incdec")
5488 (const_string "alu")))
5489 (set (attr "length_immediate")
5491 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5493 (const_string "*")))
5494 (set_attr "mode" "<MODE>")])
5496 ;; It may seem that nonimmediate operand is proper one for operand 1.
5497 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5498 ;; we take care in ix86_binary_operator_ok to not allow two memory
5499 ;; operands so proper swapping will be done in reload. This allow
5500 ;; patterns constructed from addsi_1 to match.
5502 (define_insn "*addsi_1_zext"
5503 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5505 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5506 (match_operand:SI 2 "general_operand" "g,0,li"))))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5510 switch (get_attr_type (insn))
5516 if (operands[2] == const1_rtx)
5517 return "inc{l}\t%k0";
5520 gcc_assert (operands[2] == constm1_rtx);
5521 return "dec{l}\t%k0";
5525 /* For most processors, ADD is faster than LEA. This alternative
5526 was added to use ADD as much as possible. */
5527 if (which_alternative == 1)
5530 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5533 if (x86_maybe_negate_const_int (&operands[2], SImode))
5534 return "sub{l}\t{%2, %k0|%k0, %2}";
5536 return "add{l}\t{%2, %k0|%k0, %2}";
5540 (cond [(eq_attr "alternative" "2")
5541 (const_string "lea")
5542 (match_operand:SI 2 "incdec_operand" "")
5543 (const_string "incdec")
5545 (const_string "alu")))
5546 (set (attr "length_immediate")
5548 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5550 (const_string "*")))
5551 (set_attr "mode" "SI")])
5553 (define_insn "*addhi_1"
5554 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5555 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5556 (match_operand:HI 2 "general_operand" "rn,rm")))
5557 (clobber (reg:CC FLAGS_REG))]
5558 "TARGET_PARTIAL_REG_STALL
5559 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5561 switch (get_attr_type (insn))
5564 if (operands[2] == const1_rtx)
5565 return "inc{w}\t%0";
5568 gcc_assert (operands[2] == constm1_rtx);
5569 return "dec{w}\t%0";
5573 if (x86_maybe_negate_const_int (&operands[2], HImode))
5574 return "sub{w}\t{%2, %0|%0, %2}";
5576 return "add{w}\t{%2, %0|%0, %2}";
5580 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5581 (const_string "incdec")
5582 (const_string "alu")))
5583 (set (attr "length_immediate")
5585 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5587 (const_string "*")))
5588 (set_attr "mode" "HI")])
5590 (define_insn "*addhi_1_lea"
5591 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5592 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5593 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5594 (clobber (reg:CC FLAGS_REG))]
5595 "!TARGET_PARTIAL_REG_STALL
5596 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5598 switch (get_attr_type (insn))
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (operands[2] == const1_rtx)
5606 return "inc{w}\t%0";
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{w}\t%0";
5614 /* For most processors, ADD is faster than LEA. This alternative
5615 was added to use ADD as much as possible. */
5616 if (which_alternative == 2)
5619 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5622 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5623 if (x86_maybe_negate_const_int (&operands[2], HImode))
5624 return "sub{w}\t{%2, %0|%0, %2}";
5626 return "add{w}\t{%2, %0|%0, %2}";
5630 (cond [(eq_attr "alternative" "3")
5631 (const_string "lea")
5632 (match_operand:HI 2 "incdec_operand" "")
5633 (const_string "incdec")
5635 (const_string "alu")))
5636 (set (attr "length_immediate")
5638 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5640 (const_string "*")))
5641 (set_attr "mode" "HI,HI,HI,SI")])
5643 ;; %%% Potential partial reg stall on alternative 2. What to do?
5644 (define_insn "*addqi_1"
5645 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5646 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5647 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5648 (clobber (reg:CC FLAGS_REG))]
5649 "TARGET_PARTIAL_REG_STALL
5650 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5652 int widen = (which_alternative == 2);
5653 switch (get_attr_type (insn))
5656 if (operands[2] == const1_rtx)
5657 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5660 gcc_assert (operands[2] == constm1_rtx);
5661 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5665 if (x86_maybe_negate_const_int (&operands[2], QImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5670 return "sub{b}\t{%2, %0|%0, %2}";
5673 return "add{l}\t{%k2, %k0|%k0, %k2}";
5675 return "add{b}\t{%2, %0|%0, %2}";
5679 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5680 (const_string "incdec")
5681 (const_string "alu")))
5682 (set (attr "length_immediate")
5684 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5686 (const_string "*")))
5687 (set_attr "mode" "QI,QI,SI")])
5689 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5690 (define_insn "*addqi_1_lea"
5691 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5692 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5693 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5694 (clobber (reg:CC FLAGS_REG))]
5695 "!TARGET_PARTIAL_REG_STALL
5696 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5698 int widen = (which_alternative == 3 || which_alternative == 4);
5700 switch (get_attr_type (insn))
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 if (operands[2] == const1_rtx)
5708 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5711 gcc_assert (operands[2] == constm1_rtx);
5712 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5716 /* For most processors, ADD is faster than LEA. These alternatives
5717 were added to use ADD as much as possible. */
5718 if (which_alternative == 2 || which_alternative == 4)
5721 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725 if (x86_maybe_negate_const_int (&operands[2], QImode))
5728 return "sub{l}\t{%2, %k0|%k0, %2}";
5730 return "sub{b}\t{%2, %0|%0, %2}";
5733 return "add{l}\t{%k2, %k0|%k0, %k2}";
5735 return "add{b}\t{%2, %0|%0, %2}";
5739 (cond [(eq_attr "alternative" "5")
5740 (const_string "lea")
5741 (match_operand:QI 2 "incdec_operand" "")
5742 (const_string "incdec")
5744 (const_string "alu")))
5745 (set (attr "length_immediate")
5747 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5749 (const_string "*")))
5750 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5752 (define_insn "*addqi_1_slp"
5753 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5754 (plus:QI (match_dup 0)
5755 (match_operand:QI 1 "general_operand" "qn,qnm")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5758 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5760 switch (get_attr_type (insn))
5763 if (operands[1] == const1_rtx)
5764 return "inc{b}\t%0";
5767 gcc_assert (operands[1] == constm1_rtx);
5768 return "dec{b}\t%0";
5772 if (x86_maybe_negate_const_int (&operands[1], QImode))
5773 return "sub{b}\t{%1, %0|%0, %1}";
5775 return "add{b}\t{%1, %0|%0, %1}";
5779 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5780 (const_string "incdec")
5781 (const_string "alu1")))
5782 (set (attr "memory")
5783 (if_then_else (match_operand 1 "memory_operand" "")
5784 (const_string "load")
5785 (const_string "none")))
5786 (set_attr "mode" "QI")])
5788 ;; Convert lea to the lea pattern to avoid flags dependency.
5790 [(set (match_operand 0 "register_operand" "")
5791 (plus (match_operand 1 "register_operand" "")
5792 (match_operand 2 "nonmemory_operand" "")))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5798 enum machine_mode mode = GET_MODE (operands[0]);
5800 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5801 may confuse gen_lowpart. */
5804 operands[1] = gen_lowpart (Pmode, operands[1]);
5805 operands[2] = gen_lowpart (Pmode, operands[2]);
5808 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5810 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5811 operands[0] = gen_lowpart (SImode, operands[0]);
5813 if (TARGET_64BIT && mode != Pmode)
5814 pat = gen_rtx_SUBREG (SImode, pat, 0);
5816 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5820 ;; Convert lea to the lea pattern to avoid flags dependency.
5821 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5822 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5824 [(set (match_operand:DI 0 "register_operand" "")
5825 (plus:DI (match_operand:DI 1 "register_operand" "")
5826 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5827 (clobber (reg:CC FLAGS_REG))]
5828 "TARGET_64BIT && reload_completed
5829 && true_regnum (operands[0]) != true_regnum (operands[1])"
5831 (plus:DI (match_dup 1) (match_dup 2)))])
5833 ;; Convert lea to the lea pattern to avoid flags dependency.
5835 [(set (match_operand:DI 0 "register_operand" "")
5837 (plus:SI (match_operand:SI 1 "register_operand" "")
5838 (match_operand:SI 2 "nonmemory_operand" ""))))
5839 (clobber (reg:CC FLAGS_REG))]
5840 "TARGET_64BIT && reload_completed
5841 && ix86_lea_for_add_ok (insn, operands)"
5843 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5845 operands[1] = gen_lowpart (DImode, operands[1]);
5846 operands[2] = gen_lowpart (DImode, operands[2]);
5849 (define_insn "*add<mode>_2"
5850 [(set (reg FLAGS_REG)
5853 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5854 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5856 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5857 (plus:SWI (match_dup 1) (match_dup 2)))]
5858 "ix86_match_ccmode (insn, CCGOCmode)
5859 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5861 switch (get_attr_type (insn))
5864 if (operands[2] == const1_rtx)
5865 return "inc{<imodesuffix>}\t%0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{<imodesuffix>}\t%0";
5873 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5874 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5876 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5880 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5881 (const_string "incdec")
5882 (const_string "alu")))
5883 (set (attr "length_immediate")
5885 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5887 (const_string "*")))
5888 (set_attr "mode" "<MODE>")])
5890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5891 (define_insn "*addsi_2_zext"
5892 [(set (reg FLAGS_REG)
5894 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5895 (match_operand:SI 2 "general_operand" "g"))
5897 (set (match_operand:DI 0 "register_operand" "=r")
5898 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5899 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5900 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5902 switch (get_attr_type (insn))
5905 if (operands[2] == const1_rtx)
5906 return "inc{l}\t%k0";
5909 gcc_assert (operands[2] == constm1_rtx);
5910 return "dec{l}\t%k0";
5914 if (x86_maybe_negate_const_int (&operands[2], SImode))
5915 return "sub{l}\t{%2, %k0|%k0, %2}";
5917 return "add{l}\t{%2, %k0|%k0, %2}";
5921 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5922 (const_string "incdec")
5923 (const_string "alu")))
5924 (set (attr "length_immediate")
5926 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5928 (const_string "*")))
5929 (set_attr "mode" "SI")])
5931 (define_insn "*add<mode>_3"
5932 [(set (reg FLAGS_REG)
5934 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5935 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5936 (clobber (match_scratch:SWI 0 "=<r>"))]
5937 "ix86_match_ccmode (insn, CCZmode)
5938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5940 switch (get_attr_type (insn))
5943 if (operands[2] == const1_rtx)
5944 return "inc{<imodesuffix>}\t%0";
5947 gcc_assert (operands[2] == constm1_rtx);
5948 return "dec{<imodesuffix>}\t%0";
5952 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5953 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5955 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5959 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5960 (const_string "incdec")
5961 (const_string "alu")))
5962 (set (attr "length_immediate")
5964 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966 (const_string "*")))
5967 (set_attr "mode" "<MODE>")])
5969 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5970 (define_insn "*addsi_3_zext"
5971 [(set (reg FLAGS_REG)
5973 (neg:SI (match_operand:SI 2 "general_operand" "g"))
5974 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5975 (set (match_operand:DI 0 "register_operand" "=r")
5976 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5977 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5978 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5980 switch (get_attr_type (insn))
5983 if (operands[2] == const1_rtx)
5984 return "inc{l}\t%k0";
5987 gcc_assert (operands[2] == constm1_rtx);
5988 return "dec{l}\t%k0";
5992 if (x86_maybe_negate_const_int (&operands[2], SImode))
5993 return "sub{l}\t{%2, %k0|%k0, %2}";
5995 return "add{l}\t{%2, %k0|%k0, %2}";
5999 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000 (const_string "incdec")
6001 (const_string "alu")))
6002 (set (attr "length_immediate")
6004 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6006 (const_string "*")))
6007 (set_attr "mode" "SI")])
6009 ; For comparisons against 1, -1 and 128, we may generate better code
6010 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6011 ; is matched then. We can't accept general immediate, because for
6012 ; case of overflows, the result is messed up.
6013 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6014 ; only for comparisons not depending on it.
6016 (define_insn "*adddi_4"
6017 [(set (reg FLAGS_REG)
6019 (match_operand:DI 1 "nonimmediate_operand" "0")
6020 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021 (clobber (match_scratch:DI 0 "=rm"))]
6023 && ix86_match_ccmode (insn, CCGCmode)"
6025 switch (get_attr_type (insn))
6028 if (operands[2] == constm1_rtx)
6029 return "inc{q}\t%0";
6032 gcc_assert (operands[2] == const1_rtx);
6033 return "dec{q}\t%0";
6037 if (x86_maybe_negate_const_int (&operands[2], DImode))
6038 return "add{q}\t{%2, %0|%0, %2}";
6040 return "sub{q}\t{%2, %0|%0, %2}";
6044 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045 (const_string "incdec")
6046 (const_string "alu")))
6047 (set (attr "length_immediate")
6049 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6051 (const_string "*")))
6052 (set_attr "mode" "DI")])
6054 ; For comparisons against 1, -1 and 128, we may generate better code
6055 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6056 ; is matched then. We can't accept general immediate, because for
6057 ; case of overflows, the result is messed up.
6058 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6059 ; only for comparisons not depending on it.
6061 (define_insn "*add<mode>_4"
6062 [(set (reg FLAGS_REG)
6064 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065 (match_operand:SWI124 2 "const_int_operand" "n")))
6066 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067 "ix86_match_ccmode (insn, CCGCmode)"
6069 switch (get_attr_type (insn))
6072 if (operands[2] == constm1_rtx)
6073 return "inc{<imodesuffix>}\t%0";
6076 gcc_assert (operands[2] == const1_rtx);
6077 return "dec{<imodesuffix>}\t%0";
6081 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6084 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6088 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set (attr "length_immediate")
6093 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095 (const_string "*")))
6096 (set_attr "mode" "<MODE>")])
6098 (define_insn "*add<mode>_5"
6099 [(set (reg FLAGS_REG)
6102 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6103 (match_operand:SWI 2 "<general_operand>" "<g>"))
6105 (clobber (match_scratch:SWI 0 "=<r>"))]
6106 "ix86_match_ccmode (insn, CCGOCmode)
6107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6109 switch (get_attr_type (insn))
6112 if (operands[2] == const1_rtx)
6113 return "inc{<imodesuffix>}\t%0";
6116 gcc_assert (operands[2] == constm1_rtx);
6117 return "dec{<imodesuffix>}\t%0";
6121 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6122 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6128 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set (attr "length_immediate")
6133 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6135 (const_string "*")))
6136 (set_attr "mode" "<MODE>")])
6138 (define_insn "*addqi_ext_1_rex64"
6139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6144 (match_operand 1 "ext_register_operand" "0")
6147 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6148 (clobber (reg:CC FLAGS_REG))]
6151 switch (get_attr_type (insn))
6154 if (operands[2] == const1_rtx)
6155 return "inc{b}\t%h0";
6158 gcc_assert (operands[2] == constm1_rtx);
6159 return "dec{b}\t%h0";
6163 return "add{b}\t{%2, %h0|%h0, %2}";
6167 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set_attr "modrm" "1")
6171 (set_attr "mode" "QI")])
6173 (define_insn "addqi_ext_1"
6174 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6179 (match_operand 1 "ext_register_operand" "0")
6182 (match_operand:QI 2 "general_operand" "Qmn")))
6183 (clobber (reg:CC FLAGS_REG))]
6186 switch (get_attr_type (insn))
6189 if (operands[2] == const1_rtx)
6190 return "inc{b}\t%h0";
6193 gcc_assert (operands[2] == constm1_rtx);
6194 return "dec{b}\t%h0";
6198 return "add{b}\t{%2, %h0|%h0, %2}";
6202 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6203 (const_string "incdec")
6204 (const_string "alu")))
6205 (set_attr "modrm" "1")
6206 (set_attr "mode" "QI")])
6208 (define_insn "*addqi_ext_2"
6209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6214 (match_operand 1 "ext_register_operand" "%0")
6218 (match_operand 2 "ext_register_operand" "Q")
6221 (clobber (reg:CC FLAGS_REG))]
6223 "add{b}\t{%h2, %h0|%h0, %h2}"
6224 [(set_attr "type" "alu")
6225 (set_attr "mode" "QI")])
6227 ;; The lea patterns for non-Pmodes needs to be matched by
6228 ;; several insns converted to real lea by splitters.
6230 (define_insn_and_split "*lea_general_1"
6231 [(set (match_operand 0 "register_operand" "=r")
6232 (plus (plus (match_operand 1 "index_register_operand" "l")
6233 (match_operand 2 "register_operand" "r"))
6234 (match_operand 3 "immediate_operand" "i")))]
6235 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6236 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6237 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6238 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6239 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6240 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6241 || GET_MODE (operands[3]) == VOIDmode)"
6243 "&& reload_completed"
6247 operands[0] = gen_lowpart (SImode, operands[0]);
6248 operands[1] = gen_lowpart (Pmode, operands[1]);
6249 operands[2] = gen_lowpart (Pmode, operands[2]);
6250 operands[3] = gen_lowpart (Pmode, operands[3]);
6251 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6253 if (Pmode != SImode)
6254 pat = gen_rtx_SUBREG (SImode, pat, 0);
6255 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6258 [(set_attr "type" "lea")
6259 (set_attr "mode" "SI")])
6261 (define_insn_and_split "*lea_general_1_zext"
6262 [(set (match_operand:DI 0 "register_operand" "=r")
6265 (match_operand:SI 1 "index_register_operand" "l")
6266 (match_operand:SI 2 "register_operand" "r"))
6267 (match_operand:SI 3 "immediate_operand" "i"))))]
6270 "&& reload_completed"
6272 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6274 (match_dup 3)) 0)))]
6276 operands[1] = gen_lowpart (Pmode, operands[1]);
6277 operands[2] = gen_lowpart (Pmode, operands[2]);
6278 operands[3] = gen_lowpart (Pmode, operands[3]);
6280 [(set_attr "type" "lea")
6281 (set_attr "mode" "SI")])
6283 (define_insn_and_split "*lea_general_2"
6284 [(set (match_operand 0 "register_operand" "=r")
6285 (plus (mult (match_operand 1 "index_register_operand" "l")
6286 (match_operand 2 "const248_operand" "i"))
6287 (match_operand 3 "nonmemory_operand" "ri")))]
6288 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6289 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6291 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6292 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6293 || GET_MODE (operands[3]) == VOIDmode)"
6295 "&& reload_completed"
6299 operands[0] = gen_lowpart (SImode, operands[0]);
6300 operands[1] = gen_lowpart (Pmode, operands[1]);
6301 operands[3] = gen_lowpart (Pmode, operands[3]);
6302 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6304 if (Pmode != SImode)
6305 pat = gen_rtx_SUBREG (SImode, pat, 0);
6306 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6309 [(set_attr "type" "lea")
6310 (set_attr "mode" "SI")])
6312 (define_insn_and_split "*lea_general_2_zext"
6313 [(set (match_operand:DI 0 "register_operand" "=r")
6316 (match_operand:SI 1 "index_register_operand" "l")
6317 (match_operand:SI 2 "const248_operand" "n"))
6318 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6321 "&& reload_completed"
6323 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6325 (match_dup 3)) 0)))]
6327 operands[1] = gen_lowpart (Pmode, operands[1]);
6328 operands[3] = gen_lowpart (Pmode, operands[3]);
6330 [(set_attr "type" "lea")
6331 (set_attr "mode" "SI")])
6333 (define_insn_and_split "*lea_general_3"
6334 [(set (match_operand 0 "register_operand" "=r")
6335 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6336 (match_operand 2 "const248_operand" "i"))
6337 (match_operand 3 "register_operand" "r"))
6338 (match_operand 4 "immediate_operand" "i")))]
6339 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6340 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6341 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6342 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6343 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6345 "&& reload_completed"
6349 operands[0] = gen_lowpart (SImode, operands[0]);
6350 operands[1] = gen_lowpart (Pmode, operands[1]);
6351 operands[3] = gen_lowpart (Pmode, operands[3]);
6352 operands[4] = gen_lowpart (Pmode, operands[4]);
6353 pat = gen_rtx_PLUS (Pmode,
6354 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6358 if (Pmode != SImode)
6359 pat = gen_rtx_SUBREG (SImode, pat, 0);
6360 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6363 [(set_attr "type" "lea")
6364 (set_attr "mode" "SI")])
6366 (define_insn_and_split "*lea_general_3_zext"
6367 [(set (match_operand:DI 0 "register_operand" "=r")
6371 (match_operand:SI 1 "index_register_operand" "l")
6372 (match_operand:SI 2 "const248_operand" "n"))
6373 (match_operand:SI 3 "register_operand" "r"))
6374 (match_operand:SI 4 "immediate_operand" "i"))))]
6377 "&& reload_completed"
6379 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6382 (match_dup 4)) 0)))]
6384 operands[1] = gen_lowpart (Pmode, operands[1]);
6385 operands[3] = gen_lowpart (Pmode, operands[3]);
6386 operands[4] = gen_lowpart (Pmode, operands[4]);
6388 [(set_attr "type" "lea")
6389 (set_attr "mode" "SI")])
6391 (define_insn_and_split "*lea_general_4"
6392 [(set (match_operand:SWI 0 "register_operand" "=r")
6393 (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6394 (match_operand:SWI 2 "const_int_operand" "n"))
6395 (match_operand 3 "const_int_operand" "n")))]
6396 "(<MODE>mode == DImode
6397 || <MODE>mode == SImode
6398 || !TARGET_PARTIAL_REG_STALL
6399 || optimize_function_for_size_p (cfun))
6400 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6401 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6402 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6404 "&& reload_completed"
6408 if (<MODE>mode != DImode)
6409 operands[0] = gen_lowpart (SImode, operands[0]);
6410 operands[1] = gen_lowpart (Pmode, operands[1]);
6411 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6412 pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6413 INTVAL (operands[3]));
6414 if (Pmode != SImode && <MODE>mode != DImode)
6415 pat = gen_rtx_SUBREG (SImode, pat, 0);
6416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6419 [(set_attr "type" "lea")
6421 (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6423 (const_string "DI")))])
6425 ;; Subtract instructions
6427 (define_expand "sub<mode>3"
6428 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6429 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6430 (match_operand:SDWIM 2 "<general_operand>" "")))]
6432 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6434 (define_insn_and_split "*sub<dwi>3_doubleword"
6435 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6437 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6438 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6439 (clobber (reg:CC FLAGS_REG))]
6440 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6443 [(parallel [(set (reg:CC FLAGS_REG)
6444 (compare:CC (match_dup 1) (match_dup 2)))
6446 (minus:DWIH (match_dup 1) (match_dup 2)))])
6447 (parallel [(set (match_dup 3)
6451 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6453 (clobber (reg:CC FLAGS_REG))])]
6454 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6456 (define_insn "*sub<mode>_1"
6457 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6459 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6460 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6461 (clobber (reg:CC FLAGS_REG))]
6462 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6463 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6464 [(set_attr "type" "alu")
6465 (set_attr "mode" "<MODE>")])
6467 (define_insn "*subsi_1_zext"
6468 [(set (match_operand:DI 0 "register_operand" "=r")
6470 (minus:SI (match_operand:SI 1 "register_operand" "0")
6471 (match_operand:SI 2 "general_operand" "g"))))
6472 (clobber (reg:CC FLAGS_REG))]
6473 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6474 "sub{l}\t{%2, %k0|%k0, %2}"
6475 [(set_attr "type" "alu")
6476 (set_attr "mode" "SI")])
6478 (define_insn "*subqi_1_slp"
6479 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6480 (minus:QI (match_dup 0)
6481 (match_operand:QI 1 "general_operand" "qn,qm")))
6482 (clobber (reg:CC FLAGS_REG))]
6483 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6484 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6485 "sub{b}\t{%1, %0|%0, %1}"
6486 [(set_attr "type" "alu1")
6487 (set_attr "mode" "QI")])
6489 (define_insn "*sub<mode>_2"
6490 [(set (reg FLAGS_REG)
6493 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6494 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6496 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6497 (minus:SWI (match_dup 1) (match_dup 2)))]
6498 "ix86_match_ccmode (insn, CCGOCmode)
6499 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6500 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "<MODE>")])
6504 (define_insn "*subsi_2_zext"
6505 [(set (reg FLAGS_REG)
6507 (minus:SI (match_operand:SI 1 "register_operand" "0")
6508 (match_operand:SI 2 "general_operand" "g"))
6510 (set (match_operand:DI 0 "register_operand" "=r")
6512 (minus:SI (match_dup 1)
6514 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6515 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516 "sub{l}\t{%2, %k0|%k0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "SI")])
6520 (define_insn "*sub<mode>_3"
6521 [(set (reg FLAGS_REG)
6522 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6523 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6524 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6525 (minus:SWI (match_dup 1) (match_dup 2)))]
6526 "ix86_match_ccmode (insn, CCmode)
6527 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6528 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "<MODE>")])
6532 (define_insn "*subsi_3_zext"
6533 [(set (reg FLAGS_REG)
6534 (compare (match_operand:SI 1 "register_operand" "0")
6535 (match_operand:SI 2 "general_operand" "g")))
6536 (set (match_operand:DI 0 "register_operand" "=r")
6538 (minus:SI (match_dup 1)
6540 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6541 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6542 "sub{l}\t{%2, %1|%1, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "SI")])
6546 ;; Add with carry and subtract with borrow
6548 (define_expand "<plusminus_insn><mode>3_carry"
6550 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6552 (match_operand:SWI 1 "nonimmediate_operand" "")
6553 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6554 [(match_operand 3 "flags_reg_operand" "")
6556 (match_operand:SWI 2 "<general_operand>" ""))))
6557 (clobber (reg:CC FLAGS_REG))])]
6558 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6560 (define_insn "*<plusminus_insn><mode>3_carry"
6561 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6563 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6565 (match_operator 3 "ix86_carry_flag_operator"
6566 [(reg FLAGS_REG) (const_int 0)])
6567 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6568 (clobber (reg:CC FLAGS_REG))]
6569 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6570 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "use_carry" "1")
6573 (set_attr "pent_pair" "pu")
6574 (set_attr "mode" "<MODE>")])
6576 (define_insn "*addsi3_carry_zext"
6577 [(set (match_operand:DI 0 "register_operand" "=r")
6579 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6580 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6581 [(reg FLAGS_REG) (const_int 0)])
6582 (match_operand:SI 2 "general_operand" "g")))))
6583 (clobber (reg:CC FLAGS_REG))]
6584 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6585 "adc{l}\t{%2, %k0|%k0, %2}"
6586 [(set_attr "type" "alu")
6587 (set_attr "use_carry" "1")
6588 (set_attr "pent_pair" "pu")
6589 (set_attr "mode" "SI")])
6591 (define_insn "*subsi3_carry_zext"
6592 [(set (match_operand:DI 0 "register_operand" "=r")
6594 (minus:SI (match_operand:SI 1 "register_operand" "0")
6595 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6596 [(reg FLAGS_REG) (const_int 0)])
6597 (match_operand:SI 2 "general_operand" "g")))))
6598 (clobber (reg:CC FLAGS_REG))]
6599 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6600 "sbb{l}\t{%2, %k0|%k0, %2}"
6601 [(set_attr "type" "alu")
6602 (set_attr "pent_pair" "pu")
6603 (set_attr "mode" "SI")])
6605 ;; Overflow setting add and subtract instructions
6607 (define_insn "*add<mode>3_cconly_overflow"
6608 [(set (reg:CCC FLAGS_REG)
6611 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6612 (match_operand:SWI 2 "<general_operand>" "<g>"))
6614 (clobber (match_scratch:SWI 0 "=<r>"))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "mode" "<MODE>")])
6620 (define_insn "*sub<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6625 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6628 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6629 [(set_attr "type" "icmp")
6630 (set_attr "mode" "<MODE>")])
6632 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6633 [(set (reg:CCC FLAGS_REG)
6636 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6637 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6639 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6640 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6641 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6642 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "mode" "<MODE>")])
6646 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6647 [(set (reg:CCC FLAGS_REG)
6650 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6651 (match_operand:SI 2 "general_operand" "g"))
6653 (set (match_operand:DI 0 "register_operand" "=r")
6654 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6655 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6656 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "SI")])
6660 ;; The patterns that match these are at the end of this file.
6662 (define_expand "<plusminus_insn>xf3"
6663 [(set (match_operand:XF 0 "register_operand" "")
6665 (match_operand:XF 1 "register_operand" "")
6666 (match_operand:XF 2 "register_operand" "")))]
6669 (define_expand "<plusminus_insn><mode>3"
6670 [(set (match_operand:MODEF 0 "register_operand" "")
6672 (match_operand:MODEF 1 "register_operand" "")
6673 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6674 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6675 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6677 ;; Multiply instructions
6679 (define_expand "mul<mode>3"
6680 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6682 (match_operand:SWIM248 1 "register_operand" "")
6683 (match_operand:SWIM248 2 "<general_operand>" "")))
6684 (clobber (reg:CC FLAGS_REG))])])
6686 (define_expand "mulqi3"
6687 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6689 (match_operand:QI 1 "register_operand" "")
6690 (match_operand:QI 2 "nonimmediate_operand" "")))
6691 (clobber (reg:CC FLAGS_REG))])]
6692 "TARGET_QIMODE_MATH")
6695 ;; IMUL reg32/64, reg32/64, imm8 Direct
6696 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6697 ;; IMUL reg32/64, reg32/64, imm32 Direct
6698 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6699 ;; IMUL reg32/64, reg32/64 Direct
6700 ;; IMUL reg32/64, mem32/64 Direct
6702 ;; On BDVER1, all above IMULs use DirectPath
6704 (define_insn "*mul<mode>3_1"
6705 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6707 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6708 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6709 (clobber (reg:CC FLAGS_REG))]
6710 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6712 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6713 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6714 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6715 [(set_attr "type" "imul")
6716 (set_attr "prefix_0f" "0,0,1")
6717 (set (attr "athlon_decode")
6718 (cond [(eq_attr "cpu" "athlon")
6719 (const_string "vector")
6720 (eq_attr "alternative" "1")
6721 (const_string "vector")
6722 (and (eq_attr "alternative" "2")
6723 (match_operand 1 "memory_operand" ""))
6724 (const_string "vector")]
6725 (const_string "direct")))
6726 (set (attr "amdfam10_decode")
6727 (cond [(and (eq_attr "alternative" "0,1")
6728 (match_operand 1 "memory_operand" ""))
6729 (const_string "vector")]
6730 (const_string "direct")))
6731 (set_attr "bdver1_decode" "direct")
6732 (set_attr "mode" "<MODE>")])
6734 (define_insn "*mulsi3_1_zext"
6735 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6737 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6738 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6739 (clobber (reg:CC FLAGS_REG))]
6741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6743 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6744 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6745 imul{l}\t{%2, %k0|%k0, %2}"
6746 [(set_attr "type" "imul")
6747 (set_attr "prefix_0f" "0,0,1")
6748 (set (attr "athlon_decode")
6749 (cond [(eq_attr "cpu" "athlon")
6750 (const_string "vector")
6751 (eq_attr "alternative" "1")
6752 (const_string "vector")
6753 (and (eq_attr "alternative" "2")
6754 (match_operand 1 "memory_operand" ""))
6755 (const_string "vector")]
6756 (const_string "direct")))
6757 (set (attr "amdfam10_decode")
6758 (cond [(and (eq_attr "alternative" "0,1")
6759 (match_operand 1 "memory_operand" ""))
6760 (const_string "vector")]
6761 (const_string "direct")))
6762 (set_attr "bdver1_decode" "direct")
6763 (set_attr "mode" "SI")])
6766 ;; IMUL reg16, reg16, imm8 VectorPath
6767 ;; IMUL reg16, mem16, imm8 VectorPath
6768 ;; IMUL reg16, reg16, imm16 VectorPath
6769 ;; IMUL reg16, mem16, imm16 VectorPath
6770 ;; IMUL reg16, reg16 Direct
6771 ;; IMUL reg16, mem16 Direct
6773 ;; On BDVER1, all HI MULs use DoublePath
6775 (define_insn "*mulhi3_1"
6776 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6777 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6778 (match_operand:HI 2 "general_operand" "K,n,mr")))
6779 (clobber (reg:CC FLAGS_REG))]
6781 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6783 imul{w}\t{%2, %1, %0|%0, %1, %2}
6784 imul{w}\t{%2, %1, %0|%0, %1, %2}
6785 imul{w}\t{%2, %0|%0, %2}"
6786 [(set_attr "type" "imul")
6787 (set_attr "prefix_0f" "0,0,1")
6788 (set (attr "athlon_decode")
6789 (cond [(eq_attr "cpu" "athlon")
6790 (const_string "vector")
6791 (eq_attr "alternative" "1,2")
6792 (const_string "vector")]
6793 (const_string "direct")))
6794 (set (attr "amdfam10_decode")
6795 (cond [(eq_attr "alternative" "0,1")
6796 (const_string "vector")]
6797 (const_string "direct")))
6798 (set_attr "bdver1_decode" "double")
6799 (set_attr "mode" "HI")])
6801 ;;On AMDFAM10 and BDVER1
6805 (define_insn "*mulqi3_1"
6806 [(set (match_operand:QI 0 "register_operand" "=a")
6807 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6808 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6809 (clobber (reg:CC FLAGS_REG))]
6811 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6813 [(set_attr "type" "imul")
6814 (set_attr "length_immediate" "0")
6815 (set (attr "athlon_decode")
6816 (if_then_else (eq_attr "cpu" "athlon")
6817 (const_string "vector")
6818 (const_string "direct")))
6819 (set_attr "amdfam10_decode" "direct")
6820 (set_attr "bdver1_decode" "direct")
6821 (set_attr "mode" "QI")])
6823 (define_expand "<u>mul<mode><dwi>3"
6824 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6827 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6829 (match_operand:DWIH 2 "register_operand" ""))))
6830 (clobber (reg:CC FLAGS_REG))])])
6832 (define_expand "<u>mulqihi3"
6833 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6836 (match_operand:QI 1 "nonimmediate_operand" ""))
6838 (match_operand:QI 2 "register_operand" ""))))
6839 (clobber (reg:CC FLAGS_REG))])]
6840 "TARGET_QIMODE_MATH")
6842 (define_insn "*<u>mul<mode><dwi>3_1"
6843 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6846 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6848 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6849 (clobber (reg:CC FLAGS_REG))]
6850 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6851 "<sgnprefix>mul{<imodesuffix>}\t%2"
6852 [(set_attr "type" "imul")
6853 (set_attr "length_immediate" "0")
6854 (set (attr "athlon_decode")
6855 (if_then_else (eq_attr "cpu" "athlon")
6856 (const_string "vector")
6857 (const_string "double")))
6858 (set_attr "amdfam10_decode" "double")
6859 (set_attr "bdver1_decode" "direct")
6860 (set_attr "mode" "<MODE>")])
6862 (define_insn "*<u>mulqihi3_1"
6863 [(set (match_operand:HI 0 "register_operand" "=a")
6866 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6868 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6869 (clobber (reg:CC FLAGS_REG))]
6871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872 "<sgnprefix>mul{b}\t%2"
6873 [(set_attr "type" "imul")
6874 (set_attr "length_immediate" "0")
6875 (set (attr "athlon_decode")
6876 (if_then_else (eq_attr "cpu" "athlon")
6877 (const_string "vector")
6878 (const_string "direct")))
6879 (set_attr "amdfam10_decode" "direct")
6880 (set_attr "bdver1_decode" "direct")
6881 (set_attr "mode" "QI")])
6883 (define_expand "<s>mul<mode>3_highpart"
6884 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6889 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6891 (match_operand:SWI48 2 "register_operand" "")))
6893 (clobber (match_scratch:SWI48 3 ""))
6894 (clobber (reg:CC FLAGS_REG))])]
6896 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6898 (define_insn "*<s>muldi3_highpart_1"
6899 [(set (match_operand:DI 0 "register_operand" "=d")
6904 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6906 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6908 (clobber (match_scratch:DI 3 "=1"))
6909 (clobber (reg:CC FLAGS_REG))]
6911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6912 "<sgnprefix>mul{q}\t%2"
6913 [(set_attr "type" "imul")
6914 (set_attr "length_immediate" "0")
6915 (set (attr "athlon_decode")
6916 (if_then_else (eq_attr "cpu" "athlon")
6917 (const_string "vector")
6918 (const_string "double")))
6919 (set_attr "amdfam10_decode" "double")
6920 (set_attr "bdver1_decode" "direct")
6921 (set_attr "mode" "DI")])
6923 (define_insn "*<s>mulsi3_highpart_1"
6924 [(set (match_operand:SI 0 "register_operand" "=d")
6929 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6931 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6933 (clobber (match_scratch:SI 3 "=1"))
6934 (clobber (reg:CC FLAGS_REG))]
6935 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 "<sgnprefix>mul{l}\t%2"
6937 [(set_attr "type" "imul")
6938 (set_attr "length_immediate" "0")
6939 (set (attr "athlon_decode")
6940 (if_then_else (eq_attr "cpu" "athlon")
6941 (const_string "vector")
6942 (const_string "double")))
6943 (set_attr "amdfam10_decode" "double")
6944 (set_attr "bdver1_decode" "direct")
6945 (set_attr "mode" "SI")])
6947 (define_insn "*<s>mulsi3_highpart_zext"
6948 [(set (match_operand:DI 0 "register_operand" "=d")
6949 (zero_extend:DI (truncate:SI
6951 (mult:DI (any_extend:DI
6952 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6954 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6956 (clobber (match_scratch:SI 3 "=1"))
6957 (clobber (reg:CC FLAGS_REG))]
6959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960 "<sgnprefix>mul{l}\t%2"
6961 [(set_attr "type" "imul")
6962 (set_attr "length_immediate" "0")
6963 (set (attr "athlon_decode")
6964 (if_then_else (eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (const_string "double")))
6967 (set_attr "amdfam10_decode" "double")
6968 (set_attr "bdver1_decode" "direct")
6969 (set_attr "mode" "SI")])
6971 ;; The patterns that match these are at the end of this file.
6973 (define_expand "mulxf3"
6974 [(set (match_operand:XF 0 "register_operand" "")
6975 (mult:XF (match_operand:XF 1 "register_operand" "")
6976 (match_operand:XF 2 "register_operand" "")))]
6979 (define_expand "mul<mode>3"
6980 [(set (match_operand:MODEF 0 "register_operand" "")
6981 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6982 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6983 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6984 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6986 ;; Divide instructions
6988 ;; The patterns that match these are at the end of this file.
6990 (define_expand "divxf3"
6991 [(set (match_operand:XF 0 "register_operand" "")
6992 (div:XF (match_operand:XF 1 "register_operand" "")
6993 (match_operand:XF 2 "register_operand" "")))]
6996 (define_expand "divdf3"
6997 [(set (match_operand:DF 0 "register_operand" "")
6998 (div:DF (match_operand:DF 1 "register_operand" "")
6999 (match_operand:DF 2 "nonimmediate_operand" "")))]
7000 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7001 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7003 (define_expand "divsf3"
7004 [(set (match_operand:SF 0 "register_operand" "")
7005 (div:SF (match_operand:SF 1 "register_operand" "")
7006 (match_operand:SF 2 "nonimmediate_operand" "")))]
7007 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7010 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7011 && flag_finite_math_only && !flag_trapping_math
7012 && flag_unsafe_math_optimizations)
7014 ix86_emit_swdivsf (operands[0], operands[1],
7015 operands[2], SFmode);
7020 ;; Divmod instructions.
7022 (define_expand "divmod<mode>4"
7023 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7025 (match_operand:SWIM248 1 "register_operand" "")
7026 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7027 (set (match_operand:SWIM248 3 "register_operand" "")
7028 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7029 (clobber (reg:CC FLAGS_REG))])])
7031 ;; Split with 8bit unsigned divide:
7032 ;; if (dividend an divisor are in [0-255])
7033 ;; use 8bit unsigned integer divide
7035 ;; use original integer divide
7037 [(set (match_operand:SWI48 0 "register_operand" "")
7038 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7039 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7040 (set (match_operand:SWI48 1 "register_operand" "")
7041 (mod:SWI48 (match_dup 2) (match_dup 3)))
7042 (clobber (reg:CC FLAGS_REG))]
7043 "TARGET_USE_8BIT_IDIV
7044 && TARGET_QIMODE_MATH
7045 && can_create_pseudo_p ()
7046 && !optimize_insn_for_size_p ()"
7048 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7050 (define_insn_and_split "divmod<mode>4_1"
7051 [(set (match_operand:SWI48 0 "register_operand" "=a")
7052 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7053 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7054 (set (match_operand:SWI48 1 "register_operand" "=&d")
7055 (mod:SWI48 (match_dup 2) (match_dup 3)))
7056 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7057 (clobber (reg:CC FLAGS_REG))]
7061 [(parallel [(set (match_dup 1)
7062 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7063 (clobber (reg:CC FLAGS_REG))])
7064 (parallel [(set (match_dup 0)
7065 (div:SWI48 (match_dup 2) (match_dup 3)))
7067 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (clobber (reg:CC FLAGS_REG))])]
7071 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7073 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7074 operands[4] = operands[2];
7077 /* Avoid use of cltd in favor of a mov+shift. */
7078 emit_move_insn (operands[1], operands[2]);
7079 operands[4] = operands[1];
7082 [(set_attr "type" "multi")
7083 (set_attr "mode" "<MODE>")])
7085 (define_insn_and_split "*divmod<mode>4"
7086 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7087 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7088 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7089 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7090 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7091 (clobber (reg:CC FLAGS_REG))]
7095 [(parallel [(set (match_dup 1)
7096 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7097 (clobber (reg:CC FLAGS_REG))])
7098 (parallel [(set (match_dup 0)
7099 (div:SWIM248 (match_dup 2) (match_dup 3)))
7101 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7103 (clobber (reg:CC FLAGS_REG))])]
7105 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7107 if (<MODE>mode != HImode
7108 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7109 operands[4] = operands[2];
7112 /* Avoid use of cltd in favor of a mov+shift. */
7113 emit_move_insn (operands[1], operands[2]);
7114 operands[4] = operands[1];
7117 [(set_attr "type" "multi")
7118 (set_attr "mode" "<MODE>")])
7120 (define_insn "*divmod<mode>4_noext"
7121 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7122 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7123 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7124 (set (match_operand:SWIM248 1 "register_operand" "=d")
7125 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7126 (use (match_operand:SWIM248 4 "register_operand" "1"))
7127 (clobber (reg:CC FLAGS_REG))]
7129 "idiv{<imodesuffix>}\t%3"
7130 [(set_attr "type" "idiv")
7131 (set_attr "mode" "<MODE>")])
7133 (define_expand "divmodqi4"
7134 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7136 (match_operand:QI 1 "register_operand" "")
7137 (match_operand:QI 2 "nonimmediate_operand" "")))
7138 (set (match_operand:QI 3 "register_operand" "")
7139 (mod:QI (match_dup 1) (match_dup 2)))
7140 (clobber (reg:CC FLAGS_REG))])]
7141 "TARGET_QIMODE_MATH"
7146 tmp0 = gen_reg_rtx (HImode);
7147 tmp1 = gen_reg_rtx (HImode);
7149 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7151 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7152 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7154 /* Extract remainder from AH. */
7155 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7156 insn = emit_move_insn (operands[3], tmp1);
7158 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7159 set_unique_reg_note (insn, REG_EQUAL, mod);
7161 /* Extract quotient from AL. */
7162 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7164 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7165 set_unique_reg_note (insn, REG_EQUAL, div);
7170 ;; Divide AX by r/m8, with result stored in
7173 ;; Change div/mod to HImode and extend the second argument to HImode
7174 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7175 ;; combine may fail.
7176 (define_insn "divmodhiqi3"
7177 [(set (match_operand:HI 0 "register_operand" "=a")
7182 (mod:HI (match_operand:HI 1 "register_operand" "0")
7184 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7188 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7189 (clobber (reg:CC FLAGS_REG))]
7190 "TARGET_QIMODE_MATH"
7192 [(set_attr "type" "idiv")
7193 (set_attr "mode" "QI")])
7195 (define_expand "udivmod<mode>4"
7196 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7198 (match_operand:SWIM248 1 "register_operand" "")
7199 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7200 (set (match_operand:SWIM248 3 "register_operand" "")
7201 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7202 (clobber (reg:CC FLAGS_REG))])])
7204 ;; Split with 8bit unsigned divide:
7205 ;; if (dividend an divisor are in [0-255])
7206 ;; use 8bit unsigned integer divide
7208 ;; use original integer divide
7210 [(set (match_operand:SWI48 0 "register_operand" "")
7211 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7212 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7213 (set (match_operand:SWI48 1 "register_operand" "")
7214 (umod:SWI48 (match_dup 2) (match_dup 3)))
7215 (clobber (reg:CC FLAGS_REG))]
7216 "TARGET_USE_8BIT_IDIV
7217 && TARGET_QIMODE_MATH
7218 && can_create_pseudo_p ()
7219 && !optimize_insn_for_size_p ()"
7221 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7223 (define_insn_and_split "udivmod<mode>4_1"
7224 [(set (match_operand:SWI48 0 "register_operand" "=a")
7225 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7226 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWI48 1 "register_operand" "=&d")
7228 (umod:SWI48 (match_dup 2) (match_dup 3)))
7229 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7230 (clobber (reg:CC FLAGS_REG))]
7234 [(set (match_dup 1) (const_int 0))
7235 (parallel [(set (match_dup 0)
7236 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7238 (umod:SWI48 (match_dup 2) (match_dup 3)))
7240 (clobber (reg:CC FLAGS_REG))])]
7242 [(set_attr "type" "multi")
7243 (set_attr "mode" "<MODE>")])
7245 (define_insn_and_split "*udivmod<mode>4"
7246 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7247 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7248 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7249 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7250 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7251 (clobber (reg:CC FLAGS_REG))]
7255 [(set (match_dup 1) (const_int 0))
7256 (parallel [(set (match_dup 0)
7257 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7259 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7261 (clobber (reg:CC FLAGS_REG))])]
7263 [(set_attr "type" "multi")
7264 (set_attr "mode" "<MODE>")])
7266 (define_insn "*udivmod<mode>4_noext"
7267 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7268 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7269 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7270 (set (match_operand:SWIM248 1 "register_operand" "=d")
7271 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7272 (use (match_operand:SWIM248 4 "register_operand" "1"))
7273 (clobber (reg:CC FLAGS_REG))]
7275 "div{<imodesuffix>}\t%3"
7276 [(set_attr "type" "idiv")
7277 (set_attr "mode" "<MODE>")])
7279 (define_expand "udivmodqi4"
7280 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7282 (match_operand:QI 1 "register_operand" "")
7283 (match_operand:QI 2 "nonimmediate_operand" "")))
7284 (set (match_operand:QI 3 "register_operand" "")
7285 (umod:QI (match_dup 1) (match_dup 2)))
7286 (clobber (reg:CC FLAGS_REG))])]
7287 "TARGET_QIMODE_MATH"
7292 tmp0 = gen_reg_rtx (HImode);
7293 tmp1 = gen_reg_rtx (HImode);
7295 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7297 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7298 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7300 /* Extract remainder from AH. */
7301 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7302 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7303 insn = emit_move_insn (operands[3], tmp1);
7305 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7306 set_unique_reg_note (insn, REG_EQUAL, mod);
7308 /* Extract quotient from AL. */
7309 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7311 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7312 set_unique_reg_note (insn, REG_EQUAL, div);
7317 (define_insn "udivmodhiqi3"
7318 [(set (match_operand:HI 0 "register_operand" "=a")
7323 (mod:HI (match_operand:HI 1 "register_operand" "0")
7325 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7329 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7330 (clobber (reg:CC FLAGS_REG))]
7331 "TARGET_QIMODE_MATH"
7333 [(set_attr "type" "idiv")
7334 (set_attr "mode" "QI")])
7336 ;; We cannot use div/idiv for double division, because it causes
7337 ;; "division by zero" on the overflow and that's not what we expect
7338 ;; from truncate. Because true (non truncating) double division is
7339 ;; never generated, we can't create this insn anyway.
7342 ; [(set (match_operand:SI 0 "register_operand" "=a")
7344 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7346 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7347 ; (set (match_operand:SI 3 "register_operand" "=d")
7349 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7350 ; (clobber (reg:CC FLAGS_REG))]
7352 ; "div{l}\t{%2, %0|%0, %2}"
7353 ; [(set_attr "type" "idiv")])
7355 ;;- Logical AND instructions
7357 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7358 ;; Note that this excludes ah.
7360 (define_expand "testsi_ccno_1"
7361 [(set (reg:CCNO FLAGS_REG)
7363 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7364 (match_operand:SI 1 "nonmemory_operand" ""))
7367 (define_expand "testqi_ccz_1"
7368 [(set (reg:CCZ FLAGS_REG)
7369 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7370 (match_operand:QI 1 "nonmemory_operand" ""))
7373 (define_expand "testdi_ccno_1"
7374 [(set (reg:CCNO FLAGS_REG)
7376 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7377 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7379 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7381 (define_insn "*testdi_1"
7382 [(set (reg FLAGS_REG)
7385 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7386 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7388 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7389 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7391 test{l}\t{%k1, %k0|%k0, %k1}
7392 test{l}\t{%k1, %k0|%k0, %k1}
7393 test{q}\t{%1, %0|%0, %1}
7394 test{q}\t{%1, %0|%0, %1}
7395 test{q}\t{%1, %0|%0, %1}"
7396 [(set_attr "type" "test")
7397 (set_attr "modrm" "0,1,0,1,1")
7398 (set_attr "mode" "SI,SI,DI,DI,DI")])
7400 (define_insn "*testqi_1_maybe_si"
7401 [(set (reg FLAGS_REG)
7404 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7405 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7407 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7408 && ix86_match_ccmode (insn,
7409 CONST_INT_P (operands[1])
7410 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7412 if (which_alternative == 3)
7414 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7415 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7416 return "test{l}\t{%1, %k0|%k0, %1}";
7418 return "test{b}\t{%1, %0|%0, %1}";
7420 [(set_attr "type" "test")
7421 (set_attr "modrm" "0,1,1,1")
7422 (set_attr "mode" "QI,QI,QI,SI")
7423 (set_attr "pent_pair" "uv,np,uv,np")])
7425 (define_insn "*test<mode>_1"
7426 [(set (reg FLAGS_REG)
7429 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7430 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7432 "ix86_match_ccmode (insn, CCNOmode)
7433 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7434 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7435 [(set_attr "type" "test")
7436 (set_attr "modrm" "0,1,1")
7437 (set_attr "mode" "<MODE>")
7438 (set_attr "pent_pair" "uv,np,uv")])
7440 (define_expand "testqi_ext_ccno_0"
7441 [(set (reg:CCNO FLAGS_REG)
7445 (match_operand 0 "ext_register_operand" "")
7448 (match_operand 1 "const_int_operand" ""))
7451 (define_insn "*testqi_ext_0"
7452 [(set (reg FLAGS_REG)
7456 (match_operand 0 "ext_register_operand" "Q")
7459 (match_operand 1 "const_int_operand" "n"))
7461 "ix86_match_ccmode (insn, CCNOmode)"
7462 "test{b}\t{%1, %h0|%h0, %1}"
7463 [(set_attr "type" "test")
7464 (set_attr "mode" "QI")
7465 (set_attr "length_immediate" "1")
7466 (set_attr "modrm" "1")
7467 (set_attr "pent_pair" "np")])
7469 (define_insn "*testqi_ext_1_rex64"
7470 [(set (reg FLAGS_REG)
7474 (match_operand 0 "ext_register_operand" "Q")
7478 (match_operand:QI 1 "register_operand" "Q")))
7480 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7481 "test{b}\t{%1, %h0|%h0, %1}"
7482 [(set_attr "type" "test")
7483 (set_attr "mode" "QI")])
7485 (define_insn "*testqi_ext_1"
7486 [(set (reg FLAGS_REG)
7490 (match_operand 0 "ext_register_operand" "Q")
7494 (match_operand:QI 1 "general_operand" "Qm")))
7496 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7497 "test{b}\t{%1, %h0|%h0, %1}"
7498 [(set_attr "type" "test")
7499 (set_attr "mode" "QI")])
7501 (define_insn "*testqi_ext_2"
7502 [(set (reg FLAGS_REG)
7506 (match_operand 0 "ext_register_operand" "Q")
7510 (match_operand 1 "ext_register_operand" "Q")
7514 "ix86_match_ccmode (insn, CCNOmode)"
7515 "test{b}\t{%h1, %h0|%h0, %h1}"
7516 [(set_attr "type" "test")
7517 (set_attr "mode" "QI")])
7519 (define_insn "*testqi_ext_3_rex64"
7520 [(set (reg FLAGS_REG)
7521 (compare (zero_extract:DI
7522 (match_operand 0 "nonimmediate_operand" "rm")
7523 (match_operand:DI 1 "const_int_operand" "")
7524 (match_operand:DI 2 "const_int_operand" ""))
7527 && ix86_match_ccmode (insn, CCNOmode)
7528 && INTVAL (operands[1]) > 0
7529 && INTVAL (operands[2]) >= 0
7530 /* Ensure that resulting mask is zero or sign extended operand. */
7531 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7532 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7533 && INTVAL (operands[1]) > 32))
7534 && (GET_MODE (operands[0]) == SImode
7535 || GET_MODE (operands[0]) == DImode
7536 || GET_MODE (operands[0]) == HImode
7537 || GET_MODE (operands[0]) == QImode)"
7540 ;; Combine likes to form bit extractions for some tests. Humor it.
7541 (define_insn "*testqi_ext_3"
7542 [(set (reg FLAGS_REG)
7543 (compare (zero_extract:SI
7544 (match_operand 0 "nonimmediate_operand" "rm")
7545 (match_operand:SI 1 "const_int_operand" "")
7546 (match_operand:SI 2 "const_int_operand" ""))
7548 "ix86_match_ccmode (insn, CCNOmode)
7549 && INTVAL (operands[1]) > 0
7550 && INTVAL (operands[2]) >= 0
7551 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7552 && (GET_MODE (operands[0]) == SImode
7553 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7554 || GET_MODE (operands[0]) == HImode
7555 || GET_MODE (operands[0]) == QImode)"
7559 [(set (match_operand 0 "flags_reg_operand" "")
7560 (match_operator 1 "compare_operator"
7562 (match_operand 2 "nonimmediate_operand" "")
7563 (match_operand 3 "const_int_operand" "")
7564 (match_operand 4 "const_int_operand" ""))
7566 "ix86_match_ccmode (insn, CCNOmode)"
7567 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7569 rtx val = operands[2];
7570 HOST_WIDE_INT len = INTVAL (operands[3]);
7571 HOST_WIDE_INT pos = INTVAL (operands[4]);
7573 enum machine_mode mode, submode;
7575 mode = GET_MODE (val);
7578 /* ??? Combine likes to put non-volatile mem extractions in QImode
7579 no matter the size of the test. So find a mode that works. */
7580 if (! MEM_VOLATILE_P (val))
7582 mode = smallest_mode_for_size (pos + len, MODE_INT);
7583 val = adjust_address (val, mode, 0);
7586 else if (GET_CODE (val) == SUBREG
7587 && (submode = GET_MODE (SUBREG_REG (val)),
7588 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7589 && pos + len <= GET_MODE_BITSIZE (submode)
7590 && GET_MODE_CLASS (submode) == MODE_INT)
7592 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7594 val = SUBREG_REG (val);
7596 else if (mode == HImode && pos + len <= 8)
7598 /* Small HImode tests can be converted to QImode. */
7600 val = gen_lowpart (QImode, val);
7603 if (len == HOST_BITS_PER_WIDE_INT)
7606 mask = ((HOST_WIDE_INT)1 << len) - 1;
7609 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7612 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7613 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7614 ;; this is relatively important trick.
7615 ;; Do the conversion only post-reload to avoid limiting of the register class
7618 [(set (match_operand 0 "flags_reg_operand" "")
7619 (match_operator 1 "compare_operator"
7620 [(and (match_operand 2 "register_operand" "")
7621 (match_operand 3 "const_int_operand" ""))
7624 && QI_REG_P (operands[2])
7625 && GET_MODE (operands[2]) != QImode
7626 && ((ix86_match_ccmode (insn, CCZmode)
7627 && !(INTVAL (operands[3]) & ~(255 << 8)))
7628 || (ix86_match_ccmode (insn, CCNOmode)
7629 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7632 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7635 "operands[2] = gen_lowpart (SImode, operands[2]);
7636 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7639 [(set (match_operand 0 "flags_reg_operand" "")
7640 (match_operator 1 "compare_operator"
7641 [(and (match_operand 2 "nonimmediate_operand" "")
7642 (match_operand 3 "const_int_operand" ""))
7645 && GET_MODE (operands[2]) != QImode
7646 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7647 && ((ix86_match_ccmode (insn, CCZmode)
7648 && !(INTVAL (operands[3]) & ~255))
7649 || (ix86_match_ccmode (insn, CCNOmode)
7650 && !(INTVAL (operands[3]) & ~127)))"
7652 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7654 "operands[2] = gen_lowpart (QImode, operands[2]);
7655 operands[3] = gen_lowpart (QImode, operands[3]);")
7657 ;; %%% This used to optimize known byte-wide and operations to memory,
7658 ;; and sometimes to QImode registers. If this is considered useful,
7659 ;; it should be done with splitters.
7661 (define_expand "and<mode>3"
7662 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7663 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7664 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7666 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7668 (define_insn "*anddi_1"
7669 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7671 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7672 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7673 (clobber (reg:CC FLAGS_REG))]
7674 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7676 switch (get_attr_type (insn))
7680 enum machine_mode mode;
7682 gcc_assert (CONST_INT_P (operands[2]));
7683 if (INTVAL (operands[2]) == 0xff)
7687 gcc_assert (INTVAL (operands[2]) == 0xffff);
7691 operands[1] = gen_lowpart (mode, operands[1]);
7693 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7695 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7700 if (get_attr_mode (insn) == MODE_SI)
7701 return "and{l}\t{%k2, %k0|%k0, %k2}";
7703 return "and{q}\t{%2, %0|%0, %2}";
7706 [(set_attr "type" "alu,alu,alu,imovx")
7707 (set_attr "length_immediate" "*,*,*,0")
7708 (set (attr "prefix_rex")
7710 (and (eq_attr "type" "imovx")
7711 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7712 (match_operand 1 "ext_QIreg_operand" "")))
7714 (const_string "*")))
7715 (set_attr "mode" "SI,DI,DI,SI")])
7717 (define_insn "*andsi_1"
7718 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7719 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7720 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7721 (clobber (reg:CC FLAGS_REG))]
7722 "ix86_binary_operator_ok (AND, SImode, operands)"
7724 switch (get_attr_type (insn))
7728 enum machine_mode mode;
7730 gcc_assert (CONST_INT_P (operands[2]));
7731 if (INTVAL (operands[2]) == 0xff)
7735 gcc_assert (INTVAL (operands[2]) == 0xffff);
7739 operands[1] = gen_lowpart (mode, operands[1]);
7741 return "movz{bl|x}\t{%1, %0|%0, %1}";
7743 return "movz{wl|x}\t{%1, %0|%0, %1}";
7747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748 return "and{l}\t{%2, %0|%0, %2}";
7751 [(set_attr "type" "alu,alu,imovx")
7752 (set (attr "prefix_rex")
7754 (and (eq_attr "type" "imovx")
7755 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7756 (match_operand 1 "ext_QIreg_operand" "")))
7758 (const_string "*")))
7759 (set_attr "length_immediate" "*,*,0")
7760 (set_attr "mode" "SI")])
7762 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7763 (define_insn "*andsi_1_zext"
7764 [(set (match_operand:DI 0 "register_operand" "=r")
7766 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7767 (match_operand:SI 2 "general_operand" "g"))))
7768 (clobber (reg:CC FLAGS_REG))]
7769 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7770 "and{l}\t{%2, %k0|%k0, %2}"
7771 [(set_attr "type" "alu")
7772 (set_attr "mode" "SI")])
7774 (define_insn "*andhi_1"
7775 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7776 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7777 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "ix86_binary_operator_ok (AND, HImode, operands)"
7781 switch (get_attr_type (insn))
7784 gcc_assert (CONST_INT_P (operands[2]));
7785 gcc_assert (INTVAL (operands[2]) == 0xff);
7786 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7791 return "and{w}\t{%2, %0|%0, %2}";
7794 [(set_attr "type" "alu,alu,imovx")
7795 (set_attr "length_immediate" "*,*,0")
7796 (set (attr "prefix_rex")
7798 (and (eq_attr "type" "imovx")
7799 (match_operand 1 "ext_QIreg_operand" ""))
7801 (const_string "*")))
7802 (set_attr "mode" "HI,HI,SI")])
7804 ;; %%% Potential partial reg stall on alternative 2. What to do?
7805 (define_insn "*andqi_1"
7806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7807 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7808 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "ix86_binary_operator_ok (AND, QImode, operands)"
7812 and{b}\t{%2, %0|%0, %2}
7813 and{b}\t{%2, %0|%0, %2}
7814 and{l}\t{%k2, %k0|%k0, %k2}"
7815 [(set_attr "type" "alu")
7816 (set_attr "mode" "QI,QI,SI")])
7818 (define_insn "*andqi_1_slp"
7819 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7820 (and:QI (match_dup 0)
7821 (match_operand:QI 1 "general_operand" "qn,qmn")))
7822 (clobber (reg:CC FLAGS_REG))]
7823 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7824 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7825 "and{b}\t{%1, %0|%0, %1}"
7826 [(set_attr "type" "alu1")
7827 (set_attr "mode" "QI")])
7830 [(set (match_operand 0 "register_operand" "")
7832 (const_int -65536)))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7835 || optimize_function_for_size_p (cfun)"
7836 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7837 "operands[1] = gen_lowpart (HImode, operands[0]);")
7840 [(set (match_operand 0 "ext_register_operand" "")
7843 (clobber (reg:CC FLAGS_REG))]
7844 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7845 && reload_completed"
7846 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7847 "operands[1] = gen_lowpart (QImode, operands[0]);")
7850 [(set (match_operand 0 "ext_register_operand" "")
7852 (const_int -65281)))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855 && reload_completed"
7856 [(parallel [(set (zero_extract:SI (match_dup 0)
7860 (zero_extract:SI (match_dup 0)
7863 (zero_extract:SI (match_dup 0)
7866 (clobber (reg:CC FLAGS_REG))])]
7867 "operands[0] = gen_lowpart (SImode, operands[0]);")
7869 (define_insn "*anddi_2"
7870 [(set (reg FLAGS_REG)
7873 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7874 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7876 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7877 (and:DI (match_dup 1) (match_dup 2)))]
7878 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7879 && ix86_binary_operator_ok (AND, DImode, operands)"
7881 and{l}\t{%k2, %k0|%k0, %k2}
7882 and{q}\t{%2, %0|%0, %2}
7883 and{q}\t{%2, %0|%0, %2}"
7884 [(set_attr "type" "alu")
7885 (set_attr "mode" "SI,DI,DI")])
7887 (define_insn "*andqi_2_maybe_si"
7888 [(set (reg FLAGS_REG)
7890 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7891 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7893 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7894 (and:QI (match_dup 1) (match_dup 2)))]
7895 "ix86_binary_operator_ok (AND, QImode, operands)
7896 && ix86_match_ccmode (insn,
7897 CONST_INT_P (operands[2])
7898 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7900 if (which_alternative == 2)
7902 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7903 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7904 return "and{l}\t{%2, %k0|%k0, %2}";
7906 return "and{b}\t{%2, %0|%0, %2}";
7908 [(set_attr "type" "alu")
7909 (set_attr "mode" "QI,QI,SI")])
7911 (define_insn "*and<mode>_2"
7912 [(set (reg FLAGS_REG)
7913 (compare (and:SWI124
7914 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7915 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7917 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7918 (and:SWI124 (match_dup 1) (match_dup 2)))]
7919 "ix86_match_ccmode (insn, CCNOmode)
7920 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7921 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7922 [(set_attr "type" "alu")
7923 (set_attr "mode" "<MODE>")])
7925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7926 (define_insn "*andsi_2_zext"
7927 [(set (reg FLAGS_REG)
7929 (match_operand:SI 1 "nonimmediate_operand" "%0")
7930 (match_operand:SI 2 "general_operand" "g"))
7932 (set (match_operand:DI 0 "register_operand" "=r")
7933 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7934 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7935 && ix86_binary_operator_ok (AND, SImode, operands)"
7936 "and{l}\t{%2, %k0|%k0, %2}"
7937 [(set_attr "type" "alu")
7938 (set_attr "mode" "SI")])
7940 (define_insn "*andqi_2_slp"
7941 [(set (reg FLAGS_REG)
7943 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7944 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7946 (set (strict_low_part (match_dup 0))
7947 (and:QI (match_dup 0) (match_dup 1)))]
7948 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7949 && ix86_match_ccmode (insn, CCNOmode)
7950 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7951 "and{b}\t{%1, %0|%0, %1}"
7952 [(set_attr "type" "alu1")
7953 (set_attr "mode" "QI")])
7955 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7956 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7957 ;; for a QImode operand, which of course failed.
7958 (define_insn "andqi_ext_0"
7959 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7964 (match_operand 1 "ext_register_operand" "0")
7967 (match_operand 2 "const_int_operand" "n")))
7968 (clobber (reg:CC FLAGS_REG))]
7970 "and{b}\t{%2, %h0|%h0, %2}"
7971 [(set_attr "type" "alu")
7972 (set_attr "length_immediate" "1")
7973 (set_attr "modrm" "1")
7974 (set_attr "mode" "QI")])
7976 ;; Generated by peephole translating test to and. This shows up
7977 ;; often in fp comparisons.
7978 (define_insn "*andqi_ext_0_cc"
7979 [(set (reg FLAGS_REG)
7983 (match_operand 1 "ext_register_operand" "0")
7986 (match_operand 2 "const_int_operand" "n"))
7988 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7997 "ix86_match_ccmode (insn, CCNOmode)"
7998 "and{b}\t{%2, %h0|%h0, %2}"
7999 [(set_attr "type" "alu")
8000 (set_attr "length_immediate" "1")
8001 (set_attr "modrm" "1")
8002 (set_attr "mode" "QI")])
8004 (define_insn "*andqi_ext_1_rex64"
8005 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8010 (match_operand 1 "ext_register_operand" "0")
8014 (match_operand 2 "ext_register_operand" "Q"))))
8015 (clobber (reg:CC FLAGS_REG))]
8017 "and{b}\t{%2, %h0|%h0, %2}"
8018 [(set_attr "type" "alu")
8019 (set_attr "length_immediate" "0")
8020 (set_attr "mode" "QI")])
8022 (define_insn "*andqi_ext_1"
8023 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8028 (match_operand 1 "ext_register_operand" "0")
8032 (match_operand:QI 2 "general_operand" "Qm"))))
8033 (clobber (reg:CC FLAGS_REG))]
8035 "and{b}\t{%2, %h0|%h0, %2}"
8036 [(set_attr "type" "alu")
8037 (set_attr "length_immediate" "0")
8038 (set_attr "mode" "QI")])
8040 (define_insn "*andqi_ext_2"
8041 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8046 (match_operand 1 "ext_register_operand" "%0")
8050 (match_operand 2 "ext_register_operand" "Q")
8053 (clobber (reg:CC FLAGS_REG))]
8055 "and{b}\t{%h2, %h0|%h0, %h2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "0")
8058 (set_attr "mode" "QI")])
8060 ;; Convert wide AND instructions with immediate operand to shorter QImode
8061 ;; equivalents when possible.
8062 ;; Don't do the splitting with memory operands, since it introduces risk
8063 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8064 ;; for size, but that can (should?) be handled by generic code instead.
8066 [(set (match_operand 0 "register_operand" "")
8067 (and (match_operand 1 "register_operand" "")
8068 (match_operand 2 "const_int_operand" "")))
8069 (clobber (reg:CC FLAGS_REG))]
8071 && QI_REG_P (operands[0])
8072 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8073 && !(~INTVAL (operands[2]) & ~(255 << 8))
8074 && GET_MODE (operands[0]) != QImode"
8075 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8076 (and:SI (zero_extract:SI (match_dup 1)
8077 (const_int 8) (const_int 8))
8079 (clobber (reg:CC FLAGS_REG))])]
8080 "operands[0] = gen_lowpart (SImode, operands[0]);
8081 operands[1] = gen_lowpart (SImode, operands[1]);
8082 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8084 ;; Since AND can be encoded with sign extended immediate, this is only
8085 ;; profitable when 7th bit is not set.
8087 [(set (match_operand 0 "register_operand" "")
8088 (and (match_operand 1 "general_operand" "")
8089 (match_operand 2 "const_int_operand" "")))
8090 (clobber (reg:CC FLAGS_REG))]
8092 && ANY_QI_REG_P (operands[0])
8093 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8094 && !(~INTVAL (operands[2]) & ~255)
8095 && !(INTVAL (operands[2]) & 128)
8096 && GET_MODE (operands[0]) != QImode"
8097 [(parallel [(set (strict_low_part (match_dup 0))
8098 (and:QI (match_dup 1)
8100 (clobber (reg:CC FLAGS_REG))])]
8101 "operands[0] = gen_lowpart (QImode, operands[0]);
8102 operands[1] = gen_lowpart (QImode, operands[1]);
8103 operands[2] = gen_lowpart (QImode, operands[2]);")
8105 ;; Logical inclusive and exclusive OR instructions
8107 ;; %%% This used to optimize known byte-wide and operations to memory.
8108 ;; If this is considered useful, it should be done with splitters.
8110 (define_expand "<code><mode>3"
8111 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8112 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8113 (match_operand:SWIM 2 "<general_operand>" "")))]
8115 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8117 (define_insn "*<code><mode>_1"
8118 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8120 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8121 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8124 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "mode" "<MODE>")])
8128 ;; %%% Potential partial reg stall on alternative 2. What to do?
8129 (define_insn "*<code>qi_1"
8130 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8131 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8132 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8133 (clobber (reg:CC FLAGS_REG))]
8134 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8136 <logic>{b}\t{%2, %0|%0, %2}
8137 <logic>{b}\t{%2, %0|%0, %2}
8138 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8139 [(set_attr "type" "alu")
8140 (set_attr "mode" "QI,QI,SI")])
8142 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8143 (define_insn "*<code>si_1_zext"
8144 [(set (match_operand:DI 0 "register_operand" "=r")
8146 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8147 (match_operand:SI 2 "general_operand" "g"))))
8148 (clobber (reg:CC FLAGS_REG))]
8149 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8150 "<logic>{l}\t{%2, %k0|%k0, %2}"
8151 [(set_attr "type" "alu")
8152 (set_attr "mode" "SI")])
8154 (define_insn "*<code>si_1_zext_imm"
8155 [(set (match_operand:DI 0 "register_operand" "=r")
8157 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8158 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8161 "<logic>{l}\t{%2, %k0|%k0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "mode" "SI")])
8165 (define_insn "*<code>qi_1_slp"
8166 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8167 (any_or:QI (match_dup 0)
8168 (match_operand:QI 1 "general_operand" "qmn,qn")))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8171 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8172 "<logic>{b}\t{%1, %0|%0, %1}"
8173 [(set_attr "type" "alu1")
8174 (set_attr "mode" "QI")])
8176 (define_insn "*<code><mode>_2"
8177 [(set (reg FLAGS_REG)
8178 (compare (any_or:SWI
8179 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8180 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8182 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8183 (any_or:SWI (match_dup 1) (match_dup 2)))]
8184 "ix86_match_ccmode (insn, CCNOmode)
8185 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187 [(set_attr "type" "alu")
8188 (set_attr "mode" "<MODE>")])
8190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191 ;; ??? Special case for immediate operand is missing - it is tricky.
8192 (define_insn "*<code>si_2_zext"
8193 [(set (reg FLAGS_REG)
8194 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195 (match_operand:SI 2 "general_operand" "g"))
8197 (set (match_operand:DI 0 "register_operand" "=r")
8198 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8199 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8201 "<logic>{l}\t{%2, %k0|%k0, %2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "SI")])
8205 (define_insn "*<code>si_2_zext_imm"
8206 [(set (reg FLAGS_REG)
8208 (match_operand:SI 1 "nonimmediate_operand" "%0")
8209 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8211 (set (match_operand:DI 0 "register_operand" "=r")
8212 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8213 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8214 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8215 "<logic>{l}\t{%2, %k0|%k0, %2}"
8216 [(set_attr "type" "alu")
8217 (set_attr "mode" "SI")])
8219 (define_insn "*<code>qi_2_slp"
8220 [(set (reg FLAGS_REG)
8221 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8222 (match_operand:QI 1 "general_operand" "qmn,qn"))
8224 (set (strict_low_part (match_dup 0))
8225 (any_or:QI (match_dup 0) (match_dup 1)))]
8226 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227 && ix86_match_ccmode (insn, CCNOmode)
8228 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8229 "<logic>{b}\t{%1, %0|%0, %1}"
8230 [(set_attr "type" "alu1")
8231 (set_attr "mode" "QI")])
8233 (define_insn "*<code><mode>_3"
8234 [(set (reg FLAGS_REG)
8235 (compare (any_or:SWI
8236 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8237 (match_operand:SWI 2 "<general_operand>" "<g>"))
8239 (clobber (match_scratch:SWI 0 "=<r>"))]
8240 "ix86_match_ccmode (insn, CCNOmode)
8241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8242 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "<MODE>")])
8246 (define_insn "*<code>qi_ext_0"
8247 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252 (match_operand 1 "ext_register_operand" "0")
8255 (match_operand 2 "const_int_operand" "n")))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8258 "<logic>{b}\t{%2, %h0|%h0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "length_immediate" "1")
8261 (set_attr "modrm" "1")
8262 (set_attr "mode" "QI")])
8264 (define_insn "*<code>qi_ext_1_rex64"
8265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270 (match_operand 1 "ext_register_operand" "0")
8274 (match_operand 2 "ext_register_operand" "Q"))))
8275 (clobber (reg:CC FLAGS_REG))]
8277 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8278 "<logic>{b}\t{%2, %h0|%h0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "length_immediate" "0")
8281 (set_attr "mode" "QI")])
8283 (define_insn "*<code>qi_ext_1"
8284 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8289 (match_operand 1 "ext_register_operand" "0")
8293 (match_operand:QI 2 "general_operand" "Qm"))))
8294 (clobber (reg:CC FLAGS_REG))]
8296 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8297 "<logic>{b}\t{%2, %h0|%h0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "length_immediate" "0")
8300 (set_attr "mode" "QI")])
8302 (define_insn "*<code>qi_ext_2"
8303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8307 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8310 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8313 (clobber (reg:CC FLAGS_REG))]
8314 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8315 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "length_immediate" "0")
8318 (set_attr "mode" "QI")])
8321 [(set (match_operand 0 "register_operand" "")
8322 (any_or (match_operand 1 "register_operand" "")
8323 (match_operand 2 "const_int_operand" "")))
8324 (clobber (reg:CC FLAGS_REG))]
8326 && QI_REG_P (operands[0])
8327 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8328 && !(INTVAL (operands[2]) & ~(255 << 8))
8329 && GET_MODE (operands[0]) != QImode"
8330 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8331 (any_or:SI (zero_extract:SI (match_dup 1)
8332 (const_int 8) (const_int 8))
8334 (clobber (reg:CC FLAGS_REG))])]
8335 "operands[0] = gen_lowpart (SImode, operands[0]);
8336 operands[1] = gen_lowpart (SImode, operands[1]);
8337 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8339 ;; Since OR can be encoded with sign extended immediate, this is only
8340 ;; profitable when 7th bit is set.
8342 [(set (match_operand 0 "register_operand" "")
8343 (any_or (match_operand 1 "general_operand" "")
8344 (match_operand 2 "const_int_operand" "")))
8345 (clobber (reg:CC FLAGS_REG))]
8347 && ANY_QI_REG_P (operands[0])
8348 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8349 && !(INTVAL (operands[2]) & ~255)
8350 && (INTVAL (operands[2]) & 128)
8351 && GET_MODE (operands[0]) != QImode"
8352 [(parallel [(set (strict_low_part (match_dup 0))
8353 (any_or:QI (match_dup 1)
8355 (clobber (reg:CC FLAGS_REG))])]
8356 "operands[0] = gen_lowpart (QImode, operands[0]);
8357 operands[1] = gen_lowpart (QImode, operands[1]);
8358 operands[2] = gen_lowpart (QImode, operands[2]);")
8360 (define_expand "xorqi_cc_ext_1"
8362 (set (reg:CCNO FLAGS_REG)
8366 (match_operand 1 "ext_register_operand" "")
8369 (match_operand:QI 2 "general_operand" ""))
8371 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8381 (define_insn "*xorqi_cc_ext_1_rex64"
8382 [(set (reg FLAGS_REG)
8386 (match_operand 1 "ext_register_operand" "0")
8389 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8391 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8401 "xor{b}\t{%2, %h0|%h0, %2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "modrm" "1")
8404 (set_attr "mode" "QI")])
8406 (define_insn "*xorqi_cc_ext_1"
8407 [(set (reg FLAGS_REG)
8411 (match_operand 1 "ext_register_operand" "0")
8414 (match_operand:QI 2 "general_operand" "qmn"))
8416 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8425 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8426 "xor{b}\t{%2, %h0|%h0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "modrm" "1")
8429 (set_attr "mode" "QI")])
8431 ;; Negation instructions
8433 (define_expand "neg<mode>2"
8434 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8435 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8437 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8439 (define_insn_and_split "*neg<dwi>2_doubleword"
8440 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8441 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8447 [(set (reg:CCZ FLAGS_REG)
8448 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8449 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8452 (plus:DWIH (match_dup 3)
8453 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8455 (clobber (reg:CC FLAGS_REG))])
8458 (neg:DWIH (match_dup 2)))
8459 (clobber (reg:CC FLAGS_REG))])]
8460 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8462 (define_insn "*neg<mode>2_1"
8463 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8464 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8465 (clobber (reg:CC FLAGS_REG))]
8466 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8467 "neg{<imodesuffix>}\t%0"
8468 [(set_attr "type" "negnot")
8469 (set_attr "mode" "<MODE>")])
8471 ;; Combine is quite creative about this pattern.
8472 (define_insn "*negsi2_1_zext"
8473 [(set (match_operand:DI 0 "register_operand" "=r")
8475 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8481 [(set_attr "type" "negnot")
8482 (set_attr "mode" "SI")])
8484 ;; The problem with neg is that it does not perform (compare x 0),
8485 ;; it really performs (compare 0 x), which leaves us with the zero
8486 ;; flag being the only useful item.
8488 (define_insn "*neg<mode>2_cmpz"
8489 [(set (reg:CCZ FLAGS_REG)
8491 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8493 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8494 (neg:SWI (match_dup 1)))]
8495 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8496 "neg{<imodesuffix>}\t%0"
8497 [(set_attr "type" "negnot")
8498 (set_attr "mode" "<MODE>")])
8500 (define_insn "*negsi2_cmpz_zext"
8501 [(set (reg:CCZ FLAGS_REG)
8505 (match_operand:DI 1 "register_operand" "0")
8509 (set (match_operand:DI 0 "register_operand" "=r")
8510 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8513 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8515 [(set_attr "type" "negnot")
8516 (set_attr "mode" "SI")])
8518 ;; Changing of sign for FP values is doable using integer unit too.
8520 (define_expand "<code><mode>2"
8521 [(set (match_operand:X87MODEF 0 "register_operand" "")
8522 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8523 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8524 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8526 (define_insn "*absneg<mode>2_mixed"
8527 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8528 (match_operator:MODEF 3 "absneg_operator"
8529 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8530 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8535 (define_insn "*absneg<mode>2_sse"
8536 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8537 (match_operator:MODEF 3 "absneg_operator"
8538 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8539 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8544 (define_insn "*absneg<mode>2_i387"
8545 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8546 (match_operator:X87MODEF 3 "absneg_operator"
8547 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8548 (use (match_operand 2 "" ""))
8549 (clobber (reg:CC FLAGS_REG))]
8550 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8553 (define_expand "<code>tf2"
8554 [(set (match_operand:TF 0 "register_operand" "")
8555 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8557 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8559 (define_insn "*absnegtf2_sse"
8560 [(set (match_operand:TF 0 "register_operand" "=x,x")
8561 (match_operator:TF 3 "absneg_operator"
8562 [(match_operand:TF 1 "register_operand" "0,x")]))
8563 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8564 (clobber (reg:CC FLAGS_REG))]
8568 ;; Splitters for fp abs and neg.
8571 [(set (match_operand 0 "fp_register_operand" "")
8572 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8573 (use (match_operand 2 "" ""))
8574 (clobber (reg:CC FLAGS_REG))]
8576 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8579 [(set (match_operand 0 "register_operand" "")
8580 (match_operator 3 "absneg_operator"
8581 [(match_operand 1 "register_operand" "")]))
8582 (use (match_operand 2 "nonimmediate_operand" ""))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "reload_completed && SSE_REG_P (operands[0])"
8585 [(set (match_dup 0) (match_dup 3))]
8587 enum machine_mode mode = GET_MODE (operands[0]);
8588 enum machine_mode vmode = GET_MODE (operands[2]);
8591 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8592 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8593 if (operands_match_p (operands[0], operands[2]))
8596 operands[1] = operands[2];
8599 if (GET_CODE (operands[3]) == ABS)
8600 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8602 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8607 [(set (match_operand:SF 0 "register_operand" "")
8608 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8609 (use (match_operand:V4SF 2 "" ""))
8610 (clobber (reg:CC FLAGS_REG))]
8612 [(parallel [(set (match_dup 0) (match_dup 1))
8613 (clobber (reg:CC FLAGS_REG))])]
8616 operands[0] = gen_lowpart (SImode, operands[0]);
8617 if (GET_CODE (operands[1]) == ABS)
8619 tmp = gen_int_mode (0x7fffffff, SImode);
8620 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8624 tmp = gen_int_mode (0x80000000, SImode);
8625 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8631 [(set (match_operand:DF 0 "register_operand" "")
8632 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8633 (use (match_operand 2 "" ""))
8634 (clobber (reg:CC FLAGS_REG))]
8636 [(parallel [(set (match_dup 0) (match_dup 1))
8637 (clobber (reg:CC FLAGS_REG))])]
8642 tmp = gen_lowpart (DImode, operands[0]);
8643 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8646 if (GET_CODE (operands[1]) == ABS)
8649 tmp = gen_rtx_NOT (DImode, tmp);
8653 operands[0] = gen_highpart (SImode, operands[0]);
8654 if (GET_CODE (operands[1]) == ABS)
8656 tmp = gen_int_mode (0x7fffffff, SImode);
8657 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8661 tmp = gen_int_mode (0x80000000, SImode);
8662 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8669 [(set (match_operand:XF 0 "register_operand" "")
8670 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8671 (use (match_operand 2 "" ""))
8672 (clobber (reg:CC FLAGS_REG))]
8674 [(parallel [(set (match_dup 0) (match_dup 1))
8675 (clobber (reg:CC FLAGS_REG))])]
8678 operands[0] = gen_rtx_REG (SImode,
8679 true_regnum (operands[0])
8680 + (TARGET_64BIT ? 1 : 2));
8681 if (GET_CODE (operands[1]) == ABS)
8683 tmp = GEN_INT (0x7fff);
8684 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8688 tmp = GEN_INT (0x8000);
8689 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8694 ;; Conditionalize these after reload. If they match before reload, we
8695 ;; lose the clobber and ability to use integer instructions.
8697 (define_insn "*<code><mode>2_1"
8698 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8699 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8701 && (reload_completed
8702 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8703 "f<absneg_mnemonic>"
8704 [(set_attr "type" "fsgn")
8705 (set_attr "mode" "<MODE>")])
8707 (define_insn "*<code>extendsfdf2"
8708 [(set (match_operand:DF 0 "register_operand" "=f")
8709 (absneg:DF (float_extend:DF
8710 (match_operand:SF 1 "register_operand" "0"))))]
8711 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8712 "f<absneg_mnemonic>"
8713 [(set_attr "type" "fsgn")
8714 (set_attr "mode" "DF")])
8716 (define_insn "*<code>extendsfxf2"
8717 [(set (match_operand:XF 0 "register_operand" "=f")
8718 (absneg:XF (float_extend:XF
8719 (match_operand:SF 1 "register_operand" "0"))))]
8721 "f<absneg_mnemonic>"
8722 [(set_attr "type" "fsgn")
8723 (set_attr "mode" "XF")])
8725 (define_insn "*<code>extenddfxf2"
8726 [(set (match_operand:XF 0 "register_operand" "=f")
8727 (absneg:XF (float_extend:XF
8728 (match_operand:DF 1 "register_operand" "0"))))]
8730 "f<absneg_mnemonic>"
8731 [(set_attr "type" "fsgn")
8732 (set_attr "mode" "XF")])
8734 ;; Copysign instructions
8736 (define_mode_iterator CSGNMODE [SF DF TF])
8737 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8739 (define_expand "copysign<mode>3"
8740 [(match_operand:CSGNMODE 0 "register_operand" "")
8741 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8742 (match_operand:CSGNMODE 2 "register_operand" "")]
8743 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8744 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8745 "ix86_expand_copysign (operands); DONE;")
8747 (define_insn_and_split "copysign<mode>3_const"
8748 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8750 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8751 (match_operand:CSGNMODE 2 "register_operand" "0")
8752 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8754 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8755 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8757 "&& reload_completed"
8759 "ix86_split_copysign_const (operands); DONE;")
8761 (define_insn "copysign<mode>3_var"
8762 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8764 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8765 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8766 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8767 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8769 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8770 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8771 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8775 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8777 [(match_operand:CSGNMODE 2 "register_operand" "")
8778 (match_operand:CSGNMODE 3 "register_operand" "")
8779 (match_operand:<CSGNVMODE> 4 "" "")
8780 (match_operand:<CSGNVMODE> 5 "" "")]
8782 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8783 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8784 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8785 && reload_completed"
8787 "ix86_split_copysign_var (operands); DONE;")
8789 ;; One complement instructions
8791 (define_expand "one_cmpl<mode>2"
8792 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8793 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8795 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8797 (define_insn "*one_cmpl<mode>2_1"
8798 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8799 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8800 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8801 "not{<imodesuffix>}\t%0"
8802 [(set_attr "type" "negnot")
8803 (set_attr "mode" "<MODE>")])
8805 ;; %%% Potential partial reg stall on alternative 1. What to do?
8806 (define_insn "*one_cmplqi2_1"
8807 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8808 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8809 "ix86_unary_operator_ok (NOT, QImode, operands)"
8813 [(set_attr "type" "negnot")
8814 (set_attr "mode" "QI,SI")])
8816 ;; ??? Currently never generated - xor is used instead.
8817 (define_insn "*one_cmplsi2_1_zext"
8818 [(set (match_operand:DI 0 "register_operand" "=r")
8820 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8821 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8823 [(set_attr "type" "negnot")
8824 (set_attr "mode" "SI")])
8826 (define_insn "*one_cmpl<mode>2_2"
8827 [(set (reg FLAGS_REG)
8828 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8830 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8831 (not:SWI (match_dup 1)))]
8832 "ix86_match_ccmode (insn, CCNOmode)
8833 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8835 [(set_attr "type" "alu1")
8836 (set_attr "mode" "<MODE>")])
8839 [(set (match_operand 0 "flags_reg_operand" "")
8840 (match_operator 2 "compare_operator"
8841 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8843 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8844 (not:SWI (match_dup 3)))]
8845 "ix86_match_ccmode (insn, CCNOmode)"
8846 [(parallel [(set (match_dup 0)
8847 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8850 (xor:SWI (match_dup 3) (const_int -1)))])])
8852 ;; ??? Currently never generated - xor is used instead.
8853 (define_insn "*one_cmplsi2_2_zext"
8854 [(set (reg FLAGS_REG)
8855 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8857 (set (match_operand:DI 0 "register_operand" "=r")
8858 (zero_extend:DI (not:SI (match_dup 1))))]
8859 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8860 && ix86_unary_operator_ok (NOT, SImode, operands)"
8862 [(set_attr "type" "alu1")
8863 (set_attr "mode" "SI")])
8866 [(set (match_operand 0 "flags_reg_operand" "")
8867 (match_operator 2 "compare_operator"
8868 [(not:SI (match_operand:SI 3 "register_operand" ""))
8870 (set (match_operand:DI 1 "register_operand" "")
8871 (zero_extend:DI (not:SI (match_dup 3))))]
8872 "ix86_match_ccmode (insn, CCNOmode)"
8873 [(parallel [(set (match_dup 0)
8874 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8877 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8879 ;; Shift instructions
8881 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8882 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8883 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8884 ;; from the assembler input.
8886 ;; This instruction shifts the target reg/mem as usual, but instead of
8887 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8888 ;; is a left shift double, bits are taken from the high order bits of
8889 ;; reg, else if the insn is a shift right double, bits are taken from the
8890 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8891 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8893 ;; Since sh[lr]d does not change the `reg' operand, that is done
8894 ;; separately, making all shifts emit pairs of shift double and normal
8895 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8896 ;; support a 63 bit shift, each shift where the count is in a reg expands
8897 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8899 ;; If the shift count is a constant, we need never emit more than one
8900 ;; shift pair, instead using moves and sign extension for counts greater
8903 (define_expand "ashl<mode>3"
8904 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8905 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8906 (match_operand:QI 2 "nonmemory_operand" "")))]
8908 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8910 (define_insn "*ashl<mode>3_doubleword"
8911 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8912 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8913 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8914 (clobber (reg:CC FLAGS_REG))]
8917 [(set_attr "type" "multi")])
8920 [(set (match_operand:DWI 0 "register_operand" "")
8921 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8922 (match_operand:QI 2 "nonmemory_operand" "")))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8926 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8928 ;; By default we don't ask for a scratch register, because when DWImode
8929 ;; values are manipulated, registers are already at a premium. But if
8930 ;; we have one handy, we won't turn it away.
8933 [(match_scratch:DWIH 3 "r")
8934 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8936 (match_operand:<DWI> 1 "nonmemory_operand" "")
8937 (match_operand:QI 2 "nonmemory_operand" "")))
8938 (clobber (reg:CC FLAGS_REG))])
8942 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8944 (define_insn "x86_64_shld"
8945 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8946 (ior:DI (ashift:DI (match_dup 0)
8947 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8948 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8949 (minus:QI (const_int 64) (match_dup 2)))))
8950 (clobber (reg:CC FLAGS_REG))]
8952 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8953 [(set_attr "type" "ishift")
8954 (set_attr "prefix_0f" "1")
8955 (set_attr "mode" "DI")
8956 (set_attr "athlon_decode" "vector")
8957 (set_attr "amdfam10_decode" "vector")
8958 (set_attr "bdver1_decode" "vector")])
8960 (define_insn "x86_shld"
8961 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8962 (ior:SI (ashift:SI (match_dup 0)
8963 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8964 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8965 (minus:QI (const_int 32) (match_dup 2)))))
8966 (clobber (reg:CC FLAGS_REG))]
8968 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8969 [(set_attr "type" "ishift")
8970 (set_attr "prefix_0f" "1")
8971 (set_attr "mode" "SI")
8972 (set_attr "pent_pair" "np")
8973 (set_attr "athlon_decode" "vector")
8974 (set_attr "amdfam10_decode" "vector")
8975 (set_attr "bdver1_decode" "vector")])
8977 (define_expand "x86_shift<mode>_adj_1"
8978 [(set (reg:CCZ FLAGS_REG)
8979 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8982 (set (match_operand:SWI48 0 "register_operand" "")
8983 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8984 (match_operand:SWI48 1 "register_operand" "")
8987 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8988 (match_operand:SWI48 3 "register_operand" "r")
8991 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8993 (define_expand "x86_shift<mode>_adj_2"
8994 [(use (match_operand:SWI48 0 "register_operand" ""))
8995 (use (match_operand:SWI48 1 "register_operand" ""))
8996 (use (match_operand:QI 2 "register_operand" ""))]
8999 rtx label = gen_label_rtx ();
9002 emit_insn (gen_testqi_ccz_1 (operands[2],
9003 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9005 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9006 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9007 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9008 gen_rtx_LABEL_REF (VOIDmode, label),
9010 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9011 JUMP_LABEL (tmp) = label;
9013 emit_move_insn (operands[0], operands[1]);
9014 ix86_expand_clear (operands[1]);
9017 LABEL_NUSES (label) = 1;
9022 ;; Avoid useless masking of count operand.
9023 (define_insn_and_split "*ashl<mode>3_mask"
9024 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9026 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9029 (match_operand:SI 2 "nonimmediate_operand" "c")
9030 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9031 (clobber (reg:CC FLAGS_REG))]
9032 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9033 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9034 == GET_MODE_BITSIZE (<MODE>mode)-1"
9037 [(parallel [(set (match_dup 0)
9038 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9039 (clobber (reg:CC FLAGS_REG))])]
9041 if (can_create_pseudo_p ())
9042 operands [2] = force_reg (SImode, operands[2]);
9044 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9046 [(set_attr "type" "ishift")
9047 (set_attr "mode" "<MODE>")])
9049 (define_insn "*ashl<mode>3_1"
9050 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9051 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9052 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9056 switch (get_attr_type (insn))
9062 gcc_assert (operands[2] == const1_rtx);
9063 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9064 return "add{<imodesuffix>}\t%0, %0";
9067 if (operands[2] == const1_rtx
9068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9069 return "sal{<imodesuffix>}\t%0";
9071 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9075 (cond [(eq_attr "alternative" "1")
9076 (const_string "lea")
9077 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9079 (match_operand 0 "register_operand" ""))
9080 (match_operand 2 "const1_operand" ""))
9081 (const_string "alu")
9083 (const_string "ishift")))
9084 (set (attr "length_immediate")
9086 (ior (eq_attr "type" "alu")
9087 (and (eq_attr "type" "ishift")
9088 (and (match_operand 2 "const1_operand" "")
9089 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9092 (const_string "*")))
9093 (set_attr "mode" "<MODE>")])
9095 (define_insn "*ashlsi3_1_zext"
9096 [(set (match_operand:DI 0 "register_operand" "=r,r")
9098 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9099 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9100 (clobber (reg:CC FLAGS_REG))]
9101 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9103 switch (get_attr_type (insn))
9109 gcc_assert (operands[2] == const1_rtx);
9110 return "add{l}\t%k0, %k0";
9113 if (operands[2] == const1_rtx
9114 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9115 return "sal{l}\t%k0";
9117 return "sal{l}\t{%2, %k0|%k0, %2}";
9121 (cond [(eq_attr "alternative" "1")
9122 (const_string "lea")
9123 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9125 (match_operand 2 "const1_operand" ""))
9126 (const_string "alu")
9128 (const_string "ishift")))
9129 (set (attr "length_immediate")
9131 (ior (eq_attr "type" "alu")
9132 (and (eq_attr "type" "ishift")
9133 (and (match_operand 2 "const1_operand" "")
9134 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9137 (const_string "*")))
9138 (set_attr "mode" "SI")])
9140 (define_insn "*ashlhi3_1"
9141 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9142 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9143 (match_operand:QI 2 "nonmemory_operand" "cI")))
9144 (clobber (reg:CC FLAGS_REG))]
9145 "TARGET_PARTIAL_REG_STALL
9146 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9148 switch (get_attr_type (insn))
9151 gcc_assert (operands[2] == const1_rtx);
9152 return "add{w}\t%0, %0";
9155 if (operands[2] == const1_rtx
9156 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9157 return "sal{w}\t%0";
9159 return "sal{w}\t{%2, %0|%0, %2}";
9163 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9165 (match_operand 0 "register_operand" ""))
9166 (match_operand 2 "const1_operand" ""))
9167 (const_string "alu")
9169 (const_string "ishift")))
9170 (set (attr "length_immediate")
9172 (ior (eq_attr "type" "alu")
9173 (and (eq_attr "type" "ishift")
9174 (and (match_operand 2 "const1_operand" "")
9175 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9178 (const_string "*")))
9179 (set_attr "mode" "HI")])
9181 (define_insn "*ashlhi3_1_lea"
9182 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9183 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9184 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "!TARGET_PARTIAL_REG_STALL
9187 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9189 switch (get_attr_type (insn))
9195 gcc_assert (operands[2] == const1_rtx);
9196 return "add{w}\t%0, %0";
9199 if (operands[2] == const1_rtx
9200 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9201 return "sal{w}\t%0";
9203 return "sal{w}\t{%2, %0|%0, %2}";
9207 (cond [(eq_attr "alternative" "1")
9208 (const_string "lea")
9209 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9211 (match_operand 0 "register_operand" ""))
9212 (match_operand 2 "const1_operand" ""))
9213 (const_string "alu")
9215 (const_string "ishift")))
9216 (set (attr "length_immediate")
9218 (ior (eq_attr "type" "alu")
9219 (and (eq_attr "type" "ishift")
9220 (and (match_operand 2 "const1_operand" "")
9221 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9224 (const_string "*")))
9225 (set_attr "mode" "HI,SI")])
9227 (define_insn "*ashlqi3_1"
9228 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9229 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9230 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "TARGET_PARTIAL_REG_STALL
9233 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9235 switch (get_attr_type (insn))
9238 gcc_assert (operands[2] == const1_rtx);
9239 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9240 return "add{l}\t%k0, %k0";
9242 return "add{b}\t%0, %0";
9245 if (operands[2] == const1_rtx
9246 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9248 if (get_attr_mode (insn) == MODE_SI)
9249 return "sal{l}\t%k0";
9251 return "sal{b}\t%0";
9255 if (get_attr_mode (insn) == MODE_SI)
9256 return "sal{l}\t{%2, %k0|%k0, %2}";
9258 return "sal{b}\t{%2, %0|%0, %2}";
9263 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9265 (match_operand 0 "register_operand" ""))
9266 (match_operand 2 "const1_operand" ""))
9267 (const_string "alu")
9269 (const_string "ishift")))
9270 (set (attr "length_immediate")
9272 (ior (eq_attr "type" "alu")
9273 (and (eq_attr "type" "ishift")
9274 (and (match_operand 2 "const1_operand" "")
9275 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9278 (const_string "*")))
9279 (set_attr "mode" "QI,SI")])
9281 ;; %%% Potential partial reg stall on alternative 2. What to do?
9282 (define_insn "*ashlqi3_1_lea"
9283 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9284 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9285 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "!TARGET_PARTIAL_REG_STALL
9288 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9290 switch (get_attr_type (insn))
9296 gcc_assert (operands[2] == const1_rtx);
9297 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9298 return "add{l}\t%k0, %k0";
9300 return "add{b}\t%0, %0";
9303 if (operands[2] == const1_rtx
9304 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 if (get_attr_mode (insn) == MODE_SI)
9307 return "sal{l}\t%k0";
9309 return "sal{b}\t%0";
9313 if (get_attr_mode (insn) == MODE_SI)
9314 return "sal{l}\t{%2, %k0|%k0, %2}";
9316 return "sal{b}\t{%2, %0|%0, %2}";
9321 (cond [(eq_attr "alternative" "2")
9322 (const_string "lea")
9323 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9325 (match_operand 0 "register_operand" ""))
9326 (match_operand 2 "const1_operand" ""))
9327 (const_string "alu")
9329 (const_string "ishift")))
9330 (set (attr "length_immediate")
9332 (ior (eq_attr "type" "alu")
9333 (and (eq_attr "type" "ishift")
9334 (and (match_operand 2 "const1_operand" "")
9335 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9338 (const_string "*")))
9339 (set_attr "mode" "QI,SI,SI")])
9341 (define_insn "*ashlqi3_1_slp"
9342 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9343 (ashift:QI (match_dup 0)
9344 (match_operand:QI 1 "nonmemory_operand" "cI")))
9345 (clobber (reg:CC FLAGS_REG))]
9346 "(optimize_function_for_size_p (cfun)
9347 || !TARGET_PARTIAL_FLAG_REG_STALL
9348 || (operands[1] == const1_rtx
9350 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9352 switch (get_attr_type (insn))
9355 gcc_assert (operands[1] == const1_rtx);
9356 return "add{b}\t%0, %0";
9359 if (operands[1] == const1_rtx
9360 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9361 return "sal{b}\t%0";
9363 return "sal{b}\t{%1, %0|%0, %1}";
9367 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9369 (match_operand 0 "register_operand" ""))
9370 (match_operand 1 "const1_operand" ""))
9371 (const_string "alu")
9373 (const_string "ishift1")))
9374 (set (attr "length_immediate")
9376 (ior (eq_attr "type" "alu")
9377 (and (eq_attr "type" "ishift1")
9378 (and (match_operand 1 "const1_operand" "")
9379 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9382 (const_string "*")))
9383 (set_attr "mode" "QI")])
9385 ;; Convert lea to the lea pattern to avoid flags dependency.
9387 [(set (match_operand 0 "register_operand" "")
9388 (ashift (match_operand 1 "index_register_operand" "")
9389 (match_operand:QI 2 "const_int_operand" "")))
9390 (clobber (reg:CC FLAGS_REG))]
9392 && true_regnum (operands[0]) != true_regnum (operands[1])"
9396 enum machine_mode mode = GET_MODE (operands[0]);
9399 operands[1] = gen_lowpart (Pmode, operands[1]);
9400 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9402 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9404 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9405 operands[0] = gen_lowpart (SImode, operands[0]);
9407 if (TARGET_64BIT && mode != Pmode)
9408 pat = gen_rtx_SUBREG (SImode, pat, 0);
9410 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9414 ;; Convert lea to the lea pattern to avoid flags dependency.
9416 [(set (match_operand:DI 0 "register_operand" "")
9418 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9419 (match_operand:QI 2 "const_int_operand" ""))))
9420 (clobber (reg:CC FLAGS_REG))]
9421 "TARGET_64BIT && reload_completed
9422 && true_regnum (operands[0]) != true_regnum (operands[1])"
9424 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9426 operands[1] = gen_lowpart (DImode, operands[1]);
9427 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9430 ;; This pattern can't accept a variable shift count, since shifts by
9431 ;; zero don't affect the flags. We assume that shifts by constant
9432 ;; zero are optimized away.
9433 (define_insn "*ashl<mode>3_cmp"
9434 [(set (reg FLAGS_REG)
9436 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9437 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9439 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9440 (ashift:SWI (match_dup 1) (match_dup 2)))]
9441 "(optimize_function_for_size_p (cfun)
9442 || !TARGET_PARTIAL_FLAG_REG_STALL
9443 || (operands[2] == const1_rtx
9445 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9446 && ix86_match_ccmode (insn, CCGOCmode)
9447 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9449 switch (get_attr_type (insn))
9452 gcc_assert (operands[2] == const1_rtx);
9453 return "add{<imodesuffix>}\t%0, %0";
9456 if (operands[2] == const1_rtx
9457 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9458 return "sal{<imodesuffix>}\t%0";
9460 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9464 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9466 (match_operand 0 "register_operand" ""))
9467 (match_operand 2 "const1_operand" ""))
9468 (const_string "alu")
9470 (const_string "ishift")))
9471 (set (attr "length_immediate")
9473 (ior (eq_attr "type" "alu")
9474 (and (eq_attr "type" "ishift")
9475 (and (match_operand 2 "const1_operand" "")
9476 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9479 (const_string "*")))
9480 (set_attr "mode" "<MODE>")])
9482 (define_insn "*ashlsi3_cmp_zext"
9483 [(set (reg FLAGS_REG)
9485 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9486 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9488 (set (match_operand:DI 0 "register_operand" "=r")
9489 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9491 && (optimize_function_for_size_p (cfun)
9492 || !TARGET_PARTIAL_FLAG_REG_STALL
9493 || (operands[2] == const1_rtx
9495 || TARGET_DOUBLE_WITH_ADD)))
9496 && ix86_match_ccmode (insn, CCGOCmode)
9497 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9499 switch (get_attr_type (insn))
9502 gcc_assert (operands[2] == const1_rtx);
9503 return "add{l}\t%k0, %k0";
9506 if (operands[2] == const1_rtx
9507 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508 return "sal{l}\t%k0";
9510 return "sal{l}\t{%2, %k0|%k0, %2}";
9514 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9516 (match_operand 2 "const1_operand" ""))
9517 (const_string "alu")
9519 (const_string "ishift")))
9520 (set (attr "length_immediate")
9522 (ior (eq_attr "type" "alu")
9523 (and (eq_attr "type" "ishift")
9524 (and (match_operand 2 "const1_operand" "")
9525 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9528 (const_string "*")))
9529 (set_attr "mode" "SI")])
9531 (define_insn "*ashl<mode>3_cconly"
9532 [(set (reg FLAGS_REG)
9534 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9535 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9537 (clobber (match_scratch:SWI 0 "=<r>"))]
9538 "(optimize_function_for_size_p (cfun)
9539 || !TARGET_PARTIAL_FLAG_REG_STALL
9540 || (operands[2] == const1_rtx
9542 || TARGET_DOUBLE_WITH_ADD)))
9543 && ix86_match_ccmode (insn, CCGOCmode)"
9545 switch (get_attr_type (insn))
9548 gcc_assert (operands[2] == const1_rtx);
9549 return "add{<imodesuffix>}\t%0, %0";
9552 if (operands[2] == const1_rtx
9553 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9554 return "sal{<imodesuffix>}\t%0";
9556 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9560 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9562 (match_operand 0 "register_operand" ""))
9563 (match_operand 2 "const1_operand" ""))
9564 (const_string "alu")
9566 (const_string "ishift")))
9567 (set (attr "length_immediate")
9569 (ior (eq_attr "type" "alu")
9570 (and (eq_attr "type" "ishift")
9571 (and (match_operand 2 "const1_operand" "")
9572 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9575 (const_string "*")))
9576 (set_attr "mode" "<MODE>")])
9578 ;; See comment above `ashl<mode>3' about how this works.
9580 (define_expand "<shiftrt_insn><mode>3"
9581 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9583 (match_operand:QI 2 "nonmemory_operand" "")))]
9585 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9587 ;; Avoid useless masking of count operand.
9588 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9589 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9591 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9594 (match_operand:SI 2 "nonimmediate_operand" "c")
9595 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9596 (clobber (reg:CC FLAGS_REG))]
9597 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9598 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9599 == GET_MODE_BITSIZE (<MODE>mode)-1"
9602 [(parallel [(set (match_dup 0)
9603 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9604 (clobber (reg:CC FLAGS_REG))])]
9606 if (can_create_pseudo_p ())
9607 operands [2] = force_reg (SImode, operands[2]);
9609 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9611 [(set_attr "type" "ishift")
9612 (set_attr "mode" "<MODE>")])
9614 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9615 [(set (match_operand:DWI 0 "register_operand" "=r")
9616 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9617 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9618 (clobber (reg:CC FLAGS_REG))]
9621 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9623 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9624 [(set_attr "type" "multi")])
9626 ;; By default we don't ask for a scratch register, because when DWImode
9627 ;; values are manipulated, registers are already at a premium. But if
9628 ;; we have one handy, we won't turn it away.
9631 [(match_scratch:DWIH 3 "r")
9632 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9634 (match_operand:<DWI> 1 "register_operand" "")
9635 (match_operand:QI 2 "nonmemory_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))])
9640 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9642 (define_insn "x86_64_shrd"
9643 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9644 (ior:DI (ashiftrt:DI (match_dup 0)
9645 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9646 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9647 (minus:QI (const_int 64) (match_dup 2)))))
9648 (clobber (reg:CC FLAGS_REG))]
9650 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9651 [(set_attr "type" "ishift")
9652 (set_attr "prefix_0f" "1")
9653 (set_attr "mode" "DI")
9654 (set_attr "athlon_decode" "vector")
9655 (set_attr "amdfam10_decode" "vector")
9656 (set_attr "bdver1_decode" "vector")])
9658 (define_insn "x86_shrd"
9659 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9660 (ior:SI (ashiftrt:SI (match_dup 0)
9661 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9662 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9663 (minus:QI (const_int 32) (match_dup 2)))))
9664 (clobber (reg:CC FLAGS_REG))]
9666 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9667 [(set_attr "type" "ishift")
9668 (set_attr "prefix_0f" "1")
9669 (set_attr "mode" "SI")
9670 (set_attr "pent_pair" "np")
9671 (set_attr "athlon_decode" "vector")
9672 (set_attr "amdfam10_decode" "vector")
9673 (set_attr "bdver1_decode" "vector")])
9675 (define_insn "ashrdi3_cvt"
9676 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9677 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9678 (match_operand:QI 2 "const_int_operand" "")))
9679 (clobber (reg:CC FLAGS_REG))]
9680 "TARGET_64BIT && INTVAL (operands[2]) == 63
9681 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9682 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9685 sar{q}\t{%2, %0|%0, %2}"
9686 [(set_attr "type" "imovx,ishift")
9687 (set_attr "prefix_0f" "0,*")
9688 (set_attr "length_immediate" "0,*")
9689 (set_attr "modrm" "0,1")
9690 (set_attr "mode" "DI")])
9692 (define_insn "ashrsi3_cvt"
9693 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9694 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9695 (match_operand:QI 2 "const_int_operand" "")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "INTVAL (operands[2]) == 31
9698 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9699 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9702 sar{l}\t{%2, %0|%0, %2}"
9703 [(set_attr "type" "imovx,ishift")
9704 (set_attr "prefix_0f" "0,*")
9705 (set_attr "length_immediate" "0,*")
9706 (set_attr "modrm" "0,1")
9707 (set_attr "mode" "SI")])
9709 (define_insn "*ashrsi3_cvt_zext"
9710 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9713 (match_operand:QI 2 "const_int_operand" ""))))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "TARGET_64BIT && INTVAL (operands[2]) == 31
9716 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9717 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9720 sar{l}\t{%2, %k0|%k0, %2}"
9721 [(set_attr "type" "imovx,ishift")
9722 (set_attr "prefix_0f" "0,*")
9723 (set_attr "length_immediate" "0,*")
9724 (set_attr "modrm" "0,1")
9725 (set_attr "mode" "SI")])
9727 (define_expand "x86_shift<mode>_adj_3"
9728 [(use (match_operand:SWI48 0 "register_operand" ""))
9729 (use (match_operand:SWI48 1 "register_operand" ""))
9730 (use (match_operand:QI 2 "register_operand" ""))]
9733 rtx label = gen_label_rtx ();
9736 emit_insn (gen_testqi_ccz_1 (operands[2],
9737 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9739 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9740 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9741 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9742 gen_rtx_LABEL_REF (VOIDmode, label),
9744 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9745 JUMP_LABEL (tmp) = label;
9747 emit_move_insn (operands[0], operands[1]);
9748 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9749 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9751 LABEL_NUSES (label) = 1;
9756 (define_insn "*<shiftrt_insn><mode>3_1"
9757 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9758 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9759 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9760 (clobber (reg:CC FLAGS_REG))]
9761 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9763 if (operands[2] == const1_rtx
9764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765 return "<shiftrt>{<imodesuffix>}\t%0";
9767 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9769 [(set_attr "type" "ishift")
9770 (set (attr "length_immediate")
9772 (and (match_operand 2 "const1_operand" "")
9773 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9776 (const_string "*")))
9777 (set_attr "mode" "<MODE>")])
9779 (define_insn "*<shiftrt_insn>si3_1_zext"
9780 [(set (match_operand:DI 0 "register_operand" "=r")
9782 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9783 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9784 (clobber (reg:CC FLAGS_REG))]
9785 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9787 if (operands[2] == const1_rtx
9788 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9789 return "<shiftrt>{l}\t%k0";
9791 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9793 [(set_attr "type" "ishift")
9794 (set (attr "length_immediate")
9796 (and (match_operand 2 "const1_operand" "")
9797 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9800 (const_string "*")))
9801 (set_attr "mode" "SI")])
9803 (define_insn "*<shiftrt_insn>qi3_1_slp"
9804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9805 (any_shiftrt:QI (match_dup 0)
9806 (match_operand:QI 1 "nonmemory_operand" "cI")))
9807 (clobber (reg:CC FLAGS_REG))]
9808 "(optimize_function_for_size_p (cfun)
9809 || !TARGET_PARTIAL_REG_STALL
9810 || (operands[1] == const1_rtx
9813 if (operands[1] == const1_rtx
9814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9815 return "<shiftrt>{b}\t%0";
9817 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9819 [(set_attr "type" "ishift1")
9820 (set (attr "length_immediate")
9822 (and (match_operand 1 "const1_operand" "")
9823 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826 (const_string "*")))
9827 (set_attr "mode" "QI")])
9829 ;; This pattern can't accept a variable shift count, since shifts by
9830 ;; zero don't affect the flags. We assume that shifts by constant
9831 ;; zero are optimized away.
9832 (define_insn "*<shiftrt_insn><mode>3_cmp"
9833 [(set (reg FLAGS_REG)
9836 (match_operand:SWI 1 "nonimmediate_operand" "0")
9837 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9839 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9840 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9841 "(optimize_function_for_size_p (cfun)
9842 || !TARGET_PARTIAL_FLAG_REG_STALL
9843 || (operands[2] == const1_rtx
9845 && ix86_match_ccmode (insn, CCGOCmode)
9846 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9848 if (operands[2] == const1_rtx
9849 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850 return "<shiftrt>{<imodesuffix>}\t%0";
9852 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9854 [(set_attr "type" "ishift")
9855 (set (attr "length_immediate")
9857 (and (match_operand 2 "const1_operand" "")
9858 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9861 (const_string "*")))
9862 (set_attr "mode" "<MODE>")])
9864 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9865 [(set (reg FLAGS_REG)
9867 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9868 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9870 (set (match_operand:DI 0 "register_operand" "=r")
9871 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9873 && (optimize_function_for_size_p (cfun)
9874 || !TARGET_PARTIAL_FLAG_REG_STALL
9875 || (operands[2] == const1_rtx
9877 && ix86_match_ccmode (insn, CCGOCmode)
9878 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9880 if (operands[2] == const1_rtx
9881 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9882 return "<shiftrt>{l}\t%k0";
9884 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9886 [(set_attr "type" "ishift")
9887 (set (attr "length_immediate")
9889 (and (match_operand 2 "const1_operand" "")
9890 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9893 (const_string "*")))
9894 (set_attr "mode" "SI")])
9896 (define_insn "*<shiftrt_insn><mode>3_cconly"
9897 [(set (reg FLAGS_REG)
9900 (match_operand:SWI 1 "register_operand" "0")
9901 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9903 (clobber (match_scratch:SWI 0 "=<r>"))]
9904 "(optimize_function_for_size_p (cfun)
9905 || !TARGET_PARTIAL_FLAG_REG_STALL
9906 || (operands[2] == const1_rtx
9908 && ix86_match_ccmode (insn, CCGOCmode)"
9910 if (operands[2] == const1_rtx
9911 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9912 return "<shiftrt>{<imodesuffix>}\t%0";
9914 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9916 [(set_attr "type" "ishift")
9917 (set (attr "length_immediate")
9919 (and (match_operand 2 "const1_operand" "")
9920 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9923 (const_string "*")))
9924 (set_attr "mode" "<MODE>")])
9926 ;; Rotate instructions
9928 (define_expand "<rotate_insn>ti3"
9929 [(set (match_operand:TI 0 "register_operand" "")
9930 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9931 (match_operand:QI 2 "nonmemory_operand" "")))]
9934 if (const_1_to_63_operand (operands[2], VOIDmode))
9935 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9936 (operands[0], operands[1], operands[2]));
9943 (define_expand "<rotate_insn>di3"
9944 [(set (match_operand:DI 0 "shiftdi_operand" "")
9945 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9946 (match_operand:QI 2 "nonmemory_operand" "")))]
9950 ix86_expand_binary_operator (<CODE>, DImode, operands);
9951 else if (const_1_to_31_operand (operands[2], VOIDmode))
9952 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9953 (operands[0], operands[1], operands[2]));
9960 (define_expand "<rotate_insn><mode>3"
9961 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9962 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9963 (match_operand:QI 2 "nonmemory_operand" "")))]
9965 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9967 ;; Avoid useless masking of count operand.
9968 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9969 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9971 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9974 (match_operand:SI 2 "nonimmediate_operand" "c")
9975 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9976 (clobber (reg:CC FLAGS_REG))]
9977 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9978 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9979 == GET_MODE_BITSIZE (<MODE>mode)-1"
9982 [(parallel [(set (match_dup 0)
9983 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9984 (clobber (reg:CC FLAGS_REG))])]
9986 if (can_create_pseudo_p ())
9987 operands [2] = force_reg (SImode, operands[2]);
9989 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9991 [(set_attr "type" "rotate")
9992 (set_attr "mode" "<MODE>")])
9994 ;; Implement rotation using two double-precision
9995 ;; shift instructions and a scratch register.
9997 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9998 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9999 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10000 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10001 (clobber (reg:CC FLAGS_REG))
10002 (clobber (match_scratch:DWIH 3 "=&r"))]
10006 [(set (match_dup 3) (match_dup 4))
10008 [(set (match_dup 4)
10009 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10010 (lshiftrt:DWIH (match_dup 5)
10011 (minus:QI (match_dup 6) (match_dup 2)))))
10012 (clobber (reg:CC FLAGS_REG))])
10014 [(set (match_dup 5)
10015 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10016 (lshiftrt:DWIH (match_dup 3)
10017 (minus:QI (match_dup 6) (match_dup 2)))))
10018 (clobber (reg:CC FLAGS_REG))])]
10020 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10022 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10025 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10026 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10027 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10028 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10029 (clobber (reg:CC FLAGS_REG))
10030 (clobber (match_scratch:DWIH 3 "=&r"))]
10034 [(set (match_dup 3) (match_dup 4))
10036 [(set (match_dup 4)
10037 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10038 (ashift:DWIH (match_dup 5)
10039 (minus:QI (match_dup 6) (match_dup 2)))))
10040 (clobber (reg:CC FLAGS_REG))])
10042 [(set (match_dup 5)
10043 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10044 (ashift:DWIH (match_dup 3)
10045 (minus:QI (match_dup 6) (match_dup 2)))))
10046 (clobber (reg:CC FLAGS_REG))])]
10048 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10050 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10053 (define_insn "*<rotate_insn><mode>3_1"
10054 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10055 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10056 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10057 (clobber (reg:CC FLAGS_REG))]
10058 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10060 if (operands[2] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<rotate>{<imodesuffix>}\t%0";
10064 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10066 [(set_attr "type" "rotate")
10067 (set (attr "length_immediate")
10069 (and (match_operand 2 "const1_operand" "")
10070 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10073 (const_string "*")))
10074 (set_attr "mode" "<MODE>")])
10076 (define_insn "*<rotate_insn>si3_1_zext"
10077 [(set (match_operand:DI 0 "register_operand" "=r")
10079 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10080 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10081 (clobber (reg:CC FLAGS_REG))]
10082 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10084 if (operands[2] == const1_rtx
10085 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086 return "<rotate>{l}\t%k0";
10088 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10090 [(set_attr "type" "rotate")
10091 (set (attr "length_immediate")
10093 (and (match_operand 2 "const1_operand" "")
10094 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10097 (const_string "*")))
10098 (set_attr "mode" "SI")])
10100 (define_insn "*<rotate_insn>qi3_1_slp"
10101 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10102 (any_rotate:QI (match_dup 0)
10103 (match_operand:QI 1 "nonmemory_operand" "cI")))
10104 (clobber (reg:CC FLAGS_REG))]
10105 "(optimize_function_for_size_p (cfun)
10106 || !TARGET_PARTIAL_REG_STALL
10107 || (operands[1] == const1_rtx
10108 && TARGET_SHIFT1))"
10110 if (operands[1] == const1_rtx
10111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10112 return "<rotate>{b}\t%0";
10114 return "<rotate>{b}\t{%1, %0|%0, %1}";
10116 [(set_attr "type" "rotate1")
10117 (set (attr "length_immediate")
10119 (and (match_operand 1 "const1_operand" "")
10120 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10123 (const_string "*")))
10124 (set_attr "mode" "QI")])
10127 [(set (match_operand:HI 0 "register_operand" "")
10128 (any_rotate:HI (match_dup 0) (const_int 8)))
10129 (clobber (reg:CC FLAGS_REG))]
10131 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10132 [(parallel [(set (strict_low_part (match_dup 0))
10133 (bswap:HI (match_dup 0)))
10134 (clobber (reg:CC FLAGS_REG))])])
10136 ;; Bit set / bit test instructions
10138 (define_expand "extv"
10139 [(set (match_operand:SI 0 "register_operand" "")
10140 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10141 (match_operand:SI 2 "const8_operand" "")
10142 (match_operand:SI 3 "const8_operand" "")))]
10145 /* Handle extractions from %ah et al. */
10146 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10149 /* From mips.md: extract_bit_field doesn't verify that our source
10150 matches the predicate, so check it again here. */
10151 if (! ext_register_operand (operands[1], VOIDmode))
10155 (define_expand "extzv"
10156 [(set (match_operand:SI 0 "register_operand" "")
10157 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10158 (match_operand:SI 2 "const8_operand" "")
10159 (match_operand:SI 3 "const8_operand" "")))]
10162 /* Handle extractions from %ah et al. */
10163 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10166 /* From mips.md: extract_bit_field doesn't verify that our source
10167 matches the predicate, so check it again here. */
10168 if (! ext_register_operand (operands[1], VOIDmode))
10172 (define_expand "insv"
10173 [(set (zero_extract (match_operand 0 "register_operand" "")
10174 (match_operand 1 "const_int_operand" "")
10175 (match_operand 2 "const_int_operand" ""))
10176 (match_operand 3 "register_operand" ""))]
10179 rtx (*gen_mov_insv_1) (rtx, rtx);
10181 if (ix86_expand_pinsr (operands))
10184 /* Handle insertions to %ah et al. */
10185 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10188 /* From mips.md: insert_bit_field doesn't verify that our source
10189 matches the predicate, so check it again here. */
10190 if (! ext_register_operand (operands[0], VOIDmode))
10193 gen_mov_insv_1 = (TARGET_64BIT
10194 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10196 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10200 ;; %%% bts, btr, btc, bt.
10201 ;; In general these instructions are *slow* when applied to memory,
10202 ;; since they enforce atomic operation. When applied to registers,
10203 ;; it depends on the cpu implementation. They're never faster than
10204 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10205 ;; no point. But in 64-bit, we can't hold the relevant immediates
10206 ;; within the instruction itself, so operating on bits in the high
10207 ;; 32-bits of a register becomes easier.
10209 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10210 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10211 ;; negdf respectively, so they can never be disabled entirely.
10213 (define_insn "*btsq"
10214 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10216 (match_operand:DI 1 "const_0_to_63_operand" ""))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10220 "bts{q}\t{%1, %0|%0, %1}"
10221 [(set_attr "type" "alu1")
10222 (set_attr "prefix_0f" "1")
10223 (set_attr "mode" "DI")])
10225 (define_insn "*btrq"
10226 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10228 (match_operand:DI 1 "const_0_to_63_operand" ""))
10230 (clobber (reg:CC FLAGS_REG))]
10231 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10232 "btr{q}\t{%1, %0|%0, %1}"
10233 [(set_attr "type" "alu1")
10234 (set_attr "prefix_0f" "1")
10235 (set_attr "mode" "DI")])
10237 (define_insn "*btcq"
10238 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10240 (match_operand:DI 1 "const_0_to_63_operand" ""))
10241 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10242 (clobber (reg:CC FLAGS_REG))]
10243 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10244 "btc{q}\t{%1, %0|%0, %1}"
10245 [(set_attr "type" "alu1")
10246 (set_attr "prefix_0f" "1")
10247 (set_attr "mode" "DI")])
10249 ;; Allow Nocona to avoid these instructions if a register is available.
10252 [(match_scratch:DI 2 "r")
10253 (parallel [(set (zero_extract:DI
10254 (match_operand:DI 0 "register_operand" "")
10256 (match_operand:DI 1 "const_0_to_63_operand" ""))
10258 (clobber (reg:CC FLAGS_REG))])]
10259 "TARGET_64BIT && !TARGET_USE_BT"
10262 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10265 if (HOST_BITS_PER_WIDE_INT >= 64)
10266 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10267 else if (i < HOST_BITS_PER_WIDE_INT)
10268 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10270 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10272 op1 = immed_double_const (lo, hi, DImode);
10275 emit_move_insn (operands[2], op1);
10279 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10284 [(match_scratch:DI 2 "r")
10285 (parallel [(set (zero_extract:DI
10286 (match_operand:DI 0 "register_operand" "")
10288 (match_operand:DI 1 "const_0_to_63_operand" ""))
10290 (clobber (reg:CC FLAGS_REG))])]
10291 "TARGET_64BIT && !TARGET_USE_BT"
10294 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10297 if (HOST_BITS_PER_WIDE_INT >= 64)
10298 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10299 else if (i < HOST_BITS_PER_WIDE_INT)
10300 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10302 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10304 op1 = immed_double_const (~lo, ~hi, DImode);
10307 emit_move_insn (operands[2], op1);
10311 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10316 [(match_scratch:DI 2 "r")
10317 (parallel [(set (zero_extract:DI
10318 (match_operand:DI 0 "register_operand" "")
10320 (match_operand:DI 1 "const_0_to_63_operand" ""))
10321 (not:DI (zero_extract:DI
10322 (match_dup 0) (const_int 1) (match_dup 1))))
10323 (clobber (reg:CC FLAGS_REG))])]
10324 "TARGET_64BIT && !TARGET_USE_BT"
10327 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10330 if (HOST_BITS_PER_WIDE_INT >= 64)
10331 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10332 else if (i < HOST_BITS_PER_WIDE_INT)
10333 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10335 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10337 op1 = immed_double_const (lo, hi, DImode);
10340 emit_move_insn (operands[2], op1);
10344 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10348 (define_insn "*bt<mode>"
10349 [(set (reg:CCC FLAGS_REG)
10351 (zero_extract:SWI48
10352 (match_operand:SWI48 0 "register_operand" "r")
10354 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10356 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10357 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10358 [(set_attr "type" "alu1")
10359 (set_attr "prefix_0f" "1")
10360 (set_attr "mode" "<MODE>")])
10362 ;; Store-flag instructions.
10364 ;; For all sCOND expanders, also expand the compare or test insn that
10365 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10367 (define_insn_and_split "*setcc_di_1"
10368 [(set (match_operand:DI 0 "register_operand" "=q")
10369 (match_operator:DI 1 "ix86_comparison_operator"
10370 [(reg FLAGS_REG) (const_int 0)]))]
10371 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10373 "&& reload_completed"
10374 [(set (match_dup 2) (match_dup 1))
10375 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10377 PUT_MODE (operands[1], QImode);
10378 operands[2] = gen_lowpart (QImode, operands[0]);
10381 (define_insn_and_split "*setcc_si_1_and"
10382 [(set (match_operand:SI 0 "register_operand" "=q")
10383 (match_operator:SI 1 "ix86_comparison_operator"
10384 [(reg FLAGS_REG) (const_int 0)]))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "!TARGET_PARTIAL_REG_STALL
10387 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10389 "&& reload_completed"
10390 [(set (match_dup 2) (match_dup 1))
10391 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10392 (clobber (reg:CC FLAGS_REG))])]
10394 PUT_MODE (operands[1], QImode);
10395 operands[2] = gen_lowpart (QImode, operands[0]);
10398 (define_insn_and_split "*setcc_si_1_movzbl"
10399 [(set (match_operand:SI 0 "register_operand" "=q")
10400 (match_operator:SI 1 "ix86_comparison_operator"
10401 [(reg FLAGS_REG) (const_int 0)]))]
10402 "!TARGET_PARTIAL_REG_STALL
10403 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10405 "&& reload_completed"
10406 [(set (match_dup 2) (match_dup 1))
10407 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10409 PUT_MODE (operands[1], QImode);
10410 operands[2] = gen_lowpart (QImode, operands[0]);
10413 (define_insn "*setcc_qi"
10414 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10415 (match_operator:QI 1 "ix86_comparison_operator"
10416 [(reg FLAGS_REG) (const_int 0)]))]
10419 [(set_attr "type" "setcc")
10420 (set_attr "mode" "QI")])
10422 (define_insn "*setcc_qi_slp"
10423 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10424 (match_operator:QI 1 "ix86_comparison_operator"
10425 [(reg FLAGS_REG) (const_int 0)]))]
10428 [(set_attr "type" "setcc")
10429 (set_attr "mode" "QI")])
10431 ;; In general it is not safe to assume too much about CCmode registers,
10432 ;; so simplify-rtx stops when it sees a second one. Under certain
10433 ;; conditions this is safe on x86, so help combine not create
10440 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10441 (ne:QI (match_operator 1 "ix86_comparison_operator"
10442 [(reg FLAGS_REG) (const_int 0)])
10445 [(set (match_dup 0) (match_dup 1))]
10446 "PUT_MODE (operands[1], QImode);")
10449 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10450 (ne:QI (match_operator 1 "ix86_comparison_operator"
10451 [(reg FLAGS_REG) (const_int 0)])
10454 [(set (match_dup 0) (match_dup 1))]
10455 "PUT_MODE (operands[1], QImode);")
10458 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10459 (eq:QI (match_operator 1 "ix86_comparison_operator"
10460 [(reg FLAGS_REG) (const_int 0)])
10463 [(set (match_dup 0) (match_dup 1))]
10465 rtx new_op1 = copy_rtx (operands[1]);
10466 operands[1] = new_op1;
10467 PUT_MODE (new_op1, QImode);
10468 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10469 GET_MODE (XEXP (new_op1, 0))));
10471 /* Make sure that (a) the CCmode we have for the flags is strong
10472 enough for the reversed compare or (b) we have a valid FP compare. */
10473 if (! ix86_comparison_operator (new_op1, VOIDmode))
10478 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10479 (eq:QI (match_operator 1 "ix86_comparison_operator"
10480 [(reg FLAGS_REG) (const_int 0)])
10483 [(set (match_dup 0) (match_dup 1))]
10485 rtx new_op1 = copy_rtx (operands[1]);
10486 operands[1] = new_op1;
10487 PUT_MODE (new_op1, QImode);
10488 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10489 GET_MODE (XEXP (new_op1, 0))));
10491 /* Make sure that (a) the CCmode we have for the flags is strong
10492 enough for the reversed compare or (b) we have a valid FP compare. */
10493 if (! ix86_comparison_operator (new_op1, VOIDmode))
10497 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10498 ;; subsequent logical operations are used to imitate conditional moves.
10499 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10502 (define_insn "setcc_<mode>_sse"
10503 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10504 (match_operator:MODEF 3 "sse_comparison_operator"
10505 [(match_operand:MODEF 1 "register_operand" "0,x")
10506 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10507 "SSE_FLOAT_MODE_P (<MODE>mode)"
10509 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10510 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10511 [(set_attr "isa" "noavx,avx")
10512 (set_attr "type" "ssecmp")
10513 (set_attr "length_immediate" "1")
10514 (set_attr "prefix" "orig,vex")
10515 (set_attr "mode" "<MODE>")])
10517 ;; Basic conditional jump instructions.
10518 ;; We ignore the overflow flag for signed branch instructions.
10520 (define_insn "*jcc_1"
10522 (if_then_else (match_operator 1 "ix86_comparison_operator"
10523 [(reg FLAGS_REG) (const_int 0)])
10524 (label_ref (match_operand 0 "" ""))
10528 [(set_attr "type" "ibr")
10529 (set_attr "modrm" "0")
10530 (set (attr "length")
10531 (if_then_else (and (ge (minus (match_dup 0) (pc))
10533 (lt (minus (match_dup 0) (pc))
10538 (define_insn "*jcc_2"
10540 (if_then_else (match_operator 1 "ix86_comparison_operator"
10541 [(reg FLAGS_REG) (const_int 0)])
10543 (label_ref (match_operand 0 "" ""))))]
10546 [(set_attr "type" "ibr")
10547 (set_attr "modrm" "0")
10548 (set (attr "length")
10549 (if_then_else (and (ge (minus (match_dup 0) (pc))
10551 (lt (minus (match_dup 0) (pc))
10556 ;; In general it is not safe to assume too much about CCmode registers,
10557 ;; so simplify-rtx stops when it sees a second one. Under certain
10558 ;; conditions this is safe on x86, so help combine not create
10566 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10567 [(reg FLAGS_REG) (const_int 0)])
10569 (label_ref (match_operand 1 "" ""))
10573 (if_then_else (match_dup 0)
10574 (label_ref (match_dup 1))
10576 "PUT_MODE (operands[0], VOIDmode);")
10580 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10581 [(reg FLAGS_REG) (const_int 0)])
10583 (label_ref (match_operand 1 "" ""))
10587 (if_then_else (match_dup 0)
10588 (label_ref (match_dup 1))
10591 rtx new_op0 = copy_rtx (operands[0]);
10592 operands[0] = new_op0;
10593 PUT_MODE (new_op0, VOIDmode);
10594 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10595 GET_MODE (XEXP (new_op0, 0))));
10597 /* Make sure that (a) the CCmode we have for the flags is strong
10598 enough for the reversed compare or (b) we have a valid FP compare. */
10599 if (! ix86_comparison_operator (new_op0, VOIDmode))
10603 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10604 ;; pass generates from shift insn with QImode operand. Actually, the mode
10605 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10606 ;; appropriate modulo of the bit offset value.
10608 (define_insn_and_split "*jcc_bt<mode>"
10610 (if_then_else (match_operator 0 "bt_comparison_operator"
10611 [(zero_extract:SWI48
10612 (match_operand:SWI48 1 "register_operand" "r")
10615 (match_operand:QI 2 "register_operand" "r")))
10617 (label_ref (match_operand 3 "" ""))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10623 [(set (reg:CCC FLAGS_REG)
10625 (zero_extract:SWI48
10631 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10632 (label_ref (match_dup 3))
10635 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10637 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10640 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10641 ;; also for DImode, this is what combine produces.
10642 (define_insn_and_split "*jcc_bt<mode>_mask"
10644 (if_then_else (match_operator 0 "bt_comparison_operator"
10645 [(zero_extract:SWI48
10646 (match_operand:SWI48 1 "register_operand" "r")
10649 (match_operand:SI 2 "register_operand" "r")
10650 (match_operand:SI 3 "const_int_operand" "n")))])
10651 (label_ref (match_operand 4 "" ""))
10653 (clobber (reg:CC FLAGS_REG))]
10654 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10655 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10656 == GET_MODE_BITSIZE (<MODE>mode)-1"
10659 [(set (reg:CCC FLAGS_REG)
10661 (zero_extract:SWI48
10667 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10668 (label_ref (match_dup 4))
10671 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10673 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10676 (define_insn_and_split "*jcc_btsi_1"
10678 (if_then_else (match_operator 0 "bt_comparison_operator"
10681 (match_operand:SI 1 "register_operand" "r")
10682 (match_operand:QI 2 "register_operand" "r"))
10685 (label_ref (match_operand 3 "" ""))
10687 (clobber (reg:CC FLAGS_REG))]
10688 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10691 [(set (reg:CCC FLAGS_REG)
10699 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10700 (label_ref (match_dup 3))
10703 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10705 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10708 ;; avoid useless masking of bit offset operand
10709 (define_insn_and_split "*jcc_btsi_mask_1"
10712 (match_operator 0 "bt_comparison_operator"
10715 (match_operand:SI 1 "register_operand" "r")
10718 (match_operand:SI 2 "register_operand" "r")
10719 (match_operand:SI 3 "const_int_operand" "n")) 0))
10722 (label_ref (match_operand 4 "" ""))
10724 (clobber (reg:CC FLAGS_REG))]
10725 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10726 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10729 [(set (reg:CCC FLAGS_REG)
10737 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10738 (label_ref (match_dup 4))
10740 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10742 ;; Define combination compare-and-branch fp compare instructions to help
10745 (define_insn "*fp_jcc_1_387"
10747 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10748 [(match_operand 1 "register_operand" "f")
10749 (match_operand 2 "nonimmediate_operand" "fm")])
10750 (label_ref (match_operand 3 "" ""))
10752 (clobber (reg:CCFP FPSR_REG))
10753 (clobber (reg:CCFP FLAGS_REG))
10754 (clobber (match_scratch:HI 4 "=a"))]
10756 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10757 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10758 && SELECT_CC_MODE (GET_CODE (operands[0]),
10759 operands[1], operands[2]) == CCFPmode
10763 (define_insn "*fp_jcc_1r_387"
10765 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10766 [(match_operand 1 "register_operand" "f")
10767 (match_operand 2 "nonimmediate_operand" "fm")])
10769 (label_ref (match_operand 3 "" ""))))
10770 (clobber (reg:CCFP FPSR_REG))
10771 (clobber (reg:CCFP FLAGS_REG))
10772 (clobber (match_scratch:HI 4 "=a"))]
10774 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10775 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10776 && SELECT_CC_MODE (GET_CODE (operands[0]),
10777 operands[1], operands[2]) == CCFPmode
10781 (define_insn "*fp_jcc_2_387"
10783 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10784 [(match_operand 1 "register_operand" "f")
10785 (match_operand 2 "register_operand" "f")])
10786 (label_ref (match_operand 3 "" ""))
10788 (clobber (reg:CCFP FPSR_REG))
10789 (clobber (reg:CCFP FLAGS_REG))
10790 (clobber (match_scratch:HI 4 "=a"))]
10791 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10792 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10796 (define_insn "*fp_jcc_2r_387"
10798 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10799 [(match_operand 1 "register_operand" "f")
10800 (match_operand 2 "register_operand" "f")])
10802 (label_ref (match_operand 3 "" ""))))
10803 (clobber (reg:CCFP FPSR_REG))
10804 (clobber (reg:CCFP FLAGS_REG))
10805 (clobber (match_scratch:HI 4 "=a"))]
10806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10807 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10811 (define_insn "*fp_jcc_3_387"
10813 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10814 [(match_operand 1 "register_operand" "f")
10815 (match_operand 2 "const0_operand" "")])
10816 (label_ref (match_operand 3 "" ""))
10818 (clobber (reg:CCFP FPSR_REG))
10819 (clobber (reg:CCFP FLAGS_REG))
10820 (clobber (match_scratch:HI 4 "=a"))]
10821 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10822 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10823 && SELECT_CC_MODE (GET_CODE (operands[0]),
10824 operands[1], operands[2]) == CCFPmode
10830 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10831 [(match_operand 1 "register_operand" "")
10832 (match_operand 2 "nonimmediate_operand" "")])
10833 (match_operand 3 "" "")
10834 (match_operand 4 "" "")))
10835 (clobber (reg:CCFP FPSR_REG))
10836 (clobber (reg:CCFP FLAGS_REG))]
10840 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10841 operands[3], operands[4], NULL_RTX, NULL_RTX);
10847 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10848 [(match_operand 1 "register_operand" "")
10849 (match_operand 2 "general_operand" "")])
10850 (match_operand 3 "" "")
10851 (match_operand 4 "" "")))
10852 (clobber (reg:CCFP FPSR_REG))
10853 (clobber (reg:CCFP FLAGS_REG))
10854 (clobber (match_scratch:HI 5 "=a"))]
10858 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10859 operands[3], operands[4], operands[5], NULL_RTX);
10863 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10864 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10865 ;; with a precedence over other operators and is always put in the first
10866 ;; place. Swap condition and operands to match ficom instruction.
10868 (define_insn "*fp_jcc_4_<mode>_387"
10871 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10872 [(match_operator 1 "float_operator"
10873 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10874 (match_operand 3 "register_operand" "f,f")])
10875 (label_ref (match_operand 4 "" ""))
10877 (clobber (reg:CCFP FPSR_REG))
10878 (clobber (reg:CCFP FLAGS_REG))
10879 (clobber (match_scratch:HI 5 "=a,a"))]
10880 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10881 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10882 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10883 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10890 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10891 [(match_operator 1 "float_operator"
10892 [(match_operand:SWI24 2 "memory_operand" "")])
10893 (match_operand 3 "register_operand" "")])
10894 (match_operand 4 "" "")
10895 (match_operand 5 "" "")))
10896 (clobber (reg:CCFP FPSR_REG))
10897 (clobber (reg:CCFP FLAGS_REG))
10898 (clobber (match_scratch:HI 6 "=a"))]
10902 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10904 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10905 operands[3], operands[7],
10906 operands[4], operands[5], operands[6], NULL_RTX);
10910 ;; %%% Kill this when reload knows how to do it.
10914 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10915 [(match_operator 1 "float_operator"
10916 [(match_operand:SWI24 2 "register_operand" "")])
10917 (match_operand 3 "register_operand" "")])
10918 (match_operand 4 "" "")
10919 (match_operand 5 "" "")))
10920 (clobber (reg:CCFP FPSR_REG))
10921 (clobber (reg:CCFP FLAGS_REG))
10922 (clobber (match_scratch:HI 6 "=a"))]
10926 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10927 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10929 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10930 operands[3], operands[7],
10931 operands[4], operands[5], operands[6], operands[2]);
10935 ;; Unconditional and other jump instructions
10937 (define_insn "jump"
10939 (label_ref (match_operand 0 "" "")))]
10942 [(set_attr "type" "ibr")
10943 (set (attr "length")
10944 (if_then_else (and (ge (minus (match_dup 0) (pc))
10946 (lt (minus (match_dup 0) (pc))
10950 (set_attr "modrm" "0")])
10952 (define_expand "indirect_jump"
10953 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10957 (define_insn "*indirect_jump"
10958 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10961 [(set_attr "type" "ibr")
10962 (set_attr "length_immediate" "0")])
10964 (define_expand "tablejump"
10965 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10966 (use (label_ref (match_operand 1 "" "")))])]
10969 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10970 relative. Convert the relative address to an absolute address. */
10974 enum rtx_code code;
10976 /* We can't use @GOTOFF for text labels on VxWorks;
10977 see gotoff_operand. */
10978 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10982 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10984 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10988 op1 = pic_offset_table_rtx;
10993 op0 = pic_offset_table_rtx;
10997 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11002 (define_insn "*tablejump_1"
11003 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11004 (use (label_ref (match_operand 1 "" "")))]
11007 [(set_attr "type" "ibr")
11008 (set_attr "length_immediate" "0")])
11010 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11013 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11014 (set (match_operand:QI 1 "register_operand" "")
11015 (match_operator:QI 2 "ix86_comparison_operator"
11016 [(reg FLAGS_REG) (const_int 0)]))
11017 (set (match_operand 3 "q_regs_operand" "")
11018 (zero_extend (match_dup 1)))]
11019 "(peep2_reg_dead_p (3, operands[1])
11020 || operands_match_p (operands[1], operands[3]))
11021 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11022 [(set (match_dup 4) (match_dup 0))
11023 (set (strict_low_part (match_dup 5))
11026 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11027 operands[5] = gen_lowpart (QImode, operands[3]);
11028 ix86_expand_clear (operands[3]);
11031 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11034 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11035 (set (match_operand:QI 1 "register_operand" "")
11036 (match_operator:QI 2 "ix86_comparison_operator"
11037 [(reg FLAGS_REG) (const_int 0)]))
11038 (parallel [(set (match_operand 3 "q_regs_operand" "")
11039 (zero_extend (match_dup 1)))
11040 (clobber (reg:CC FLAGS_REG))])]
11041 "(peep2_reg_dead_p (3, operands[1])
11042 || operands_match_p (operands[1], operands[3]))
11043 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11044 [(set (match_dup 4) (match_dup 0))
11045 (set (strict_low_part (match_dup 5))
11048 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11049 operands[5] = gen_lowpart (QImode, operands[3]);
11050 ix86_expand_clear (operands[3]);
11053 ;; Call instructions.
11055 ;; The predicates normally associated with named expanders are not properly
11056 ;; checked for calls. This is a bug in the generic code, but it isn't that
11057 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11059 ;; P6 processors will jump to the address after the decrement when %esp
11060 ;; is used as a call operand, so they will execute return address as a code.
11061 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11063 ;; Register constraint for call instruction.
11064 (define_mode_attr c [(SI "l") (DI "r")])
11066 ;; Call subroutine returning no value.
11068 (define_expand "call"
11069 [(call (match_operand:QI 0 "" "")
11070 (match_operand 1 "" ""))
11071 (use (match_operand 2 "" ""))]
11074 ix86_expand_call (NULL, operands[0], operands[1],
11075 operands[2], NULL, false);
11079 (define_expand "sibcall"
11080 [(call (match_operand:QI 0 "" "")
11081 (match_operand 1 "" ""))
11082 (use (match_operand 2 "" ""))]
11085 ix86_expand_call (NULL, operands[0], operands[1],
11086 operands[2], NULL, true);
11090 (define_insn_and_split "*call_vzeroupper"
11091 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11092 (match_operand 1 "" ""))
11093 (unspec [(match_operand 2 "const_int_operand" "")]
11094 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11095 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11097 "&& reload_completed"
11099 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11100 [(set_attr "type" "call")])
11102 (define_insn "*call"
11103 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11104 (match_operand 1 "" ""))]
11105 "!SIBLING_CALL_P (insn)"
11106 "* return ix86_output_call_insn (insn, operands[0]);"
11107 [(set_attr "type" "call")])
11109 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11111 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11112 (match_operand 1 "" ""))
11113 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11114 (clobber (reg:TI XMM6_REG))
11115 (clobber (reg:TI XMM7_REG))
11116 (clobber (reg:TI XMM8_REG))
11117 (clobber (reg:TI XMM9_REG))
11118 (clobber (reg:TI XMM10_REG))
11119 (clobber (reg:TI XMM11_REG))
11120 (clobber (reg:TI XMM12_REG))
11121 (clobber (reg:TI XMM13_REG))
11122 (clobber (reg:TI XMM14_REG))
11123 (clobber (reg:TI XMM15_REG))
11124 (clobber (reg:DI SI_REG))
11125 (clobber (reg:DI DI_REG))])
11126 (unspec [(match_operand 2 "const_int_operand" "")]
11127 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11128 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11130 "&& reload_completed"
11132 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11133 [(set_attr "type" "call")])
11135 (define_insn "*call_rex64_ms_sysv"
11136 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11137 (match_operand 1 "" ""))
11138 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11139 (clobber (reg:TI XMM6_REG))
11140 (clobber (reg:TI XMM7_REG))
11141 (clobber (reg:TI XMM8_REG))
11142 (clobber (reg:TI XMM9_REG))
11143 (clobber (reg:TI XMM10_REG))
11144 (clobber (reg:TI XMM11_REG))
11145 (clobber (reg:TI XMM12_REG))
11146 (clobber (reg:TI XMM13_REG))
11147 (clobber (reg:TI XMM14_REG))
11148 (clobber (reg:TI XMM15_REG))
11149 (clobber (reg:DI SI_REG))
11150 (clobber (reg:DI DI_REG))]
11151 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11152 "* return ix86_output_call_insn (insn, operands[0]);"
11153 [(set_attr "type" "call")])
11155 (define_insn_and_split "*sibcall_vzeroupper"
11156 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11157 (match_operand 1 "" ""))
11158 (unspec [(match_operand 2 "const_int_operand" "")]
11159 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11160 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11162 "&& reload_completed"
11164 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11165 [(set_attr "type" "call")])
11167 (define_insn "*sibcall"
11168 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11169 (match_operand 1 "" ""))]
11170 "SIBLING_CALL_P (insn)"
11171 "* return ix86_output_call_insn (insn, operands[0]);"
11172 [(set_attr "type" "call")])
11174 (define_expand "call_pop"
11175 [(parallel [(call (match_operand:QI 0 "" "")
11176 (match_operand:SI 1 "" ""))
11177 (set (reg:SI SP_REG)
11178 (plus:SI (reg:SI SP_REG)
11179 (match_operand:SI 3 "" "")))])]
11182 ix86_expand_call (NULL, operands[0], operands[1],
11183 operands[2], operands[3], false);
11187 (define_insn_and_split "*call_pop_vzeroupper"
11189 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11190 (match_operand:SI 1 "" ""))
11191 (set (reg:SI SP_REG)
11192 (plus:SI (reg:SI SP_REG)
11193 (match_operand:SI 2 "immediate_operand" "i")))])
11194 (unspec [(match_operand 3 "const_int_operand" "")]
11195 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11196 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11198 "&& reload_completed"
11200 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11201 [(set_attr "type" "call")])
11203 (define_insn "*call_pop"
11204 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11205 (match_operand 1 "" ""))
11206 (set (reg:SI SP_REG)
11207 (plus:SI (reg:SI SP_REG)
11208 (match_operand:SI 2 "immediate_operand" "i")))]
11209 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11210 "* return ix86_output_call_insn (insn, operands[0]);"
11211 [(set_attr "type" "call")])
11213 (define_insn_and_split "*sibcall_pop_vzeroupper"
11215 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11216 (match_operand 1 "" ""))
11217 (set (reg:SI SP_REG)
11218 (plus:SI (reg:SI SP_REG)
11219 (match_operand:SI 2 "immediate_operand" "i")))])
11220 (unspec [(match_operand 3 "const_int_operand" "")]
11221 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11222 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11224 "&& reload_completed"
11226 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11227 [(set_attr "type" "call")])
11229 (define_insn "*sibcall_pop"
11230 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11231 (match_operand 1 "" ""))
11232 (set (reg:SI SP_REG)
11233 (plus:SI (reg:SI SP_REG)
11234 (match_operand:SI 2 "immediate_operand" "i")))]
11235 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11236 "* return ix86_output_call_insn (insn, operands[0]);"
11237 [(set_attr "type" "call")])
11239 ;; Call subroutine, returning value in operand 0
11241 (define_expand "call_value"
11242 [(set (match_operand 0 "" "")
11243 (call (match_operand:QI 1 "" "")
11244 (match_operand 2 "" "")))
11245 (use (match_operand 3 "" ""))]
11248 ix86_expand_call (operands[0], operands[1], operands[2],
11249 operands[3], NULL, false);
11253 (define_expand "sibcall_value"
11254 [(set (match_operand 0 "" "")
11255 (call (match_operand:QI 1 "" "")
11256 (match_operand 2 "" "")))
11257 (use (match_operand 3 "" ""))]
11260 ix86_expand_call (operands[0], operands[1], operands[2],
11261 operands[3], NULL, true);
11265 (define_insn_and_split "*call_value_vzeroupper"
11266 [(set (match_operand 0 "" "")
11267 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11268 (match_operand 2 "" "")))
11269 (unspec [(match_operand 3 "const_int_operand" "")]
11270 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11271 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11273 "&& reload_completed"
11275 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11276 [(set_attr "type" "callv")])
11278 (define_insn "*call_value"
11279 [(set (match_operand 0 "" "")
11280 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11281 (match_operand 2 "" "")))]
11282 "!SIBLING_CALL_P (insn)"
11283 "* return ix86_output_call_insn (insn, operands[1]);"
11284 [(set_attr "type" "callv")])
11286 (define_insn_and_split "*sibcall_value_vzeroupper"
11287 [(set (match_operand 0 "" "")
11288 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11289 (match_operand 2 "" "")))
11290 (unspec [(match_operand 3 "const_int_operand" "")]
11291 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11292 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11294 "&& reload_completed"
11296 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11297 [(set_attr "type" "callv")])
11299 (define_insn "*sibcall_value"
11300 [(set (match_operand 0 "" "")
11301 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11302 (match_operand 2 "" "")))]
11303 "SIBLING_CALL_P (insn)"
11304 "* return ix86_output_call_insn (insn, operands[1]);"
11305 [(set_attr "type" "callv")])
11307 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11309 [(set (match_operand 0 "" "")
11310 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11311 (match_operand 2 "" "")))
11312 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11313 (clobber (reg:TI XMM6_REG))
11314 (clobber (reg:TI XMM7_REG))
11315 (clobber (reg:TI XMM8_REG))
11316 (clobber (reg:TI XMM9_REG))
11317 (clobber (reg:TI XMM10_REG))
11318 (clobber (reg:TI XMM11_REG))
11319 (clobber (reg:TI XMM12_REG))
11320 (clobber (reg:TI XMM13_REG))
11321 (clobber (reg:TI XMM14_REG))
11322 (clobber (reg:TI XMM15_REG))
11323 (clobber (reg:DI SI_REG))
11324 (clobber (reg:DI DI_REG))])
11325 (unspec [(match_operand 3 "const_int_operand" "")]
11326 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11327 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11329 "&& reload_completed"
11331 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11332 [(set_attr "type" "callv")])
11334 (define_insn "*call_value_rex64_ms_sysv"
11335 [(set (match_operand 0 "" "")
11336 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11337 (match_operand 2 "" "")))
11338 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11339 (clobber (reg:TI XMM6_REG))
11340 (clobber (reg:TI XMM7_REG))
11341 (clobber (reg:TI XMM8_REG))
11342 (clobber (reg:TI XMM9_REG))
11343 (clobber (reg:TI XMM10_REG))
11344 (clobber (reg:TI XMM11_REG))
11345 (clobber (reg:TI XMM12_REG))
11346 (clobber (reg:TI XMM13_REG))
11347 (clobber (reg:TI XMM14_REG))
11348 (clobber (reg:TI XMM15_REG))
11349 (clobber (reg:DI SI_REG))
11350 (clobber (reg:DI DI_REG))]
11351 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11352 "* return ix86_output_call_insn (insn, operands[1]);"
11353 [(set_attr "type" "callv")])
11355 (define_expand "call_value_pop"
11356 [(parallel [(set (match_operand 0 "" "")
11357 (call (match_operand:QI 1 "" "")
11358 (match_operand:SI 2 "" "")))
11359 (set (reg:SI SP_REG)
11360 (plus:SI (reg:SI SP_REG)
11361 (match_operand:SI 4 "" "")))])]
11364 ix86_expand_call (operands[0], operands[1], operands[2],
11365 operands[3], operands[4], false);
11369 (define_insn_and_split "*call_value_pop_vzeroupper"
11371 [(set (match_operand 0 "" "")
11372 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11373 (match_operand 2 "" "")))
11374 (set (reg:SI SP_REG)
11375 (plus:SI (reg:SI SP_REG)
11376 (match_operand:SI 3 "immediate_operand" "i")))])
11377 (unspec [(match_operand 4 "const_int_operand" "")]
11378 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11379 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11381 "&& reload_completed"
11383 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11384 [(set_attr "type" "callv")])
11386 (define_insn "*call_value_pop"
11387 [(set (match_operand 0 "" "")
11388 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11389 (match_operand 2 "" "")))
11390 (set (reg:SI SP_REG)
11391 (plus:SI (reg:SI SP_REG)
11392 (match_operand:SI 3 "immediate_operand" "i")))]
11393 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11394 "* return ix86_output_call_insn (insn, operands[1]);"
11395 [(set_attr "type" "callv")])
11397 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11399 [(set (match_operand 0 "" "")
11400 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11401 (match_operand 2 "" "")))
11402 (set (reg:SI SP_REG)
11403 (plus:SI (reg:SI SP_REG)
11404 (match_operand:SI 3 "immediate_operand" "i")))])
11405 (unspec [(match_operand 4 "const_int_operand" "")]
11406 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11407 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11409 "&& reload_completed"
11411 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11412 [(set_attr "type" "callv")])
11414 (define_insn "*sibcall_value_pop"
11415 [(set (match_operand 0 "" "")
11416 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11417 (match_operand 2 "" "")))
11418 (set (reg:SI SP_REG)
11419 (plus:SI (reg:SI SP_REG)
11420 (match_operand:SI 3 "immediate_operand" "i")))]
11421 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11422 "* return ix86_output_call_insn (insn, operands[1]);"
11423 [(set_attr "type" "callv")])
11425 ;; Call subroutine returning any type.
11427 (define_expand "untyped_call"
11428 [(parallel [(call (match_operand 0 "" "")
11430 (match_operand 1 "" "")
11431 (match_operand 2 "" "")])]
11436 /* In order to give reg-stack an easier job in validating two
11437 coprocessor registers as containing a possible return value,
11438 simply pretend the untyped call returns a complex long double
11441 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11442 and should have the default ABI. */
11444 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11445 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11446 operands[0], const0_rtx,
11447 GEN_INT ((TARGET_64BIT
11448 ? (ix86_abi == SYSV_ABI
11449 ? X86_64_SSE_REGPARM_MAX
11450 : X86_64_MS_SSE_REGPARM_MAX)
11451 : X86_32_SSE_REGPARM_MAX)
11455 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11457 rtx set = XVECEXP (operands[2], 0, i);
11458 emit_move_insn (SET_DEST (set), SET_SRC (set));
11461 /* The optimizer does not know that the call sets the function value
11462 registers we stored in the result block. We avoid problems by
11463 claiming that all hard registers are used and clobbered at this
11465 emit_insn (gen_blockage ());
11470 ;; Prologue and epilogue instructions
11472 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11473 ;; all of memory. This blocks insns from being moved across this point.
11475 (define_insn "blockage"
11476 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11479 [(set_attr "length" "0")])
11481 ;; Do not schedule instructions accessing memory across this point.
11483 (define_expand "memory_blockage"
11484 [(set (match_dup 0)
11485 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11488 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11489 MEM_VOLATILE_P (operands[0]) = 1;
11492 (define_insn "*memory_blockage"
11493 [(set (match_operand:BLK 0 "" "")
11494 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11497 [(set_attr "length" "0")])
11499 ;; As USE insns aren't meaningful after reload, this is used instead
11500 ;; to prevent deleting instructions setting registers for PIC code
11501 (define_insn "prologue_use"
11502 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11505 [(set_attr "length" "0")])
11507 ;; Insn emitted into the body of a function to return from a function.
11508 ;; This is only done if the function's epilogue is known to be simple.
11509 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11511 (define_expand "return"
11513 "ix86_can_use_return_insn_p ()"
11515 if (crtl->args.pops_args)
11517 rtx popc = GEN_INT (crtl->args.pops_args);
11518 emit_jump_insn (gen_return_pop_internal (popc));
11523 (define_insn "return_internal"
11527 [(set_attr "length" "1")
11528 (set_attr "atom_unit" "jeu")
11529 (set_attr "length_immediate" "0")
11530 (set_attr "modrm" "0")])
11532 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11533 ;; instruction Athlon and K8 have.
11535 (define_insn "return_internal_long"
11537 (unspec [(const_int 0)] UNSPEC_REP)]
11540 [(set_attr "length" "2")
11541 (set_attr "atom_unit" "jeu")
11542 (set_attr "length_immediate" "0")
11543 (set_attr "prefix_rep" "1")
11544 (set_attr "modrm" "0")])
11546 (define_insn "return_pop_internal"
11548 (use (match_operand:SI 0 "const_int_operand" ""))]
11551 [(set_attr "length" "3")
11552 (set_attr "atom_unit" "jeu")
11553 (set_attr "length_immediate" "2")
11554 (set_attr "modrm" "0")])
11556 (define_insn "return_indirect_internal"
11558 (use (match_operand:SI 0 "register_operand" "r"))]
11561 [(set_attr "type" "ibr")
11562 (set_attr "length_immediate" "0")])
11568 [(set_attr "length" "1")
11569 (set_attr "length_immediate" "0")
11570 (set_attr "modrm" "0")])
11572 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11573 (define_insn "nops"
11574 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11578 int num = INTVAL (operands[0]);
11580 gcc_assert (num >= 1 && num <= 8);
11583 fputs ("\tnop\n", asm_out_file);
11587 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11588 (set_attr "length_immediate" "0")
11589 (set_attr "modrm" "0")])
11591 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11592 ;; branch prediction penalty for the third jump in a 16-byte
11596 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11599 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11600 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11602 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11603 The align insn is used to avoid 3 jump instructions in the row to improve
11604 branch prediction and the benefits hardly outweigh the cost of extra 8
11605 nops on the average inserted by full alignment pseudo operation. */
11609 [(set_attr "length" "16")])
11611 (define_expand "prologue"
11614 "ix86_expand_prologue (); DONE;")
11616 (define_insn "set_got"
11617 [(set (match_operand:SI 0 "register_operand" "=r")
11618 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11619 (clobber (reg:CC FLAGS_REG))]
11621 "* return output_set_got (operands[0], NULL_RTX);"
11622 [(set_attr "type" "multi")
11623 (set_attr "length" "12")])
11625 (define_insn "set_got_labelled"
11626 [(set (match_operand:SI 0 "register_operand" "=r")
11627 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11629 (clobber (reg:CC FLAGS_REG))]
11631 "* return output_set_got (operands[0], operands[1]);"
11632 [(set_attr "type" "multi")
11633 (set_attr "length" "12")])
11635 (define_insn "set_got_rex64"
11636 [(set (match_operand:DI 0 "register_operand" "=r")
11637 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11639 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11640 [(set_attr "type" "lea")
11641 (set_attr "length_address" "4")
11642 (set_attr "mode" "DI")])
11644 (define_insn "set_rip_rex64"
11645 [(set (match_operand:DI 0 "register_operand" "=r")
11646 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11648 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11649 [(set_attr "type" "lea")
11650 (set_attr "length_address" "4")
11651 (set_attr "mode" "DI")])
11653 (define_insn "set_got_offset_rex64"
11654 [(set (match_operand:DI 0 "register_operand" "=r")
11656 [(label_ref (match_operand 1 "" ""))]
11657 UNSPEC_SET_GOT_OFFSET))]
11659 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11660 [(set_attr "type" "imov")
11661 (set_attr "length_immediate" "0")
11662 (set_attr "length_address" "8")
11663 (set_attr "mode" "DI")])
11665 (define_expand "epilogue"
11668 "ix86_expand_epilogue (1); DONE;")
11670 (define_expand "sibcall_epilogue"
11673 "ix86_expand_epilogue (0); DONE;")
11675 (define_expand "eh_return"
11676 [(use (match_operand 0 "register_operand" ""))]
11679 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11681 /* Tricky bit: we write the address of the handler to which we will
11682 be returning into someone else's stack frame, one word below the
11683 stack address we wish to restore. */
11684 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11685 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11686 tmp = gen_rtx_MEM (Pmode, tmp);
11687 emit_move_insn (tmp, ra);
11689 emit_jump_insn (gen_eh_return_internal ());
11694 (define_insn_and_split "eh_return_internal"
11698 "epilogue_completed"
11700 "ix86_expand_epilogue (2); DONE;")
11702 (define_insn "leave"
11703 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11704 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11705 (clobber (mem:BLK (scratch)))]
11708 [(set_attr "type" "leave")])
11710 (define_insn "leave_rex64"
11711 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11712 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11713 (clobber (mem:BLK (scratch)))]
11716 [(set_attr "type" "leave")])
11718 ;; Handle -fsplit-stack.
11720 (define_expand "split_stack_prologue"
11724 ix86_expand_split_stack_prologue ();
11728 ;; In order to support the call/return predictor, we use a return
11729 ;; instruction which the middle-end doesn't see.
11730 (define_insn "split_stack_return"
11731 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11732 UNSPECV_SPLIT_STACK_RETURN)]
11735 if (operands[0] == const0_rtx)
11740 [(set_attr "atom_unit" "jeu")
11741 (set_attr "modrm" "0")
11742 (set (attr "length")
11743 (if_then_else (match_operand:SI 0 "const0_operand" "")
11746 (set (attr "length_immediate")
11747 (if_then_else (match_operand:SI 0 "const0_operand" "")
11751 ;; If there are operand 0 bytes available on the stack, jump to
11754 (define_expand "split_stack_space_check"
11755 [(set (pc) (if_then_else
11756 (ltu (minus (reg SP_REG)
11757 (match_operand 0 "register_operand" ""))
11758 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11759 (label_ref (match_operand 1 "" ""))
11763 rtx reg, size, limit;
11765 reg = gen_reg_rtx (Pmode);
11766 size = force_reg (Pmode, operands[0]);
11767 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11768 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11769 UNSPEC_STACK_CHECK);
11770 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11771 ix86_expand_branch (GEU, reg, limit, operands[1]);
11776 ;; Bit manipulation instructions.
11778 (define_expand "ffs<mode>2"
11779 [(set (match_dup 2) (const_int -1))
11780 (parallel [(set (reg:CCZ FLAGS_REG)
11782 (match_operand:SWI48 1 "nonimmediate_operand" "")
11784 (set (match_operand:SWI48 0 "register_operand" "")
11785 (ctz:SWI48 (match_dup 1)))])
11786 (set (match_dup 0) (if_then_else:SWI48
11787 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11790 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11791 (clobber (reg:CC FLAGS_REG))])]
11794 if (<MODE>mode == SImode && !TARGET_CMOVE)
11796 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11799 operands[2] = gen_reg_rtx (<MODE>mode);
11802 (define_insn_and_split "ffssi2_no_cmove"
11803 [(set (match_operand:SI 0 "register_operand" "=r")
11804 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11805 (clobber (match_scratch:SI 2 "=&q"))
11806 (clobber (reg:CC FLAGS_REG))]
11809 "&& reload_completed"
11810 [(parallel [(set (reg:CCZ FLAGS_REG)
11811 (compare:CCZ (match_dup 1) (const_int 0)))
11812 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11813 (set (strict_low_part (match_dup 3))
11814 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11815 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11816 (clobber (reg:CC FLAGS_REG))])
11817 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11818 (clobber (reg:CC FLAGS_REG))])
11819 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11820 (clobber (reg:CC FLAGS_REG))])]
11822 operands[3] = gen_lowpart (QImode, operands[2]);
11823 ix86_expand_clear (operands[2]);
11826 (define_insn "*ffs<mode>_1"
11827 [(set (reg:CCZ FLAGS_REG)
11828 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11830 (set (match_operand:SWI48 0 "register_operand" "=r")
11831 (ctz:SWI48 (match_dup 1)))]
11833 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11834 [(set_attr "type" "alu1")
11835 (set_attr "prefix_0f" "1")
11836 (set_attr "mode" "<MODE>")])
11838 (define_insn "ctz<mode>2"
11839 [(set (match_operand:SWI248 0 "register_operand" "=r")
11840 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11841 (clobber (reg:CC FLAGS_REG))]
11845 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11847 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11849 [(set_attr "type" "alu1")
11850 (set_attr "prefix_0f" "1")
11851 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11852 (set_attr "mode" "<MODE>")])
11854 (define_expand "clz<mode>2"
11856 [(set (match_operand:SWI248 0 "register_operand" "")
11859 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11860 (clobber (reg:CC FLAGS_REG))])
11862 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11863 (clobber (reg:CC FLAGS_REG))])]
11868 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11871 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11874 (define_insn "clz<mode>2_abm"
11875 [(set (match_operand:SWI248 0 "register_operand" "=r")
11876 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11877 (clobber (reg:CC FLAGS_REG))]
11878 "TARGET_ABM || TARGET_BMI"
11879 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11880 [(set_attr "prefix_rep" "1")
11881 (set_attr "type" "bitmanip")
11882 (set_attr "mode" "<MODE>")])
11884 ;; BMI instructions.
11885 (define_insn "*bmi_andn_<mode>"
11886 [(set (match_operand:SWI48 0 "register_operand" "=r")
11889 (match_operand:SWI48 1 "register_operand" "r"))
11890 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11891 (clobber (reg:CC FLAGS_REG))]
11893 "andn\t{%2, %1, %0|%0, %1, %2}"
11894 [(set_attr "type" "bitmanip")
11895 (set_attr "mode" "<MODE>")])
11897 (define_insn "bmi_bextr_<mode>"
11898 [(set (match_operand:SWI48 0 "register_operand" "=r")
11899 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11900 (match_operand:SWI48 2 "register_operand" "r")]
11902 (clobber (reg:CC FLAGS_REG))]
11904 "bextr\t{%2, %1, %0|%0, %1, %2}"
11905 [(set_attr "type" "bitmanip")
11906 (set_attr "mode" "<MODE>")])
11908 (define_insn "*bmi_blsi_<mode>"
11909 [(set (match_operand:SWI48 0 "register_operand" "=r")
11912 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11914 (clobber (reg:CC FLAGS_REG))]
11916 "blsi\t{%1, %0|%0, %1}"
11917 [(set_attr "type" "bitmanip")
11918 (set_attr "mode" "<MODE>")])
11920 (define_insn "*bmi_blsmsk_<mode>"
11921 [(set (match_operand:SWI48 0 "register_operand" "=r")
11924 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11927 (clobber (reg:CC FLAGS_REG))]
11929 "blsmsk\t{%1, %0|%0, %1}"
11930 [(set_attr "type" "bitmanip")
11931 (set_attr "mode" "<MODE>")])
11933 (define_insn "*bmi_blsr_<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 "blsr\t{%1, %0|%0, %1}"
11943 [(set_attr "type" "bitmanip")
11944 (set_attr "mode" "<MODE>")])
11946 ;; TBM instructions.
11947 (define_insn "tbm_bextri_<mode>"
11948 [(set (match_operand:SWI48 0 "register_operand" "=r")
11949 (zero_extract:SWI48
11950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11951 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11952 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11953 (clobber (reg:CC FLAGS_REG))]
11956 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11957 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11959 [(set_attr "type" "bitmanip")
11960 (set_attr "mode" "<MODE>")])
11962 (define_insn "*tbm_blcfill_<mode>"
11963 [(set (match_operand:SWI48 0 "register_operand" "=r")
11966 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11969 (clobber (reg:CC FLAGS_REG))]
11971 "blcfill\t{%1, %0|%0, %1}"
11972 [(set_attr "type" "bitmanip")
11973 (set_attr "mode" "<MODE>")])
11975 (define_insn "*tbm_blci_<mode>"
11976 [(set (match_operand:SWI48 0 "register_operand" "=r")
11980 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11983 (clobber (reg:CC FLAGS_REG))]
11985 "blci\t{%1, %0|%0, %1}"
11986 [(set_attr "type" "bitmanip")
11987 (set_attr "mode" "<MODE>")])
11989 (define_insn "*tbm_blcic_<mode>"
11990 [(set (match_operand:SWI48 0 "register_operand" "=r")
11993 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11997 (clobber (reg:CC FLAGS_REG))]
11999 "blcic\t{%1, %0|%0, %1}"
12000 [(set_attr "type" "bitmanip")
12001 (set_attr "mode" "<MODE>")])
12003 (define_insn "*tbm_blcmsk_<mode>"
12004 [(set (match_operand:SWI48 0 "register_operand" "=r")
12007 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12010 (clobber (reg:CC FLAGS_REG))]
12012 "blcmsk\t{%1, %0|%0, %1}"
12013 [(set_attr "type" "bitmanip")
12014 (set_attr "mode" "<MODE>")])
12016 (define_insn "*tbm_blcs_<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 "blcs\t{%1, %0|%0, %1}"
12026 [(set_attr "type" "bitmanip")
12027 (set_attr "mode" "<MODE>")])
12029 (define_insn "*tbm_blsfill_<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 "blsfill\t{%1, %0|%0, %1}"
12039 [(set_attr "type" "bitmanip")
12040 (set_attr "mode" "<MODE>")])
12042 (define_insn "*tbm_blsic_<mode>"
12043 [(set (match_operand:SWI48 0 "register_operand" "=r")
12046 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12050 (clobber (reg:CC FLAGS_REG))]
12052 "blsic\t{%1, %0|%0, %1}"
12053 [(set_attr "type" "bitmanip")
12054 (set_attr "mode" "<MODE>")])
12056 (define_insn "*tbm_t1mskc_<mode>"
12057 [(set (match_operand:SWI48 0 "register_operand" "=r")
12060 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12064 (clobber (reg:CC FLAGS_REG))]
12066 "t1mskc\t{%1, %0|%0, %1}"
12067 [(set_attr "type" "bitmanip")
12068 (set_attr "mode" "<MODE>")])
12070 (define_insn "*tbm_tzmsk_<mode>"
12071 [(set (match_operand:SWI48 0 "register_operand" "=r")
12074 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12078 (clobber (reg:CC FLAGS_REG))]
12080 "tzmsk\t{%1, %0|%0, %1}"
12081 [(set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12084 (define_insn "bsr_rex64"
12085 [(set (match_operand:DI 0 "register_operand" "=r")
12086 (minus:DI (const_int 63)
12087 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12088 (clobber (reg:CC FLAGS_REG))]
12090 "bsr{q}\t{%1, %0|%0, %1}"
12091 [(set_attr "type" "alu1")
12092 (set_attr "prefix_0f" "1")
12093 (set_attr "mode" "DI")])
12096 [(set (match_operand:SI 0 "register_operand" "=r")
12097 (minus:SI (const_int 31)
12098 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12099 (clobber (reg:CC FLAGS_REG))]
12101 "bsr{l}\t{%1, %0|%0, %1}"
12102 [(set_attr "type" "alu1")
12103 (set_attr "prefix_0f" "1")
12104 (set_attr "mode" "SI")])
12106 (define_insn "*bsrhi"
12107 [(set (match_operand:HI 0 "register_operand" "=r")
12108 (minus:HI (const_int 15)
12109 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12110 (clobber (reg:CC FLAGS_REG))]
12112 "bsr{w}\t{%1, %0|%0, %1}"
12113 [(set_attr "type" "alu1")
12114 (set_attr "prefix_0f" "1")
12115 (set_attr "mode" "HI")])
12117 (define_insn "popcount<mode>2"
12118 [(set (match_operand:SWI248 0 "register_operand" "=r")
12120 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12121 (clobber (reg:CC FLAGS_REG))]
12125 return "popcnt\t{%1, %0|%0, %1}";
12127 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12130 [(set_attr "prefix_rep" "1")
12131 (set_attr "type" "bitmanip")
12132 (set_attr "mode" "<MODE>")])
12134 (define_insn "*popcount<mode>2_cmp"
12135 [(set (reg FLAGS_REG)
12138 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12140 (set (match_operand:SWI248 0 "register_operand" "=r")
12141 (popcount:SWI248 (match_dup 1)))]
12142 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12145 return "popcnt\t{%1, %0|%0, %1}";
12147 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12150 [(set_attr "prefix_rep" "1")
12151 (set_attr "type" "bitmanip")
12152 (set_attr "mode" "<MODE>")])
12154 (define_insn "*popcountsi2_cmp_zext"
12155 [(set (reg FLAGS_REG)
12157 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12159 (set (match_operand:DI 0 "register_operand" "=r")
12160 (zero_extend:DI(popcount:SI (match_dup 1))))]
12161 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12164 return "popcnt\t{%1, %0|%0, %1}";
12166 return "popcnt{l}\t{%1, %0|%0, %1}";
12169 [(set_attr "prefix_rep" "1")
12170 (set_attr "type" "bitmanip")
12171 (set_attr "mode" "SI")])
12173 (define_expand "bswap<mode>2"
12174 [(set (match_operand:SWI48 0 "register_operand" "")
12175 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12178 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12180 rtx x = operands[0];
12182 emit_move_insn (x, operands[1]);
12183 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12184 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12185 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12190 (define_insn "*bswap<mode>2_movbe"
12191 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12192 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12197 movbe\t{%1, %0|%0, %1}
12198 movbe\t{%1, %0|%0, %1}"
12199 [(set_attr "type" "bitmanip,imov,imov")
12200 (set_attr "modrm" "0,1,1")
12201 (set_attr "prefix_0f" "*,1,1")
12202 (set_attr "prefix_extra" "*,1,1")
12203 (set_attr "mode" "<MODE>")])
12205 (define_insn "*bswap<mode>2_1"
12206 [(set (match_operand:SWI48 0 "register_operand" "=r")
12207 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12210 [(set_attr "type" "bitmanip")
12211 (set_attr "modrm" "0")
12212 (set_attr "mode" "<MODE>")])
12214 (define_insn "*bswaphi_lowpart_1"
12215 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12216 (bswap:HI (match_dup 0)))
12217 (clobber (reg:CC FLAGS_REG))]
12218 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12220 xchg{b}\t{%h0, %b0|%b0, %h0}
12221 rol{w}\t{$8, %0|%0, 8}"
12222 [(set_attr "length" "2,4")
12223 (set_attr "mode" "QI,HI")])
12225 (define_insn "bswaphi_lowpart"
12226 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12227 (bswap:HI (match_dup 0)))
12228 (clobber (reg:CC FLAGS_REG))]
12230 "rol{w}\t{$8, %0|%0, 8}"
12231 [(set_attr "length" "4")
12232 (set_attr "mode" "HI")])
12234 (define_expand "paritydi2"
12235 [(set (match_operand:DI 0 "register_operand" "")
12236 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12239 rtx scratch = gen_reg_rtx (QImode);
12242 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12243 NULL_RTX, operands[1]));
12245 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12246 gen_rtx_REG (CCmode, FLAGS_REG),
12248 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12251 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12254 rtx tmp = gen_reg_rtx (SImode);
12256 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12257 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12262 (define_expand "paritysi2"
12263 [(set (match_operand:SI 0 "register_operand" "")
12264 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12267 rtx scratch = gen_reg_rtx (QImode);
12270 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12272 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12273 gen_rtx_REG (CCmode, FLAGS_REG),
12275 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12277 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12281 (define_insn_and_split "paritydi2_cmp"
12282 [(set (reg:CC FLAGS_REG)
12283 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12285 (clobber (match_scratch:DI 0 "=r"))
12286 (clobber (match_scratch:SI 1 "=&r"))
12287 (clobber (match_scratch:HI 2 "=Q"))]
12290 "&& reload_completed"
12292 [(set (match_dup 1)
12293 (xor:SI (match_dup 1) (match_dup 4)))
12294 (clobber (reg:CC FLAGS_REG))])
12296 [(set (reg:CC FLAGS_REG)
12297 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12298 (clobber (match_dup 1))
12299 (clobber (match_dup 2))])]
12301 operands[4] = gen_lowpart (SImode, operands[3]);
12305 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12306 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12309 operands[1] = gen_highpart (SImode, operands[3]);
12312 (define_insn_and_split "paritysi2_cmp"
12313 [(set (reg:CC FLAGS_REG)
12314 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12316 (clobber (match_scratch:SI 0 "=r"))
12317 (clobber (match_scratch:HI 1 "=&Q"))]
12320 "&& reload_completed"
12322 [(set (match_dup 1)
12323 (xor:HI (match_dup 1) (match_dup 3)))
12324 (clobber (reg:CC FLAGS_REG))])
12326 [(set (reg:CC FLAGS_REG)
12327 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12328 (clobber (match_dup 1))])]
12330 operands[3] = gen_lowpart (HImode, operands[2]);
12332 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12333 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12336 (define_insn "*parityhi2_cmp"
12337 [(set (reg:CC FLAGS_REG)
12338 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12340 (clobber (match_scratch:HI 0 "=Q"))]
12342 "xor{b}\t{%h0, %b0|%b0, %h0}"
12343 [(set_attr "length" "2")
12344 (set_attr "mode" "HI")])
12346 ;; Thread-local storage patterns for ELF.
12348 ;; Note that these code sequences must appear exactly as shown
12349 ;; in order to allow linker relaxation.
12351 (define_insn "*tls_global_dynamic_32_gnu"
12352 [(set (match_operand:SI 0 "register_operand" "=a")
12354 [(match_operand:SI 1 "register_operand" "b")
12355 (match_operand:SI 2 "tls_symbolic_operand" "")
12356 (match_operand:SI 3 "constant_call_address_operand" "z")]
12358 (clobber (match_scratch:SI 4 "=d"))
12359 (clobber (match_scratch:SI 5 "=c"))
12360 (clobber (reg:CC FLAGS_REG))]
12361 "!TARGET_64BIT && TARGET_GNU_TLS"
12364 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12365 if (TARGET_SUN_TLS)
12366 #ifdef HAVE_AS_IX86_TLSGDPLT
12367 return "call\t%a2@tlsgdplt";
12369 return "call\t%p3@plt";
12371 return "call\t%P3";
12373 [(set_attr "type" "multi")
12374 (set_attr "length" "12")])
12376 (define_expand "tls_global_dynamic_32"
12378 [(set (match_operand:SI 0 "register_operand" "")
12379 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12380 (match_operand:SI 1 "tls_symbolic_operand" "")
12381 (match_operand:SI 3 "constant_call_address_operand" "")]
12383 (clobber (match_scratch:SI 4 ""))
12384 (clobber (match_scratch:SI 5 ""))
12385 (clobber (reg:CC FLAGS_REG))])])
12387 (define_insn "*tls_global_dynamic_64"
12388 [(set (match_operand:DI 0 "register_operand" "=a")
12390 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12391 (match_operand:DI 3 "" "")))
12392 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12396 fputs (ASM_BYTE "0x66\n", asm_out_file);
12398 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12399 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12400 fputs ("\trex64\n", asm_out_file);
12401 if (TARGET_SUN_TLS)
12402 return "call\t%p2@plt";
12403 return "call\t%P2";
12405 [(set_attr "type" "multi")
12406 (set_attr "length" "16")])
12408 (define_expand "tls_global_dynamic_64"
12410 [(set (match_operand:DI 0 "register_operand" "")
12412 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12414 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12417 (define_insn "*tls_local_dynamic_base_32_gnu"
12418 [(set (match_operand:SI 0 "register_operand" "=a")
12420 [(match_operand:SI 1 "register_operand" "b")
12421 (match_operand:SI 2 "constant_call_address_operand" "z")]
12422 UNSPEC_TLS_LD_BASE))
12423 (clobber (match_scratch:SI 3 "=d"))
12424 (clobber (match_scratch:SI 4 "=c"))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "!TARGET_64BIT && TARGET_GNU_TLS"
12429 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12430 if (TARGET_SUN_TLS)
12431 #ifdef HAVE_AS_IX86_TLSLDMPLT
12432 return "call\t%&@tlsldmplt";
12434 return "call\t%p2@plt";
12436 return "call\t%P2";
12438 [(set_attr "type" "multi")
12439 (set_attr "length" "11")])
12441 (define_expand "tls_local_dynamic_base_32"
12443 [(set (match_operand:SI 0 "register_operand" "")
12445 [(match_operand:SI 1 "register_operand" "")
12446 (match_operand:SI 2 "constant_call_address_operand" "")]
12447 UNSPEC_TLS_LD_BASE))
12448 (clobber (match_scratch:SI 3 ""))
12449 (clobber (match_scratch:SI 4 ""))
12450 (clobber (reg:CC FLAGS_REG))])])
12452 (define_insn "*tls_local_dynamic_base_64"
12453 [(set (match_operand:DI 0 "register_operand" "=a")
12455 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12456 (match_operand:DI 2 "" "")))
12457 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12461 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12462 if (TARGET_SUN_TLS)
12463 return "call\t%p1@plt";
12464 return "call\t%P1";
12466 [(set_attr "type" "multi")
12467 (set_attr "length" "12")])
12469 (define_expand "tls_local_dynamic_base_64"
12471 [(set (match_operand:DI 0 "register_operand" "")
12473 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12475 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12477 ;; Local dynamic of a single variable is a lose. Show combine how
12478 ;; to convert that back to global dynamic.
12480 (define_insn_and_split "*tls_local_dynamic_32_once"
12481 [(set (match_operand:SI 0 "register_operand" "=a")
12483 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12484 (match_operand:SI 2 "constant_call_address_operand" "z")]
12485 UNSPEC_TLS_LD_BASE)
12486 (const:SI (unspec:SI
12487 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12489 (clobber (match_scratch:SI 4 "=d"))
12490 (clobber (match_scratch:SI 5 "=c"))
12491 (clobber (reg:CC FLAGS_REG))]
12496 [(set (match_dup 0)
12497 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12499 (clobber (match_dup 4))
12500 (clobber (match_dup 5))
12501 (clobber (reg:CC FLAGS_REG))])])
12503 ;; Segment register for the thread base ptr load
12504 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12506 ;; Load and add the thread base pointer from %<tp_seg>:0.
12507 (define_insn "*load_tp_<mode>"
12508 [(set (match_operand:P 0 "register_operand" "=r")
12509 (unspec:P [(const_int 0)] UNSPEC_TP))]
12511 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12512 [(set_attr "type" "imov")
12513 (set_attr "modrm" "0")
12514 (set_attr "length" "7")
12515 (set_attr "memory" "load")
12516 (set_attr "imm_disp" "false")])
12518 (define_insn "*add_tp_<mode>"
12519 [(set (match_operand:P 0 "register_operand" "=r")
12520 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12521 (match_operand:P 1 "register_operand" "0")))
12522 (clobber (reg:CC FLAGS_REG))]
12524 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12525 [(set_attr "type" "alu")
12526 (set_attr "modrm" "0")
12527 (set_attr "length" "7")
12528 (set_attr "memory" "load")
12529 (set_attr "imm_disp" "false")])
12531 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12532 ;; %rax as destination of the initial executable code sequence.
12533 (define_insn "tls_initial_exec_64_sun"
12534 [(set (match_operand:DI 0 "register_operand" "=a")
12536 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12537 UNSPEC_TLS_IE_SUN))
12538 (clobber (reg:CC FLAGS_REG))]
12539 "TARGET_64BIT && TARGET_SUN_TLS"
12542 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12543 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12545 [(set_attr "type" "multi")])
12547 ;; GNU2 TLS patterns can be split.
12549 (define_expand "tls_dynamic_gnu2_32"
12550 [(set (match_dup 3)
12551 (plus:SI (match_operand:SI 2 "register_operand" "")
12553 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12556 [(set (match_operand:SI 0 "register_operand" "")
12557 (unspec:SI [(match_dup 1) (match_dup 3)
12558 (match_dup 2) (reg:SI SP_REG)]
12560 (clobber (reg:CC FLAGS_REG))])]
12561 "!TARGET_64BIT && TARGET_GNU2_TLS"
12563 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12564 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12567 (define_insn "*tls_dynamic_lea_32"
12568 [(set (match_operand:SI 0 "register_operand" "=r")
12569 (plus:SI (match_operand:SI 1 "register_operand" "b")
12571 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12572 UNSPEC_TLSDESC))))]
12573 "!TARGET_64BIT && TARGET_GNU2_TLS"
12574 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12575 [(set_attr "type" "lea")
12576 (set_attr "mode" "SI")
12577 (set_attr "length" "6")
12578 (set_attr "length_address" "4")])
12580 (define_insn "*tls_dynamic_call_32"
12581 [(set (match_operand:SI 0 "register_operand" "=a")
12582 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12583 (match_operand:SI 2 "register_operand" "0")
12584 ;; we have to make sure %ebx still points to the GOT
12585 (match_operand:SI 3 "register_operand" "b")
12588 (clobber (reg:CC FLAGS_REG))]
12589 "!TARGET_64BIT && TARGET_GNU2_TLS"
12590 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12591 [(set_attr "type" "call")
12592 (set_attr "length" "2")
12593 (set_attr "length_address" "0")])
12595 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12596 [(set (match_operand:SI 0 "register_operand" "=&a")
12598 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12599 (match_operand:SI 4 "" "")
12600 (match_operand:SI 2 "register_operand" "b")
12603 (const:SI (unspec:SI
12604 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12606 (clobber (reg:CC FLAGS_REG))]
12607 "!TARGET_64BIT && TARGET_GNU2_TLS"
12610 [(set (match_dup 0) (match_dup 5))]
12612 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12613 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12616 (define_expand "tls_dynamic_gnu2_64"
12617 [(set (match_dup 2)
12618 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12621 [(set (match_operand:DI 0 "register_operand" "")
12622 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12624 (clobber (reg:CC FLAGS_REG))])]
12625 "TARGET_64BIT && TARGET_GNU2_TLS"
12627 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12628 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12631 (define_insn "*tls_dynamic_lea_64"
12632 [(set (match_operand:DI 0 "register_operand" "=r")
12633 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12635 "TARGET_64BIT && TARGET_GNU2_TLS"
12636 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12637 [(set_attr "type" "lea")
12638 (set_attr "mode" "DI")
12639 (set_attr "length" "7")
12640 (set_attr "length_address" "4")])
12642 (define_insn "*tls_dynamic_call_64"
12643 [(set (match_operand:DI 0 "register_operand" "=a")
12644 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12645 (match_operand:DI 2 "register_operand" "0")
12648 (clobber (reg:CC FLAGS_REG))]
12649 "TARGET_64BIT && TARGET_GNU2_TLS"
12650 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12651 [(set_attr "type" "call")
12652 (set_attr "length" "2")
12653 (set_attr "length_address" "0")])
12655 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12656 [(set (match_operand:DI 0 "register_operand" "=&a")
12658 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12659 (match_operand:DI 3 "" "")
12662 (const:DI (unspec:DI
12663 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12665 (clobber (reg:CC FLAGS_REG))]
12666 "TARGET_64BIT && TARGET_GNU2_TLS"
12669 [(set (match_dup 0) (match_dup 4))]
12671 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12672 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12675 ;; These patterns match the binary 387 instructions for addM3, subM3,
12676 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12677 ;; SFmode. The first is the normal insn, the second the same insn but
12678 ;; with one operand a conversion, and the third the same insn but with
12679 ;; the other operand a conversion. The conversion may be SFmode or
12680 ;; SImode if the target mode DFmode, but only SImode if the target mode
12683 ;; Gcc is slightly more smart about handling normal two address instructions
12684 ;; so use special patterns for add and mull.
12686 (define_insn "*fop_<mode>_comm_mixed"
12687 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12688 (match_operator:MODEF 3 "binary_fp_operator"
12689 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12690 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12691 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12692 && COMMUTATIVE_ARITH_P (operands[3])
12693 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694 "* return output_387_binary_op (insn, operands);"
12695 [(set (attr "type")
12696 (if_then_else (eq_attr "alternative" "1,2")
12697 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12698 (const_string "ssemul")
12699 (const_string "sseadd"))
12700 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12701 (const_string "fmul")
12702 (const_string "fop"))))
12703 (set_attr "isa" "base,noavx,avx")
12704 (set_attr "prefix" "orig,orig,vex")
12705 (set_attr "mode" "<MODE>")])
12707 (define_insn "*fop_<mode>_comm_sse"
12708 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12709 (match_operator:MODEF 3 "binary_fp_operator"
12710 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12711 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12712 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12713 && COMMUTATIVE_ARITH_P (operands[3])
12714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12715 "* return output_387_binary_op (insn, operands);"
12716 [(set (attr "type")
12717 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12718 (const_string "ssemul")
12719 (const_string "sseadd")))
12720 (set_attr "isa" "noavx,avx")
12721 (set_attr "prefix" "orig,vex")
12722 (set_attr "mode" "<MODE>")])
12724 (define_insn "*fop_<mode>_comm_i387"
12725 [(set (match_operand:MODEF 0 "register_operand" "=f")
12726 (match_operator:MODEF 3 "binary_fp_operator"
12727 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12728 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12729 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12730 && COMMUTATIVE_ARITH_P (operands[3])
12731 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12732 "* return output_387_binary_op (insn, operands);"
12733 [(set (attr "type")
12734 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12735 (const_string "fmul")
12736 (const_string "fop")))
12737 (set_attr "mode" "<MODE>")])
12739 (define_insn "*fop_<mode>_1_mixed"
12740 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12741 (match_operator:MODEF 3 "binary_fp_operator"
12742 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12743 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12744 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12745 && !COMMUTATIVE_ARITH_P (operands[3])
12746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12747 "* return output_387_binary_op (insn, operands);"
12748 [(set (attr "type")
12749 (cond [(and (eq_attr "alternative" "2,3")
12750 (match_operand:MODEF 3 "mult_operator" ""))
12751 (const_string "ssemul")
12752 (and (eq_attr "alternative" "2,3")
12753 (match_operand:MODEF 3 "div_operator" ""))
12754 (const_string "ssediv")
12755 (eq_attr "alternative" "2,3")
12756 (const_string "sseadd")
12757 (match_operand:MODEF 3 "mult_operator" "")
12758 (const_string "fmul")
12759 (match_operand:MODEF 3 "div_operator" "")
12760 (const_string "fdiv")
12762 (const_string "fop")))
12763 (set_attr "isa" "base,base,noavx,avx")
12764 (set_attr "prefix" "orig,orig,orig,vex")
12765 (set_attr "mode" "<MODE>")])
12767 (define_insn "*rcpsf2_sse"
12768 [(set (match_operand:SF 0 "register_operand" "=x")
12769 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12772 "%vrcpss\t{%1, %d0|%d0, %1}"
12773 [(set_attr "type" "sse")
12774 (set_attr "atom_sse_attr" "rcp")
12775 (set_attr "prefix" "maybe_vex")
12776 (set_attr "mode" "SF")])
12778 (define_insn "*fop_<mode>_1_sse"
12779 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12780 (match_operator:MODEF 3 "binary_fp_operator"
12781 [(match_operand:MODEF 1 "register_operand" "0,x")
12782 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12783 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12784 && !COMMUTATIVE_ARITH_P (operands[3])"
12785 "* return output_387_binary_op (insn, operands);"
12786 [(set (attr "type")
12787 (cond [(match_operand:MODEF 3 "mult_operator" "")
12788 (const_string "ssemul")
12789 (match_operand:MODEF 3 "div_operator" "")
12790 (const_string "ssediv")
12792 (const_string "sseadd")))
12793 (set_attr "isa" "noavx,avx")
12794 (set_attr "prefix" "orig,vex")
12795 (set_attr "mode" "<MODE>")])
12797 ;; This pattern is not fully shadowed by the pattern above.
12798 (define_insn "*fop_<mode>_1_i387"
12799 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12800 (match_operator:MODEF 3 "binary_fp_operator"
12801 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12802 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12803 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12804 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12805 && !COMMUTATIVE_ARITH_P (operands[3])
12806 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12807 "* return output_387_binary_op (insn, operands);"
12808 [(set (attr "type")
12809 (cond [(match_operand:MODEF 3 "mult_operator" "")
12810 (const_string "fmul")
12811 (match_operand:MODEF 3 "div_operator" "")
12812 (const_string "fdiv")
12814 (const_string "fop")))
12815 (set_attr "mode" "<MODE>")])
12817 ;; ??? Add SSE splitters for these!
12818 (define_insn "*fop_<MODEF:mode>_2_i387"
12819 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12820 (match_operator:MODEF 3 "binary_fp_operator"
12822 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12823 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12824 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12825 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12826 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12827 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12828 [(set (attr "type")
12829 (cond [(match_operand:MODEF 3 "mult_operator" "")
12830 (const_string "fmul")
12831 (match_operand:MODEF 3 "div_operator" "")
12832 (const_string "fdiv")
12834 (const_string "fop")))
12835 (set_attr "fp_int_src" "true")
12836 (set_attr "mode" "<SWI24:MODE>")])
12838 (define_insn "*fop_<MODEF:mode>_3_i387"
12839 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12840 (match_operator:MODEF 3 "binary_fp_operator"
12841 [(match_operand:MODEF 1 "register_operand" "0,0")
12843 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12844 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12845 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12846 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12847 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12848 [(set (attr "type")
12849 (cond [(match_operand:MODEF 3 "mult_operator" "")
12850 (const_string "fmul")
12851 (match_operand:MODEF 3 "div_operator" "")
12852 (const_string "fdiv")
12854 (const_string "fop")))
12855 (set_attr "fp_int_src" "true")
12856 (set_attr "mode" "<MODE>")])
12858 (define_insn "*fop_df_4_i387"
12859 [(set (match_operand:DF 0 "register_operand" "=f,f")
12860 (match_operator:DF 3 "binary_fp_operator"
12862 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12863 (match_operand:DF 2 "register_operand" "0,f")]))]
12864 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12865 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12867 "* return output_387_binary_op (insn, operands);"
12868 [(set (attr "type")
12869 (cond [(match_operand:DF 3 "mult_operator" "")
12870 (const_string "fmul")
12871 (match_operand:DF 3 "div_operator" "")
12872 (const_string "fdiv")
12874 (const_string "fop")))
12875 (set_attr "mode" "SF")])
12877 (define_insn "*fop_df_5_i387"
12878 [(set (match_operand:DF 0 "register_operand" "=f,f")
12879 (match_operator:DF 3 "binary_fp_operator"
12880 [(match_operand:DF 1 "register_operand" "0,f")
12882 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12883 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12884 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12885 "* return output_387_binary_op (insn, operands);"
12886 [(set (attr "type")
12887 (cond [(match_operand:DF 3 "mult_operator" "")
12888 (const_string "fmul")
12889 (match_operand:DF 3 "div_operator" "")
12890 (const_string "fdiv")
12892 (const_string "fop")))
12893 (set_attr "mode" "SF")])
12895 (define_insn "*fop_df_6_i387"
12896 [(set (match_operand:DF 0 "register_operand" "=f,f")
12897 (match_operator:DF 3 "binary_fp_operator"
12899 (match_operand:SF 1 "register_operand" "0,f"))
12901 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12902 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12903 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12904 "* return output_387_binary_op (insn, operands);"
12905 [(set (attr "type")
12906 (cond [(match_operand:DF 3 "mult_operator" "")
12907 (const_string "fmul")
12908 (match_operand:DF 3 "div_operator" "")
12909 (const_string "fdiv")
12911 (const_string "fop")))
12912 (set_attr "mode" "SF")])
12914 (define_insn "*fop_xf_comm_i387"
12915 [(set (match_operand:XF 0 "register_operand" "=f")
12916 (match_operator:XF 3 "binary_fp_operator"
12917 [(match_operand:XF 1 "register_operand" "%0")
12918 (match_operand:XF 2 "register_operand" "f")]))]
12920 && COMMUTATIVE_ARITH_P (operands[3])"
12921 "* return output_387_binary_op (insn, operands);"
12922 [(set (attr "type")
12923 (if_then_else (match_operand:XF 3 "mult_operator" "")
12924 (const_string "fmul")
12925 (const_string "fop")))
12926 (set_attr "mode" "XF")])
12928 (define_insn "*fop_xf_1_i387"
12929 [(set (match_operand:XF 0 "register_operand" "=f,f")
12930 (match_operator:XF 3 "binary_fp_operator"
12931 [(match_operand:XF 1 "register_operand" "0,f")
12932 (match_operand:XF 2 "register_operand" "f,0")]))]
12934 && !COMMUTATIVE_ARITH_P (operands[3])"
12935 "* return output_387_binary_op (insn, operands);"
12936 [(set (attr "type")
12937 (cond [(match_operand:XF 3 "mult_operator" "")
12938 (const_string "fmul")
12939 (match_operand:XF 3 "div_operator" "")
12940 (const_string "fdiv")
12942 (const_string "fop")))
12943 (set_attr "mode" "XF")])
12945 (define_insn "*fop_xf_2_i387"
12946 [(set (match_operand:XF 0 "register_operand" "=f,f")
12947 (match_operator:XF 3 "binary_fp_operator"
12949 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12950 (match_operand:XF 2 "register_operand" "0,0")]))]
12951 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12952 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12953 [(set (attr "type")
12954 (cond [(match_operand:XF 3 "mult_operator" "")
12955 (const_string "fmul")
12956 (match_operand:XF 3 "div_operator" "")
12957 (const_string "fdiv")
12959 (const_string "fop")))
12960 (set_attr "fp_int_src" "true")
12961 (set_attr "mode" "<MODE>")])
12963 (define_insn "*fop_xf_3_i387"
12964 [(set (match_operand:XF 0 "register_operand" "=f,f")
12965 (match_operator:XF 3 "binary_fp_operator"
12966 [(match_operand:XF 1 "register_operand" "0,0")
12968 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12969 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12970 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12971 [(set (attr "type")
12972 (cond [(match_operand:XF 3 "mult_operator" "")
12973 (const_string "fmul")
12974 (match_operand:XF 3 "div_operator" "")
12975 (const_string "fdiv")
12977 (const_string "fop")))
12978 (set_attr "fp_int_src" "true")
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "*fop_xf_4_i387"
12982 [(set (match_operand:XF 0 "register_operand" "=f,f")
12983 (match_operator:XF 3 "binary_fp_operator"
12985 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12986 (match_operand:XF 2 "register_operand" "0,f")]))]
12988 "* return output_387_binary_op (insn, operands);"
12989 [(set (attr "type")
12990 (cond [(match_operand:XF 3 "mult_operator" "")
12991 (const_string "fmul")
12992 (match_operand:XF 3 "div_operator" "")
12993 (const_string "fdiv")
12995 (const_string "fop")))
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_xf_5_i387"
12999 [(set (match_operand:XF 0 "register_operand" "=f,f")
13000 (match_operator:XF 3 "binary_fp_operator"
13001 [(match_operand:XF 1 "register_operand" "0,f")
13003 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13005 "* return output_387_binary_op (insn, operands);"
13006 [(set (attr "type")
13007 (cond [(match_operand:XF 3 "mult_operator" "")
13008 (const_string "fmul")
13009 (match_operand:XF 3 "div_operator" "")
13010 (const_string "fdiv")
13012 (const_string "fop")))
13013 (set_attr "mode" "<MODE>")])
13015 (define_insn "*fop_xf_6_i387"
13016 [(set (match_operand:XF 0 "register_operand" "=f,f")
13017 (match_operator:XF 3 "binary_fp_operator"
13019 (match_operand:MODEF 1 "register_operand" "0,f"))
13021 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13023 "* return output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (cond [(match_operand:XF 3 "mult_operator" "")
13026 (const_string "fmul")
13027 (match_operand:XF 3 "div_operator" "")
13028 (const_string "fdiv")
13030 (const_string "fop")))
13031 (set_attr "mode" "<MODE>")])
13034 [(set (match_operand 0 "register_operand" "")
13035 (match_operator 3 "binary_fp_operator"
13036 [(float (match_operand:SWI24 1 "register_operand" ""))
13037 (match_operand 2 "register_operand" "")]))]
13039 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13040 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13043 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13044 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13045 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13046 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13047 GET_MODE (operands[3]),
13050 ix86_free_from_memory (GET_MODE (operands[1]));
13055 [(set (match_operand 0 "register_operand" "")
13056 (match_operator 3 "binary_fp_operator"
13057 [(match_operand 1 "register_operand" "")
13058 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13060 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13061 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13064 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13065 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13066 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13067 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13068 GET_MODE (operands[3]),
13071 ix86_free_from_memory (GET_MODE (operands[2]));
13075 ;; FPU special functions.
13077 ;; This pattern implements a no-op XFmode truncation for
13078 ;; all fancy i386 XFmode math functions.
13080 (define_insn "truncxf<mode>2_i387_noop_unspec"
13081 [(set (match_operand:MODEF 0 "register_operand" "=f")
13082 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13083 UNSPEC_TRUNC_NOOP))]
13084 "TARGET_USE_FANCY_MATH_387"
13085 "* return output_387_reg_move (insn, operands);"
13086 [(set_attr "type" "fmov")
13087 (set_attr "mode" "<MODE>")])
13089 (define_insn "sqrtxf2"
13090 [(set (match_operand:XF 0 "register_operand" "=f")
13091 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13092 "TARGET_USE_FANCY_MATH_387"
13094 [(set_attr "type" "fpspc")
13095 (set_attr "mode" "XF")
13096 (set_attr "athlon_decode" "direct")
13097 (set_attr "amdfam10_decode" "direct")
13098 (set_attr "bdver1_decode" "direct")])
13100 (define_insn "sqrt_extend<mode>xf2_i387"
13101 [(set (match_operand:XF 0 "register_operand" "=f")
13104 (match_operand:MODEF 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 "*rsqrtsf2_sse"
13114 [(set (match_operand:SF 0 "register_operand" "=x")
13115 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13118 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13119 [(set_attr "type" "sse")
13120 (set_attr "atom_sse_attr" "rcp")
13121 (set_attr "prefix" "maybe_vex")
13122 (set_attr "mode" "SF")])
13124 (define_expand "rsqrtsf2"
13125 [(set (match_operand:SF 0 "register_operand" "")
13126 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13130 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13134 (define_insn "*sqrt<mode>2_sse"
13135 [(set (match_operand:MODEF 0 "register_operand" "=x")
13137 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13138 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13139 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13140 [(set_attr "type" "sse")
13141 (set_attr "atom_sse_attr" "sqrt")
13142 (set_attr "prefix" "maybe_vex")
13143 (set_attr "mode" "<MODE>")
13144 (set_attr "athlon_decode" "*")
13145 (set_attr "amdfam10_decode" "*")
13146 (set_attr "bdver1_decode" "*")])
13148 (define_expand "sqrt<mode>2"
13149 [(set (match_operand:MODEF 0 "register_operand" "")
13151 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13152 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13153 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13155 if (<MODE>mode == SFmode
13156 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13157 && flag_finite_math_only && !flag_trapping_math
13158 && flag_unsafe_math_optimizations)
13160 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13164 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13166 rtx op0 = gen_reg_rtx (XFmode);
13167 rtx op1 = force_reg (<MODE>mode, operands[1]);
13169 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13170 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13175 (define_insn "fpremxf4_i387"
13176 [(set (match_operand:XF 0 "register_operand" "=f")
13177 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13178 (match_operand:XF 3 "register_operand" "1")]
13180 (set (match_operand:XF 1 "register_operand" "=u")
13181 (unspec:XF [(match_dup 2) (match_dup 3)]
13183 (set (reg:CCFP FPSR_REG)
13184 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13186 "TARGET_USE_FANCY_MATH_387"
13188 [(set_attr "type" "fpspc")
13189 (set_attr "mode" "XF")])
13191 (define_expand "fmodxf3"
13192 [(use (match_operand:XF 0 "register_operand" ""))
13193 (use (match_operand:XF 1 "general_operand" ""))
13194 (use (match_operand:XF 2 "general_operand" ""))]
13195 "TARGET_USE_FANCY_MATH_387"
13197 rtx label = gen_label_rtx ();
13199 rtx op1 = gen_reg_rtx (XFmode);
13200 rtx op2 = gen_reg_rtx (XFmode);
13202 emit_move_insn (op2, operands[2]);
13203 emit_move_insn (op1, operands[1]);
13205 emit_label (label);
13206 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13207 ix86_emit_fp_unordered_jump (label);
13208 LABEL_NUSES (label) = 1;
13210 emit_move_insn (operands[0], op1);
13214 (define_expand "fmod<mode>3"
13215 [(use (match_operand:MODEF 0 "register_operand" ""))
13216 (use (match_operand:MODEF 1 "general_operand" ""))
13217 (use (match_operand:MODEF 2 "general_operand" ""))]
13218 "TARGET_USE_FANCY_MATH_387"
13220 rtx (*gen_truncxf) (rtx, rtx);
13222 rtx label = gen_label_rtx ();
13224 rtx op1 = gen_reg_rtx (XFmode);
13225 rtx op2 = gen_reg_rtx (XFmode);
13227 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13228 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13230 emit_label (label);
13231 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13232 ix86_emit_fp_unordered_jump (label);
13233 LABEL_NUSES (label) = 1;
13235 /* Truncate the result properly for strict SSE math. */
13236 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13237 && !TARGET_MIX_SSE_I387)
13238 gen_truncxf = gen_truncxf<mode>2;
13240 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13242 emit_insn (gen_truncxf (operands[0], op1));
13246 (define_insn "fprem1xf4_i387"
13247 [(set (match_operand:XF 0 "register_operand" "=f")
13248 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13249 (match_operand:XF 3 "register_operand" "1")]
13251 (set (match_operand:XF 1 "register_operand" "=u")
13252 (unspec:XF [(match_dup 2) (match_dup 3)]
13254 (set (reg:CCFP FPSR_REG)
13255 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13257 "TARGET_USE_FANCY_MATH_387"
13259 [(set_attr "type" "fpspc")
13260 (set_attr "mode" "XF")])
13262 (define_expand "remainderxf3"
13263 [(use (match_operand:XF 0 "register_operand" ""))
13264 (use (match_operand:XF 1 "general_operand" ""))
13265 (use (match_operand:XF 2 "general_operand" ""))]
13266 "TARGET_USE_FANCY_MATH_387"
13268 rtx label = gen_label_rtx ();
13270 rtx op1 = gen_reg_rtx (XFmode);
13271 rtx op2 = gen_reg_rtx (XFmode);
13273 emit_move_insn (op2, operands[2]);
13274 emit_move_insn (op1, operands[1]);
13276 emit_label (label);
13277 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13278 ix86_emit_fp_unordered_jump (label);
13279 LABEL_NUSES (label) = 1;
13281 emit_move_insn (operands[0], op1);
13285 (define_expand "remainder<mode>3"
13286 [(use (match_operand:MODEF 0 "register_operand" ""))
13287 (use (match_operand:MODEF 1 "general_operand" ""))
13288 (use (match_operand:MODEF 2 "general_operand" ""))]
13289 "TARGET_USE_FANCY_MATH_387"
13291 rtx (*gen_truncxf) (rtx, rtx);
13293 rtx label = gen_label_rtx ();
13295 rtx op1 = gen_reg_rtx (XFmode);
13296 rtx op2 = gen_reg_rtx (XFmode);
13298 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13299 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13301 emit_label (label);
13303 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13304 ix86_emit_fp_unordered_jump (label);
13305 LABEL_NUSES (label) = 1;
13307 /* Truncate the result properly for strict SSE math. */
13308 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13309 && !TARGET_MIX_SSE_I387)
13310 gen_truncxf = gen_truncxf<mode>2;
13312 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13314 emit_insn (gen_truncxf (operands[0], op1));
13318 (define_insn "*sinxf2_i387"
13319 [(set (match_operand:XF 0 "register_operand" "=f")
13320 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13321 "TARGET_USE_FANCY_MATH_387
13322 && flag_unsafe_math_optimizations"
13324 [(set_attr "type" "fpspc")
13325 (set_attr "mode" "XF")])
13327 (define_insn "*sin_extend<mode>xf2_i387"
13328 [(set (match_operand:XF 0 "register_operand" "=f")
13329 (unspec:XF [(float_extend:XF
13330 (match_operand:MODEF 1 "register_operand" "0"))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13334 || TARGET_MIX_SSE_I387)
13335 && flag_unsafe_math_optimizations"
13337 [(set_attr "type" "fpspc")
13338 (set_attr "mode" "XF")])
13340 (define_insn "*cosxf2_i387"
13341 [(set (match_operand:XF 0 "register_operand" "=f")
13342 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13343 "TARGET_USE_FANCY_MATH_387
13344 && flag_unsafe_math_optimizations"
13346 [(set_attr "type" "fpspc")
13347 (set_attr "mode" "XF")])
13349 (define_insn "*cos_extend<mode>xf2_i387"
13350 [(set (match_operand:XF 0 "register_operand" "=f")
13351 (unspec:XF [(float_extend:XF
13352 (match_operand:MODEF 1 "register_operand" "0"))]
13354 "TARGET_USE_FANCY_MATH_387
13355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13356 || TARGET_MIX_SSE_I387)
13357 && flag_unsafe_math_optimizations"
13359 [(set_attr "type" "fpspc")
13360 (set_attr "mode" "XF")])
13362 ;; When sincos pattern is defined, sin and cos builtin functions will be
13363 ;; expanded to sincos pattern with one of its outputs left unused.
13364 ;; CSE pass will figure out if two sincos patterns can be combined,
13365 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13366 ;; depending on the unused output.
13368 (define_insn "sincosxf3"
13369 [(set (match_operand:XF 0 "register_operand" "=f")
13370 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13371 UNSPEC_SINCOS_COS))
13372 (set (match_operand:XF 1 "register_operand" "=u")
13373 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13374 "TARGET_USE_FANCY_MATH_387
13375 && flag_unsafe_math_optimizations"
13377 [(set_attr "type" "fpspc")
13378 (set_attr "mode" "XF")])
13381 [(set (match_operand:XF 0 "register_operand" "")
13382 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13383 UNSPEC_SINCOS_COS))
13384 (set (match_operand:XF 1 "register_operand" "")
13385 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13386 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13387 && can_create_pseudo_p ()"
13388 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13391 [(set (match_operand:XF 0 "register_operand" "")
13392 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13393 UNSPEC_SINCOS_COS))
13394 (set (match_operand:XF 1 "register_operand" "")
13395 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13396 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13397 && can_create_pseudo_p ()"
13398 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13400 (define_insn "sincos_extend<mode>xf3_i387"
13401 [(set (match_operand:XF 0 "register_operand" "=f")
13402 (unspec:XF [(float_extend:XF
13403 (match_operand:MODEF 2 "register_operand" "0"))]
13404 UNSPEC_SINCOS_COS))
13405 (set (match_operand:XF 1 "register_operand" "=u")
13406 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13407 "TARGET_USE_FANCY_MATH_387
13408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13409 || TARGET_MIX_SSE_I387)
13410 && flag_unsafe_math_optimizations"
13412 [(set_attr "type" "fpspc")
13413 (set_attr "mode" "XF")])
13416 [(set (match_operand:XF 0 "register_operand" "")
13417 (unspec:XF [(float_extend:XF
13418 (match_operand:MODEF 2 "register_operand" ""))]
13419 UNSPEC_SINCOS_COS))
13420 (set (match_operand:XF 1 "register_operand" "")
13421 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13422 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13423 && can_create_pseudo_p ()"
13424 [(set (match_dup 1)
13425 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13428 [(set (match_operand:XF 0 "register_operand" "")
13429 (unspec:XF [(float_extend:XF
13430 (match_operand:MODEF 2 "register_operand" ""))]
13431 UNSPEC_SINCOS_COS))
13432 (set (match_operand:XF 1 "register_operand" "")
13433 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13434 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13435 && can_create_pseudo_p ()"
13436 [(set (match_dup 0)
13437 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13439 (define_expand "sincos<mode>3"
13440 [(use (match_operand:MODEF 0 "register_operand" ""))
13441 (use (match_operand:MODEF 1 "register_operand" ""))
13442 (use (match_operand:MODEF 2 "register_operand" ""))]
13443 "TARGET_USE_FANCY_MATH_387
13444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13445 || TARGET_MIX_SSE_I387)
13446 && flag_unsafe_math_optimizations"
13448 rtx op0 = gen_reg_rtx (XFmode);
13449 rtx op1 = gen_reg_rtx (XFmode);
13451 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13452 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13453 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13457 (define_insn "fptanxf4_i387"
13458 [(set (match_operand:XF 0 "register_operand" "=f")
13459 (match_operand:XF 3 "const_double_operand" "F"))
13460 (set (match_operand:XF 1 "register_operand" "=u")
13461 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13463 "TARGET_USE_FANCY_MATH_387
13464 && flag_unsafe_math_optimizations
13465 && standard_80387_constant_p (operands[3]) == 2"
13467 [(set_attr "type" "fpspc")
13468 (set_attr "mode" "XF")])
13470 (define_insn "fptan_extend<mode>xf4_i387"
13471 [(set (match_operand:MODEF 0 "register_operand" "=f")
13472 (match_operand:MODEF 3 "const_double_operand" "F"))
13473 (set (match_operand:XF 1 "register_operand" "=u")
13474 (unspec:XF [(float_extend:XF
13475 (match_operand:MODEF 2 "register_operand" "0"))]
13477 "TARGET_USE_FANCY_MATH_387
13478 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13479 || TARGET_MIX_SSE_I387)
13480 && flag_unsafe_math_optimizations
13481 && standard_80387_constant_p (operands[3]) == 2"
13483 [(set_attr "type" "fpspc")
13484 (set_attr "mode" "XF")])
13486 (define_expand "tanxf2"
13487 [(use (match_operand:XF 0 "register_operand" ""))
13488 (use (match_operand:XF 1 "register_operand" ""))]
13489 "TARGET_USE_FANCY_MATH_387
13490 && flag_unsafe_math_optimizations"
13492 rtx one = gen_reg_rtx (XFmode);
13493 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13495 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13499 (define_expand "tan<mode>2"
13500 [(use (match_operand:MODEF 0 "register_operand" ""))
13501 (use (match_operand:MODEF 1 "register_operand" ""))]
13502 "TARGET_USE_FANCY_MATH_387
13503 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13504 || TARGET_MIX_SSE_I387)
13505 && flag_unsafe_math_optimizations"
13507 rtx op0 = gen_reg_rtx (XFmode);
13509 rtx one = gen_reg_rtx (<MODE>mode);
13510 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13512 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13513 operands[1], op2));
13514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13518 (define_insn "*fpatanxf3_i387"
13519 [(set (match_operand:XF 0 "register_operand" "=f")
13520 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13521 (match_operand:XF 2 "register_operand" "u")]
13523 (clobber (match_scratch:XF 3 "=2"))]
13524 "TARGET_USE_FANCY_MATH_387
13525 && flag_unsafe_math_optimizations"
13527 [(set_attr "type" "fpspc")
13528 (set_attr "mode" "XF")])
13530 (define_insn "fpatan_extend<mode>xf3_i387"
13531 [(set (match_operand:XF 0 "register_operand" "=f")
13532 (unspec:XF [(float_extend:XF
13533 (match_operand:MODEF 1 "register_operand" "0"))
13535 (match_operand:MODEF 2 "register_operand" "u"))]
13537 (clobber (match_scratch:XF 3 "=2"))]
13538 "TARGET_USE_FANCY_MATH_387
13539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13540 || TARGET_MIX_SSE_I387)
13541 && flag_unsafe_math_optimizations"
13543 [(set_attr "type" "fpspc")
13544 (set_attr "mode" "XF")])
13546 (define_expand "atan2xf3"
13547 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13548 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13549 (match_operand:XF 1 "register_operand" "")]
13551 (clobber (match_scratch:XF 3 ""))])]
13552 "TARGET_USE_FANCY_MATH_387
13553 && flag_unsafe_math_optimizations")
13555 (define_expand "atan2<mode>3"
13556 [(use (match_operand:MODEF 0 "register_operand" ""))
13557 (use (match_operand:MODEF 1 "register_operand" ""))
13558 (use (match_operand:MODEF 2 "register_operand" ""))]
13559 "TARGET_USE_FANCY_MATH_387
13560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13561 || TARGET_MIX_SSE_I387)
13562 && flag_unsafe_math_optimizations"
13564 rtx op0 = gen_reg_rtx (XFmode);
13566 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13571 (define_expand "atanxf2"
13572 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13573 (unspec:XF [(match_dup 2)
13574 (match_operand:XF 1 "register_operand" "")]
13576 (clobber (match_scratch:XF 3 ""))])]
13577 "TARGET_USE_FANCY_MATH_387
13578 && flag_unsafe_math_optimizations"
13580 operands[2] = gen_reg_rtx (XFmode);
13581 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13584 (define_expand "atan<mode>2"
13585 [(use (match_operand:MODEF 0 "register_operand" ""))
13586 (use (match_operand:MODEF 1 "register_operand" ""))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589 || TARGET_MIX_SSE_I387)
13590 && flag_unsafe_math_optimizations"
13592 rtx op0 = gen_reg_rtx (XFmode);
13594 rtx op2 = gen_reg_rtx (<MODE>mode);
13595 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13597 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13598 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13602 (define_expand "asinxf2"
13603 [(set (match_dup 2)
13604 (mult:XF (match_operand:XF 1 "register_operand" "")
13606 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13607 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13608 (parallel [(set (match_operand:XF 0 "register_operand" "")
13609 (unspec:XF [(match_dup 5) (match_dup 1)]
13611 (clobber (match_scratch:XF 6 ""))])]
13612 "TARGET_USE_FANCY_MATH_387
13613 && flag_unsafe_math_optimizations"
13617 if (optimize_insn_for_size_p ())
13620 for (i = 2; i < 6; i++)
13621 operands[i] = gen_reg_rtx (XFmode);
13623 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13626 (define_expand "asin<mode>2"
13627 [(use (match_operand:MODEF 0 "register_operand" ""))
13628 (use (match_operand:MODEF 1 "general_operand" ""))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13631 || TARGET_MIX_SSE_I387)
13632 && flag_unsafe_math_optimizations"
13634 rtx op0 = gen_reg_rtx (XFmode);
13635 rtx op1 = gen_reg_rtx (XFmode);
13637 if (optimize_insn_for_size_p ())
13640 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13641 emit_insn (gen_asinxf2 (op0, op1));
13642 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13646 (define_expand "acosxf2"
13647 [(set (match_dup 2)
13648 (mult:XF (match_operand:XF 1 "register_operand" "")
13650 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13651 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13652 (parallel [(set (match_operand:XF 0 "register_operand" "")
13653 (unspec:XF [(match_dup 1) (match_dup 5)]
13655 (clobber (match_scratch:XF 6 ""))])]
13656 "TARGET_USE_FANCY_MATH_387
13657 && flag_unsafe_math_optimizations"
13661 if (optimize_insn_for_size_p ())
13664 for (i = 2; i < 6; i++)
13665 operands[i] = gen_reg_rtx (XFmode);
13667 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13670 (define_expand "acos<mode>2"
13671 [(use (match_operand:MODEF 0 "register_operand" ""))
13672 (use (match_operand:MODEF 1 "general_operand" ""))]
13673 "TARGET_USE_FANCY_MATH_387
13674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675 || TARGET_MIX_SSE_I387)
13676 && flag_unsafe_math_optimizations"
13678 rtx op0 = gen_reg_rtx (XFmode);
13679 rtx op1 = gen_reg_rtx (XFmode);
13681 if (optimize_insn_for_size_p ())
13684 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13685 emit_insn (gen_acosxf2 (op0, op1));
13686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13690 (define_insn "fyl2xxf3_i387"
13691 [(set (match_operand:XF 0 "register_operand" "=f")
13692 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13693 (match_operand:XF 2 "register_operand" "u")]
13695 (clobber (match_scratch:XF 3 "=2"))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && flag_unsafe_math_optimizations"
13699 [(set_attr "type" "fpspc")
13700 (set_attr "mode" "XF")])
13702 (define_insn "fyl2x_extend<mode>xf3_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (unspec:XF [(float_extend:XF
13705 (match_operand:MODEF 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 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13711 || TARGET_MIX_SSE_I387)
13712 && flag_unsafe_math_optimizations"
13714 [(set_attr "type" "fpspc")
13715 (set_attr "mode" "XF")])
13717 (define_expand "logxf2"
13718 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13719 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13720 (match_dup 2)] UNSPEC_FYL2X))
13721 (clobber (match_scratch:XF 3 ""))])]
13722 "TARGET_USE_FANCY_MATH_387
13723 && flag_unsafe_math_optimizations"
13725 operands[2] = gen_reg_rtx (XFmode);
13726 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13729 (define_expand "log<mode>2"
13730 [(use (match_operand:MODEF 0 "register_operand" ""))
13731 (use (match_operand:MODEF 1 "register_operand" ""))]
13732 "TARGET_USE_FANCY_MATH_387
13733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734 || TARGET_MIX_SSE_I387)
13735 && flag_unsafe_math_optimizations"
13737 rtx op0 = gen_reg_rtx (XFmode);
13739 rtx op2 = gen_reg_rtx (XFmode);
13740 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13742 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 (define_expand "log10xf2"
13748 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13749 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13750 (match_dup 2)] UNSPEC_FYL2X))
13751 (clobber (match_scratch:XF 3 ""))])]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13755 operands[2] = gen_reg_rtx (XFmode);
13756 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13759 (define_expand "log10<mode>2"
13760 [(use (match_operand:MODEF 0 "register_operand" ""))
13761 (use (match_operand:MODEF 1 "register_operand" ""))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13764 || TARGET_MIX_SSE_I387)
13765 && flag_unsafe_math_optimizations"
13767 rtx op0 = gen_reg_rtx (XFmode);
13769 rtx op2 = gen_reg_rtx (XFmode);
13770 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13772 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13773 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13777 (define_expand "log2xf2"
13778 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13779 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13780 (match_dup 2)] UNSPEC_FYL2X))
13781 (clobber (match_scratch:XF 3 ""))])]
13782 "TARGET_USE_FANCY_MATH_387
13783 && flag_unsafe_math_optimizations"
13785 operands[2] = gen_reg_rtx (XFmode);
13786 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13789 (define_expand "log2<mode>2"
13790 [(use (match_operand:MODEF 0 "register_operand" ""))
13791 (use (match_operand:MODEF 1 "register_operand" ""))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794 || TARGET_MIX_SSE_I387)
13795 && flag_unsafe_math_optimizations"
13797 rtx op0 = gen_reg_rtx (XFmode);
13799 rtx op2 = gen_reg_rtx (XFmode);
13800 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13802 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807 (define_insn "fyl2xp1xf3_i387"
13808 [(set (match_operand:XF 0 "register_operand" "=f")
13809 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13810 (match_operand:XF 2 "register_operand" "u")]
13812 (clobber (match_scratch:XF 3 "=2"))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && flag_unsafe_math_optimizations"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13819 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13820 [(set (match_operand:XF 0 "register_operand" "=f")
13821 (unspec:XF [(float_extend:XF
13822 (match_operand:MODEF 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 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations"
13831 [(set_attr "type" "fpspc")
13832 (set_attr "mode" "XF")])
13834 (define_expand "log1pxf2"
13835 [(use (match_operand:XF 0 "register_operand" ""))
13836 (use (match_operand:XF 1 "register_operand" ""))]
13837 "TARGET_USE_FANCY_MATH_387
13838 && flag_unsafe_math_optimizations"
13840 if (optimize_insn_for_size_p ())
13843 ix86_emit_i387_log1p (operands[0], operands[1]);
13847 (define_expand "log1p<mode>2"
13848 [(use (match_operand:MODEF 0 "register_operand" ""))
13849 (use (match_operand:MODEF 1 "register_operand" ""))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852 || TARGET_MIX_SSE_I387)
13853 && flag_unsafe_math_optimizations"
13857 if (optimize_insn_for_size_p ())
13860 op0 = gen_reg_rtx (XFmode);
13862 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13864 ix86_emit_i387_log1p (op0, operands[1]);
13865 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13869 (define_insn "fxtractxf3_i387"
13870 [(set (match_operand:XF 0 "register_operand" "=f")
13871 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13872 UNSPEC_XTRACT_FRACT))
13873 (set (match_operand:XF 1 "register_operand" "=u")
13874 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13875 "TARGET_USE_FANCY_MATH_387
13876 && flag_unsafe_math_optimizations"
13878 [(set_attr "type" "fpspc")
13879 (set_attr "mode" "XF")])
13881 (define_insn "fxtract_extend<mode>xf3_i387"
13882 [(set (match_operand:XF 0 "register_operand" "=f")
13883 (unspec:XF [(float_extend:XF
13884 (match_operand:MODEF 2 "register_operand" "0"))]
13885 UNSPEC_XTRACT_FRACT))
13886 (set (match_operand:XF 1 "register_operand" "=u")
13887 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13888 "TARGET_USE_FANCY_MATH_387
13889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13890 || TARGET_MIX_SSE_I387)
13891 && flag_unsafe_math_optimizations"
13893 [(set_attr "type" "fpspc")
13894 (set_attr "mode" "XF")])
13896 (define_expand "logbxf2"
13897 [(parallel [(set (match_dup 2)
13898 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13899 UNSPEC_XTRACT_FRACT))
13900 (set (match_operand:XF 0 "register_operand" "")
13901 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13902 "TARGET_USE_FANCY_MATH_387
13903 && flag_unsafe_math_optimizations"
13904 "operands[2] = gen_reg_rtx (XFmode);")
13906 (define_expand "logb<mode>2"
13907 [(use (match_operand:MODEF 0 "register_operand" ""))
13908 (use (match_operand:MODEF 1 "register_operand" ""))]
13909 "TARGET_USE_FANCY_MATH_387
13910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911 || TARGET_MIX_SSE_I387)
13912 && flag_unsafe_math_optimizations"
13914 rtx op0 = gen_reg_rtx (XFmode);
13915 rtx op1 = gen_reg_rtx (XFmode);
13917 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13918 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13922 (define_expand "ilogbxf2"
13923 [(use (match_operand:SI 0 "register_operand" ""))
13924 (use (match_operand:XF 1 "register_operand" ""))]
13925 "TARGET_USE_FANCY_MATH_387
13926 && flag_unsafe_math_optimizations"
13930 if (optimize_insn_for_size_p ())
13933 op0 = gen_reg_rtx (XFmode);
13934 op1 = gen_reg_rtx (XFmode);
13936 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13937 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13941 (define_expand "ilogb<mode>2"
13942 [(use (match_operand:SI 0 "register_operand" ""))
13943 (use (match_operand:MODEF 1 "register_operand" ""))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13951 if (optimize_insn_for_size_p ())
13954 op0 = gen_reg_rtx (XFmode);
13955 op1 = gen_reg_rtx (XFmode);
13957 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13958 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13962 (define_insn "*f2xm1xf2_i387"
13963 [(set (match_operand:XF 0 "register_operand" "=f")
13964 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13966 "TARGET_USE_FANCY_MATH_387
13967 && flag_unsafe_math_optimizations"
13969 [(set_attr "type" "fpspc")
13970 (set_attr "mode" "XF")])
13972 (define_insn "*fscalexf4_i387"
13973 [(set (match_operand:XF 0 "register_operand" "=f")
13974 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13975 (match_operand:XF 3 "register_operand" "1")]
13976 UNSPEC_FSCALE_FRACT))
13977 (set (match_operand:XF 1 "register_operand" "=u")
13978 (unspec:XF [(match_dup 2) (match_dup 3)]
13979 UNSPEC_FSCALE_EXP))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && flag_unsafe_math_optimizations"
13983 [(set_attr "type" "fpspc")
13984 (set_attr "mode" "XF")])
13986 (define_expand "expNcorexf3"
13987 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13988 (match_operand:XF 2 "register_operand" "")))
13989 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13990 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13991 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13992 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13993 (parallel [(set (match_operand:XF 0 "register_operand" "")
13994 (unspec:XF [(match_dup 8) (match_dup 4)]
13995 UNSPEC_FSCALE_FRACT))
13997 (unspec:XF [(match_dup 8) (match_dup 4)]
13998 UNSPEC_FSCALE_EXP))])]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations"
14004 if (optimize_insn_for_size_p ())
14007 for (i = 3; i < 10; i++)
14008 operands[i] = gen_reg_rtx (XFmode);
14010 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14013 (define_expand "expxf2"
14014 [(use (match_operand:XF 0 "register_operand" ""))
14015 (use (match_operand:XF 1 "register_operand" ""))]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14021 if (optimize_insn_for_size_p ())
14024 op2 = gen_reg_rtx (XFmode);
14025 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14027 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14031 (define_expand "exp<mode>2"
14032 [(use (match_operand:MODEF 0 "register_operand" ""))
14033 (use (match_operand:MODEF 1 "general_operand" ""))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036 || TARGET_MIX_SSE_I387)
14037 && flag_unsafe_math_optimizations"
14041 if (optimize_insn_for_size_p ())
14044 op0 = gen_reg_rtx (XFmode);
14045 op1 = gen_reg_rtx (XFmode);
14047 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14048 emit_insn (gen_expxf2 (op0, op1));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 (define_expand "exp10xf2"
14054 [(use (match_operand:XF 0 "register_operand" ""))
14055 (use (match_operand:XF 1 "register_operand" ""))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && flag_unsafe_math_optimizations"
14061 if (optimize_insn_for_size_p ())
14064 op2 = gen_reg_rtx (XFmode);
14065 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14067 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14071 (define_expand "exp10<mode>2"
14072 [(use (match_operand:MODEF 0 "register_operand" ""))
14073 (use (match_operand:MODEF 1 "general_operand" ""))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14081 if (optimize_insn_for_size_p ())
14084 op0 = gen_reg_rtx (XFmode);
14085 op1 = gen_reg_rtx (XFmode);
14087 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14088 emit_insn (gen_exp10xf2 (op0, op1));
14089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093 (define_expand "exp2xf2"
14094 [(use (match_operand:XF 0 "register_operand" ""))
14095 (use (match_operand:XF 1 "register_operand" ""))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && flag_unsafe_math_optimizations"
14101 if (optimize_insn_for_size_p ())
14104 op2 = gen_reg_rtx (XFmode);
14105 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14107 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14111 (define_expand "exp2<mode>2"
14112 [(use (match_operand:MODEF 0 "register_operand" ""))
14113 (use (match_operand:MODEF 1 "general_operand" ""))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116 || TARGET_MIX_SSE_I387)
14117 && flag_unsafe_math_optimizations"
14121 if (optimize_insn_for_size_p ())
14124 op0 = gen_reg_rtx (XFmode);
14125 op1 = gen_reg_rtx (XFmode);
14127 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14128 emit_insn (gen_exp2xf2 (op0, op1));
14129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14133 (define_expand "expm1xf2"
14134 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14136 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14137 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14138 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14139 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14140 (parallel [(set (match_dup 7)
14141 (unspec:XF [(match_dup 6) (match_dup 4)]
14142 UNSPEC_FSCALE_FRACT))
14144 (unspec:XF [(match_dup 6) (match_dup 4)]
14145 UNSPEC_FSCALE_EXP))])
14146 (parallel [(set (match_dup 10)
14147 (unspec:XF [(match_dup 9) (match_dup 8)]
14148 UNSPEC_FSCALE_FRACT))
14149 (set (match_dup 11)
14150 (unspec:XF [(match_dup 9) (match_dup 8)]
14151 UNSPEC_FSCALE_EXP))])
14152 (set (match_dup 12) (minus:XF (match_dup 10)
14153 (float_extend:XF (match_dup 13))))
14154 (set (match_operand:XF 0 "register_operand" "")
14155 (plus:XF (match_dup 12) (match_dup 7)))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_unsafe_math_optimizations"
14161 if (optimize_insn_for_size_p ())
14164 for (i = 2; i < 13; i++)
14165 operands[i] = gen_reg_rtx (XFmode);
14168 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14170 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14173 (define_expand "expm1<mode>2"
14174 [(use (match_operand:MODEF 0 "register_operand" ""))
14175 (use (match_operand:MODEF 1 "general_operand" ""))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178 || TARGET_MIX_SSE_I387)
14179 && flag_unsafe_math_optimizations"
14183 if (optimize_insn_for_size_p ())
14186 op0 = gen_reg_rtx (XFmode);
14187 op1 = gen_reg_rtx (XFmode);
14189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14190 emit_insn (gen_expm1xf2 (op0, op1));
14191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195 (define_expand "ldexpxf3"
14196 [(set (match_dup 3)
14197 (float:XF (match_operand:SI 2 "register_operand" "")))
14198 (parallel [(set (match_operand:XF 0 " register_operand" "")
14199 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14201 UNSPEC_FSCALE_FRACT))
14203 (unspec:XF [(match_dup 1) (match_dup 3)]
14204 UNSPEC_FSCALE_EXP))])]
14205 "TARGET_USE_FANCY_MATH_387
14206 && flag_unsafe_math_optimizations"
14208 if (optimize_insn_for_size_p ())
14211 operands[3] = gen_reg_rtx (XFmode);
14212 operands[4] = gen_reg_rtx (XFmode);
14215 (define_expand "ldexp<mode>3"
14216 [(use (match_operand:MODEF 0 "register_operand" ""))
14217 (use (match_operand:MODEF 1 "general_operand" ""))
14218 (use (match_operand:SI 2 "register_operand" ""))]
14219 "TARGET_USE_FANCY_MATH_387
14220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221 || TARGET_MIX_SSE_I387)
14222 && flag_unsafe_math_optimizations"
14226 if (optimize_insn_for_size_p ())
14229 op0 = gen_reg_rtx (XFmode);
14230 op1 = gen_reg_rtx (XFmode);
14232 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14233 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14234 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14238 (define_expand "scalbxf3"
14239 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14240 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14241 (match_operand:XF 2 "register_operand" "")]
14242 UNSPEC_FSCALE_FRACT))
14244 (unspec:XF [(match_dup 1) (match_dup 2)]
14245 UNSPEC_FSCALE_EXP))])]
14246 "TARGET_USE_FANCY_MATH_387
14247 && flag_unsafe_math_optimizations"
14249 if (optimize_insn_for_size_p ())
14252 operands[3] = gen_reg_rtx (XFmode);
14255 (define_expand "scalb<mode>3"
14256 [(use (match_operand:MODEF 0 "register_operand" ""))
14257 (use (match_operand:MODEF 1 "general_operand" ""))
14258 (use (match_operand:MODEF 2 "general_operand" ""))]
14259 "TARGET_USE_FANCY_MATH_387
14260 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14261 || TARGET_MIX_SSE_I387)
14262 && flag_unsafe_math_optimizations"
14266 if (optimize_insn_for_size_p ())
14269 op0 = gen_reg_rtx (XFmode);
14270 op1 = gen_reg_rtx (XFmode);
14271 op2 = gen_reg_rtx (XFmode);
14273 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14274 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14275 emit_insn (gen_scalbxf3 (op0, op1, op2));
14276 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14280 (define_expand "significandxf2"
14281 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14282 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14283 UNSPEC_XTRACT_FRACT))
14285 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14286 "TARGET_USE_FANCY_MATH_387
14287 && flag_unsafe_math_optimizations"
14288 "operands[2] = gen_reg_rtx (XFmode);")
14290 (define_expand "significand<mode>2"
14291 [(use (match_operand:MODEF 0 "register_operand" ""))
14292 (use (match_operand:MODEF 1 "register_operand" ""))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295 || TARGET_MIX_SSE_I387)
14296 && flag_unsafe_math_optimizations"
14298 rtx op0 = gen_reg_rtx (XFmode);
14299 rtx op1 = gen_reg_rtx (XFmode);
14301 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14302 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14307 (define_insn "sse4_1_round<mode>2"
14308 [(set (match_operand:MODEF 0 "register_operand" "=x")
14309 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14310 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14313 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14314 [(set_attr "type" "ssecvt")
14315 (set_attr "prefix_extra" "1")
14316 (set_attr "prefix" "maybe_vex")
14317 (set_attr "mode" "<MODE>")])
14319 (define_insn "rintxf2"
14320 [(set (match_operand:XF 0 "register_operand" "=f")
14321 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14323 "TARGET_USE_FANCY_MATH_387
14324 && flag_unsafe_math_optimizations"
14326 [(set_attr "type" "fpspc")
14327 (set_attr "mode" "XF")])
14329 (define_expand "rint<mode>2"
14330 [(use (match_operand:MODEF 0 "register_operand" ""))
14331 (use (match_operand:MODEF 1 "register_operand" ""))]
14332 "(TARGET_USE_FANCY_MATH_387
14333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334 || TARGET_MIX_SSE_I387)
14335 && flag_unsafe_math_optimizations)
14336 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14337 && !flag_trapping_math)"
14339 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14340 && !flag_trapping_math)
14342 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14345 emit_insn (gen_sse4_1_round<mode>2
14346 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14348 ix86_expand_rint (operand0, operand1);
14352 rtx op0 = gen_reg_rtx (XFmode);
14353 rtx op1 = gen_reg_rtx (XFmode);
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_rintxf2 (op0, op1));
14358 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14363 (define_expand "round<mode>2"
14364 [(match_operand:MODEF 0 "register_operand" "")
14365 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14366 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14367 && !flag_trapping_math && !flag_rounding_math"
14369 if (optimize_insn_for_size_p ())
14371 if (TARGET_64BIT || (<MODE>mode != DFmode))
14372 ix86_expand_round (operand0, operand1);
14374 ix86_expand_rounddf_32 (operand0, operand1);
14378 (define_insn_and_split "*fistdi2_1"
14379 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14380 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14382 "TARGET_USE_FANCY_MATH_387
14383 && can_create_pseudo_p ()"
14388 if (memory_operand (operands[0], VOIDmode))
14389 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14392 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14393 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "DI")])
14401 (define_insn "fistdi2"
14402 [(set (match_operand:DI 0 "memory_operand" "=m")
14403 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14405 (clobber (match_scratch:XF 2 "=&1f"))]
14406 "TARGET_USE_FANCY_MATH_387"
14407 "* return output_fix_trunc (insn, operands, false);"
14408 [(set_attr "type" "fpspc")
14409 (set_attr "mode" "DI")])
14411 (define_insn "fistdi2_with_temp"
14412 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14413 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14415 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14416 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14417 "TARGET_USE_FANCY_MATH_387"
14419 [(set_attr "type" "fpspc")
14420 (set_attr "mode" "DI")])
14423 [(set (match_operand:DI 0 "register_operand" "")
14424 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14426 (clobber (match_operand:DI 2 "memory_operand" ""))
14427 (clobber (match_scratch 3 ""))]
14429 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430 (clobber (match_dup 3))])
14431 (set (match_dup 0) (match_dup 2))])
14434 [(set (match_operand:DI 0 "memory_operand" "")
14435 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14437 (clobber (match_operand:DI 2 "memory_operand" ""))
14438 (clobber (match_scratch 3 ""))]
14440 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14441 (clobber (match_dup 3))])])
14443 (define_insn_and_split "*fist<mode>2_1"
14444 [(set (match_operand:SWI24 0 "register_operand" "")
14445 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14447 "TARGET_USE_FANCY_MATH_387
14448 && can_create_pseudo_p ()"
14453 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14454 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14458 [(set_attr "type" "fpspc")
14459 (set_attr "mode" "<MODE>")])
14461 (define_insn "fist<mode>2"
14462 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14463 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14465 "TARGET_USE_FANCY_MATH_387"
14466 "* return output_fix_trunc (insn, operands, false);"
14467 [(set_attr "type" "fpspc")
14468 (set_attr "mode" "<MODE>")])
14470 (define_insn "fist<mode>2_with_temp"
14471 [(set (match_operand:SWI24 0 "register_operand" "=r")
14472 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14474 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14475 "TARGET_USE_FANCY_MATH_387"
14477 [(set_attr "type" "fpspc")
14478 (set_attr "mode" "<MODE>")])
14481 [(set (match_operand:SWI24 0 "register_operand" "")
14482 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14484 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14486 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14487 (set (match_dup 0) (match_dup 2))])
14490 [(set (match_operand:SWI24 0 "memory_operand" "")
14491 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14493 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14495 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14497 (define_expand "lrintxf<mode>2"
14498 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14499 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14501 "TARGET_USE_FANCY_MATH_387")
14503 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14504 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14505 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14506 UNSPEC_FIX_NOTRUNC))]
14507 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14508 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14510 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14511 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14512 (match_operand:MODEF 1 "register_operand" "")]
14513 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14514 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14515 && !flag_trapping_math && !flag_rounding_math"
14517 if (optimize_insn_for_size_p ())
14519 ix86_expand_lround (operand0, operand1);
14523 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14524 (define_insn_and_split "frndintxf2_floor"
14525 [(set (match_operand:XF 0 "register_operand" "")
14526 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14527 UNSPEC_FRNDINT_FLOOR))
14528 (clobber (reg:CC FLAGS_REG))]
14529 "TARGET_USE_FANCY_MATH_387
14530 && flag_unsafe_math_optimizations
14531 && can_create_pseudo_p ()"
14536 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14538 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14539 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14541 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14542 operands[2], operands[3]));
14545 [(set_attr "type" "frndint")
14546 (set_attr "i387_cw" "floor")
14547 (set_attr "mode" "XF")])
14549 (define_insn "frndintxf2_floor_i387"
14550 [(set (match_operand:XF 0 "register_operand" "=f")
14551 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14552 UNSPEC_FRNDINT_FLOOR))
14553 (use (match_operand:HI 2 "memory_operand" "m"))
14554 (use (match_operand:HI 3 "memory_operand" "m"))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && flag_unsafe_math_optimizations"
14557 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14558 [(set_attr "type" "frndint")
14559 (set_attr "i387_cw" "floor")
14560 (set_attr "mode" "XF")])
14562 (define_expand "floorxf2"
14563 [(use (match_operand:XF 0 "register_operand" ""))
14564 (use (match_operand:XF 1 "register_operand" ""))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14568 if (optimize_insn_for_size_p ())
14570 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14574 (define_expand "floor<mode>2"
14575 [(use (match_operand:MODEF 0 "register_operand" ""))
14576 (use (match_operand:MODEF 1 "register_operand" ""))]
14577 "(TARGET_USE_FANCY_MATH_387
14578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14579 || TARGET_MIX_SSE_I387)
14580 && flag_unsafe_math_optimizations)
14581 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14582 && !flag_trapping_math)"
14584 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585 && !flag_trapping_math
14586 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14588 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14591 emit_insn (gen_sse4_1_round<mode>2
14592 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14593 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14594 ix86_expand_floorceil (operand0, operand1, true);
14596 ix86_expand_floorceildf_32 (operand0, operand1, true);
14602 if (optimize_insn_for_size_p ())
14605 op0 = gen_reg_rtx (XFmode);
14606 op1 = gen_reg_rtx (XFmode);
14607 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14608 emit_insn (gen_frndintxf2_floor (op0, op1));
14610 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14615 (define_insn_and_split "*fist<mode>2_floor_1"
14616 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14617 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14618 UNSPEC_FIST_FLOOR))
14619 (clobber (reg:CC FLAGS_REG))]
14620 "TARGET_USE_FANCY_MATH_387
14621 && flag_unsafe_math_optimizations
14622 && can_create_pseudo_p ()"
14627 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14629 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14630 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14631 if (memory_operand (operands[0], VOIDmode))
14632 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14633 operands[2], operands[3]));
14636 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14637 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14638 operands[2], operands[3],
14643 [(set_attr "type" "fistp")
14644 (set_attr "i387_cw" "floor")
14645 (set_attr "mode" "<MODE>")])
14647 (define_insn "fistdi2_floor"
14648 [(set (match_operand:DI 0 "memory_operand" "=m")
14649 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14650 UNSPEC_FIST_FLOOR))
14651 (use (match_operand:HI 2 "memory_operand" "m"))
14652 (use (match_operand:HI 3 "memory_operand" "m"))
14653 (clobber (match_scratch:XF 4 "=&1f"))]
14654 "TARGET_USE_FANCY_MATH_387
14655 && flag_unsafe_math_optimizations"
14656 "* return output_fix_trunc (insn, operands, false);"
14657 [(set_attr "type" "fistp")
14658 (set_attr "i387_cw" "floor")
14659 (set_attr "mode" "DI")])
14661 (define_insn "fistdi2_floor_with_temp"
14662 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14664 UNSPEC_FIST_FLOOR))
14665 (use (match_operand:HI 2 "memory_operand" "m,m"))
14666 (use (match_operand:HI 3 "memory_operand" "m,m"))
14667 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14668 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14669 "TARGET_USE_FANCY_MATH_387
14670 && flag_unsafe_math_optimizations"
14672 [(set_attr "type" "fistp")
14673 (set_attr "i387_cw" "floor")
14674 (set_attr "mode" "DI")])
14677 [(set (match_operand:DI 0 "register_operand" "")
14678 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14679 UNSPEC_FIST_FLOOR))
14680 (use (match_operand:HI 2 "memory_operand" ""))
14681 (use (match_operand:HI 3 "memory_operand" ""))
14682 (clobber (match_operand:DI 4 "memory_operand" ""))
14683 (clobber (match_scratch 5 ""))]
14685 [(parallel [(set (match_dup 4)
14686 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14687 (use (match_dup 2))
14688 (use (match_dup 3))
14689 (clobber (match_dup 5))])
14690 (set (match_dup 0) (match_dup 4))])
14693 [(set (match_operand:DI 0 "memory_operand" "")
14694 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14695 UNSPEC_FIST_FLOOR))
14696 (use (match_operand:HI 2 "memory_operand" ""))
14697 (use (match_operand:HI 3 "memory_operand" ""))
14698 (clobber (match_operand:DI 4 "memory_operand" ""))
14699 (clobber (match_scratch 5 ""))]
14701 [(parallel [(set (match_dup 0)
14702 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14703 (use (match_dup 2))
14704 (use (match_dup 3))
14705 (clobber (match_dup 5))])])
14707 (define_insn "fist<mode>2_floor"
14708 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14709 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14710 UNSPEC_FIST_FLOOR))
14711 (use (match_operand:HI 2 "memory_operand" "m"))
14712 (use (match_operand:HI 3 "memory_operand" "m"))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && flag_unsafe_math_optimizations"
14715 "* return output_fix_trunc (insn, operands, false);"
14716 [(set_attr "type" "fistp")
14717 (set_attr "i387_cw" "floor")
14718 (set_attr "mode" "<MODE>")])
14720 (define_insn "fist<mode>2_floor_with_temp"
14721 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14722 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14723 UNSPEC_FIST_FLOOR))
14724 (use (match_operand:HI 2 "memory_operand" "m,m"))
14725 (use (match_operand:HI 3 "memory_operand" "m,m"))
14726 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14727 "TARGET_USE_FANCY_MATH_387
14728 && flag_unsafe_math_optimizations"
14730 [(set_attr "type" "fistp")
14731 (set_attr "i387_cw" "floor")
14732 (set_attr "mode" "<MODE>")])
14735 [(set (match_operand:SWI24 0 "register_operand" "")
14736 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14737 UNSPEC_FIST_FLOOR))
14738 (use (match_operand:HI 2 "memory_operand" ""))
14739 (use (match_operand:HI 3 "memory_operand" ""))
14740 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14742 [(parallel [(set (match_dup 4)
14743 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14744 (use (match_dup 2))
14745 (use (match_dup 3))])
14746 (set (match_dup 0) (match_dup 4))])
14749 [(set (match_operand:SWI24 0 "memory_operand" "")
14750 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14751 UNSPEC_FIST_FLOOR))
14752 (use (match_operand:HI 2 "memory_operand" ""))
14753 (use (match_operand:HI 3 "memory_operand" ""))
14754 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14756 [(parallel [(set (match_dup 0)
14757 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14758 (use (match_dup 2))
14759 (use (match_dup 3))])])
14761 (define_expand "lfloorxf<mode>2"
14762 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14763 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14764 UNSPEC_FIST_FLOOR))
14765 (clobber (reg:CC FLAGS_REG))])]
14766 "TARGET_USE_FANCY_MATH_387
14767 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14768 && flag_unsafe_math_optimizations")
14770 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14771 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14772 (match_operand:MODEF 1 "register_operand" "")]
14773 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14774 && !flag_trapping_math"
14776 if (TARGET_64BIT && optimize_insn_for_size_p ())
14778 ix86_expand_lfloorceil (operand0, operand1, true);
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_ceil"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_CEIL))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14795 ix86_optimize_mode_switching[I387_CEIL] = 1;
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14800 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "ceil")
14806 (set_attr "mode" "XF")])
14808 (define_insn "frndintxf2_ceil_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_CEIL))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "ceil")
14819 (set_attr "mode" "XF")])
14821 (define_expand "ceilxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14827 if (optimize_insn_for_size_p ())
14829 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14833 (define_expand "ceil<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math
14845 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14848 emit_insn (gen_sse4_1_round<mode>2
14849 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14850 else if (optimize_insn_for_size_p ())
14852 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853 ix86_expand_floorceil (operand0, operand1, false);
14855 ix86_expand_floorceildf_32 (operand0, operand1, false);
14861 if (optimize_insn_for_size_p ())
14864 op0 = gen_reg_rtx (XFmode);
14865 op1 = gen_reg_rtx (XFmode);
14866 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867 emit_insn (gen_frndintxf2_ceil (op0, op1));
14869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874 (define_insn_and_split "*fist<mode>2_ceil_1"
14875 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14876 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14878 (clobber (reg:CC FLAGS_REG))]
14879 "TARGET_USE_FANCY_MATH_387
14880 && flag_unsafe_math_optimizations
14881 && can_create_pseudo_p ()"
14886 ix86_optimize_mode_switching[I387_CEIL] = 1;
14888 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14889 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14890 if (memory_operand (operands[0], VOIDmode))
14891 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14892 operands[2], operands[3]));
14895 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14897 operands[2], operands[3],
14902 [(set_attr "type" "fistp")
14903 (set_attr "i387_cw" "ceil")
14904 (set_attr "mode" "<MODE>")])
14906 (define_insn "fistdi2_ceil"
14907 [(set (match_operand:DI 0 "memory_operand" "=m")
14908 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14910 (use (match_operand:HI 2 "memory_operand" "m"))
14911 (use (match_operand:HI 3 "memory_operand" "m"))
14912 (clobber (match_scratch:XF 4 "=&1f"))]
14913 "TARGET_USE_FANCY_MATH_387
14914 && flag_unsafe_math_optimizations"
14915 "* return output_fix_trunc (insn, operands, false);"
14916 [(set_attr "type" "fistp")
14917 (set_attr "i387_cw" "ceil")
14918 (set_attr "mode" "DI")])
14920 (define_insn "fistdi2_ceil_with_temp"
14921 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14922 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14924 (use (match_operand:HI 2 "memory_operand" "m,m"))
14925 (use (match_operand:HI 3 "memory_operand" "m,m"))
14926 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14927 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14928 "TARGET_USE_FANCY_MATH_387
14929 && flag_unsafe_math_optimizations"
14931 [(set_attr "type" "fistp")
14932 (set_attr "i387_cw" "ceil")
14933 (set_attr "mode" "DI")])
14936 [(set (match_operand:DI 0 "register_operand" "")
14937 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14939 (use (match_operand:HI 2 "memory_operand" ""))
14940 (use (match_operand:HI 3 "memory_operand" ""))
14941 (clobber (match_operand:DI 4 "memory_operand" ""))
14942 (clobber (match_scratch 5 ""))]
14944 [(parallel [(set (match_dup 4)
14945 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14946 (use (match_dup 2))
14947 (use (match_dup 3))
14948 (clobber (match_dup 5))])
14949 (set (match_dup 0) (match_dup 4))])
14952 [(set (match_operand:DI 0 "memory_operand" "")
14953 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14955 (use (match_operand:HI 2 "memory_operand" ""))
14956 (use (match_operand:HI 3 "memory_operand" ""))
14957 (clobber (match_operand:DI 4 "memory_operand" ""))
14958 (clobber (match_scratch 5 ""))]
14960 [(parallel [(set (match_dup 0)
14961 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14962 (use (match_dup 2))
14963 (use (match_dup 3))
14964 (clobber (match_dup 5))])])
14966 (define_insn "fist<mode>2_ceil"
14967 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14968 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14970 (use (match_operand:HI 2 "memory_operand" "m"))
14971 (use (match_operand:HI 3 "memory_operand" "m"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14974 "* return output_fix_trunc (insn, operands, false);"
14975 [(set_attr "type" "fistp")
14976 (set_attr "i387_cw" "ceil")
14977 (set_attr "mode" "<MODE>")])
14979 (define_insn "fist<mode>2_ceil_with_temp"
14980 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14981 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14983 (use (match_operand:HI 2 "memory_operand" "m,m"))
14984 (use (match_operand:HI 3 "memory_operand" "m,m"))
14985 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && flag_unsafe_math_optimizations"
14989 [(set_attr "type" "fistp")
14990 (set_attr "i387_cw" "ceil")
14991 (set_attr "mode" "<MODE>")])
14994 [(set (match_operand:SWI24 0 "register_operand" "")
14995 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14997 (use (match_operand:HI 2 "memory_operand" ""))
14998 (use (match_operand:HI 3 "memory_operand" ""))
14999 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15001 [(parallel [(set (match_dup 4)
15002 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15003 (use (match_dup 2))
15004 (use (match_dup 3))])
15005 (set (match_dup 0) (match_dup 4))])
15008 [(set (match_operand:SWI24 0 "memory_operand" "")
15009 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15011 (use (match_operand:HI 2 "memory_operand" ""))
15012 (use (match_operand:HI 3 "memory_operand" ""))
15013 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15015 [(parallel [(set (match_dup 0)
15016 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15017 (use (match_dup 2))
15018 (use (match_dup 3))])])
15020 (define_expand "lceilxf<mode>2"
15021 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15022 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15024 (clobber (reg:CC FLAGS_REG))])]
15025 "TARGET_USE_FANCY_MATH_387
15026 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15027 && flag_unsafe_math_optimizations")
15029 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15030 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15031 (match_operand:MODEF 1 "register_operand" "")]
15032 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15033 && !flag_trapping_math"
15035 ix86_expand_lfloorceil (operand0, operand1, false);
15039 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15040 (define_insn_and_split "frndintxf2_trunc"
15041 [(set (match_operand:XF 0 "register_operand" "")
15042 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15043 UNSPEC_FRNDINT_TRUNC))
15044 (clobber (reg:CC FLAGS_REG))]
15045 "TARGET_USE_FANCY_MATH_387
15046 && flag_unsafe_math_optimizations
15047 && can_create_pseudo_p ()"
15052 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15054 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15055 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15057 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15058 operands[2], operands[3]));
15061 [(set_attr "type" "frndint")
15062 (set_attr "i387_cw" "trunc")
15063 (set_attr "mode" "XF")])
15065 (define_insn "frndintxf2_trunc_i387"
15066 [(set (match_operand:XF 0 "register_operand" "=f")
15067 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15068 UNSPEC_FRNDINT_TRUNC))
15069 (use (match_operand:HI 2 "memory_operand" "m"))
15070 (use (match_operand:HI 3 "memory_operand" "m"))]
15071 "TARGET_USE_FANCY_MATH_387
15072 && flag_unsafe_math_optimizations"
15073 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15074 [(set_attr "type" "frndint")
15075 (set_attr "i387_cw" "trunc")
15076 (set_attr "mode" "XF")])
15078 (define_expand "btruncxf2"
15079 [(use (match_operand:XF 0 "register_operand" ""))
15080 (use (match_operand:XF 1 "register_operand" ""))]
15081 "TARGET_USE_FANCY_MATH_387
15082 && flag_unsafe_math_optimizations"
15084 if (optimize_insn_for_size_p ())
15086 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15090 (define_expand "btrunc<mode>2"
15091 [(use (match_operand:MODEF 0 "register_operand" ""))
15092 (use (match_operand:MODEF 1 "register_operand" ""))]
15093 "(TARGET_USE_FANCY_MATH_387
15094 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15095 || TARGET_MIX_SSE_I387)
15096 && flag_unsafe_math_optimizations)
15097 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15098 && !flag_trapping_math)"
15100 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101 && !flag_trapping_math
15102 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15105 emit_insn (gen_sse4_1_round<mode>2
15106 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15107 else if (optimize_insn_for_size_p ())
15109 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15110 ix86_expand_trunc (operand0, operand1);
15112 ix86_expand_truncdf_32 (operand0, operand1);
15118 if (optimize_insn_for_size_p ())
15121 op0 = gen_reg_rtx (XFmode);
15122 op1 = gen_reg_rtx (XFmode);
15123 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15124 emit_insn (gen_frndintxf2_trunc (op0, op1));
15126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15131 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15132 (define_insn_and_split "frndintxf2_mask_pm"
15133 [(set (match_operand:XF 0 "register_operand" "")
15134 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15135 UNSPEC_FRNDINT_MASK_PM))
15136 (clobber (reg:CC FLAGS_REG))]
15137 "TARGET_USE_FANCY_MATH_387
15138 && flag_unsafe_math_optimizations
15139 && can_create_pseudo_p ()"
15144 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15146 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15147 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15149 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15150 operands[2], operands[3]));
15153 [(set_attr "type" "frndint")
15154 (set_attr "i387_cw" "mask_pm")
15155 (set_attr "mode" "XF")])
15157 (define_insn "frndintxf2_mask_pm_i387"
15158 [(set (match_operand:XF 0 "register_operand" "=f")
15159 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15160 UNSPEC_FRNDINT_MASK_PM))
15161 (use (match_operand:HI 2 "memory_operand" "m"))
15162 (use (match_operand:HI 3 "memory_operand" "m"))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && flag_unsafe_math_optimizations"
15165 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15166 [(set_attr "type" "frndint")
15167 (set_attr "i387_cw" "mask_pm")
15168 (set_attr "mode" "XF")])
15170 (define_expand "nearbyintxf2"
15171 [(use (match_operand:XF 0 "register_operand" ""))
15172 (use (match_operand:XF 1 "register_operand" ""))]
15173 "TARGET_USE_FANCY_MATH_387
15174 && flag_unsafe_math_optimizations"
15176 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15180 (define_expand "nearbyint<mode>2"
15181 [(use (match_operand:MODEF 0 "register_operand" ""))
15182 (use (match_operand:MODEF 1 "register_operand" ""))]
15183 "TARGET_USE_FANCY_MATH_387
15184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15185 || TARGET_MIX_SSE_I387)
15186 && flag_unsafe_math_optimizations"
15188 rtx op0 = gen_reg_rtx (XFmode);
15189 rtx op1 = gen_reg_rtx (XFmode);
15191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15192 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15198 (define_insn "fxam<mode>2_i387"
15199 [(set (match_operand:HI 0 "register_operand" "=a")
15201 [(match_operand:X87MODEF 1 "register_operand" "f")]
15203 "TARGET_USE_FANCY_MATH_387"
15204 "fxam\n\tfnstsw\t%0"
15205 [(set_attr "type" "multi")
15206 (set_attr "length" "4")
15207 (set_attr "unit" "i387")
15208 (set_attr "mode" "<MODE>")])
15210 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15211 [(set (match_operand:HI 0 "register_operand" "")
15213 [(match_operand:MODEF 1 "memory_operand" "")]
15215 "TARGET_USE_FANCY_MATH_387
15216 && can_create_pseudo_p ()"
15219 [(set (match_dup 2)(match_dup 1))
15221 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15223 operands[2] = gen_reg_rtx (<MODE>mode);
15225 MEM_VOLATILE_P (operands[1]) = 1;
15227 [(set_attr "type" "multi")
15228 (set_attr "unit" "i387")
15229 (set_attr "mode" "<MODE>")])
15231 (define_expand "isinfxf2"
15232 [(use (match_operand:SI 0 "register_operand" ""))
15233 (use (match_operand:XF 1 "register_operand" ""))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && TARGET_C99_FUNCTIONS"
15237 rtx mask = GEN_INT (0x45);
15238 rtx val = GEN_INT (0x05);
15242 rtx scratch = gen_reg_rtx (HImode);
15243 rtx res = gen_reg_rtx (QImode);
15245 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15247 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15248 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15249 cond = gen_rtx_fmt_ee (EQ, QImode,
15250 gen_rtx_REG (CCmode, FLAGS_REG),
15252 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15253 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15257 (define_expand "isinf<mode>2"
15258 [(use (match_operand:SI 0 "register_operand" ""))
15259 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15260 "TARGET_USE_FANCY_MATH_387
15261 && TARGET_C99_FUNCTIONS
15262 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15264 rtx mask = GEN_INT (0x45);
15265 rtx val = GEN_INT (0x05);
15269 rtx scratch = gen_reg_rtx (HImode);
15270 rtx res = gen_reg_rtx (QImode);
15272 /* Remove excess precision by forcing value through memory. */
15273 if (memory_operand (operands[1], VOIDmode))
15274 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15277 enum ix86_stack_slot slot = (virtuals_instantiated
15280 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15282 emit_move_insn (temp, operands[1]);
15283 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15286 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15287 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15288 cond = gen_rtx_fmt_ee (EQ, QImode,
15289 gen_rtx_REG (CCmode, FLAGS_REG),
15291 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15292 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15296 (define_expand "signbitxf2"
15297 [(use (match_operand:SI 0 "register_operand" ""))
15298 (use (match_operand:XF 1 "register_operand" ""))]
15299 "TARGET_USE_FANCY_MATH_387"
15301 rtx scratch = gen_reg_rtx (HImode);
15303 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15304 emit_insn (gen_andsi3 (operands[0],
15305 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15309 (define_insn "movmsk_df"
15310 [(set (match_operand:SI 0 "register_operand" "=r")
15312 [(match_operand:DF 1 "register_operand" "x")]
15314 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15315 "%vmovmskpd\t{%1, %0|%0, %1}"
15316 [(set_attr "type" "ssemov")
15317 (set_attr "prefix" "maybe_vex")
15318 (set_attr "mode" "DF")])
15320 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15321 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15322 (define_expand "signbitdf2"
15323 [(use (match_operand:SI 0 "register_operand" ""))
15324 (use (match_operand:DF 1 "register_operand" ""))]
15325 "TARGET_USE_FANCY_MATH_387
15326 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15328 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15330 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15331 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15335 rtx scratch = gen_reg_rtx (HImode);
15337 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15338 emit_insn (gen_andsi3 (operands[0],
15339 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15344 (define_expand "signbitsf2"
15345 [(use (match_operand:SI 0 "register_operand" ""))
15346 (use (match_operand:SF 1 "register_operand" ""))]
15347 "TARGET_USE_FANCY_MATH_387
15348 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15350 rtx scratch = gen_reg_rtx (HImode);
15352 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15353 emit_insn (gen_andsi3 (operands[0],
15354 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15358 ;; Block operation instructions
15361 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15364 [(set_attr "length" "1")
15365 (set_attr "length_immediate" "0")
15366 (set_attr "modrm" "0")])
15368 (define_expand "movmem<mode>"
15369 [(use (match_operand:BLK 0 "memory_operand" ""))
15370 (use (match_operand:BLK 1 "memory_operand" ""))
15371 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15372 (use (match_operand:SWI48 3 "const_int_operand" ""))
15373 (use (match_operand:SI 4 "const_int_operand" ""))
15374 (use (match_operand:SI 5 "const_int_operand" ""))]
15377 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15378 operands[4], operands[5]))
15384 ;; Most CPUs don't like single string operations
15385 ;; Handle this case here to simplify previous expander.
15387 (define_expand "strmov"
15388 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15389 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15390 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15391 (clobber (reg:CC FLAGS_REG))])
15392 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15393 (clobber (reg:CC FLAGS_REG))])]
15396 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15398 /* If .md ever supports :P for Pmode, these can be directly
15399 in the pattern above. */
15400 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15401 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15403 /* Can't use this if the user has appropriated esi or edi. */
15404 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15405 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15407 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15408 operands[2], operands[3],
15409 operands[5], operands[6]));
15413 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15416 (define_expand "strmov_singleop"
15417 [(parallel [(set (match_operand 1 "memory_operand" "")
15418 (match_operand 3 "memory_operand" ""))
15419 (set (match_operand 0 "register_operand" "")
15420 (match_operand 4 "" ""))
15421 (set (match_operand 2 "register_operand" "")
15422 (match_operand 5 "" ""))])]
15424 "ix86_current_function_needs_cld = 1;")
15426 (define_insn "*strmovdi_rex_1"
15427 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15428 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15429 (set (match_operand:DI 0 "register_operand" "=D")
15430 (plus:DI (match_dup 2)
15432 (set (match_operand:DI 1 "register_operand" "=S")
15433 (plus:DI (match_dup 3)
15437 [(set_attr "type" "str")
15438 (set_attr "memory" "both")
15439 (set_attr "mode" "DI")])
15441 (define_insn "*strmovsi_1"
15442 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15443 (mem:SI (match_operand:P 3 "register_operand" "1")))
15444 (set (match_operand:P 0 "register_operand" "=D")
15445 (plus:P (match_dup 2)
15447 (set (match_operand:P 1 "register_operand" "=S")
15448 (plus:P (match_dup 3)
15452 [(set_attr "type" "str")
15453 (set_attr "memory" "both")
15454 (set_attr "mode" "SI")])
15456 (define_insn "*strmovhi_1"
15457 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15458 (mem:HI (match_operand:P 3 "register_operand" "1")))
15459 (set (match_operand:P 0 "register_operand" "=D")
15460 (plus:P (match_dup 2)
15462 (set (match_operand:P 1 "register_operand" "=S")
15463 (plus:P (match_dup 3)
15467 [(set_attr "type" "str")
15468 (set_attr "memory" "both")
15469 (set_attr "mode" "HI")])
15471 (define_insn "*strmovqi_1"
15472 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15473 (mem:QI (match_operand:P 3 "register_operand" "1")))
15474 (set (match_operand:P 0 "register_operand" "=D")
15475 (plus:P (match_dup 2)
15477 (set (match_operand:P 1 "register_operand" "=S")
15478 (plus:P (match_dup 3)
15482 [(set_attr "type" "str")
15483 (set_attr "memory" "both")
15484 (set (attr "prefix_rex")
15486 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15488 (const_string "*")))
15489 (set_attr "mode" "QI")])
15491 (define_expand "rep_mov"
15492 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15493 (set (match_operand 0 "register_operand" "")
15494 (match_operand 5 "" ""))
15495 (set (match_operand 2 "register_operand" "")
15496 (match_operand 6 "" ""))
15497 (set (match_operand 1 "memory_operand" "")
15498 (match_operand 3 "memory_operand" ""))
15499 (use (match_dup 4))])]
15501 "ix86_current_function_needs_cld = 1;")
15503 (define_insn "*rep_movdi_rex64"
15504 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15505 (set (match_operand:DI 0 "register_operand" "=D")
15506 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15508 (match_operand:DI 3 "register_operand" "0")))
15509 (set (match_operand:DI 1 "register_operand" "=S")
15510 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15511 (match_operand:DI 4 "register_operand" "1")))
15512 (set (mem:BLK (match_dup 3))
15513 (mem:BLK (match_dup 4)))
15514 (use (match_dup 5))]
15517 [(set_attr "type" "str")
15518 (set_attr "prefix_rep" "1")
15519 (set_attr "memory" "both")
15520 (set_attr "mode" "DI")])
15522 (define_insn "*rep_movsi"
15523 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15524 (set (match_operand:P 0 "register_operand" "=D")
15525 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15527 (match_operand:P 3 "register_operand" "0")))
15528 (set (match_operand:P 1 "register_operand" "=S")
15529 (plus:P (ashift:P (match_dup 5) (const_int 2))
15530 (match_operand:P 4 "register_operand" "1")))
15531 (set (mem:BLK (match_dup 3))
15532 (mem:BLK (match_dup 4)))
15533 (use (match_dup 5))]
15535 "rep{%;} movs{l|d}"
15536 [(set_attr "type" "str")
15537 (set_attr "prefix_rep" "1")
15538 (set_attr "memory" "both")
15539 (set_attr "mode" "SI")])
15541 (define_insn "*rep_movqi"
15542 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15543 (set (match_operand:P 0 "register_operand" "=D")
15544 (plus:P (match_operand:P 3 "register_operand" "0")
15545 (match_operand:P 5 "register_operand" "2")))
15546 (set (match_operand:P 1 "register_operand" "=S")
15547 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15548 (set (mem:BLK (match_dup 3))
15549 (mem:BLK (match_dup 4)))
15550 (use (match_dup 5))]
15553 [(set_attr "type" "str")
15554 (set_attr "prefix_rep" "1")
15555 (set_attr "memory" "both")
15556 (set_attr "mode" "QI")])
15558 (define_expand "setmem<mode>"
15559 [(use (match_operand:BLK 0 "memory_operand" ""))
15560 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15561 (use (match_operand:QI 2 "nonmemory_operand" ""))
15562 (use (match_operand 3 "const_int_operand" ""))
15563 (use (match_operand:SI 4 "const_int_operand" ""))
15564 (use (match_operand:SI 5 "const_int_operand" ""))]
15567 if (ix86_expand_setmem (operands[0], operands[1],
15568 operands[2], operands[3],
15569 operands[4], operands[5]))
15575 ;; Most CPUs don't like single string operations
15576 ;; Handle this case here to simplify previous expander.
15578 (define_expand "strset"
15579 [(set (match_operand 1 "memory_operand" "")
15580 (match_operand 2 "register_operand" ""))
15581 (parallel [(set (match_operand 0 "register_operand" "")
15583 (clobber (reg:CC FLAGS_REG))])]
15586 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15587 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15589 /* If .md ever supports :P for Pmode, this can be directly
15590 in the pattern above. */
15591 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15592 GEN_INT (GET_MODE_SIZE (GET_MODE
15594 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15596 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15602 (define_expand "strset_singleop"
15603 [(parallel [(set (match_operand 1 "memory_operand" "")
15604 (match_operand 2 "register_operand" ""))
15605 (set (match_operand 0 "register_operand" "")
15606 (match_operand 3 "" ""))])]
15608 "ix86_current_function_needs_cld = 1;")
15610 (define_insn "*strsetdi_rex_1"
15611 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15612 (match_operand:DI 2 "register_operand" "a"))
15613 (set (match_operand:DI 0 "register_operand" "=D")
15614 (plus:DI (match_dup 1)
15618 [(set_attr "type" "str")
15619 (set_attr "memory" "store")
15620 (set_attr "mode" "DI")])
15622 (define_insn "*strsetsi_1"
15623 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15624 (match_operand:SI 2 "register_operand" "a"))
15625 (set (match_operand:P 0 "register_operand" "=D")
15626 (plus:P (match_dup 1)
15630 [(set_attr "type" "str")
15631 (set_attr "memory" "store")
15632 (set_attr "mode" "SI")])
15634 (define_insn "*strsethi_1"
15635 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15636 (match_operand:HI 2 "register_operand" "a"))
15637 (set (match_operand:P 0 "register_operand" "=D")
15638 (plus:P (match_dup 1)
15642 [(set_attr "type" "str")
15643 (set_attr "memory" "store")
15644 (set_attr "mode" "HI")])
15646 (define_insn "*strsetqi_1"
15647 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15648 (match_operand:QI 2 "register_operand" "a"))
15649 (set (match_operand:P 0 "register_operand" "=D")
15650 (plus:P (match_dup 1)
15654 [(set_attr "type" "str")
15655 (set_attr "memory" "store")
15656 (set (attr "prefix_rex")
15658 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15660 (const_string "*")))
15661 (set_attr "mode" "QI")])
15663 (define_expand "rep_stos"
15664 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15665 (set (match_operand 0 "register_operand" "")
15666 (match_operand 4 "" ""))
15667 (set (match_operand 2 "memory_operand" "") (const_int 0))
15668 (use (match_operand 3 "register_operand" ""))
15669 (use (match_dup 1))])]
15671 "ix86_current_function_needs_cld = 1;")
15673 (define_insn "*rep_stosdi_rex64"
15674 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15675 (set (match_operand:DI 0 "register_operand" "=D")
15676 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15678 (match_operand:DI 3 "register_operand" "0")))
15679 (set (mem:BLK (match_dup 3))
15681 (use (match_operand:DI 2 "register_operand" "a"))
15682 (use (match_dup 4))]
15685 [(set_attr "type" "str")
15686 (set_attr "prefix_rep" "1")
15687 (set_attr "memory" "store")
15688 (set_attr "mode" "DI")])
15690 (define_insn "*rep_stossi"
15691 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15692 (set (match_operand:P 0 "register_operand" "=D")
15693 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15695 (match_operand:P 3 "register_operand" "0")))
15696 (set (mem:BLK (match_dup 3))
15698 (use (match_operand:SI 2 "register_operand" "a"))
15699 (use (match_dup 4))]
15701 "rep{%;} stos{l|d}"
15702 [(set_attr "type" "str")
15703 (set_attr "prefix_rep" "1")
15704 (set_attr "memory" "store")
15705 (set_attr "mode" "SI")])
15707 (define_insn "*rep_stosqi"
15708 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15709 (set (match_operand:P 0 "register_operand" "=D")
15710 (plus:P (match_operand:P 3 "register_operand" "0")
15711 (match_operand:P 4 "register_operand" "1")))
15712 (set (mem:BLK (match_dup 3))
15714 (use (match_operand:QI 2 "register_operand" "a"))
15715 (use (match_dup 4))]
15718 [(set_attr "type" "str")
15719 (set_attr "prefix_rep" "1")
15720 (set_attr "memory" "store")
15721 (set (attr "prefix_rex")
15723 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15725 (const_string "*")))
15726 (set_attr "mode" "QI")])
15728 (define_expand "cmpstrnsi"
15729 [(set (match_operand:SI 0 "register_operand" "")
15730 (compare:SI (match_operand:BLK 1 "general_operand" "")
15731 (match_operand:BLK 2 "general_operand" "")))
15732 (use (match_operand 3 "general_operand" ""))
15733 (use (match_operand 4 "immediate_operand" ""))]
15736 rtx addr1, addr2, out, outlow, count, countreg, align;
15738 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15741 /* Can't use this if the user has appropriated esi or edi. */
15742 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15747 out = gen_reg_rtx (SImode);
15749 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15750 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15751 if (addr1 != XEXP (operands[1], 0))
15752 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15753 if (addr2 != XEXP (operands[2], 0))
15754 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15756 count = operands[3];
15757 countreg = ix86_zero_extend_to_Pmode (count);
15759 /* %%% Iff we are testing strict equality, we can use known alignment
15760 to good advantage. This may be possible with combine, particularly
15761 once cc0 is dead. */
15762 align = operands[4];
15764 if (CONST_INT_P (count))
15766 if (INTVAL (count) == 0)
15768 emit_move_insn (operands[0], const0_rtx);
15771 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15772 operands[1], operands[2]));
15776 rtx (*gen_cmp) (rtx, rtx);
15778 gen_cmp = (TARGET_64BIT
15779 ? gen_cmpdi_1 : gen_cmpsi_1);
15781 emit_insn (gen_cmp (countreg, countreg));
15782 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15783 operands[1], operands[2]));
15786 outlow = gen_lowpart (QImode, out);
15787 emit_insn (gen_cmpintqi (outlow));
15788 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15790 if (operands[0] != out)
15791 emit_move_insn (operands[0], out);
15796 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15798 (define_expand "cmpintqi"
15799 [(set (match_dup 1)
15800 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15802 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15803 (parallel [(set (match_operand:QI 0 "register_operand" "")
15804 (minus:QI (match_dup 1)
15806 (clobber (reg:CC FLAGS_REG))])]
15809 operands[1] = gen_reg_rtx (QImode);
15810 operands[2] = gen_reg_rtx (QImode);
15813 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15814 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15816 (define_expand "cmpstrnqi_nz_1"
15817 [(parallel [(set (reg:CC FLAGS_REG)
15818 (compare:CC (match_operand 4 "memory_operand" "")
15819 (match_operand 5 "memory_operand" "")))
15820 (use (match_operand 2 "register_operand" ""))
15821 (use (match_operand:SI 3 "immediate_operand" ""))
15822 (clobber (match_operand 0 "register_operand" ""))
15823 (clobber (match_operand 1 "register_operand" ""))
15824 (clobber (match_dup 2))])]
15826 "ix86_current_function_needs_cld = 1;")
15828 (define_insn "*cmpstrnqi_nz_1"
15829 [(set (reg:CC FLAGS_REG)
15830 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15831 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15832 (use (match_operand:P 6 "register_operand" "2"))
15833 (use (match_operand:SI 3 "immediate_operand" "i"))
15834 (clobber (match_operand:P 0 "register_operand" "=S"))
15835 (clobber (match_operand:P 1 "register_operand" "=D"))
15836 (clobber (match_operand:P 2 "register_operand" "=c"))]
15839 [(set_attr "type" "str")
15840 (set_attr "mode" "QI")
15841 (set (attr "prefix_rex")
15843 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15845 (const_string "*")))
15846 (set_attr "prefix_rep" "1")])
15848 ;; The same, but the count is not known to not be zero.
15850 (define_expand "cmpstrnqi_1"
15851 [(parallel [(set (reg:CC FLAGS_REG)
15852 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15854 (compare:CC (match_operand 4 "memory_operand" "")
15855 (match_operand 5 "memory_operand" ""))
15857 (use (match_operand:SI 3 "immediate_operand" ""))
15858 (use (reg:CC FLAGS_REG))
15859 (clobber (match_operand 0 "register_operand" ""))
15860 (clobber (match_operand 1 "register_operand" ""))
15861 (clobber (match_dup 2))])]
15863 "ix86_current_function_needs_cld = 1;")
15865 (define_insn "*cmpstrnqi_1"
15866 [(set (reg:CC FLAGS_REG)
15867 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15869 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15870 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15872 (use (match_operand:SI 3 "immediate_operand" "i"))
15873 (use (reg:CC FLAGS_REG))
15874 (clobber (match_operand:P 0 "register_operand" "=S"))
15875 (clobber (match_operand:P 1 "register_operand" "=D"))
15876 (clobber (match_operand:P 2 "register_operand" "=c"))]
15879 [(set_attr "type" "str")
15880 (set_attr "mode" "QI")
15881 (set (attr "prefix_rex")
15883 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15885 (const_string "*")))
15886 (set_attr "prefix_rep" "1")])
15888 (define_expand "strlen<mode>"
15889 [(set (match_operand:SWI48x 0 "register_operand" "")
15890 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15891 (match_operand:QI 2 "immediate_operand" "")
15892 (match_operand 3 "immediate_operand" "")]
15896 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15902 (define_expand "strlenqi_1"
15903 [(parallel [(set (match_operand 0 "register_operand" "")
15904 (match_operand 2 "" ""))
15905 (clobber (match_operand 1 "register_operand" ""))
15906 (clobber (reg:CC FLAGS_REG))])]
15908 "ix86_current_function_needs_cld = 1;")
15910 (define_insn "*strlenqi_1"
15911 [(set (match_operand:P 0 "register_operand" "=&c")
15912 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15913 (match_operand:QI 2 "register_operand" "a")
15914 (match_operand:P 3 "immediate_operand" "i")
15915 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15916 (clobber (match_operand:P 1 "register_operand" "=D"))
15917 (clobber (reg:CC FLAGS_REG))]
15920 [(set_attr "type" "str")
15921 (set_attr "mode" "QI")
15922 (set (attr "prefix_rex")
15924 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15926 (const_string "*")))
15927 (set_attr "prefix_rep" "1")])
15929 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15930 ;; handled in combine, but it is not currently up to the task.
15931 ;; When used for their truth value, the cmpstrn* expanders generate
15940 ;; The intermediate three instructions are unnecessary.
15942 ;; This one handles cmpstrn*_nz_1...
15945 (set (reg:CC FLAGS_REG)
15946 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15947 (mem:BLK (match_operand 5 "register_operand" ""))))
15948 (use (match_operand 6 "register_operand" ""))
15949 (use (match_operand:SI 3 "immediate_operand" ""))
15950 (clobber (match_operand 0 "register_operand" ""))
15951 (clobber (match_operand 1 "register_operand" ""))
15952 (clobber (match_operand 2 "register_operand" ""))])
15953 (set (match_operand:QI 7 "register_operand" "")
15954 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15955 (set (match_operand:QI 8 "register_operand" "")
15956 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15957 (set (reg FLAGS_REG)
15958 (compare (match_dup 7) (match_dup 8)))
15960 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15962 (set (reg:CC FLAGS_REG)
15963 (compare:CC (mem:BLK (match_dup 4))
15964 (mem:BLK (match_dup 5))))
15965 (use (match_dup 6))
15966 (use (match_dup 3))
15967 (clobber (match_dup 0))
15968 (clobber (match_dup 1))
15969 (clobber (match_dup 2))])])
15971 ;; ...and this one handles cmpstrn*_1.
15974 (set (reg:CC FLAGS_REG)
15975 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15977 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15978 (mem:BLK (match_operand 5 "register_operand" "")))
15980 (use (match_operand:SI 3 "immediate_operand" ""))
15981 (use (reg:CC FLAGS_REG))
15982 (clobber (match_operand 0 "register_operand" ""))
15983 (clobber (match_operand 1 "register_operand" ""))
15984 (clobber (match_operand 2 "register_operand" ""))])
15985 (set (match_operand:QI 7 "register_operand" "")
15986 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15987 (set (match_operand:QI 8 "register_operand" "")
15988 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15989 (set (reg FLAGS_REG)
15990 (compare (match_dup 7) (match_dup 8)))
15992 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15994 (set (reg:CC FLAGS_REG)
15995 (if_then_else:CC (ne (match_dup 6)
15997 (compare:CC (mem:BLK (match_dup 4))
15998 (mem:BLK (match_dup 5)))
16000 (use (match_dup 3))
16001 (use (reg:CC FLAGS_REG))
16002 (clobber (match_dup 0))
16003 (clobber (match_dup 1))
16004 (clobber (match_dup 2))])])
16006 ;; Conditional move instructions.
16008 (define_expand "mov<mode>cc"
16009 [(set (match_operand:SWIM 0 "register_operand" "")
16010 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16011 (match_operand:SWIM 2 "general_operand" "")
16012 (match_operand:SWIM 3 "general_operand" "")))]
16014 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16016 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16017 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16018 ;; So just document what we're doing explicitly.
16020 (define_expand "x86_mov<mode>cc_0_m1"
16022 [(set (match_operand:SWI48 0 "register_operand" "")
16023 (if_then_else:SWI48
16024 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16025 [(match_operand 1 "flags_reg_operand" "")
16029 (clobber (reg:CC FLAGS_REG))])])
16031 (define_insn "*x86_mov<mode>cc_0_m1"
16032 [(set (match_operand:SWI48 0 "register_operand" "=r")
16033 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16034 [(reg FLAGS_REG) (const_int 0)])
16037 (clobber (reg:CC FLAGS_REG))]
16039 "sbb{<imodesuffix>}\t%0, %0"
16040 ; Since we don't have the proper number of operands for an alu insn,
16041 ; fill in all the blanks.
16042 [(set_attr "type" "alu")
16043 (set_attr "use_carry" "1")
16044 (set_attr "pent_pair" "pu")
16045 (set_attr "memory" "none")
16046 (set_attr "imm_disp" "false")
16047 (set_attr "mode" "<MODE>")
16048 (set_attr "length_immediate" "0")])
16050 (define_insn "*x86_mov<mode>cc_0_m1_se"
16051 [(set (match_operand:SWI48 0 "register_operand" "=r")
16052 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16053 [(reg FLAGS_REG) (const_int 0)])
16056 (clobber (reg:CC FLAGS_REG))]
16058 "sbb{<imodesuffix>}\t%0, %0"
16059 [(set_attr "type" "alu")
16060 (set_attr "use_carry" "1")
16061 (set_attr "pent_pair" "pu")
16062 (set_attr "memory" "none")
16063 (set_attr "imm_disp" "false")
16064 (set_attr "mode" "<MODE>")
16065 (set_attr "length_immediate" "0")])
16067 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16068 [(set (match_operand:SWI48 0 "register_operand" "=r")
16069 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16070 [(reg FLAGS_REG) (const_int 0)])))]
16072 "sbb{<imodesuffix>}\t%0, %0"
16073 [(set_attr "type" "alu")
16074 (set_attr "use_carry" "1")
16075 (set_attr "pent_pair" "pu")
16076 (set_attr "memory" "none")
16077 (set_attr "imm_disp" "false")
16078 (set_attr "mode" "<MODE>")
16079 (set_attr "length_immediate" "0")])
16081 (define_insn "*mov<mode>cc_noc"
16082 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16083 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16084 [(reg FLAGS_REG) (const_int 0)])
16085 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16086 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16087 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16089 cmov%O2%C1\t{%2, %0|%0, %2}
16090 cmov%O2%c1\t{%3, %0|%0, %3}"
16091 [(set_attr "type" "icmov")
16092 (set_attr "mode" "<MODE>")])
16094 (define_insn_and_split "*movqicc_noc"
16095 [(set (match_operand:QI 0 "register_operand" "=r,r")
16096 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16097 [(match_operand 4 "flags_reg_operand" "")
16099 (match_operand:QI 2 "register_operand" "r,0")
16100 (match_operand:QI 3 "register_operand" "0,r")))]
16101 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16103 "&& reload_completed"
16104 [(set (match_dup 0)
16105 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16108 "operands[0] = gen_lowpart (SImode, operands[0]);
16109 operands[2] = gen_lowpart (SImode, operands[2]);
16110 operands[3] = gen_lowpart (SImode, operands[3]);"
16111 [(set_attr "type" "icmov")
16112 (set_attr "mode" "SI")])
16114 (define_expand "mov<mode>cc"
16115 [(set (match_operand:X87MODEF 0 "register_operand" "")
16116 (if_then_else:X87MODEF
16117 (match_operand 1 "ix86_fp_comparison_operator" "")
16118 (match_operand:X87MODEF 2 "register_operand" "")
16119 (match_operand:X87MODEF 3 "register_operand" "")))]
16120 "(TARGET_80387 && TARGET_CMOVE)
16121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16122 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16124 (define_insn "*movxfcc_1"
16125 [(set (match_operand:XF 0 "register_operand" "=f,f")
16126 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16127 [(reg FLAGS_REG) (const_int 0)])
16128 (match_operand:XF 2 "register_operand" "f,0")
16129 (match_operand:XF 3 "register_operand" "0,f")))]
16130 "TARGET_80387 && TARGET_CMOVE"
16132 fcmov%F1\t{%2, %0|%0, %2}
16133 fcmov%f1\t{%3, %0|%0, %3}"
16134 [(set_attr "type" "fcmov")
16135 (set_attr "mode" "XF")])
16137 (define_insn "*movdfcc_1_rex64"
16138 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16139 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16140 [(reg FLAGS_REG) (const_int 0)])
16141 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16142 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16143 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16144 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16146 fcmov%F1\t{%2, %0|%0, %2}
16147 fcmov%f1\t{%3, %0|%0, %3}
16148 cmov%O2%C1\t{%2, %0|%0, %2}
16149 cmov%O2%c1\t{%3, %0|%0, %3}"
16150 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16151 (set_attr "mode" "DF,DF,DI,DI")])
16153 (define_insn "*movdfcc_1"
16154 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16155 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16156 [(reg FLAGS_REG) (const_int 0)])
16157 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16158 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16159 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16160 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16162 fcmov%F1\t{%2, %0|%0, %2}
16163 fcmov%f1\t{%3, %0|%0, %3}
16166 [(set_attr "type" "fcmov,fcmov,multi,multi")
16167 (set_attr "mode" "DF,DF,DI,DI")])
16170 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16171 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16172 [(match_operand 4 "flags_reg_operand" "")
16174 (match_operand:DF 2 "nonimmediate_operand" "")
16175 (match_operand:DF 3 "nonimmediate_operand" "")))]
16176 "!TARGET_64BIT && reload_completed"
16177 [(set (match_dup 2)
16178 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16182 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16186 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16187 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16190 (define_insn "*movsfcc_1_387"
16191 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16192 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16193 [(reg FLAGS_REG) (const_int 0)])
16194 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16195 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16196 "TARGET_80387 && TARGET_CMOVE
16197 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16199 fcmov%F1\t{%2, %0|%0, %2}
16200 fcmov%f1\t{%3, %0|%0, %3}
16201 cmov%O2%C1\t{%2, %0|%0, %2}
16202 cmov%O2%c1\t{%3, %0|%0, %3}"
16203 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16204 (set_attr "mode" "SF,SF,SI,SI")])
16206 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16207 ;; the scalar versions to have only XMM registers as operands.
16209 ;; XOP conditional move
16210 (define_insn "*xop_pcmov_<mode>"
16211 [(set (match_operand:MODEF 0 "register_operand" "=x")
16212 (if_then_else:MODEF
16213 (match_operand:MODEF 1 "register_operand" "x")
16214 (match_operand:MODEF 2 "register_operand" "x")
16215 (match_operand:MODEF 3 "register_operand" "x")))]
16217 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16218 [(set_attr "type" "sse4arg")])
16220 ;; These versions of the min/max patterns are intentionally ignorant of
16221 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16222 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16223 ;; are undefined in this condition, we're certain this is correct.
16225 (define_insn "<code><mode>3"
16226 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16228 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16229 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16230 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16232 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16233 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16234 [(set_attr "isa" "noavx,avx")
16235 (set_attr "prefix" "orig,vex")
16236 (set_attr "type" "sseadd")
16237 (set_attr "mode" "<MODE>")])
16239 ;; These versions of the min/max patterns implement exactly the operations
16240 ;; min = (op1 < op2 ? op1 : op2)
16241 ;; max = (!(op1 < op2) ? op1 : op2)
16242 ;; Their operands are not commutative, and thus they may be used in the
16243 ;; presence of -0.0 and NaN.
16245 (define_insn "*ieee_smin<mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16248 [(match_operand:MODEF 1 "register_operand" "0,x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16251 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16253 min<ssemodesuffix>\t{%2, %0|%0, %2}
16254 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16255 [(set_attr "isa" "noavx,avx")
16256 (set_attr "prefix" "orig,vex")
16257 (set_attr "type" "sseadd")
16258 (set_attr "mode" "<MODE>")])
16260 (define_insn "*ieee_smax<mode>3"
16261 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16263 [(match_operand:MODEF 1 "register_operand" "0,x")
16264 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16266 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16268 max<ssemodesuffix>\t{%2, %0|%0, %2}
16269 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16270 [(set_attr "isa" "noavx,avx")
16271 (set_attr "prefix" "orig,vex")
16272 (set_attr "type" "sseadd")
16273 (set_attr "mode" "<MODE>")])
16275 ;; Make two stack loads independent:
16277 ;; fld %st(0) -> fld bb
16278 ;; fmul bb fmul %st(1), %st
16280 ;; Actually we only match the last two instructions for simplicity.
16282 [(set (match_operand 0 "fp_register_operand" "")
16283 (match_operand 1 "fp_register_operand" ""))
16285 (match_operator 2 "binary_fp_operator"
16287 (match_operand 3 "memory_operand" "")]))]
16288 "REGNO (operands[0]) != REGNO (operands[1])"
16289 [(set (match_dup 0) (match_dup 3))
16290 (set (match_dup 0) (match_dup 4))]
16292 ;; The % modifier is not operational anymore in peephole2's, so we have to
16293 ;; swap the operands manually in the case of addition and multiplication.
16294 "if (COMMUTATIVE_ARITH_P (operands[2]))
16295 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16296 GET_MODE (operands[2]),
16297 operands[0], operands[1]);
16299 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16300 GET_MODE (operands[2]),
16301 operands[1], operands[0]);")
16303 ;; Conditional addition patterns
16304 (define_expand "add<mode>cc"
16305 [(match_operand:SWI 0 "register_operand" "")
16306 (match_operand 1 "ordered_comparison_operator" "")
16307 (match_operand:SWI 2 "register_operand" "")
16308 (match_operand:SWI 3 "const_int_operand" "")]
16310 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16312 ;; Misc patterns (?)
16314 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16315 ;; Otherwise there will be nothing to keep
16317 ;; [(set (reg ebp) (reg esp))]
16318 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16319 ;; (clobber (eflags)]
16320 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16322 ;; in proper program order.
16324 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16325 [(set (match_operand:P 0 "register_operand" "=r,r")
16326 (plus:P (match_operand:P 1 "register_operand" "0,r")
16327 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16328 (clobber (reg:CC FLAGS_REG))
16329 (clobber (mem:BLK (scratch)))]
16332 switch (get_attr_type (insn))
16335 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16338 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16339 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16340 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16342 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16345 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16346 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16349 [(set (attr "type")
16350 (cond [(and (eq_attr "alternative" "0")
16351 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16352 (const_string "alu")
16353 (match_operand:<MODE> 2 "const0_operand" "")
16354 (const_string "imov")
16356 (const_string "lea")))
16357 (set (attr "length_immediate")
16358 (cond [(eq_attr "type" "imov")
16360 (and (eq_attr "type" "alu")
16361 (match_operand 2 "const128_operand" ""))
16364 (const_string "*")))
16365 (set_attr "mode" "<MODE>")])
16367 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16368 [(set (match_operand:P 0 "register_operand" "=r")
16369 (minus:P (match_operand:P 1 "register_operand" "0")
16370 (match_operand:P 2 "register_operand" "r")))
16371 (clobber (reg:CC FLAGS_REG))
16372 (clobber (mem:BLK (scratch)))]
16374 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16375 [(set_attr "type" "alu")
16376 (set_attr "mode" "<MODE>")])
16378 (define_insn "allocate_stack_worker_probe_<mode>"
16379 [(set (match_operand:P 0 "register_operand" "=a")
16380 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16381 UNSPECV_STACK_PROBE))
16382 (clobber (reg:CC FLAGS_REG))]
16383 "ix86_target_stack_probe ()"
16384 "call\t___chkstk_ms"
16385 [(set_attr "type" "multi")
16386 (set_attr "length" "5")])
16388 (define_expand "allocate_stack"
16389 [(match_operand 0 "register_operand" "")
16390 (match_operand 1 "general_operand" "")]
16391 "ix86_target_stack_probe ()"
16395 #ifndef CHECK_STACK_LIMIT
16396 #define CHECK_STACK_LIMIT 0
16399 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16400 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16402 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16403 stack_pointer_rtx, 0, OPTAB_DIRECT);
16404 if (x != stack_pointer_rtx)
16405 emit_move_insn (stack_pointer_rtx, x);
16409 x = copy_to_mode_reg (Pmode, operands[1]);
16411 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16413 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16414 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16415 stack_pointer_rtx, 0, OPTAB_DIRECT);
16416 if (x != stack_pointer_rtx)
16417 emit_move_insn (stack_pointer_rtx, x);
16420 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16424 ;; Use IOR for stack probes, this is shorter.
16425 (define_expand "probe_stack"
16426 [(match_operand 0 "memory_operand" "")]
16429 rtx (*gen_ior3) (rtx, rtx, rtx);
16431 gen_ior3 = (GET_MODE (operands[0]) == DImode
16432 ? gen_iordi3 : gen_iorsi3);
16434 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16438 (define_insn "adjust_stack_and_probe<mode>"
16439 [(set (match_operand:P 0 "register_operand" "=r")
16440 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16441 UNSPECV_PROBE_STACK_RANGE))
16442 (set (reg:P SP_REG)
16443 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16444 (clobber (reg:CC FLAGS_REG))
16445 (clobber (mem:BLK (scratch)))]
16447 "* return output_adjust_stack_and_probe (operands[0]);"
16448 [(set_attr "type" "multi")])
16450 (define_insn "probe_stack_range<mode>"
16451 [(set (match_operand:P 0 "register_operand" "=r")
16452 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16453 (match_operand:P 2 "const_int_operand" "n")]
16454 UNSPECV_PROBE_STACK_RANGE))
16455 (clobber (reg:CC FLAGS_REG))]
16457 "* return output_probe_stack_range (operands[0], operands[2]);"
16458 [(set_attr "type" "multi")])
16460 (define_expand "builtin_setjmp_receiver"
16461 [(label_ref (match_operand 0 "" ""))]
16462 "!TARGET_64BIT && flag_pic"
16468 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16469 rtx label_rtx = gen_label_rtx ();
16470 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16471 xops[0] = xops[1] = picreg;
16472 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16473 ix86_expand_binary_operator (MINUS, SImode, xops);
16477 emit_insn (gen_set_got (pic_offset_table_rtx));
16481 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16484 [(set (match_operand 0 "register_operand" "")
16485 (match_operator 3 "promotable_binary_operator"
16486 [(match_operand 1 "register_operand" "")
16487 (match_operand 2 "aligned_operand" "")]))
16488 (clobber (reg:CC FLAGS_REG))]
16489 "! TARGET_PARTIAL_REG_STALL && reload_completed
16490 && ((GET_MODE (operands[0]) == HImode
16491 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16492 /* ??? next two lines just !satisfies_constraint_K (...) */
16493 || !CONST_INT_P (operands[2])
16494 || satisfies_constraint_K (operands[2])))
16495 || (GET_MODE (operands[0]) == QImode
16496 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16497 [(parallel [(set (match_dup 0)
16498 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16499 (clobber (reg:CC FLAGS_REG))])]
16500 "operands[0] = gen_lowpart (SImode, operands[0]);
16501 operands[1] = gen_lowpart (SImode, operands[1]);
16502 if (GET_CODE (operands[3]) != ASHIFT)
16503 operands[2] = gen_lowpart (SImode, operands[2]);
16504 PUT_MODE (operands[3], SImode);")
16506 ; Promote the QImode tests, as i386 has encoding of the AND
16507 ; instruction with 32-bit sign-extended immediate and thus the
16508 ; instruction size is unchanged, except in the %eax case for
16509 ; which it is increased by one byte, hence the ! optimize_size.
16511 [(set (match_operand 0 "flags_reg_operand" "")
16512 (match_operator 2 "compare_operator"
16513 [(and (match_operand 3 "aligned_operand" "")
16514 (match_operand 4 "const_int_operand" ""))
16516 (set (match_operand 1 "register_operand" "")
16517 (and (match_dup 3) (match_dup 4)))]
16518 "! TARGET_PARTIAL_REG_STALL && reload_completed
16519 && optimize_insn_for_speed_p ()
16520 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16521 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16522 /* Ensure that the operand will remain sign-extended immediate. */
16523 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16524 [(parallel [(set (match_dup 0)
16525 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16528 (and:SI (match_dup 3) (match_dup 4)))])]
16531 = gen_int_mode (INTVAL (operands[4])
16532 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16533 operands[1] = gen_lowpart (SImode, operands[1]);
16534 operands[3] = gen_lowpart (SImode, operands[3]);
16537 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16538 ; the TEST instruction with 32-bit sign-extended immediate and thus
16539 ; the instruction size would at least double, which is not what we
16540 ; want even with ! optimize_size.
16542 [(set (match_operand 0 "flags_reg_operand" "")
16543 (match_operator 1 "compare_operator"
16544 [(and (match_operand:HI 2 "aligned_operand" "")
16545 (match_operand:HI 3 "const_int_operand" ""))
16547 "! TARGET_PARTIAL_REG_STALL && reload_completed
16548 && ! TARGET_FAST_PREFIX
16549 && optimize_insn_for_speed_p ()
16550 /* Ensure that the operand will remain sign-extended immediate. */
16551 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16552 [(set (match_dup 0)
16553 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16557 = gen_int_mode (INTVAL (operands[3])
16558 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16559 operands[2] = gen_lowpart (SImode, operands[2]);
16563 [(set (match_operand 0 "register_operand" "")
16564 (neg (match_operand 1 "register_operand" "")))
16565 (clobber (reg:CC FLAGS_REG))]
16566 "! TARGET_PARTIAL_REG_STALL && reload_completed
16567 && (GET_MODE (operands[0]) == HImode
16568 || (GET_MODE (operands[0]) == QImode
16569 && (TARGET_PROMOTE_QImode
16570 || optimize_insn_for_size_p ())))"
16571 [(parallel [(set (match_dup 0)
16572 (neg:SI (match_dup 1)))
16573 (clobber (reg:CC FLAGS_REG))])]
16574 "operands[0] = gen_lowpart (SImode, operands[0]);
16575 operands[1] = gen_lowpart (SImode, operands[1]);")
16578 [(set (match_operand 0 "register_operand" "")
16579 (not (match_operand 1 "register_operand" "")))]
16580 "! TARGET_PARTIAL_REG_STALL && reload_completed
16581 && (GET_MODE (operands[0]) == HImode
16582 || (GET_MODE (operands[0]) == QImode
16583 && (TARGET_PROMOTE_QImode
16584 || optimize_insn_for_size_p ())))"
16585 [(set (match_dup 0)
16586 (not:SI (match_dup 1)))]
16587 "operands[0] = gen_lowpart (SImode, operands[0]);
16588 operands[1] = gen_lowpart (SImode, operands[1]);")
16591 [(set (match_operand 0 "register_operand" "")
16592 (if_then_else (match_operator 1 "ordered_comparison_operator"
16593 [(reg FLAGS_REG) (const_int 0)])
16594 (match_operand 2 "register_operand" "")
16595 (match_operand 3 "register_operand" "")))]
16596 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16597 && (GET_MODE (operands[0]) == HImode
16598 || (GET_MODE (operands[0]) == QImode
16599 && (TARGET_PROMOTE_QImode
16600 || optimize_insn_for_size_p ())))"
16601 [(set (match_dup 0)
16602 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16603 "operands[0] = gen_lowpart (SImode, operands[0]);
16604 operands[2] = gen_lowpart (SImode, operands[2]);
16605 operands[3] = gen_lowpart (SImode, operands[3]);")
16607 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16608 ;; transform a complex memory operation into two memory to register operations.
16610 ;; Don't push memory operands
16612 [(set (match_operand:SWI 0 "push_operand" "")
16613 (match_operand:SWI 1 "memory_operand" ""))
16614 (match_scratch:SWI 2 "<r>")]
16615 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16616 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16617 [(set (match_dup 2) (match_dup 1))
16618 (set (match_dup 0) (match_dup 2))])
16620 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16623 [(set (match_operand:SF 0 "push_operand" "")
16624 (match_operand:SF 1 "memory_operand" ""))
16625 (match_scratch:SF 2 "r")]
16626 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16627 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16628 [(set (match_dup 2) (match_dup 1))
16629 (set (match_dup 0) (match_dup 2))])
16631 ;; Don't move an immediate directly to memory when the instruction
16634 [(match_scratch:SWI124 1 "<r>")
16635 (set (match_operand:SWI124 0 "memory_operand" "")
16637 "optimize_insn_for_speed_p ()
16638 && !TARGET_USE_MOV0
16639 && TARGET_SPLIT_LONG_MOVES
16640 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16641 && peep2_regno_dead_p (0, FLAGS_REG)"
16642 [(parallel [(set (match_dup 2) (const_int 0))
16643 (clobber (reg:CC FLAGS_REG))])
16644 (set (match_dup 0) (match_dup 1))]
16645 "operands[2] = gen_lowpart (SImode, operands[1]);")
16648 [(match_scratch:SWI124 2 "<r>")
16649 (set (match_operand:SWI124 0 "memory_operand" "")
16650 (match_operand:SWI124 1 "immediate_operand" ""))]
16651 "optimize_insn_for_speed_p ()
16652 && TARGET_SPLIT_LONG_MOVES
16653 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16654 [(set (match_dup 2) (match_dup 1))
16655 (set (match_dup 0) (match_dup 2))])
16657 ;; Don't compare memory with zero, load and use a test instead.
16659 [(set (match_operand 0 "flags_reg_operand" "")
16660 (match_operator 1 "compare_operator"
16661 [(match_operand:SI 2 "memory_operand" "")
16663 (match_scratch:SI 3 "r")]
16664 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16665 [(set (match_dup 3) (match_dup 2))
16666 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16668 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16669 ;; Don't split NOTs with a displacement operand, because resulting XOR
16670 ;; will not be pairable anyway.
16672 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16673 ;; represented using a modRM byte. The XOR replacement is long decoded,
16674 ;; so this split helps here as well.
16676 ;; Note: Can't do this as a regular split because we can't get proper
16677 ;; lifetime information then.
16680 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16681 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16682 "optimize_insn_for_speed_p ()
16683 && ((TARGET_NOT_UNPAIRABLE
16684 && (!MEM_P (operands[0])
16685 || !memory_displacement_operand (operands[0], <MODE>mode)))
16686 || (TARGET_NOT_VECTORMODE
16687 && long_memory_operand (operands[0], <MODE>mode)))
16688 && peep2_regno_dead_p (0, FLAGS_REG)"
16689 [(parallel [(set (match_dup 0)
16690 (xor:SWI124 (match_dup 1) (const_int -1)))
16691 (clobber (reg:CC FLAGS_REG))])])
16693 ;; Non pairable "test imm, reg" instructions can be translated to
16694 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16695 ;; byte opcode instead of two, have a short form for byte operands),
16696 ;; so do it for other CPUs as well. Given that the value was dead,
16697 ;; this should not create any new dependencies. Pass on the sub-word
16698 ;; versions if we're concerned about partial register stalls.
16701 [(set (match_operand 0 "flags_reg_operand" "")
16702 (match_operator 1 "compare_operator"
16703 [(and:SI (match_operand:SI 2 "register_operand" "")
16704 (match_operand:SI 3 "immediate_operand" ""))
16706 "ix86_match_ccmode (insn, CCNOmode)
16707 && (true_regnum (operands[2]) != AX_REG
16708 || satisfies_constraint_K (operands[3]))
16709 && peep2_reg_dead_p (1, operands[2])"
16711 [(set (match_dup 0)
16712 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16715 (and:SI (match_dup 2) (match_dup 3)))])])
16717 ;; We don't need to handle HImode case, because it will be promoted to SImode
16718 ;; on ! TARGET_PARTIAL_REG_STALL
16721 [(set (match_operand 0 "flags_reg_operand" "")
16722 (match_operator 1 "compare_operator"
16723 [(and:QI (match_operand:QI 2 "register_operand" "")
16724 (match_operand:QI 3 "immediate_operand" ""))
16726 "! TARGET_PARTIAL_REG_STALL
16727 && ix86_match_ccmode (insn, CCNOmode)
16728 && true_regnum (operands[2]) != AX_REG
16729 && peep2_reg_dead_p (1, operands[2])"
16731 [(set (match_dup 0)
16732 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16735 (and:QI (match_dup 2) (match_dup 3)))])])
16738 [(set (match_operand 0 "flags_reg_operand" "")
16739 (match_operator 1 "compare_operator"
16742 (match_operand 2 "ext_register_operand" "")
16745 (match_operand 3 "const_int_operand" ""))
16747 "! TARGET_PARTIAL_REG_STALL
16748 && ix86_match_ccmode (insn, CCNOmode)
16749 && true_regnum (operands[2]) != AX_REG
16750 && peep2_reg_dead_p (1, operands[2])"
16751 [(parallel [(set (match_dup 0)
16760 (set (zero_extract:SI (match_dup 2)
16768 (match_dup 3)))])])
16770 ;; Don't do logical operations with memory inputs.
16772 [(match_scratch:SI 2 "r")
16773 (parallel [(set (match_operand:SI 0 "register_operand" "")
16774 (match_operator:SI 3 "arith_or_logical_operator"
16776 (match_operand:SI 1 "memory_operand" "")]))
16777 (clobber (reg:CC FLAGS_REG))])]
16778 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16779 [(set (match_dup 2) (match_dup 1))
16780 (parallel [(set (match_dup 0)
16781 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16782 (clobber (reg:CC FLAGS_REG))])])
16785 [(match_scratch:SI 2 "r")
16786 (parallel [(set (match_operand:SI 0 "register_operand" "")
16787 (match_operator:SI 3 "arith_or_logical_operator"
16788 [(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 2) (match_dup 0)]))
16795 (clobber (reg:CC FLAGS_REG))])])
16797 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16798 ;; refers to the destination of the load!
16801 [(set (match_operand:SI 0 "register_operand" "")
16802 (match_operand:SI 1 "register_operand" ""))
16803 (parallel [(set (match_dup 0)
16804 (match_operator:SI 3 "commutative_operator"
16806 (match_operand:SI 2 "memory_operand" "")]))
16807 (clobber (reg:CC FLAGS_REG))])]
16808 "REGNO (operands[0]) != REGNO (operands[1])
16809 && GENERAL_REGNO_P (REGNO (operands[0]))
16810 && GENERAL_REGNO_P (REGNO (operands[1]))"
16811 [(set (match_dup 0) (match_dup 4))
16812 (parallel [(set (match_dup 0)
16813 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16814 (clobber (reg:CC FLAGS_REG))])]
16815 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16818 [(set (match_operand 0 "register_operand" "")
16819 (match_operand 1 "register_operand" ""))
16821 (match_operator 3 "commutative_operator"
16823 (match_operand 2 "memory_operand" "")]))]
16824 "REGNO (operands[0]) != REGNO (operands[1])
16825 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16826 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16827 [(set (match_dup 0) (match_dup 2))
16829 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16831 ; Don't do logical operations with memory outputs
16833 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16834 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16835 ; the same decoder scheduling characteristics as the original.
16838 [(match_scratch:SI 2 "r")
16839 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16840 (match_operator:SI 3 "arith_or_logical_operator"
16842 (match_operand:SI 1 "nonmemory_operand" "")]))
16843 (clobber (reg:CC FLAGS_REG))])]
16844 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16845 /* Do not split stack checking probes. */
16846 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16847 [(set (match_dup 2) (match_dup 0))
16848 (parallel [(set (match_dup 2)
16849 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16850 (clobber (reg:CC FLAGS_REG))])
16851 (set (match_dup 0) (match_dup 2))])
16854 [(match_scratch:SI 2 "r")
16855 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16856 (match_operator:SI 3 "arith_or_logical_operator"
16857 [(match_operand:SI 1 "nonmemory_operand" "")
16859 (clobber (reg:CC FLAGS_REG))])]
16860 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16861 /* Do not split stack checking probes. */
16862 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16863 [(set (match_dup 2) (match_dup 0))
16864 (parallel [(set (match_dup 2)
16865 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16866 (clobber (reg:CC FLAGS_REG))])
16867 (set (match_dup 0) (match_dup 2))])
16869 ;; Attempt to use arith or logical operations with memory outputs with
16870 ;; setting of flags.
16872 [(set (match_operand:SWI 0 "register_operand" "")
16873 (match_operand:SWI 1 "memory_operand" ""))
16874 (parallel [(set (match_dup 0)
16875 (match_operator:SWI 3 "plusminuslogic_operator"
16877 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16878 (clobber (reg:CC FLAGS_REG))])
16879 (set (match_dup 1) (match_dup 0))
16880 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16881 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16882 && peep2_reg_dead_p (4, operands[0])
16883 && !reg_overlap_mentioned_p (operands[0], operands[1])
16884 && ix86_match_ccmode (peep2_next_insn (3),
16885 (GET_CODE (operands[3]) == PLUS
16886 || GET_CODE (operands[3]) == MINUS)
16887 ? CCGOCmode : CCNOmode)"
16888 [(parallel [(set (match_dup 4) (match_dup 5))
16889 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16890 (match_dup 2)]))])]
16891 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16892 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16893 copy_rtx (operands[1]),
16894 copy_rtx (operands[2]));
16895 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16896 operands[5], const0_rtx);")
16899 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16900 (match_operator:SWI 2 "plusminuslogic_operator"
16902 (match_operand:SWI 1 "memory_operand" "")]))
16903 (clobber (reg:CC FLAGS_REG))])
16904 (set (match_dup 1) (match_dup 0))
16905 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16906 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16907 && GET_CODE (operands[2]) != MINUS
16908 && peep2_reg_dead_p (3, operands[0])
16909 && !reg_overlap_mentioned_p (operands[0], operands[1])
16910 && ix86_match_ccmode (peep2_next_insn (2),
16911 GET_CODE (operands[2]) == PLUS
16912 ? CCGOCmode : CCNOmode)"
16913 [(parallel [(set (match_dup 3) (match_dup 4))
16914 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16915 (match_dup 0)]))])]
16916 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16917 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16918 copy_rtx (operands[1]),
16919 copy_rtx (operands[0]));
16920 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16921 operands[4], const0_rtx);")
16924 [(set (match_operand:SWI12 0 "register_operand" "")
16925 (match_operand:SWI12 1 "memory_operand" ""))
16926 (parallel [(set (match_operand:SI 4 "register_operand" "")
16927 (match_operator:SI 3 "plusminuslogic_operator"
16929 (match_operand:SI 2 "nonmemory_operand" "")]))
16930 (clobber (reg:CC FLAGS_REG))])
16931 (set (match_dup 1) (match_dup 0))
16932 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16933 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16934 && REG_P (operands[0]) && REG_P (operands[4])
16935 && REGNO (operands[0]) == REGNO (operands[4])
16936 && peep2_reg_dead_p (4, operands[0])
16937 && !reg_overlap_mentioned_p (operands[0], operands[1])
16938 && ix86_match_ccmode (peep2_next_insn (3),
16939 (GET_CODE (operands[3]) == PLUS
16940 || GET_CODE (operands[3]) == MINUS)
16941 ? CCGOCmode : CCNOmode)"
16942 [(parallel [(set (match_dup 4) (match_dup 5))
16943 (set (match_dup 1) (match_dup 6))])]
16944 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16945 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16946 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16947 copy_rtx (operands[1]), operands[2]);
16948 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16949 operands[5], const0_rtx);
16950 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16951 copy_rtx (operands[1]),
16952 copy_rtx (operands[2]));")
16954 ;; Attempt to always use XOR for zeroing registers.
16956 [(set (match_operand 0 "register_operand" "")
16957 (match_operand 1 "const0_operand" ""))]
16958 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16959 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16960 && GENERAL_REG_P (operands[0])
16961 && peep2_regno_dead_p (0, FLAGS_REG)"
16962 [(parallel [(set (match_dup 0) (const_int 0))
16963 (clobber (reg:CC FLAGS_REG))])]
16964 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16967 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16969 "(GET_MODE (operands[0]) == QImode
16970 || GET_MODE (operands[0]) == HImode)
16971 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16972 && peep2_regno_dead_p (0, FLAGS_REG)"
16973 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16974 (clobber (reg:CC FLAGS_REG))])])
16976 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16978 [(set (match_operand:SWI248 0 "register_operand" "")
16980 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16981 && peep2_regno_dead_p (0, FLAGS_REG)"
16982 [(parallel [(set (match_dup 0) (const_int -1))
16983 (clobber (reg:CC FLAGS_REG))])]
16985 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16986 operands[0] = gen_lowpart (SImode, operands[0]);
16989 ;; Attempt to convert simple lea to add/shift.
16990 ;; These can be created by move expanders.
16993 [(set (match_operand:SWI48 0 "register_operand" "")
16994 (plus:SWI48 (match_dup 0)
16995 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16996 "peep2_regno_dead_p (0, FLAGS_REG)"
16997 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16998 (clobber (reg:CC FLAGS_REG))])])
17001 [(set (match_operand:SI 0 "register_operand" "")
17002 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17003 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17005 && peep2_regno_dead_p (0, FLAGS_REG)
17006 && REGNO (operands[0]) == REGNO (operands[1])"
17007 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17008 (clobber (reg:CC FLAGS_REG))])]
17009 "operands[2] = gen_lowpart (SImode, operands[2]);")
17012 [(set (match_operand:SWI48 0 "register_operand" "")
17013 (mult:SWI48 (match_dup 0)
17014 (match_operand:SWI48 1 "const_int_operand" "")))]
17015 "exact_log2 (INTVAL (operands[1])) >= 0
17016 && peep2_regno_dead_p (0, FLAGS_REG)"
17017 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17018 (clobber (reg:CC FLAGS_REG))])]
17019 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17022 [(set (match_operand:SI 0 "register_operand" "")
17023 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17024 (match_operand:DI 2 "const_int_operand" "")) 0))]
17026 && exact_log2 (INTVAL (operands[2])) >= 0
17027 && REGNO (operands[0]) == REGNO (operands[1])
17028 && peep2_regno_dead_p (0, FLAGS_REG)"
17029 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17030 (clobber (reg:CC FLAGS_REG))])]
17031 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17033 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17034 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17035 ;; On many CPUs it is also faster, since special hardware to avoid esp
17036 ;; dependencies is present.
17038 ;; While some of these conversions may be done using splitters, we use
17039 ;; peepholes in order to allow combine_stack_adjustments pass to see
17040 ;; nonobfuscated RTL.
17042 ;; Convert prologue esp subtractions to push.
17043 ;; We need register to push. In order to keep verify_flow_info happy we have
17045 ;; - use scratch and clobber it in order to avoid dependencies
17046 ;; - use already live register
17047 ;; We can't use the second way right now, since there is no reliable way how to
17048 ;; verify that given register is live. First choice will also most likely in
17049 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17050 ;; call clobbered registers are dead. We may want to use base pointer as an
17051 ;; alternative when no register is available later.
17054 [(match_scratch:P 1 "r")
17055 (parallel [(set (reg:P SP_REG)
17056 (plus:P (reg:P SP_REG)
17057 (match_operand:P 0 "const_int_operand" "")))
17058 (clobber (reg:CC FLAGS_REG))
17059 (clobber (mem:BLK (scratch)))])]
17060 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17061 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17062 [(clobber (match_dup 1))
17063 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17064 (clobber (mem:BLK (scratch)))])])
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_DOUBLE_PUSH || optimize_insn_for_size_p ())
17074 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17075 [(clobber (match_dup 1))
17076 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17077 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17078 (clobber (mem:BLK (scratch)))])])
17080 ;; Convert esp subtractions to push.
17082 [(match_scratch:P 1 "r")
17083 (parallel [(set (reg:P SP_REG)
17084 (plus:P (reg:P SP_REG)
17085 (match_operand:P 0 "const_int_operand" "")))
17086 (clobber (reg:CC FLAGS_REG))])]
17087 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17088 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17089 [(clobber (match_dup 1))
17090 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17093 [(match_scratch:P 1 "r")
17094 (parallel [(set (reg:P SP_REG)
17095 (plus:P (reg:P SP_REG)
17096 (match_operand:P 0 "const_int_operand" "")))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17099 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17100 [(clobber (match_dup 1))
17101 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17102 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17104 ;; Convert epilogue deallocator to pop.
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 (clobber (mem:BLK (scratch)))])]
17112 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17113 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17114 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17115 (clobber (mem:BLK (scratch)))])])
17117 ;; Two pops case is tricky, since pop causes dependency
17118 ;; on destination register. We use two registers if available.
17120 [(match_scratch:P 1 "r")
17121 (match_scratch:P 2 "r")
17122 (parallel [(set (reg:P SP_REG)
17123 (plus:P (reg:P SP_REG)
17124 (match_operand:P 0 "const_int_operand" "")))
17125 (clobber (reg:CC FLAGS_REG))
17126 (clobber (mem:BLK (scratch)))])]
17127 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17128 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17129 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17130 (clobber (mem:BLK (scratch)))])
17131 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17134 [(match_scratch:P 1 "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 "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 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17146 ;; Convert esp additions to pop.
17148 [(match_scratch:P 1 "r")
17149 (parallel [(set (reg:P SP_REG)
17150 (plus:P (reg:P SP_REG)
17151 (match_operand:P 0 "const_int_operand" "")))
17152 (clobber (reg:CC FLAGS_REG))])]
17153 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17154 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17156 ;; Two pops case is tricky, since pop causes dependency
17157 ;; on destination register. We use two registers if available.
17159 [(match_scratch:P 1 "r")
17160 (match_scratch:P 2 "r")
17161 (parallel [(set (reg:P SP_REG)
17162 (plus:P (reg:P SP_REG)
17163 (match_operand:P 0 "const_int_operand" "")))
17164 (clobber (reg:CC FLAGS_REG))])]
17165 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17166 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17167 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17170 [(match_scratch:P 1 "r")
17171 (parallel [(set (reg:P SP_REG)
17172 (plus:P (reg:P SP_REG)
17173 (match_operand:P 0 "const_int_operand" "")))
17174 (clobber (reg:CC FLAGS_REG))])]
17175 "optimize_insn_for_size_p ()
17176 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17177 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17178 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17180 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17181 ;; required and register dies. Similarly for 128 to -128.
17183 [(set (match_operand 0 "flags_reg_operand" "")
17184 (match_operator 1 "compare_operator"
17185 [(match_operand 2 "register_operand" "")
17186 (match_operand 3 "const_int_operand" "")]))]
17187 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17188 && incdec_operand (operands[3], GET_MODE (operands[3])))
17189 || (!TARGET_FUSE_CMP_AND_BRANCH
17190 && INTVAL (operands[3]) == 128))
17191 && ix86_match_ccmode (insn, CCGCmode)
17192 && peep2_reg_dead_p (1, operands[2])"
17193 [(parallel [(set (match_dup 0)
17194 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17195 (clobber (match_dup 2))])])
17197 ;; Convert imul by three, five and nine into lea
17200 [(set (match_operand:SWI48 0 "register_operand" "")
17201 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17202 (match_operand:SWI48 2 "const_int_operand" "")))
17203 (clobber (reg:CC FLAGS_REG))])]
17204 "INTVAL (operands[2]) == 3
17205 || INTVAL (operands[2]) == 5
17206 || INTVAL (operands[2]) == 9"
17207 [(set (match_dup 0)
17208 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17210 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17214 [(set (match_operand:SWI48 0 "register_operand" "")
17215 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17216 (match_operand:SWI48 2 "const_int_operand" "")))
17217 (clobber (reg:CC FLAGS_REG))])]
17218 "optimize_insn_for_speed_p ()
17219 && (INTVAL (operands[2]) == 3
17220 || INTVAL (operands[2]) == 5
17221 || INTVAL (operands[2]) == 9)"
17222 [(set (match_dup 0) (match_dup 1))
17224 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17226 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17228 ;; imul $32bit_imm, mem, reg is vector decoded, while
17229 ;; imul $32bit_imm, reg, reg is direct decoded.
17231 [(match_scratch:SWI48 3 "r")
17232 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17233 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17234 (match_operand:SWI48 2 "immediate_operand" "")))
17235 (clobber (reg:CC FLAGS_REG))])]
17236 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17237 && !satisfies_constraint_K (operands[2])"
17238 [(set (match_dup 3) (match_dup 1))
17239 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17240 (clobber (reg:CC FLAGS_REG))])])
17243 [(match_scratch:SI 3 "r")
17244 (parallel [(set (match_operand:DI 0 "register_operand" "")
17246 (mult:SI (match_operand:SI 1 "memory_operand" "")
17247 (match_operand:SI 2 "immediate_operand" ""))))
17248 (clobber (reg:CC FLAGS_REG))])]
17250 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17251 && !satisfies_constraint_K (operands[2])"
17252 [(set (match_dup 3) (match_dup 1))
17253 (parallel [(set (match_dup 0)
17254 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17255 (clobber (reg:CC FLAGS_REG))])])
17257 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17258 ;; Convert it into imul reg, reg
17259 ;; It would be better to force assembler to encode instruction using long
17260 ;; immediate, but there is apparently no way to do so.
17262 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17264 (match_operand:SWI248 1 "nonimmediate_operand" "")
17265 (match_operand:SWI248 2 "const_int_operand" "")))
17266 (clobber (reg:CC FLAGS_REG))])
17267 (match_scratch:SWI248 3 "r")]
17268 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17269 && satisfies_constraint_K (operands[2])"
17270 [(set (match_dup 3) (match_dup 2))
17271 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17272 (clobber (reg:CC FLAGS_REG))])]
17274 if (!rtx_equal_p (operands[0], operands[1]))
17275 emit_move_insn (operands[0], operands[1]);
17278 ;; After splitting up read-modify operations, array accesses with memory
17279 ;; operands might end up in form:
17281 ;; movl 4(%esp), %edx
17283 ;; instead of pre-splitting:
17285 ;; addl 4(%esp), %eax
17287 ;; movl 4(%esp), %edx
17288 ;; leal (%edx,%eax,4), %eax
17291 [(match_scratch:P 5 "r")
17292 (parallel [(set (match_operand 0 "register_operand" "")
17293 (ashift (match_operand 1 "register_operand" "")
17294 (match_operand 2 "const_int_operand" "")))
17295 (clobber (reg:CC FLAGS_REG))])
17296 (parallel [(set (match_operand 3 "register_operand" "")
17297 (plus (match_dup 0)
17298 (match_operand 4 "x86_64_general_operand" "")))
17299 (clobber (reg:CC FLAGS_REG))])]
17300 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17301 /* Validate MODE for lea. */
17302 && ((!TARGET_PARTIAL_REG_STALL
17303 && (GET_MODE (operands[0]) == QImode
17304 || GET_MODE (operands[0]) == HImode))
17305 || GET_MODE (operands[0]) == SImode
17306 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17307 && (rtx_equal_p (operands[0], operands[3])
17308 || peep2_reg_dead_p (2, operands[0]))
17309 /* We reorder load and the shift. */
17310 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17311 [(set (match_dup 5) (match_dup 4))
17312 (set (match_dup 0) (match_dup 1))]
17314 enum machine_mode op1mode = GET_MODE (operands[1]);
17315 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17316 int scale = 1 << INTVAL (operands[2]);
17317 rtx index = gen_lowpart (Pmode, operands[1]);
17318 rtx base = gen_lowpart (Pmode, operands[5]);
17319 rtx dest = gen_lowpart (mode, operands[3]);
17321 operands[1] = gen_rtx_PLUS (Pmode, base,
17322 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17323 operands[5] = base;
17325 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17326 if (op1mode != Pmode)
17327 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17328 operands[0] = dest;
17331 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17332 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17333 ;; caught for use by garbage collectors and the like. Using an insn that
17334 ;; maps to SIGILL makes it more likely the program will rightfully die.
17335 ;; Keeping with tradition, "6" is in honor of #UD.
17336 (define_insn "trap"
17337 [(trap_if (const_int 1) (const_int 6))]
17339 { return ASM_SHORT "0x0b0f"; }
17340 [(set_attr "length" "2")])
17342 (define_expand "prefetch"
17343 [(prefetch (match_operand 0 "address_operand" "")
17344 (match_operand:SI 1 "const_int_operand" "")
17345 (match_operand:SI 2 "const_int_operand" ""))]
17346 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17348 int rw = INTVAL (operands[1]);
17349 int locality = INTVAL (operands[2]);
17351 gcc_assert (rw == 0 || rw == 1);
17352 gcc_assert (locality >= 0 && locality <= 3);
17353 gcc_assert (GET_MODE (operands[0]) == Pmode
17354 || GET_MODE (operands[0]) == VOIDmode);
17356 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17357 supported by SSE counterpart or the SSE prefetch is not available
17358 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17360 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17361 operands[2] = GEN_INT (3);
17363 operands[1] = const0_rtx;
17366 (define_insn "*prefetch_sse_<mode>"
17367 [(prefetch (match_operand:P 0 "address_operand" "p")
17369 (match_operand:SI 1 "const_int_operand" ""))]
17370 "TARGET_PREFETCH_SSE"
17372 static const char * const patterns[4] = {
17373 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17376 int locality = INTVAL (operands[1]);
17377 gcc_assert (locality >= 0 && locality <= 3);
17379 return patterns[locality];
17381 [(set_attr "type" "sse")
17382 (set_attr "atom_sse_attr" "prefetch")
17383 (set (attr "length_address")
17384 (symbol_ref "memory_address_length (operands[0])"))
17385 (set_attr "memory" "none")])
17387 (define_insn "*prefetch_3dnow_<mode>"
17388 [(prefetch (match_operand:P 0 "address_operand" "p")
17389 (match_operand:SI 1 "const_int_operand" "n")
17393 if (INTVAL (operands[1]) == 0)
17394 return "prefetch\t%a0";
17396 return "prefetchw\t%a0";
17398 [(set_attr "type" "mmx")
17399 (set (attr "length_address")
17400 (symbol_ref "memory_address_length (operands[0])"))
17401 (set_attr "memory" "none")])
17403 (define_expand "stack_protect_set"
17404 [(match_operand 0 "memory_operand" "")
17405 (match_operand 1 "memory_operand" "")]
17408 rtx (*insn)(rtx, rtx);
17410 #ifdef TARGET_THREAD_SSP_OFFSET
17411 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17412 insn = (TARGET_64BIT
17413 ? gen_stack_tls_protect_set_di
17414 : gen_stack_tls_protect_set_si);
17416 insn = (TARGET_64BIT
17417 ? gen_stack_protect_set_di
17418 : gen_stack_protect_set_si);
17421 emit_insn (insn (operands[0], operands[1]));
17425 (define_insn "stack_protect_set_<mode>"
17426 [(set (match_operand:P 0 "memory_operand" "=m")
17427 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17428 (set (match_scratch:P 2 "=&r") (const_int 0))
17429 (clobber (reg:CC FLAGS_REG))]
17431 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17432 [(set_attr "type" "multi")])
17434 (define_insn "stack_tls_protect_set_<mode>"
17435 [(set (match_operand:P 0 "memory_operand" "=m")
17436 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17437 UNSPEC_SP_TLS_SET))
17438 (set (match_scratch:P 2 "=&r") (const_int 0))
17439 (clobber (reg:CC FLAGS_REG))]
17441 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17442 [(set_attr "type" "multi")])
17444 (define_expand "stack_protect_test"
17445 [(match_operand 0 "memory_operand" "")
17446 (match_operand 1 "memory_operand" "")
17447 (match_operand 2 "" "")]
17450 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17452 rtx (*insn)(rtx, rtx, rtx);
17454 #ifdef TARGET_THREAD_SSP_OFFSET
17455 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17456 insn = (TARGET_64BIT
17457 ? gen_stack_tls_protect_test_di
17458 : gen_stack_tls_protect_test_si);
17460 insn = (TARGET_64BIT
17461 ? gen_stack_protect_test_di
17462 : gen_stack_protect_test_si);
17465 emit_insn (insn (flags, operands[0], operands[1]));
17467 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17468 flags, const0_rtx, operands[2]));
17472 (define_insn "stack_protect_test_<mode>"
17473 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17474 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17475 (match_operand:P 2 "memory_operand" "m")]
17477 (clobber (match_scratch:P 3 "=&r"))]
17479 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17480 [(set_attr "type" "multi")])
17482 (define_insn "stack_tls_protect_test_<mode>"
17483 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17484 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17485 (match_operand:P 2 "const_int_operand" "i")]
17486 UNSPEC_SP_TLS_TEST))
17487 (clobber (match_scratch:P 3 "=r"))]
17489 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17490 [(set_attr "type" "multi")])
17492 (define_insn "sse4_2_crc32<mode>"
17493 [(set (match_operand:SI 0 "register_operand" "=r")
17495 [(match_operand:SI 1 "register_operand" "0")
17496 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17498 "TARGET_SSE4_2 || TARGET_CRC32"
17499 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17500 [(set_attr "type" "sselog1")
17501 (set_attr "prefix_rep" "1")
17502 (set_attr "prefix_extra" "1")
17503 (set (attr "prefix_data16")
17504 (if_then_else (match_operand:HI 2 "" "")
17506 (const_string "*")))
17507 (set (attr "prefix_rex")
17508 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17510 (const_string "*")))
17511 (set_attr "mode" "SI")])
17513 (define_insn "sse4_2_crc32di"
17514 [(set (match_operand:DI 0 "register_operand" "=r")
17516 [(match_operand:DI 1 "register_operand" "0")
17517 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17519 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17520 "crc32{q}\t{%2, %0|%0, %2}"
17521 [(set_attr "type" "sselog1")
17522 (set_attr "prefix_rep" "1")
17523 (set_attr "prefix_extra" "1")
17524 (set_attr "mode" "DI")])
17526 (define_expand "rdpmc"
17527 [(match_operand:DI 0 "register_operand" "")
17528 (match_operand:SI 1 "register_operand" "")]
17531 rtx reg = gen_reg_rtx (DImode);
17534 /* Force operand 1 into ECX. */
17535 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17536 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17537 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17542 rtvec vec = rtvec_alloc (2);
17543 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17544 rtx upper = gen_reg_rtx (DImode);
17545 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17546 gen_rtvec (1, const0_rtx),
17548 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17549 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17551 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17552 NULL, 1, OPTAB_DIRECT);
17553 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17557 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17558 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17562 (define_insn "*rdpmc"
17563 [(set (match_operand:DI 0 "register_operand" "=A")
17564 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17568 [(set_attr "type" "other")
17569 (set_attr "length" "2")])
17571 (define_insn "*rdpmc_rex64"
17572 [(set (match_operand:DI 0 "register_operand" "=a")
17573 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17575 (set (match_operand:DI 1 "register_operand" "=d")
17576 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17579 [(set_attr "type" "other")
17580 (set_attr "length" "2")])
17582 (define_expand "rdtsc"
17583 [(set (match_operand:DI 0 "register_operand" "")
17584 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17589 rtvec vec = rtvec_alloc (2);
17590 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17591 rtx upper = gen_reg_rtx (DImode);
17592 rtx lower = gen_reg_rtx (DImode);
17593 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17594 gen_rtvec (1, const0_rtx),
17596 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17597 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17599 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17600 NULL, 1, OPTAB_DIRECT);
17601 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17603 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17608 (define_insn "*rdtsc"
17609 [(set (match_operand:DI 0 "register_operand" "=A")
17610 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17613 [(set_attr "type" "other")
17614 (set_attr "length" "2")])
17616 (define_insn "*rdtsc_rex64"
17617 [(set (match_operand:DI 0 "register_operand" "=a")
17618 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17619 (set (match_operand:DI 1 "register_operand" "=d")
17620 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17623 [(set_attr "type" "other")
17624 (set_attr "length" "2")])
17626 (define_expand "rdtscp"
17627 [(match_operand:DI 0 "register_operand" "")
17628 (match_operand:SI 1 "memory_operand" "")]
17631 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17632 gen_rtvec (1, const0_rtx),
17634 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17635 gen_rtvec (1, const0_rtx),
17637 rtx reg = gen_reg_rtx (DImode);
17638 rtx tmp = gen_reg_rtx (SImode);
17642 rtvec vec = rtvec_alloc (3);
17643 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17644 rtx upper = gen_reg_rtx (DImode);
17645 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17646 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17647 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17649 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17650 NULL, 1, OPTAB_DIRECT);
17651 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17656 rtvec vec = rtvec_alloc (2);
17657 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17658 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17659 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17662 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17663 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17667 (define_insn "*rdtscp"
17668 [(set (match_operand:DI 0 "register_operand" "=A")
17669 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17670 (set (match_operand:SI 1 "register_operand" "=c")
17671 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17674 [(set_attr "type" "other")
17675 (set_attr "length" "3")])
17677 (define_insn "*rdtscp_rex64"
17678 [(set (match_operand:DI 0 "register_operand" "=a")
17679 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17680 (set (match_operand:DI 1 "register_operand" "=d")
17681 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17682 (set (match_operand:SI 2 "register_operand" "=c")
17683 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17686 [(set_attr "type" "other")
17687 (set_attr "length" "3")])
17689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17691 ;; LWP instructions
17693 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17695 (define_expand "lwp_llwpcb"
17696 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17697 UNSPECV_LLWP_INTRINSIC)]
17700 (define_insn "*lwp_llwpcb<mode>1"
17701 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17702 UNSPECV_LLWP_INTRINSIC)]
17705 [(set_attr "type" "lwp")
17706 (set_attr "mode" "<MODE>")
17707 (set_attr "length" "5")])
17709 (define_expand "lwp_slwpcb"
17710 [(set (match_operand 0 "register_operand" "=r")
17711 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17716 insn = (TARGET_64BIT
17718 : gen_lwp_slwpcbsi);
17720 emit_insn (insn (operands[0]));
17724 (define_insn "lwp_slwpcb<mode>"
17725 [(set (match_operand:P 0 "register_operand" "=r")
17726 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17729 [(set_attr "type" "lwp")
17730 (set_attr "mode" "<MODE>")
17731 (set_attr "length" "5")])
17733 (define_expand "lwp_lwpval<mode>3"
17734 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17735 (match_operand:SI 2 "nonimmediate_operand" "rm")
17736 (match_operand:SI 3 "const_int_operand" "i")]
17737 UNSPECV_LWPVAL_INTRINSIC)]
17739 "/* Avoid unused variable warning. */
17742 (define_insn "*lwp_lwpval<mode>3_1"
17743 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17744 (match_operand:SI 1 "nonimmediate_operand" "rm")
17745 (match_operand:SI 2 "const_int_operand" "i")]
17746 UNSPECV_LWPVAL_INTRINSIC)]
17748 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17749 [(set_attr "type" "lwp")
17750 (set_attr "mode" "<MODE>")
17751 (set (attr "length")
17752 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17754 (define_expand "lwp_lwpins<mode>3"
17755 [(set (reg:CCC FLAGS_REG)
17756 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17757 (match_operand:SI 2 "nonimmediate_operand" "rm")
17758 (match_operand:SI 3 "const_int_operand" "i")]
17759 UNSPECV_LWPINS_INTRINSIC))
17760 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17761 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17764 (define_insn "*lwp_lwpins<mode>3_1"
17765 [(set (reg:CCC FLAGS_REG)
17766 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17767 (match_operand:SI 1 "nonimmediate_operand" "rm")
17768 (match_operand:SI 2 "const_int_operand" "i")]
17769 UNSPECV_LWPINS_INTRINSIC))]
17771 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17772 [(set_attr "type" "lwp")
17773 (set_attr "mode" "<MODE>")
17774 (set (attr "length")
17775 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17777 (define_insn "rdfsbase<mode>"
17778 [(set (match_operand:SWI48 0 "register_operand" "=r")
17779 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17780 "TARGET_64BIT && TARGET_FSGSBASE"
17782 [(set_attr "type" "other")
17783 (set_attr "prefix_extra" "2")])
17785 (define_insn "rdgsbase<mode>"
17786 [(set (match_operand:SWI48 0 "register_operand" "=r")
17787 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17788 "TARGET_64BIT && TARGET_FSGSBASE"
17790 [(set_attr "type" "other")
17791 (set_attr "prefix_extra" "2")])
17793 (define_insn "wrfsbase<mode>"
17794 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17796 "TARGET_64BIT && TARGET_FSGSBASE"
17798 [(set_attr "type" "other")
17799 (set_attr "prefix_extra" "2")])
17801 (define_insn "wrgsbase<mode>"
17802 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17804 "TARGET_64BIT && TARGET_FSGSBASE"
17806 [(set_attr "type" "other")
17807 (set_attr "prefix_extra" "2")])
17809 (define_insn "rdrand<mode>_1"
17810 [(set (match_operand:SWI248 0 "register_operand" "=r")
17811 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17812 (set (reg:CCC FLAGS_REG)
17813 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17816 [(set_attr "type" "other")
17817 (set_attr "prefix_extra" "1")])
17819 (define_expand "pause"
17820 [(set (match_dup 0)
17821 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17824 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17825 MEM_VOLATILE_P (operands[0]) = 1;
17828 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17829 ;; They have the same encoding.
17830 (define_insn "*pause"
17831 [(set (match_operand:BLK 0 "" "")
17832 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17835 [(set_attr "length" "2")
17836 (set_attr "memory" "unknown")])
17840 (include "sync.md")