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,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*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" "5")
2031 (const_string "mmx")
2032 (eq_attr "alternative" "6,7,8,9,10")
2033 (const_string "mmxmov")
2034 (eq_attr "alternative" "11")
2035 (const_string "sselog1")
2036 (eq_attr "alternative" "12,13,14,15,16")
2037 (const_string "ssemov")
2038 (eq_attr "alternative" "17,18")
2039 (const_string "ssecvt")
2040 (eq_attr "alternative" "4")
2041 (const_string "multi")
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" "7,9")
2059 (const_string "*")))
2060 (set (attr "prefix_data16")
2061 (if_then_else (eq_attr "alternative" "15")
2063 (const_string "*")))
2064 (set (attr "prefix")
2065 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2066 (const_string "maybe_vex")
2067 (const_string "orig")))
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,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 "%vmovdqa\t{%1, %0|%0, %1}";
2963 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2964 return "%vmovapd\t{%1, %0|%0, %1}";
2966 return "%vmovaps\t{%1, %0|%0, %1}";
2969 return "%vmovq\t{%1, %0|%0, %1}";
2971 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2972 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2974 return "%vmovsd\t{%1, %0|%0, %1}";
2976 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2978 return "%vmovlps\t{%1, %d0|%d0, %1}";
2985 /* Handle broken assemblers that require movd instead of movq. */
2986 return "%vmovd\t{%1, %0|%0, %1}";
2992 [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2995 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997 (const_string "*")))
2998 (set (attr "length_immediate")
3000 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3002 (const_string "*")))
3003 (set (attr "prefix")
3004 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3005 (const_string "orig")
3006 (const_string "maybe_vex")))
3007 (set (attr "prefix_data16")
3008 (if_then_else (eq_attr "mode" "V1DF")
3010 (const_string "*")))
3012 (cond [(eq_attr "alternative" "0,1,2")
3014 (eq_attr "alternative" "3,4,5,6,11,12")
3017 /* For SSE1, we have many fewer alternatives. */
3018 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3019 (cond [(eq_attr "alternative" "7,8")
3020 (const_string "V4SF")
3022 (const_string "V2SF"))
3024 /* xorps is one byte shorter. */
3025 (eq_attr "alternative" "7")
3026 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028 (const_string "V4SF")
3029 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3033 (const_string "V2DF"))
3035 /* For architectures resolving dependencies on
3036 whole SSE registers use APD move to break dependency
3037 chains, otherwise use short move to avoid extra work.
3039 movaps encodes one byte shorter. */
3040 (eq_attr "alternative" "8")
3042 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3044 (const_string "V4SF")
3045 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3047 (const_string "V2DF")
3049 (const_string "DF"))
3050 /* For architectures resolving dependencies on register
3051 parts we may avoid extra work to zero out upper part
3053 (eq_attr "alternative" "9")
3055 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3057 (const_string "V1DF")
3058 (const_string "DF"))
3060 (const_string "DF")))])
3062 ;; Possible store forwarding (partial memory) stall in alternative 4.
3063 (define_insn "*movdf_internal"
3064 [(set (match_operand:DF 0 "nonimmediate_operand"
3065 "=f,m,f,?Yd*r ,!o ,Y2*x,Y2*x,Y2*x,m ")
3066 (match_operand:DF 1 "general_operand"
3067 "fm,f,G,Yd*roF,FYd*r,C ,Y2*x,m ,Y2*x"))]
3068 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3069 && (!can_create_pseudo_p ()
3070 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3071 || GET_CODE (operands[1]) != CONST_DOUBLE
3072 || (optimize_function_for_size_p (cfun)
3073 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3074 && standard_80387_constant_p (operands[1]) > 0)
3075 || (TARGET_SSE2 && TARGET_SSE_MATH
3076 && standard_sse_constant_p (operands[1])))
3077 && !memory_operand (operands[0], DFmode))
3078 || (!TARGET_MEMORY_MISMATCH_STALL
3079 && memory_operand (operands[0], DFmode)))"
3081 switch (which_alternative)
3085 return output_387_reg_move (insn, operands);
3088 return standard_80387_constant_opcode (operands[1]);
3095 return standard_sse_constant_opcode (insn, operands[1]);
3100 switch (get_attr_mode (insn))
3103 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3104 return "%vmovdqa\t{%1, %0|%0, %1}";
3106 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3107 return "%vmovapd\t{%1, %0|%0, %1}";
3109 return "%vmovaps\t{%1, %0|%0, %1}";
3112 return "%vmovq\t{%1, %0|%0, %1}";
3114 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3115 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3117 return "%vmovsd\t{%1, %0|%0, %1}";
3119 if (TARGET_AVX && REG_P (operands[0]))
3120 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3122 return "%vmovlpd\t{%1, %0|%0, %1}";
3124 if (TARGET_AVX && REG_P (operands[0]))
3125 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3127 return "%vmovlps\t{%1, %0|%0, %1}";
3136 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3137 (set (attr "prefix")
3138 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3139 (const_string "orig")
3140 (const_string "maybe_vex")))
3141 (set (attr "prefix_data16")
3142 (if_then_else (eq_attr "mode" "V1DF")
3144 (const_string "*")))
3146 (cond [(eq_attr "alternative" "0,1,2")
3148 (eq_attr "alternative" "3,4")
3151 /* For SSE1, we have many fewer alternatives. */
3152 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3153 (cond [(eq_attr "alternative" "5,6")
3154 (const_string "V4SF")
3156 (const_string "V2SF"))
3158 /* xorps is one byte shorter. */
3159 (eq_attr "alternative" "5")
3160 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3167 (const_string "V2DF"))
3169 /* For architectures resolving dependencies on
3170 whole SSE registers use APD move to break dependency
3171 chains, otherwise use short move to avoid extra work.
3173 movaps encodes one byte shorter. */
3174 (eq_attr "alternative" "6")
3176 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3178 (const_string "V4SF")
3179 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3181 (const_string "V2DF")
3183 (const_string "DF"))
3184 /* For architectures resolving dependencies on register
3185 parts we may avoid extra work to zero out upper part
3187 (eq_attr "alternative" "7")
3189 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3191 (const_string "V1DF")
3192 (const_string "DF"))
3194 (const_string "DF")))])
3196 (define_insn "*movsf_internal"
3197 [(set (match_operand:SF 0 "nonimmediate_operand"
3198 "=f,m,f,?r ,?m,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3199 (match_operand:SF 1 "general_operand"
3200 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3201 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3202 && (!can_create_pseudo_p ()
3203 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3204 || GET_CODE (operands[1]) != CONST_DOUBLE
3205 || (optimize_function_for_size_p (cfun)
3206 && ((!TARGET_SSE_MATH
3207 && standard_80387_constant_p (operands[1]) > 0)
3209 && standard_sse_constant_p (operands[1]))))
3210 || memory_operand (operands[0], SFmode))"
3212 switch (which_alternative)
3216 return output_387_reg_move (insn, operands);
3219 return standard_80387_constant_opcode (operands[1]);
3223 return "mov{l}\t{%1, %0|%0, %1}";
3226 return standard_sse_constant_opcode (insn, operands[1]);
3229 if (get_attr_mode (insn) == MODE_V4SF)
3230 return "%vmovaps\t{%1, %0|%0, %1}";
3232 return "%vmovss\t{%1, %d0|%d0, %1}";
3234 if (TARGET_AVX && REG_P (operands[1]))
3235 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3237 return "%vmovss\t{%1, %0|%0, %1}";
3239 return "%vmovss\t{%1, %0|%0, %1}";
3241 case 9: case 10: case 14: case 15:
3242 return "movd\t{%1, %0|%0, %1}";
3245 return "movq\t{%1, %0|%0, %1}";
3248 return "%vmovd\t{%1, %0|%0, %1}";
3254 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3255 (set (attr "prefix")
3256 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3257 (const_string "maybe_vex")
3258 (const_string "orig")))
3260 (cond [(eq_attr "alternative" "3,4,9,10")
3262 (eq_attr "alternative" "5")
3264 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3266 (ne (symbol_ref "TARGET_SSE2")
3268 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3271 (const_string "V4SF"))
3272 /* For architectures resolving dependencies on
3273 whole SSE registers use APS move to break dependency
3274 chains, otherwise use short move to avoid extra work.
3276 Do the same for architectures resolving dependencies on
3277 the parts. While in DF mode it is better to always handle
3278 just register parts, the SF mode is different due to lack
3279 of instructions to load just part of the register. It is
3280 better to maintain the whole registers in single format
3281 to avoid problems on using packed logical operations. */
3282 (eq_attr "alternative" "6")
3284 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3286 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3288 (const_string "V4SF")
3289 (const_string "SF"))
3290 (eq_attr "alternative" "11")
3291 (const_string "DI")]
3292 (const_string "SF")))])
3295 [(set (match_operand 0 "any_fp_register_operand" "")
3296 (match_operand 1 "memory_operand" ""))]
3298 && (GET_MODE (operands[0]) == TFmode
3299 || GET_MODE (operands[0]) == XFmode
3300 || GET_MODE (operands[0]) == DFmode
3301 || GET_MODE (operands[0]) == SFmode)
3302 && (operands[2] = find_constant_src (insn))"
3303 [(set (match_dup 0) (match_dup 2))]
3305 rtx c = operands[2];
3306 int r = REGNO (operands[0]);
3308 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3309 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3314 [(set (match_operand 0 "any_fp_register_operand" "")
3315 (float_extend (match_operand 1 "memory_operand" "")))]
3317 && (GET_MODE (operands[0]) == TFmode
3318 || GET_MODE (operands[0]) == XFmode
3319 || GET_MODE (operands[0]) == DFmode)
3320 && (operands[2] = find_constant_src (insn))"
3321 [(set (match_dup 0) (match_dup 2))]
3323 rtx c = operands[2];
3324 int r = REGNO (operands[0]);
3326 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3327 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3331 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3333 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3334 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3336 && (standard_80387_constant_p (operands[1]) == 8
3337 || standard_80387_constant_p (operands[1]) == 9)"
3338 [(set (match_dup 0)(match_dup 1))
3340 (neg:X87MODEF (match_dup 0)))]
3344 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3345 if (real_isnegzero (&r))
3346 operands[1] = CONST0_RTX (<MODE>mode);
3348 operands[1] = CONST1_RTX (<MODE>mode);
3352 [(set (match_operand 0 "nonimmediate_operand" "")
3353 (match_operand 1 "general_operand" ""))]
3355 && (GET_MODE (operands[0]) == TFmode
3356 || GET_MODE (operands[0]) == XFmode
3357 || GET_MODE (operands[0]) == DFmode)
3358 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3360 "ix86_split_long_move (operands); DONE;")
3362 (define_insn "swapxf"
3363 [(set (match_operand:XF 0 "register_operand" "+f")
3364 (match_operand:XF 1 "register_operand" "+f"))
3369 if (STACK_TOP_P (operands[0]))
3374 [(set_attr "type" "fxch")
3375 (set_attr "mode" "XF")])
3377 (define_insn "*swap<mode>"
3378 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3379 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3382 "TARGET_80387 || reload_completed"
3384 if (STACK_TOP_P (operands[0]))
3389 [(set_attr "type" "fxch")
3390 (set_attr "mode" "<MODE>")])
3392 ;; Zero extension instructions
3394 (define_expand "zero_extendsidi2"
3395 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3396 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3401 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3406 (define_insn "*zero_extendsidi2_rex64"
3407 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3409 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3412 mov\t{%k1, %k0|%k0, %k1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 %vmovd\t{%1, %0|%0, %1}
3417 %vmovd\t{%1, %0|%0, %1}"
3418 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3419 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3420 (set_attr "prefix_0f" "0,*,*,*,*,*")
3421 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3424 [(set (match_operand:DI 0 "memory_operand" "")
3425 (zero_extend:DI (match_dup 0)))]
3427 [(set (match_dup 4) (const_int 0))]
3428 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3430 ;; %%% Kill me once multi-word ops are sane.
3431 (define_insn "zero_extendsidi2_1"
3432 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3434 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3435 (clobber (reg:CC FLAGS_REG))]
3441 movd\t{%1, %0|%0, %1}
3442 movd\t{%1, %0|%0, %1}
3443 %vmovd\t{%1, %0|%0, %1}
3444 %vmovd\t{%1, %0|%0, %1}"
3445 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3446 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3447 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3450 [(set (match_operand:DI 0 "register_operand" "")
3451 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3452 (clobber (reg:CC FLAGS_REG))]
3453 "!TARGET_64BIT && reload_completed
3454 && true_regnum (operands[0]) == true_regnum (operands[1])"
3455 [(set (match_dup 4) (const_int 0))]
3456 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3459 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3460 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3461 (clobber (reg:CC FLAGS_REG))]
3462 "!TARGET_64BIT && reload_completed
3463 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3464 [(set (match_dup 3) (match_dup 1))
3465 (set (match_dup 4) (const_int 0))]
3466 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3468 (define_insn "zero_extend<mode>di2"
3469 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3473 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "SI")])
3477 (define_expand "zero_extendhisi2"
3478 [(set (match_operand:SI 0 "register_operand" "")
3479 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3482 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3484 operands[1] = force_reg (HImode, operands[1]);
3485 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3490 (define_insn_and_split "zero_extendhisi2_and"
3491 [(set (match_operand:SI 0 "register_operand" "=r")
3492 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3496 "&& reload_completed"
3497 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3498 (clobber (reg:CC FLAGS_REG))])]
3500 [(set_attr "type" "alu1")
3501 (set_attr "mode" "SI")])
3503 (define_insn "*zero_extendhisi2_movzwl"
3504 [(set (match_operand:SI 0 "register_operand" "=r")
3505 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3506 "!TARGET_ZERO_EXTEND_WITH_AND
3507 || optimize_function_for_size_p (cfun)"
3508 "movz{wl|x}\t{%1, %0|%0, %1}"
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "SI")])
3512 (define_expand "zero_extendqi<mode>2"
3514 [(set (match_operand:SWI24 0 "register_operand" "")
3515 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))])])
3518 (define_insn "*zero_extendqi<mode>2_and"
3519 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3520 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3521 (clobber (reg:CC FLAGS_REG))]
3522 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3524 [(set_attr "type" "alu1")
3525 (set_attr "mode" "<MODE>")])
3527 ;; When source and destination does not overlap, clear destination
3528 ;; first and then do the movb
3530 [(set (match_operand:SWI24 0 "register_operand" "")
3531 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3532 (clobber (reg:CC FLAGS_REG))]
3534 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3535 && ANY_QI_REG_P (operands[0])
3536 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3537 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3538 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3540 operands[2] = gen_lowpart (QImode, operands[0]);
3541 ix86_expand_clear (operands[0]);
3544 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3545 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3547 (clobber (reg:CC FLAGS_REG))]
3548 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3550 [(set_attr "type" "imovx,alu1")
3551 (set_attr "mode" "<MODE>")])
3553 ;; For the movzbl case strip only the clobber
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))]
3559 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3560 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3562 (zero_extend:SWI24 (match_dup 1)))])
3564 ; zero extend to SImode to avoid partial register stalls
3565 (define_insn "*zero_extendqi<mode>2_movzbl"
3566 [(set (match_operand:SWI24 0 "register_operand" "=r")
3567 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3569 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3570 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3571 [(set_attr "type" "imovx")
3572 (set_attr "mode" "SI")])
3574 ;; Rest is handled by single and.
3576 [(set (match_operand:SWI24 0 "register_operand" "")
3577 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))]
3580 && true_regnum (operands[0]) == true_regnum (operands[1])"
3581 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3582 (clobber (reg:CC FLAGS_REG))])])
3584 ;; Sign extension instructions
3586 (define_expand "extendsidi2"
3587 [(set (match_operand:DI 0 "register_operand" "")
3588 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3593 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3598 (define_insn "*extendsidi2_rex64"
3599 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3600 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3604 movs{lq|x}\t{%1, %0|%0, %1}"
3605 [(set_attr "type" "imovx")
3606 (set_attr "mode" "DI")
3607 (set_attr "prefix_0f" "0")
3608 (set_attr "modrm" "0,1")])
3610 (define_insn "extendsidi2_1"
3611 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3612 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3613 (clobber (reg:CC FLAGS_REG))
3614 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3618 ;; Extend to memory case when source register does die.
3620 [(set (match_operand:DI 0 "memory_operand" "")
3621 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3622 (clobber (reg:CC FLAGS_REG))
3623 (clobber (match_operand:SI 2 "register_operand" ""))]
3625 && dead_or_set_p (insn, operands[1])
3626 && !reg_mentioned_p (operands[1], operands[0]))"
3627 [(set (match_dup 3) (match_dup 1))
3628 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3629 (clobber (reg:CC FLAGS_REG))])
3630 (set (match_dup 4) (match_dup 1))]
3631 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3633 ;; Extend to memory case when source register does not die.
3635 [(set (match_operand:DI 0 "memory_operand" "")
3636 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637 (clobber (reg:CC FLAGS_REG))
3638 (clobber (match_operand:SI 2 "register_operand" ""))]
3642 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3644 emit_move_insn (operands[3], operands[1]);
3646 /* Generate a cltd if possible and doing so it profitable. */
3647 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3648 && true_regnum (operands[1]) == AX_REG
3649 && true_regnum (operands[2]) == DX_REG)
3651 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3655 emit_move_insn (operands[2], operands[1]);
3656 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3658 emit_move_insn (operands[4], operands[2]);
3662 ;; Extend to register case. Optimize case where source and destination
3663 ;; registers match and cases where we can use cltd.
3665 [(set (match_operand:DI 0 "register_operand" "")
3666 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3667 (clobber (reg:CC FLAGS_REG))
3668 (clobber (match_scratch:SI 2 ""))]
3672 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3674 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3675 emit_move_insn (operands[3], operands[1]);
3677 /* Generate a cltd if possible and doing so it profitable. */
3678 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3679 && true_regnum (operands[3]) == AX_REG
3680 && true_regnum (operands[4]) == DX_REG)
3682 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3686 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3687 emit_move_insn (operands[4], operands[1]);
3689 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3693 (define_insn "extend<mode>di2"
3694 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3698 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3699 [(set_attr "type" "imovx")
3700 (set_attr "mode" "DI")])
3702 (define_insn "extendhisi2"
3703 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3704 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3707 switch (get_attr_prefix_0f (insn))
3710 return "{cwtl|cwde}";
3712 return "movs{wl|x}\t{%1, %0|%0, %1}";
3715 [(set_attr "type" "imovx")
3716 (set_attr "mode" "SI")
3717 (set (attr "prefix_0f")
3718 ;; movsx is short decodable while cwtl is vector decoded.
3719 (if_then_else (and (eq_attr "cpu" "!k6")
3720 (eq_attr "alternative" "0"))
3722 (const_string "1")))
3724 (if_then_else (eq_attr "prefix_0f" "0")
3726 (const_string "1")))])
3728 (define_insn "*extendhisi2_zext"
3729 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3735 switch (get_attr_prefix_0f (insn))
3738 return "{cwtl|cwde}";
3740 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3743 [(set_attr "type" "imovx")
3744 (set_attr "mode" "SI")
3745 (set (attr "prefix_0f")
3746 ;; movsx is short decodable while cwtl is vector decoded.
3747 (if_then_else (and (eq_attr "cpu" "!k6")
3748 (eq_attr "alternative" "0"))
3750 (const_string "1")))
3752 (if_then_else (eq_attr "prefix_0f" "0")
3754 (const_string "1")))])
3756 (define_insn "extendqisi2"
3757 [(set (match_operand:SI 0 "register_operand" "=r")
3758 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760 "movs{bl|x}\t{%1, %0|%0, %1}"
3761 [(set_attr "type" "imovx")
3762 (set_attr "mode" "SI")])
3764 (define_insn "*extendqisi2_zext"
3765 [(set (match_operand:DI 0 "register_operand" "=r")
3767 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3769 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "SI")])
3773 (define_insn "extendqihi2"
3774 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3775 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3778 switch (get_attr_prefix_0f (insn))
3781 return "{cbtw|cbw}";
3783 return "movs{bw|x}\t{%1, %0|%0, %1}";
3786 [(set_attr "type" "imovx")
3787 (set_attr "mode" "HI")
3788 (set (attr "prefix_0f")
3789 ;; movsx is short decodable while cwtl is vector decoded.
3790 (if_then_else (and (eq_attr "cpu" "!k6")
3791 (eq_attr "alternative" "0"))
3793 (const_string "1")))
3795 (if_then_else (eq_attr "prefix_0f" "0")
3797 (const_string "1")))])
3799 ;; Conversions between float and double.
3801 ;; These are all no-ops in the model used for the 80387.
3802 ;; So just emit moves.
3804 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3806 [(set (match_operand:DF 0 "push_operand" "")
3807 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3809 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3810 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3813 [(set (match_operand:XF 0 "push_operand" "")
3814 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3816 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3817 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3818 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3820 (define_expand "extendsfdf2"
3821 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3822 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3823 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3825 /* ??? Needed for compress_float_constant since all fp constants
3826 are TARGET_LEGITIMATE_CONSTANT_P. */
3827 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3829 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3830 && standard_80387_constant_p (operands[1]) > 0)
3832 operands[1] = simplify_const_unary_operation
3833 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3834 emit_move_insn_1 (operands[0], operands[1]);
3837 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3841 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3843 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3845 We do the conversion post reload to avoid producing of 128bit spills
3846 that might lead to ICE on 32bit target. The sequence unlikely combine
3849 [(set (match_operand:DF 0 "register_operand" "")
3851 (match_operand:SF 1 "nonimmediate_operand" "")))]
3852 "TARGET_USE_VECTOR_FP_CONVERTS
3853 && optimize_insn_for_speed_p ()
3854 && reload_completed && SSE_REG_P (operands[0])"
3859 (parallel [(const_int 0) (const_int 1)]))))]
3861 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3862 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3863 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3864 Try to avoid move when unpacking can be done in source. */
3865 if (REG_P (operands[1]))
3867 /* If it is unsafe to overwrite upper half of source, we need
3868 to move to destination and unpack there. */
3869 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3870 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3871 && true_regnum (operands[0]) != true_regnum (operands[1]))
3873 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3874 emit_move_insn (tmp, operands[1]);
3877 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3878 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3882 emit_insn (gen_vec_setv4sf_0 (operands[3],
3883 CONST0_RTX (V4SFmode), operands[1]));
3886 (define_insn "*extendsfdf2_mixed"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3889 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3890 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3892 switch (which_alternative)
3896 return output_387_reg_move (insn, operands);
3899 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3905 [(set_attr "type" "fmov,fmov,ssecvt")
3906 (set_attr "prefix" "orig,orig,maybe_vex")
3907 (set_attr "mode" "SF,XF,DF")])
3909 (define_insn "*extendsfdf2_sse"
3910 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3911 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3912 "TARGET_SSE2 && TARGET_SSE_MATH"
3913 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3914 [(set_attr "type" "ssecvt")
3915 (set_attr "prefix" "maybe_vex")
3916 (set_attr "mode" "DF")])
3918 (define_insn "*extendsfdf2_i387"
3919 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3920 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3922 "* return output_387_reg_move (insn, operands);"
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "SF,XF")])
3926 (define_expand "extend<mode>xf2"
3927 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3928 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3931 /* ??? Needed for compress_float_constant since all fp constants
3932 are TARGET_LEGITIMATE_CONSTANT_P. */
3933 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3935 if (standard_80387_constant_p (operands[1]) > 0)
3937 operands[1] = simplify_const_unary_operation
3938 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3939 emit_move_insn_1 (operands[0], operands[1]);
3942 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3946 (define_insn "*extend<mode>xf2_i387"
3947 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3949 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3951 "* return output_387_reg_move (insn, operands);"
3952 [(set_attr "type" "fmov")
3953 (set_attr "mode" "<MODE>,XF")])
3955 ;; %%% This seems bad bad news.
3956 ;; This cannot output into an f-reg because there is no way to be sure
3957 ;; of truncating in that case. Otherwise this is just like a simple move
3958 ;; insn. So we pretend we can output to a reg in order to get better
3959 ;; register preferencing, but we really use a stack slot.
3961 ;; Conversion from DFmode to SFmode.
3963 (define_expand "truncdfsf2"
3964 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3966 (match_operand:DF 1 "nonimmediate_operand" "")))]
3967 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3969 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3971 else if (flag_unsafe_math_optimizations)
3975 enum ix86_stack_slot slot = (virtuals_instantiated
3978 rtx temp = assign_386_stack_local (SFmode, slot);
3979 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3984 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3986 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3988 We do the conversion post reload to avoid producing of 128bit spills
3989 that might lead to ICE on 32bit target. The sequence unlikely combine
3992 [(set (match_operand:SF 0 "register_operand" "")
3994 (match_operand:DF 1 "nonimmediate_operand" "")))]
3995 "TARGET_USE_VECTOR_FP_CONVERTS
3996 && optimize_insn_for_speed_p ()
3997 && reload_completed && SSE_REG_P (operands[0])"
4000 (float_truncate:V2SF
4004 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4005 operands[3] = CONST0_RTX (V2SFmode);
4006 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4007 /* Use movsd for loading from memory, unpcklpd for registers.
4008 Try to avoid move when unpacking can be done in source, or SSE3
4009 movddup is available. */
4010 if (REG_P (operands[1]))
4013 && true_regnum (operands[0]) != true_regnum (operands[1])
4014 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4015 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4017 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4018 emit_move_insn (tmp, operands[1]);
4021 else if (!TARGET_SSE3)
4022 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4023 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4026 emit_insn (gen_sse2_loadlpd (operands[4],
4027 CONST0_RTX (V2DFmode), operands[1]));
4030 (define_expand "truncdfsf2_with_temp"
4031 [(parallel [(set (match_operand:SF 0 "" "")
4032 (float_truncate:SF (match_operand:DF 1 "" "")))
4033 (clobber (match_operand:SF 2 "" ""))])])
4035 (define_insn "*truncdfsf_fast_mixed"
4036 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4038 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4039 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4041 switch (which_alternative)
4044 return output_387_reg_move (insn, operands);
4046 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4051 [(set_attr "type" "fmov,ssecvt")
4052 (set_attr "prefix" "orig,maybe_vex")
4053 (set_attr "mode" "SF")])
4055 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4056 ;; because nothing we do here is unsafe.
4057 (define_insn "*truncdfsf_fast_sse"
4058 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4060 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4061 "TARGET_SSE2 && TARGET_SSE_MATH"
4062 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4063 [(set_attr "type" "ssecvt")
4064 (set_attr "prefix" "maybe_vex")
4065 (set_attr "mode" "SF")])
4067 (define_insn "*truncdfsf_fast_i387"
4068 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4070 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4071 "TARGET_80387 && flag_unsafe_math_optimizations"
4072 "* return output_387_reg_move (insn, operands);"
4073 [(set_attr "type" "fmov")
4074 (set_attr "mode" "SF")])
4076 (define_insn "*truncdfsf_mixed"
4077 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4079 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4080 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4081 "TARGET_MIX_SSE_I387"
4083 switch (which_alternative)
4086 return output_387_reg_move (insn, operands);
4088 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4094 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4095 (set_attr "unit" "*,*,i387,i387,i387")
4096 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf_i387"
4100 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4102 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4103 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4106 switch (which_alternative)
4109 return output_387_reg_move (insn, operands);
4115 [(set_attr "type" "fmov,multi,multi,multi")
4116 (set_attr "unit" "*,i387,i387,i387")
4117 (set_attr "mode" "SF")])
4119 (define_insn "*truncdfsf2_i387_1"
4120 [(set (match_operand:SF 0 "memory_operand" "=m")
4122 (match_operand:DF 1 "register_operand" "f")))]
4124 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4125 && !TARGET_MIX_SSE_I387"
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "SF")])
4131 [(set (match_operand:SF 0 "register_operand" "")
4133 (match_operand:DF 1 "fp_register_operand" "")))
4134 (clobber (match_operand 2 "" ""))]
4136 [(set (match_dup 2) (match_dup 1))
4137 (set (match_dup 0) (match_dup 2))]
4138 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4140 ;; Conversion from XFmode to {SF,DF}mode
4142 (define_expand "truncxf<mode>2"
4143 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4144 (float_truncate:MODEF
4145 (match_operand:XF 1 "register_operand" "")))
4146 (clobber (match_dup 2))])]
4149 if (flag_unsafe_math_optimizations)
4151 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4152 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4153 if (reg != operands[0])
4154 emit_move_insn (operands[0], reg);
4159 enum ix86_stack_slot slot = (virtuals_instantiated
4162 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4166 (define_insn "*truncxfsf2_mixed"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4169 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4170 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4173 gcc_assert (!which_alternative);
4174 return output_387_reg_move (insn, operands);
4176 [(set_attr "type" "fmov,multi,multi,multi")
4177 (set_attr "unit" "*,i387,i387,i387")
4178 (set_attr "mode" "SF")])
4180 (define_insn "*truncxfdf2_mixed"
4181 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4183 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4184 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4187 gcc_assert (!which_alternative);
4188 return output_387_reg_move (insn, operands);
4190 [(set_attr "type" "fmov,multi,multi,multi")
4191 (set_attr "unit" "*,i387,i387,i387")
4192 (set_attr "mode" "DF")])
4194 (define_insn "truncxf<mode>2_i387_noop"
4195 [(set (match_operand:MODEF 0 "register_operand" "=f")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "f")))]
4198 "TARGET_80387 && flag_unsafe_math_optimizations"
4199 "* return output_387_reg_move (insn, operands);"
4200 [(set_attr "type" "fmov")
4201 (set_attr "mode" "<MODE>")])
4203 (define_insn "*truncxf<mode>2_i387"
4204 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4205 (float_truncate:MODEF
4206 (match_operand:XF 1 "register_operand" "f")))]
4208 "* return output_387_reg_move (insn, operands);"
4209 [(set_attr "type" "fmov")
4210 (set_attr "mode" "<MODE>")])
4213 [(set (match_operand:MODEF 0 "register_operand" "")
4214 (float_truncate:MODEF
4215 (match_operand:XF 1 "register_operand" "")))
4216 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4217 "TARGET_80387 && reload_completed"
4218 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4219 (set (match_dup 0) (match_dup 2))])
4222 [(set (match_operand:MODEF 0 "memory_operand" "")
4223 (float_truncate:MODEF
4224 (match_operand:XF 1 "register_operand" "")))
4225 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4227 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4229 ;; Signed conversion to DImode.
4231 (define_expand "fix_truncxfdi2"
4232 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4233 (fix:DI (match_operand:XF 1 "register_operand" "")))
4234 (clobber (reg:CC FLAGS_REG))])]
4239 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4244 (define_expand "fix_trunc<mode>di2"
4245 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4246 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4247 (clobber (reg:CC FLAGS_REG))])]
4248 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4251 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4253 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4256 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4258 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4259 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4260 if (out != operands[0])
4261 emit_move_insn (operands[0], out);
4266 ;; Signed conversion to SImode.
4268 (define_expand "fix_truncxfsi2"
4269 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4270 (fix:SI (match_operand:XF 1 "register_operand" "")))
4271 (clobber (reg:CC FLAGS_REG))])]
4276 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4281 (define_expand "fix_trunc<mode>si2"
4282 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4283 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4284 (clobber (reg:CC FLAGS_REG))])]
4285 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4288 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4290 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4293 if (SSE_FLOAT_MODE_P (<MODE>mode))
4295 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4296 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4297 if (out != operands[0])
4298 emit_move_insn (operands[0], out);
4303 ;; Signed conversion to HImode.
4305 (define_expand "fix_trunc<mode>hi2"
4306 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4307 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4308 (clobber (reg:CC FLAGS_REG))])]
4310 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4314 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4319 ;; Unsigned conversion to SImode.
4321 (define_expand "fixuns_trunc<mode>si2"
4323 [(set (match_operand:SI 0 "register_operand" "")
4325 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4327 (clobber (match_scratch:<ssevecmode> 3 ""))
4328 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4329 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4331 enum machine_mode mode = <MODE>mode;
4332 enum machine_mode vecmode = <ssevecmode>mode;
4333 REAL_VALUE_TYPE TWO31r;
4336 if (optimize_insn_for_size_p ())
4339 real_ldexp (&TWO31r, &dconst1, 31);
4340 two31 = const_double_from_real_value (TWO31r, mode);
4341 two31 = ix86_build_const_vector (vecmode, true, two31);
4342 operands[2] = force_reg (vecmode, two31);
4345 (define_insn_and_split "*fixuns_trunc<mode>_1"
4346 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4348 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4349 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4350 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4351 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4352 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4353 && optimize_function_for_speed_p (cfun)"
4355 "&& reload_completed"
4358 ix86_split_convert_uns_si_sse (operands);
4362 ;; Unsigned conversion to HImode.
4363 ;; Without these patterns, we'll try the unsigned SI conversion which
4364 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4366 (define_expand "fixuns_trunc<mode>hi2"
4368 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4369 (set (match_operand:HI 0 "nonimmediate_operand" "")
4370 (subreg:HI (match_dup 2) 0))]
4371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4372 "operands[2] = gen_reg_rtx (SImode);")
4374 ;; When SSE is available, it is always faster to use it!
4375 (define_insn "fix_trunc<mode>di_sse"
4376 [(set (match_operand:DI 0 "register_operand" "=r,r")
4377 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4378 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4379 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4380 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4381 [(set_attr "type" "sseicvt")
4382 (set_attr "prefix" "maybe_vex")
4383 (set_attr "prefix_rex" "1")
4384 (set_attr "mode" "<MODE>")
4385 (set_attr "athlon_decode" "double,vector")
4386 (set_attr "amdfam10_decode" "double,double")
4387 (set_attr "bdver1_decode" "double,double")])
4389 (define_insn "fix_trunc<mode>si_sse"
4390 [(set (match_operand:SI 0 "register_operand" "=r,r")
4391 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4392 "SSE_FLOAT_MODE_P (<MODE>mode)
4393 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4394 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4395 [(set_attr "type" "sseicvt")
4396 (set_attr "prefix" "maybe_vex")
4397 (set_attr "mode" "<MODE>")
4398 (set_attr "athlon_decode" "double,vector")
4399 (set_attr "amdfam10_decode" "double,double")
4400 (set_attr "bdver1_decode" "double,double")])
4402 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4404 [(set (match_operand:MODEF 0 "register_operand" "")
4405 (match_operand:MODEF 1 "memory_operand" ""))
4406 (set (match_operand:SWI48x 2 "register_operand" "")
4407 (fix:SWI48x (match_dup 0)))]
4408 "TARGET_SHORTEN_X87_SSE
4409 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4410 && peep2_reg_dead_p (2, operands[0])"
4411 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4413 ;; Avoid vector decoded forms of the instruction.
4415 [(match_scratch:DF 2 "Y2")
4416 (set (match_operand:SWI48x 0 "register_operand" "")
4417 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4418 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4419 [(set (match_dup 2) (match_dup 1))
4420 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4423 [(match_scratch:SF 2 "x")
4424 (set (match_operand:SWI48x 0 "register_operand" "")
4425 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4426 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4427 [(set (match_dup 2) (match_dup 1))
4428 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4430 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4431 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4432 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4433 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4436 && (TARGET_64BIT || <MODE>mode != DImode))
4438 && can_create_pseudo_p ()"
4443 if (memory_operand (operands[0], VOIDmode))
4444 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4447 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4448 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4454 [(set_attr "type" "fisttp")
4455 (set_attr "mode" "<MODE>")])
4457 (define_insn "fix_trunc<mode>_i387_fisttp"
4458 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4459 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4460 (clobber (match_scratch:XF 2 "=&1f"))]
4461 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4463 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4464 && (TARGET_64BIT || <MODE>mode != DImode))
4465 && TARGET_SSE_MATH)"
4466 "* return output_fix_trunc (insn, operands, true);"
4467 [(set_attr "type" "fisttp")
4468 (set_attr "mode" "<MODE>")])
4470 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4471 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4472 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4473 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4474 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4475 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4477 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4478 && (TARGET_64BIT || <MODE>mode != DImode))
4479 && TARGET_SSE_MATH)"
4481 [(set_attr "type" "fisttp")
4482 (set_attr "mode" "<MODE>")])
4485 [(set (match_operand:SWI248x 0 "register_operand" "")
4486 (fix:SWI248x (match_operand 1 "register_operand" "")))
4487 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4488 (clobber (match_scratch 3 ""))]
4490 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4491 (clobber (match_dup 3))])
4492 (set (match_dup 0) (match_dup 2))])
4495 [(set (match_operand:SWI248x 0 "memory_operand" "")
4496 (fix:SWI248x (match_operand 1 "register_operand" "")))
4497 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4498 (clobber (match_scratch 3 ""))]
4500 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4501 (clobber (match_dup 3))])])
4503 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4504 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4505 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4506 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4507 ;; function in i386.c.
4508 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4509 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4510 (fix:SWI248x (match_operand 1 "register_operand" "")))
4511 (clobber (reg:CC FLAGS_REG))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && (TARGET_64BIT || <MODE>mode != DImode))
4516 && can_create_pseudo_p ()"
4521 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4523 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4524 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4525 if (memory_operand (operands[0], VOIDmode))
4526 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4527 operands[2], operands[3]));
4530 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4531 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4532 operands[2], operands[3],
4537 [(set_attr "type" "fistp")
4538 (set_attr "i387_cw" "trunc")
4539 (set_attr "mode" "<MODE>")])
4541 (define_insn "fix_truncdi_i387"
4542 [(set (match_operand:DI 0 "memory_operand" "=m")
4543 (fix:DI (match_operand 1 "register_operand" "f")))
4544 (use (match_operand:HI 2 "memory_operand" "m"))
4545 (use (match_operand:HI 3 "memory_operand" "m"))
4546 (clobber (match_scratch:XF 4 "=&1f"))]
4547 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4549 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4550 "* return output_fix_trunc (insn, operands, false);"
4551 [(set_attr "type" "fistp")
4552 (set_attr "i387_cw" "trunc")
4553 (set_attr "mode" "DI")])
4555 (define_insn "fix_truncdi_i387_with_temp"
4556 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4557 (fix:DI (match_operand 1 "register_operand" "f,f")))
4558 (use (match_operand:HI 2 "memory_operand" "m,m"))
4559 (use (match_operand:HI 3 "memory_operand" "m,m"))
4560 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4561 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4566 [(set_attr "type" "fistp")
4567 (set_attr "i387_cw" "trunc")
4568 (set_attr "mode" "DI")])
4571 [(set (match_operand:DI 0 "register_operand" "")
4572 (fix:DI (match_operand 1 "register_operand" "")))
4573 (use (match_operand:HI 2 "memory_operand" ""))
4574 (use (match_operand:HI 3 "memory_operand" ""))
4575 (clobber (match_operand:DI 4 "memory_operand" ""))
4576 (clobber (match_scratch 5 ""))]
4578 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4581 (clobber (match_dup 5))])
4582 (set (match_dup 0) (match_dup 4))])
4585 [(set (match_operand:DI 0 "memory_operand" "")
4586 (fix:DI (match_operand 1 "register_operand" "")))
4587 (use (match_operand:HI 2 "memory_operand" ""))
4588 (use (match_operand:HI 3 "memory_operand" ""))
4589 (clobber (match_operand:DI 4 "memory_operand" ""))
4590 (clobber (match_scratch 5 ""))]
4592 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4595 (clobber (match_dup 5))])])
4597 (define_insn "fix_trunc<mode>_i387"
4598 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4599 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4600 (use (match_operand:HI 2 "memory_operand" "m"))
4601 (use (match_operand:HI 3 "memory_operand" "m"))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4605 "* return output_fix_trunc (insn, operands, false);"
4606 [(set_attr "type" "fistp")
4607 (set_attr "i387_cw" "trunc")
4608 (set_attr "mode" "<MODE>")])
4610 (define_insn "fix_trunc<mode>_i387_with_temp"
4611 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4612 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4613 (use (match_operand:HI 2 "memory_operand" "m,m"))
4614 (use (match_operand:HI 3 "memory_operand" "m,m"))
4615 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4616 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620 [(set_attr "type" "fistp")
4621 (set_attr "i387_cw" "trunc")
4622 (set_attr "mode" "<MODE>")])
4625 [(set (match_operand:SWI24 0 "register_operand" "")
4626 (fix:SWI24 (match_operand 1 "register_operand" "")))
4627 (use (match_operand:HI 2 "memory_operand" ""))
4628 (use (match_operand:HI 3 "memory_operand" ""))
4629 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4631 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4633 (use (match_dup 3))])
4634 (set (match_dup 0) (match_dup 4))])
4637 [(set (match_operand:SWI24 0 "memory_operand" "")
4638 (fix:SWI24 (match_operand 1 "register_operand" "")))
4639 (use (match_operand:HI 2 "memory_operand" ""))
4640 (use (match_operand:HI 3 "memory_operand" ""))
4641 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4643 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4645 (use (match_dup 3))])])
4647 (define_insn "x86_fnstcw_1"
4648 [(set (match_operand:HI 0 "memory_operand" "=m")
4649 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4652 [(set (attr "length")
4653 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4654 (set_attr "mode" "HI")
4655 (set_attr "unit" "i387")
4656 (set_attr "bdver1_decode" "vector")])
4658 (define_insn "x86_fldcw_1"
4659 [(set (reg:HI FPCR_REG)
4660 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4663 [(set (attr "length")
4664 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4665 (set_attr "mode" "HI")
4666 (set_attr "unit" "i387")
4667 (set_attr "athlon_decode" "vector")
4668 (set_attr "amdfam10_decode" "vector")
4669 (set_attr "bdver1_decode" "vector")])
4671 ;; Conversion between fixed point and floating point.
4673 ;; Even though we only accept memory inputs, the backend _really_
4674 ;; wants to be able to do this between registers.
4676 (define_expand "floathi<mode>2"
4677 [(set (match_operand:X87MODEF 0 "register_operand" "")
4678 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4681 || TARGET_MIX_SSE_I387)")
4683 ;; Pre-reload splitter to add memory clobber to the pattern.
4684 (define_insn_and_split "*floathi<mode>2_1"
4685 [(set (match_operand:X87MODEF 0 "register_operand" "")
4686 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4688 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4689 || TARGET_MIX_SSE_I387)
4690 && can_create_pseudo_p ()"
4693 [(parallel [(set (match_dup 0)
4694 (float:X87MODEF (match_dup 1)))
4695 (clobber (match_dup 2))])]
4696 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4698 (define_insn "*floathi<mode>2_i387_with_temp"
4699 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4700 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4701 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)"
4706 [(set_attr "type" "fmov,multi")
4707 (set_attr "mode" "<MODE>")
4708 (set_attr "unit" "*,i387")
4709 (set_attr "fp_int_src" "true")])
4711 (define_insn "*floathi<mode>2_i387"
4712 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4713 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4716 || TARGET_MIX_SSE_I387)"
4718 [(set_attr "type" "fmov")
4719 (set_attr "mode" "<MODE>")
4720 (set_attr "fp_int_src" "true")])
4723 [(set (match_operand:X87MODEF 0 "register_operand" "")
4724 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4725 (clobber (match_operand:HI 2 "memory_operand" ""))]
4727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4728 || TARGET_MIX_SSE_I387)
4729 && reload_completed"
4730 [(set (match_dup 2) (match_dup 1))
4731 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4734 [(set (match_operand:X87MODEF 0 "register_operand" "")
4735 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4736 (clobber (match_operand:HI 2 "memory_operand" ""))]
4738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4739 || TARGET_MIX_SSE_I387)
4740 && reload_completed"
4741 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4743 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4744 [(set (match_operand:X87MODEF 0 "register_operand" "")
4746 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4748 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4749 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4751 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4752 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4753 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4755 rtx reg = gen_reg_rtx (XFmode);
4756 rtx (*insn)(rtx, rtx);
4758 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4760 if (<X87MODEF:MODE>mode == SFmode)
4761 insn = gen_truncxfsf2;
4762 else if (<X87MODEF:MODE>mode == DFmode)
4763 insn = gen_truncxfdf2;
4767 emit_insn (insn (operands[0], reg));
4772 ;; Pre-reload splitter to add memory clobber to the pattern.
4773 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4774 [(set (match_operand:X87MODEF 0 "register_operand" "")
4775 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4777 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4778 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4779 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4780 || TARGET_MIX_SSE_I387))
4781 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4782 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4783 && ((<SWI48x:MODE>mode == SImode
4784 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4785 && optimize_function_for_speed_p (cfun)
4786 && flag_trapping_math)
4787 || !(TARGET_INTER_UNIT_CONVERSIONS
4788 || optimize_function_for_size_p (cfun)))))
4789 && can_create_pseudo_p ()"
4792 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4793 (clobber (match_dup 2))])]
4795 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4797 /* Avoid store forwarding (partial memory) stall penalty
4798 by passing DImode value through XMM registers. */
4799 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4800 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4801 && optimize_function_for_speed_p (cfun))
4803 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4810 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4811 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4813 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4814 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4815 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4816 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4818 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4819 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4820 (set_attr "unit" "*,i387,*,*,*")
4821 (set_attr "athlon_decode" "*,*,double,direct,double")
4822 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4823 (set_attr "bdver1_decode" "*,*,double,direct,double")
4824 (set_attr "fp_int_src" "true")])
4826 (define_insn "*floatsi<mode>2_vector_mixed"
4827 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4828 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4829 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4830 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4834 [(set_attr "type" "fmov,sseicvt")
4835 (set_attr "mode" "<MODE>,<ssevecmode>")
4836 (set_attr "unit" "i387,*")
4837 (set_attr "athlon_decode" "*,direct")
4838 (set_attr "amdfam10_decode" "*,double")
4839 (set_attr "bdver1_decode" "*,direct")
4840 (set_attr "fp_int_src" "true")])
4842 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4843 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4845 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4846 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4847 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4848 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851 (set_attr "mode" "<MODEF:MODE>")
4852 (set_attr "unit" "*,i387,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct")
4854 (set_attr "amdfam10_decode" "*,*,vector,double")
4855 (set_attr "bdver1_decode" "*,*,double,direct")
4856 (set_attr "fp_int_src" "true")])
4859 [(set (match_operand:MODEF 0 "register_operand" "")
4860 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4861 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4862 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4864 && TARGET_INTER_UNIT_CONVERSIONS
4866 && (SSE_REG_P (operands[0])
4867 || (GET_CODE (operands[0]) == SUBREG
4868 && SSE_REG_P (operands[0])))"
4869 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4872 [(set (match_operand:MODEF 0 "register_operand" "")
4873 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4874 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4875 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4876 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4877 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4879 && (SSE_REG_P (operands[0])
4880 || (GET_CODE (operands[0]) == SUBREG
4881 && SSE_REG_P (operands[0])))"
4882 [(set (match_dup 2) (match_dup 1))
4883 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4885 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4886 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4888 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4889 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4890 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4891 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4894 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4895 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4896 [(set_attr "type" "fmov,sseicvt,sseicvt")
4897 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4898 (set_attr "mode" "<MODEF:MODE>")
4899 (set (attr "prefix_rex")
4901 (and (eq_attr "prefix" "maybe_vex")
4902 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4904 (const_string "*")))
4905 (set_attr "unit" "i387,*,*")
4906 (set_attr "athlon_decode" "*,double,direct")
4907 (set_attr "amdfam10_decode" "*,vector,double")
4908 (set_attr "bdver1_decode" "*,double,direct")
4909 (set_attr "fp_int_src" "true")])
4911 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4912 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4914 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4915 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4917 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4920 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4921 [(set_attr "type" "fmov,sseicvt")
4922 (set_attr "prefix" "orig,maybe_vex")
4923 (set_attr "mode" "<MODEF:MODE>")
4924 (set (attr "prefix_rex")
4926 (and (eq_attr "prefix" "maybe_vex")
4927 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4929 (const_string "*")))
4930 (set_attr "athlon_decode" "*,direct")
4931 (set_attr "amdfam10_decode" "*,double")
4932 (set_attr "bdver1_decode" "*,direct")
4933 (set_attr "fp_int_src" "true")])
4935 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4936 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4938 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4939 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4940 "TARGET_SSE2 && TARGET_SSE_MATH
4941 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4943 [(set_attr "type" "sseicvt")
4944 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4945 (set_attr "athlon_decode" "double,direct,double")
4946 (set_attr "amdfam10_decode" "vector,double,double")
4947 (set_attr "bdver1_decode" "double,direct,double")
4948 (set_attr "fp_int_src" "true")])
4950 (define_insn "*floatsi<mode>2_vector_sse"
4951 [(set (match_operand:MODEF 0 "register_operand" "=x")
4952 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4953 "TARGET_SSE2 && TARGET_SSE_MATH
4954 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4956 [(set_attr "type" "sseicvt")
4957 (set_attr "mode" "<MODE>")
4958 (set_attr "athlon_decode" "direct")
4959 (set_attr "amdfam10_decode" "double")
4960 (set_attr "bdver1_decode" "direct")
4961 (set_attr "fp_int_src" "true")])
4964 [(set (match_operand:MODEF 0 "register_operand" "")
4965 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4966 (clobber (match_operand:SI 2 "memory_operand" ""))]
4967 "TARGET_SSE2 && TARGET_SSE_MATH
4968 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4970 && (SSE_REG_P (operands[0])
4971 || (GET_CODE (operands[0]) == SUBREG
4972 && SSE_REG_P (operands[0])))"
4975 rtx op1 = operands[1];
4977 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4979 if (GET_CODE (op1) == SUBREG)
4980 op1 = SUBREG_REG (op1);
4982 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4984 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4985 emit_insn (gen_sse2_loadld (operands[4],
4986 CONST0_RTX (V4SImode), operands[1]));
4988 /* We can ignore possible trapping value in the
4989 high part of SSE register for non-trapping math. */
4990 else if (SSE_REG_P (op1) && !flag_trapping_math)
4991 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4994 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4995 emit_move_insn (operands[2], operands[1]);
4996 emit_insn (gen_sse2_loadld (operands[4],
4997 CONST0_RTX (V4SImode), operands[2]));
5000 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5005 [(set (match_operand:MODEF 0 "register_operand" "")
5006 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5007 (clobber (match_operand:SI 2 "memory_operand" ""))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5011 && (SSE_REG_P (operands[0])
5012 || (GET_CODE (operands[0]) == SUBREG
5013 && SSE_REG_P (operands[0])))"
5016 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5018 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5020 emit_insn (gen_sse2_loadld (operands[4],
5021 CONST0_RTX (V4SImode), operands[1]));
5023 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5028 [(set (match_operand:MODEF 0 "register_operand" "")
5029 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5030 "TARGET_SSE2 && TARGET_SSE_MATH
5031 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5033 && (SSE_REG_P (operands[0])
5034 || (GET_CODE (operands[0]) == SUBREG
5035 && SSE_REG_P (operands[0])))"
5038 rtx op1 = operands[1];
5040 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5042 if (GET_CODE (op1) == SUBREG)
5043 op1 = SUBREG_REG (op1);
5045 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5047 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[1]));
5051 /* We can ignore possible trapping value in the
5052 high part of SSE register for non-trapping math. */
5053 else if (SSE_REG_P (op1) && !flag_trapping_math)
5054 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5058 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5063 [(set (match_operand:MODEF 0 "register_operand" "")
5064 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5065 "TARGET_SSE2 && TARGET_SSE_MATH
5066 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5068 && (SSE_REG_P (operands[0])
5069 || (GET_CODE (operands[0]) == SUBREG
5070 && SSE_REG_P (operands[0])))"
5073 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[1]));
5080 (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5084 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5085 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5087 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5088 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5089 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5090 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "mode" "<MODEF:MODE>")
5094 (set_attr "athlon_decode" "double,direct")
5095 (set_attr "amdfam10_decode" "vector,double")
5096 (set_attr "bdver1_decode" "double,direct")
5097 (set_attr "fp_int_src" "true")])
5099 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5100 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5102 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5103 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5104 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5105 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5106 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5107 [(set_attr "type" "sseicvt")
5108 (set_attr "prefix" "maybe_vex")
5109 (set_attr "mode" "<MODEF:MODE>")
5110 (set (attr "prefix_rex")
5112 (and (eq_attr "prefix" "maybe_vex")
5113 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5115 (const_string "*")))
5116 (set_attr "athlon_decode" "double,direct")
5117 (set_attr "amdfam10_decode" "vector,double")
5118 (set_attr "bdver1_decode" "double,direct")
5119 (set_attr "fp_int_src" "true")])
5122 [(set (match_operand:MODEF 0 "register_operand" "")
5123 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5124 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5125 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5126 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5127 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5129 && (SSE_REG_P (operands[0])
5130 || (GET_CODE (operands[0]) == SUBREG
5131 && SSE_REG_P (operands[0])))"
5132 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5134 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5135 [(set (match_operand:MODEF 0 "register_operand" "=x")
5137 (match_operand:SWI48x 1 "memory_operand" "m")))]
5138 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5139 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5140 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5141 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5142 [(set_attr "type" "sseicvt")
5143 (set_attr "prefix" "maybe_vex")
5144 (set_attr "mode" "<MODEF:MODE>")
5145 (set (attr "prefix_rex")
5147 (and (eq_attr "prefix" "maybe_vex")
5148 (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5150 (const_string "*")))
5151 (set_attr "athlon_decode" "direct")
5152 (set_attr "amdfam10_decode" "double")
5153 (set_attr "bdver1_decode" "direct")
5154 (set_attr "fp_int_src" "true")])
5157 [(set (match_operand:MODEF 0 "register_operand" "")
5158 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5159 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5160 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5161 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5162 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5164 && (SSE_REG_P (operands[0])
5165 || (GET_CODE (operands[0]) == SUBREG
5166 && SSE_REG_P (operands[0])))"
5167 [(set (match_dup 2) (match_dup 1))
5168 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5171 [(set (match_operand:MODEF 0 "register_operand" "")
5172 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5173 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5174 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5175 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && (SSE_REG_P (operands[0])
5178 || (GET_CODE (operands[0]) == SUBREG
5179 && SSE_REG_P (operands[0])))"
5180 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5182 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5183 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5185 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5186 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5188 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5192 [(set_attr "type" "fmov,multi")
5193 (set_attr "mode" "<X87MODEF:MODE>")
5194 (set_attr "unit" "*,i387")
5195 (set_attr "fp_int_src" "true")])
5197 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5198 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5200 (match_operand:SWI48x 1 "memory_operand" "m")))]
5202 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5204 [(set_attr "type" "fmov")
5205 (set_attr "mode" "<X87MODEF:MODE>")
5206 (set_attr "fp_int_src" "true")])
5209 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5210 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5211 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5213 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5214 && reload_completed"
5215 [(set (match_dup 2) (match_dup 1))
5216 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5219 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5220 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5221 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5223 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5224 && reload_completed"
5225 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5227 ;; Avoid store forwarding (partial memory) stall penalty
5228 ;; by passing DImode value through XMM registers. */
5230 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5231 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5233 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5234 (clobber (match_scratch:V4SI 3 "=X,x"))
5235 (clobber (match_scratch:V4SI 4 "=X,x"))
5236 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5237 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5238 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5239 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5241 [(set_attr "type" "multi")
5242 (set_attr "mode" "<X87MODEF:MODE>")
5243 (set_attr "unit" "i387")
5244 (set_attr "fp_int_src" "true")])
5247 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5248 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5249 (clobber (match_scratch:V4SI 3 ""))
5250 (clobber (match_scratch:V4SI 4 ""))
5251 (clobber (match_operand:DI 2 "memory_operand" ""))]
5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5255 && reload_completed"
5256 [(set (match_dup 2) (match_dup 3))
5257 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5259 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5260 Assemble the 64-bit DImode value in an xmm register. */
5261 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 0)));
5263 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5264 gen_rtx_SUBREG (SImode, operands[1], 4)));
5265 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5268 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5272 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5273 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5274 (clobber (match_scratch:V4SI 3 ""))
5275 (clobber (match_scratch:V4SI 4 ""))
5276 (clobber (match_operand:DI 2 "memory_operand" ""))]
5277 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5278 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5279 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5280 && reload_completed"
5281 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5283 ;; Avoid store forwarding (partial memory) stall penalty by extending
5284 ;; SImode value to DImode through XMM register instead of pushing two
5285 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5286 ;; targets benefit from this optimization. Also note that fild
5287 ;; loads from memory only.
5289 (define_insn "*floatunssi<mode>2_1"
5290 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5291 (unsigned_float:X87MODEF
5292 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5293 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5294 (clobber (match_scratch:SI 3 "=X,x"))]
5296 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299 [(set_attr "type" "multi")
5300 (set_attr "mode" "<MODE>")])
5303 [(set (match_operand:X87MODEF 0 "register_operand" "")
5304 (unsigned_float:X87MODEF
5305 (match_operand:SI 1 "register_operand" "")))
5306 (clobber (match_operand:DI 2 "memory_operand" ""))
5307 (clobber (match_scratch:SI 3 ""))]
5309 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311 && reload_completed"
5312 [(set (match_dup 2) (match_dup 1))
5314 (float:X87MODEF (match_dup 2)))]
5315 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5318 [(set (match_operand:X87MODEF 0 "register_operand" "")
5319 (unsigned_float:X87MODEF
5320 (match_operand:SI 1 "memory_operand" "")))
5321 (clobber (match_operand:DI 2 "memory_operand" ""))
5322 (clobber (match_scratch:SI 3 ""))]
5324 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && reload_completed"
5327 [(set (match_dup 2) (match_dup 3))
5329 (float:X87MODEF (match_dup 2)))]
5331 emit_move_insn (operands[3], operands[1]);
5332 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5335 (define_expand "floatunssi<mode>2"
5337 [(set (match_operand:X87MODEF 0 "register_operand" "")
5338 (unsigned_float:X87MODEF
5339 (match_operand:SI 1 "nonimmediate_operand" "")))
5340 (clobber (match_dup 2))
5341 (clobber (match_scratch:SI 3 ""))])]
5343 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5345 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5347 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5349 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5354 enum ix86_stack_slot slot = (virtuals_instantiated
5357 operands[2] = assign_386_stack_local (DImode, slot);
5361 (define_expand "floatunsdisf2"
5362 [(use (match_operand:SF 0 "register_operand" ""))
5363 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5364 "TARGET_64BIT && TARGET_SSE_MATH"
5365 "x86_emit_floatuns (operands); DONE;")
5367 (define_expand "floatunsdidf2"
5368 [(use (match_operand:DF 0 "register_operand" ""))
5369 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5370 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5371 && TARGET_SSE2 && TARGET_SSE_MATH"
5374 x86_emit_floatuns (operands);
5376 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5382 (define_expand "add<mode>3"
5383 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5384 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5385 (match_operand:SDWIM 2 "<general_operand>" "")))]
5387 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5389 (define_insn_and_split "*add<dwi>3_doubleword"
5390 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5392 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5393 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5394 (clobber (reg:CC FLAGS_REG))]
5395 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5398 [(parallel [(set (reg:CC FLAGS_REG)
5399 (unspec:CC [(match_dup 1) (match_dup 2)]
5402 (plus:DWIH (match_dup 1) (match_dup 2)))])
5403 (parallel [(set (match_dup 3)
5407 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5409 (clobber (reg:CC FLAGS_REG))])]
5410 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5412 (define_insn "*add<mode>3_cc"
5413 [(set (reg:CC FLAGS_REG)
5415 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5416 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5418 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5419 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5420 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5421 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5422 [(set_attr "type" "alu")
5423 (set_attr "mode" "<MODE>")])
5425 (define_insn "addqi3_cc"
5426 [(set (reg:CC FLAGS_REG)
5428 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5429 (match_operand:QI 2 "general_operand" "qn,qm")]
5431 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5432 (plus:QI (match_dup 1) (match_dup 2)))]
5433 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5434 "add{b}\t{%2, %0|%0, %2}"
5435 [(set_attr "type" "alu")
5436 (set_attr "mode" "QI")])
5438 (define_insn "*lea_1"
5439 [(set (match_operand:P 0 "register_operand" "=r")
5440 (match_operand:P 1 "no_seg_address_operand" "p"))]
5442 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5443 [(set_attr "type" "lea")
5444 (set_attr "mode" "<MODE>")])
5446 (define_insn "*lea_2"
5447 [(set (match_operand:SI 0 "register_operand" "=r")
5448 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5450 "lea{l}\t{%a1, %0|%0, %a1}"
5451 [(set_attr "type" "lea")
5452 (set_attr "mode" "SI")])
5454 (define_insn "*lea_2_zext"
5455 [(set (match_operand:DI 0 "register_operand" "=r")
5457 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5459 "lea{l}\t{%a1, %k0|%k0, %a1}"
5460 [(set_attr "type" "lea")
5461 (set_attr "mode" "SI")])
5463 (define_insn "*add<mode>_1"
5464 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5466 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5467 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5471 switch (get_attr_type (insn))
5477 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5478 if (operands[2] == const1_rtx)
5479 return "inc{<imodesuffix>}\t%0";
5482 gcc_assert (operands[2] == constm1_rtx);
5483 return "dec{<imodesuffix>}\t%0";
5487 /* For most processors, ADD is faster than LEA. This alternative
5488 was added to use ADD as much as possible. */
5489 if (which_alternative == 2)
5492 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5496 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5497 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5499 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5503 (cond [(eq_attr "alternative" "3")
5504 (const_string "lea")
5505 (match_operand:SWI48 2 "incdec_operand" "")
5506 (const_string "incdec")
5508 (const_string "alu")))
5509 (set (attr "length_immediate")
5511 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5513 (const_string "*")))
5514 (set_attr "mode" "<MODE>")])
5516 ;; It may seem that nonimmediate operand is proper one for operand 1.
5517 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5518 ;; we take care in ix86_binary_operator_ok to not allow two memory
5519 ;; operands so proper swapping will be done in reload. This allow
5520 ;; patterns constructed from addsi_1 to match.
5522 (define_insn "*addsi_1_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5525 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5526 (match_operand:SI 2 "general_operand" "g,0,li"))))
5527 (clobber (reg:CC FLAGS_REG))]
5528 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5530 switch (get_attr_type (insn))
5536 if (operands[2] == const1_rtx)
5537 return "inc{l}\t%k0";
5540 gcc_assert (operands[2] == constm1_rtx);
5541 return "dec{l}\t%k0";
5545 /* For most processors, ADD is faster than LEA. This alternative
5546 was added to use ADD as much as possible. */
5547 if (which_alternative == 1)
5550 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5553 if (x86_maybe_negate_const_int (&operands[2], SImode))
5554 return "sub{l}\t{%2, %k0|%k0, %2}";
5556 return "add{l}\t{%2, %k0|%k0, %2}";
5560 (cond [(eq_attr "alternative" "2")
5561 (const_string "lea")
5562 (match_operand:SI 2 "incdec_operand" "")
5563 (const_string "incdec")
5565 (const_string "alu")))
5566 (set (attr "length_immediate")
5568 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5570 (const_string "*")))
5571 (set_attr "mode" "SI")])
5573 (define_insn "*addhi_1"
5574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5575 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5576 (match_operand:HI 2 "general_operand" "rn,rm")))
5577 (clobber (reg:CC FLAGS_REG))]
5578 "TARGET_PARTIAL_REG_STALL
5579 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5581 switch (get_attr_type (insn))
5584 if (operands[2] == const1_rtx)
5585 return "inc{w}\t%0";
5588 gcc_assert (operands[2] == constm1_rtx);
5589 return "dec{w}\t%0";
5593 if (x86_maybe_negate_const_int (&operands[2], HImode))
5594 return "sub{w}\t{%2, %0|%0, %2}";
5596 return "add{w}\t{%2, %0|%0, %2}";
5600 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5601 (const_string "incdec")
5602 (const_string "alu")))
5603 (set (attr "length_immediate")
5605 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5607 (const_string "*")))
5608 (set_attr "mode" "HI")])
5610 (define_insn "*addhi_1_lea"
5611 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5612 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5613 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5614 (clobber (reg:CC FLAGS_REG))]
5615 "!TARGET_PARTIAL_REG_STALL
5616 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5618 switch (get_attr_type (insn))
5624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5625 if (operands[2] == const1_rtx)
5626 return "inc{w}\t%0";
5629 gcc_assert (operands[2] == constm1_rtx);
5630 return "dec{w}\t%0";
5634 /* For most processors, ADD is faster than LEA. This alternative
5635 was added to use ADD as much as possible. */
5636 if (which_alternative == 2)
5639 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643 if (x86_maybe_negate_const_int (&operands[2], HImode))
5644 return "sub{w}\t{%2, %0|%0, %2}";
5646 return "add{w}\t{%2, %0|%0, %2}";
5650 (cond [(eq_attr "alternative" "3")
5651 (const_string "lea")
5652 (match_operand:HI 2 "incdec_operand" "")
5653 (const_string "incdec")
5655 (const_string "alu")))
5656 (set (attr "length_immediate")
5658 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5660 (const_string "*")))
5661 (set_attr "mode" "HI,HI,HI,SI")])
5663 ;; %%% Potential partial reg stall on alternative 2. What to do?
5664 (define_insn "*addqi_1"
5665 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5666 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5667 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5668 (clobber (reg:CC FLAGS_REG))]
5669 "TARGET_PARTIAL_REG_STALL
5670 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 int widen = (which_alternative == 2);
5673 switch (get_attr_type (insn))
5676 if (operands[2] == const1_rtx)
5677 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5680 gcc_assert (operands[2] == constm1_rtx);
5681 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5685 if (x86_maybe_negate_const_int (&operands[2], QImode))
5688 return "sub{l}\t{%2, %k0|%k0, %2}";
5690 return "sub{b}\t{%2, %0|%0, %2}";
5693 return "add{l}\t{%k2, %k0|%k0, %k2}";
5695 return "add{b}\t{%2, %0|%0, %2}";
5699 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5700 (const_string "incdec")
5701 (const_string "alu")))
5702 (set (attr "length_immediate")
5704 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5706 (const_string "*")))
5707 (set_attr "mode" "QI,QI,SI")])
5709 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5710 (define_insn "*addqi_1_lea"
5711 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5712 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5713 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5714 (clobber (reg:CC FLAGS_REG))]
5715 "!TARGET_PARTIAL_REG_STALL
5716 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5718 int widen = (which_alternative == 3 || which_alternative == 4);
5720 switch (get_attr_type (insn))
5726 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5727 if (operands[2] == const1_rtx)
5728 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5731 gcc_assert (operands[2] == constm1_rtx);
5732 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5736 /* For most processors, ADD is faster than LEA. These alternatives
5737 were added to use ADD as much as possible. */
5738 if (which_alternative == 2 || which_alternative == 4)
5741 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5744 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745 if (x86_maybe_negate_const_int (&operands[2], QImode))
5748 return "sub{l}\t{%2, %k0|%k0, %2}";
5750 return "sub{b}\t{%2, %0|%0, %2}";
5753 return "add{l}\t{%k2, %k0|%k0, %k2}";
5755 return "add{b}\t{%2, %0|%0, %2}";
5759 (cond [(eq_attr "alternative" "5")
5760 (const_string "lea")
5761 (match_operand:QI 2 "incdec_operand" "")
5762 (const_string "incdec")
5764 (const_string "alu")))
5765 (set (attr "length_immediate")
5767 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5769 (const_string "*")))
5770 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5772 (define_insn "*addqi_1_slp"
5773 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5774 (plus:QI (match_dup 0)
5775 (match_operand:QI 1 "general_operand" "qn,qnm")))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5780 switch (get_attr_type (insn))
5783 if (operands[1] == const1_rtx)
5784 return "inc{b}\t%0";
5787 gcc_assert (operands[1] == constm1_rtx);
5788 return "dec{b}\t%0";
5792 if (x86_maybe_negate_const_int (&operands[1], QImode))
5793 return "sub{b}\t{%1, %0|%0, %1}";
5795 return "add{b}\t{%1, %0|%0, %1}";
5799 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5800 (const_string "incdec")
5801 (const_string "alu1")))
5802 (set (attr "memory")
5803 (if_then_else (match_operand 1 "memory_operand" "")
5804 (const_string "load")
5805 (const_string "none")))
5806 (set_attr "mode" "QI")])
5808 ;; Convert lea to the lea pattern to avoid flags dependency.
5810 [(set (match_operand 0 "register_operand" "")
5811 (plus (match_operand 1 "register_operand" "")
5812 (match_operand 2 "nonmemory_operand" "")))
5813 (clobber (reg:CC FLAGS_REG))]
5814 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5818 enum machine_mode mode = GET_MODE (operands[0]);
5820 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5821 may confuse gen_lowpart. */
5824 operands[1] = gen_lowpart (Pmode, operands[1]);
5825 operands[2] = gen_lowpart (Pmode, operands[2]);
5828 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5830 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5831 operands[0] = gen_lowpart (SImode, operands[0]);
5833 if (TARGET_64BIT && mode != Pmode)
5834 pat = gen_rtx_SUBREG (SImode, pat, 0);
5836 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5840 ;; Convert lea to the lea pattern to avoid flags dependency.
5841 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5842 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5844 [(set (match_operand:DI 0 "register_operand" "")
5845 (plus:DI (match_operand:DI 1 "register_operand" "")
5846 (match_operand:DI 2 "x86_64_immediate_operand" "")))
5847 (clobber (reg:CC FLAGS_REG))]
5848 "TARGET_64BIT && reload_completed
5849 && true_regnum (operands[0]) != true_regnum (operands[1])"
5851 (plus:DI (match_dup 1) (match_dup 2)))])
5853 ;; Convert lea to the lea pattern to avoid flags dependency.
5855 [(set (match_operand:DI 0 "register_operand" "")
5857 (plus:SI (match_operand:SI 1 "register_operand" "")
5858 (match_operand:SI 2 "nonmemory_operand" ""))))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "TARGET_64BIT && reload_completed
5861 && ix86_lea_for_add_ok (insn, operands)"
5863 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5865 operands[1] = gen_lowpart (DImode, operands[1]);
5866 operands[2] = gen_lowpart (DImode, operands[2]);
5869 (define_insn "*add<mode>_2"
5870 [(set (reg FLAGS_REG)
5873 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5874 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5876 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5877 (plus:SWI (match_dup 1) (match_dup 2)))]
5878 "ix86_match_ccmode (insn, CCGOCmode)
5879 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5881 switch (get_attr_type (insn))
5884 if (operands[2] == const1_rtx)
5885 return "inc{<imodesuffix>}\t%0";
5888 gcc_assert (operands[2] == constm1_rtx);
5889 return "dec{<imodesuffix>}\t%0";
5893 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5894 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5896 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5900 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set (attr "length_immediate")
5905 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5907 (const_string "*")))
5908 (set_attr "mode" "<MODE>")])
5910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5911 (define_insn "*addsi_2_zext"
5912 [(set (reg FLAGS_REG)
5914 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5915 (match_operand:SI 2 "general_operand" "g"))
5917 (set (match_operand:DI 0 "register_operand" "=r")
5918 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5919 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == const1_rtx)
5926 return "inc{l}\t%k0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{l}\t%k0";
5934 if (x86_maybe_negate_const_int (&operands[2], SImode))
5935 return "sub{l}\t{%2, %k0|%k0, %2}";
5937 return "add{l}\t{%2, %k0|%k0, %2}";
5941 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set (attr "length_immediate")
5946 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5948 (const_string "*")))
5949 (set_attr "mode" "SI")])
5951 (define_insn "*add<mode>_3"
5952 [(set (reg FLAGS_REG)
5954 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5955 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5956 (clobber (match_scratch:SWI 0 "=<r>"))]
5957 "ix86_match_ccmode (insn, CCZmode)
5958 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5960 switch (get_attr_type (insn))
5963 if (operands[2] == const1_rtx)
5964 return "inc{<imodesuffix>}\t%0";
5967 gcc_assert (operands[2] == constm1_rtx);
5968 return "dec{<imodesuffix>}\t%0";
5972 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5973 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5975 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5979 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5980 (const_string "incdec")
5981 (const_string "alu")))
5982 (set (attr "length_immediate")
5984 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5986 (const_string "*")))
5987 (set_attr "mode" "<MODE>")])
5989 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5990 (define_insn "*addsi_3_zext"
5991 [(set (reg FLAGS_REG)
5993 (neg:SI (match_operand:SI 2 "general_operand" "g"))
5994 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5995 (set (match_operand:DI 0 "register_operand" "=r")
5996 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5997 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5998 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6000 switch (get_attr_type (insn))
6003 if (operands[2] == const1_rtx)
6004 return "inc{l}\t%k0";
6007 gcc_assert (operands[2] == constm1_rtx);
6008 return "dec{l}\t%k0";
6012 if (x86_maybe_negate_const_int (&operands[2], SImode))
6013 return "sub{l}\t{%2, %k0|%k0, %2}";
6015 return "add{l}\t{%2, %k0|%k0, %2}";
6019 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set (attr "length_immediate")
6024 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6026 (const_string "*")))
6027 (set_attr "mode" "SI")])
6029 ; For comparisons against 1, -1 and 128, we may generate better code
6030 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6031 ; is matched then. We can't accept general immediate, because for
6032 ; case of overflows, the result is messed up.
6033 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6034 ; only for comparisons not depending on it.
6036 (define_insn "*adddi_4"
6037 [(set (reg FLAGS_REG)
6039 (match_operand:DI 1 "nonimmediate_operand" "0")
6040 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6041 (clobber (match_scratch:DI 0 "=rm"))]
6043 && ix86_match_ccmode (insn, CCGCmode)"
6045 switch (get_attr_type (insn))
6048 if (operands[2] == constm1_rtx)
6049 return "inc{q}\t%0";
6052 gcc_assert (operands[2] == const1_rtx);
6053 return "dec{q}\t%0";
6057 if (x86_maybe_negate_const_int (&operands[2], DImode))
6058 return "add{q}\t{%2, %0|%0, %2}";
6060 return "sub{q}\t{%2, %0|%0, %2}";
6064 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6065 (const_string "incdec")
6066 (const_string "alu")))
6067 (set (attr "length_immediate")
6069 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6071 (const_string "*")))
6072 (set_attr "mode" "DI")])
6074 ; For comparisons against 1, -1 and 128, we may generate better code
6075 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6076 ; is matched then. We can't accept general immediate, because for
6077 ; case of overflows, the result is messed up.
6078 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6079 ; only for comparisons not depending on it.
6081 (define_insn "*add<mode>_4"
6082 [(set (reg FLAGS_REG)
6084 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6085 (match_operand:SWI124 2 "const_int_operand" "n")))
6086 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6087 "ix86_match_ccmode (insn, CCGCmode)"
6089 switch (get_attr_type (insn))
6092 if (operands[2] == constm1_rtx)
6093 return "inc{<imodesuffix>}\t%0";
6096 gcc_assert (operands[2] == const1_rtx);
6097 return "dec{<imodesuffix>}\t%0";
6101 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6102 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6104 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6108 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6109 (const_string "incdec")
6110 (const_string "alu")))
6111 (set (attr "length_immediate")
6113 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6115 (const_string "*")))
6116 (set_attr "mode" "<MODE>")])
6118 (define_insn "*add<mode>_5"
6119 [(set (reg FLAGS_REG)
6122 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6123 (match_operand:SWI 2 "<general_operand>" "<g>"))
6125 (clobber (match_scratch:SWI 0 "=<r>"))]
6126 "ix86_match_ccmode (insn, CCGOCmode)
6127 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6129 switch (get_attr_type (insn))
6132 if (operands[2] == const1_rtx)
6133 return "inc{<imodesuffix>}\t%0";
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{<imodesuffix>}\t%0";
6141 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6142 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6148 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6149 (const_string "incdec")
6150 (const_string "alu")))
6151 (set (attr "length_immediate")
6153 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6155 (const_string "*")))
6156 (set_attr "mode" "<MODE>")])
6158 (define_insn "*addqi_ext_1_rex64"
6159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6164 (match_operand 1 "ext_register_operand" "0")
6167 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6168 (clobber (reg:CC FLAGS_REG))]
6171 switch (get_attr_type (insn))
6174 if (operands[2] == const1_rtx)
6175 return "inc{b}\t%h0";
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{b}\t%h0";
6183 return "add{b}\t{%2, %h0|%h0, %2}";
6187 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set_attr "modrm" "1")
6191 (set_attr "mode" "QI")])
6193 (define_insn "addqi_ext_1"
6194 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6199 (match_operand 1 "ext_register_operand" "0")
6202 (match_operand:QI 2 "general_operand" "Qmn")))
6203 (clobber (reg:CC FLAGS_REG))]
6206 switch (get_attr_type (insn))
6209 if (operands[2] == const1_rtx)
6210 return "inc{b}\t%h0";
6213 gcc_assert (operands[2] == constm1_rtx);
6214 return "dec{b}\t%h0";
6218 return "add{b}\t{%2, %h0|%h0, %2}";
6222 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6223 (const_string "incdec")
6224 (const_string "alu")))
6225 (set_attr "modrm" "1")
6226 (set_attr "mode" "QI")])
6228 (define_insn "*addqi_ext_2"
6229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6234 (match_operand 1 "ext_register_operand" "%0")
6238 (match_operand 2 "ext_register_operand" "Q")
6241 (clobber (reg:CC FLAGS_REG))]
6243 "add{b}\t{%h2, %h0|%h0, %h2}"
6244 [(set_attr "type" "alu")
6245 (set_attr "mode" "QI")])
6247 ;; The lea patterns for non-Pmodes needs to be matched by
6248 ;; several insns converted to real lea by splitters.
6250 (define_insn_and_split "*lea_general_1"
6251 [(set (match_operand 0 "register_operand" "=r")
6252 (plus (plus (match_operand 1 "index_register_operand" "l")
6253 (match_operand 2 "register_operand" "r"))
6254 (match_operand 3 "immediate_operand" "i")))]
6255 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6256 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6257 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6258 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6259 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6260 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6261 || GET_MODE (operands[3]) == VOIDmode)"
6263 "&& reload_completed"
6267 operands[0] = gen_lowpart (SImode, operands[0]);
6268 operands[1] = gen_lowpart (Pmode, operands[1]);
6269 operands[2] = gen_lowpart (Pmode, operands[2]);
6270 operands[3] = gen_lowpart (Pmode, operands[3]);
6271 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6273 if (Pmode != SImode)
6274 pat = gen_rtx_SUBREG (SImode, pat, 0);
6275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6278 [(set_attr "type" "lea")
6279 (set_attr "mode" "SI")])
6281 (define_insn_and_split "*lea_general_1_zext"
6282 [(set (match_operand:DI 0 "register_operand" "=r")
6285 (match_operand:SI 1 "index_register_operand" "l")
6286 (match_operand:SI 2 "register_operand" "r"))
6287 (match_operand:SI 3 "immediate_operand" "i"))))]
6290 "&& reload_completed"
6292 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6294 (match_dup 3)) 0)))]
6296 operands[1] = gen_lowpart (Pmode, operands[1]);
6297 operands[2] = gen_lowpart (Pmode, operands[2]);
6298 operands[3] = gen_lowpart (Pmode, operands[3]);
6300 [(set_attr "type" "lea")
6301 (set_attr "mode" "SI")])
6303 (define_insn_and_split "*lea_general_2"
6304 [(set (match_operand 0 "register_operand" "=r")
6305 (plus (mult (match_operand 1 "index_register_operand" "l")
6306 (match_operand 2 "const248_operand" "i"))
6307 (match_operand 3 "nonmemory_operand" "ri")))]
6308 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6309 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6310 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6311 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6312 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6313 || GET_MODE (operands[3]) == VOIDmode)"
6315 "&& reload_completed"
6319 operands[0] = gen_lowpart (SImode, operands[0]);
6320 operands[1] = gen_lowpart (Pmode, operands[1]);
6321 operands[3] = gen_lowpart (Pmode, operands[3]);
6322 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6324 if (Pmode != SImode)
6325 pat = gen_rtx_SUBREG (SImode, pat, 0);
6326 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6329 [(set_attr "type" "lea")
6330 (set_attr "mode" "SI")])
6332 (define_insn_and_split "*lea_general_2_zext"
6333 [(set (match_operand:DI 0 "register_operand" "=r")
6336 (match_operand:SI 1 "index_register_operand" "l")
6337 (match_operand:SI 2 "const248_operand" "n"))
6338 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6341 "&& reload_completed"
6343 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6345 (match_dup 3)) 0)))]
6347 operands[1] = gen_lowpart (Pmode, operands[1]);
6348 operands[3] = gen_lowpart (Pmode, operands[3]);
6350 [(set_attr "type" "lea")
6351 (set_attr "mode" "SI")])
6353 (define_insn_and_split "*lea_general_3"
6354 [(set (match_operand 0 "register_operand" "=r")
6355 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6356 (match_operand 2 "const248_operand" "i"))
6357 (match_operand 3 "register_operand" "r"))
6358 (match_operand 4 "immediate_operand" "i")))]
6359 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6360 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6361 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6362 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6363 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6365 "&& reload_completed"
6369 operands[0] = gen_lowpart (SImode, operands[0]);
6370 operands[1] = gen_lowpart (Pmode, operands[1]);
6371 operands[3] = gen_lowpart (Pmode, operands[3]);
6372 operands[4] = gen_lowpart (Pmode, operands[4]);
6373 pat = gen_rtx_PLUS (Pmode,
6374 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6378 if (Pmode != SImode)
6379 pat = gen_rtx_SUBREG (SImode, pat, 0);
6380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6383 [(set_attr "type" "lea")
6384 (set_attr "mode" "SI")])
6386 (define_insn_and_split "*lea_general_3_zext"
6387 [(set (match_operand:DI 0 "register_operand" "=r")
6391 (match_operand:SI 1 "index_register_operand" "l")
6392 (match_operand:SI 2 "const248_operand" "n"))
6393 (match_operand:SI 3 "register_operand" "r"))
6394 (match_operand:SI 4 "immediate_operand" "i"))))]
6397 "&& reload_completed"
6399 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6402 (match_dup 4)) 0)))]
6404 operands[1] = gen_lowpart (Pmode, operands[1]);
6405 operands[3] = gen_lowpart (Pmode, operands[3]);
6406 operands[4] = gen_lowpart (Pmode, operands[4]);
6408 [(set_attr "type" "lea")
6409 (set_attr "mode" "SI")])
6411 (define_insn_and_split "*lea_general_4"
6412 [(set (match_operand:SWI 0 "register_operand" "=r")
6413 (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l")
6414 (match_operand:SWI 2 "const_int_operand" "n"))
6415 (match_operand 3 "const_int_operand" "n")))]
6416 "(<MODE>mode == DImode
6417 || <MODE>mode == SImode
6418 || !TARGET_PARTIAL_REG_STALL
6419 || optimize_function_for_size_p (cfun))
6420 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6421 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6422 <= ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6424 "&& reload_completed"
6428 if (<MODE>mode != DImode)
6429 operands[0] = gen_lowpart (SImode, operands[0]);
6430 operands[1] = gen_lowpart (Pmode, operands[1]);
6431 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6432 pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]),
6433 INTVAL (operands[3]));
6434 if (Pmode != SImode && <MODE>mode != DImode)
6435 pat = gen_rtx_SUBREG (SImode, pat, 0);
6436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6439 [(set_attr "type" "lea")
6441 (if_then_else (eq (symbol_ref "<MODE>mode == DImode") (const_int 0))
6443 (const_string "DI")))])
6445 ;; Subtract instructions
6447 (define_expand "sub<mode>3"
6448 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6449 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6450 (match_operand:SDWIM 2 "<general_operand>" "")))]
6452 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6454 (define_insn_and_split "*sub<dwi>3_doubleword"
6455 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6457 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6458 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6459 (clobber (reg:CC FLAGS_REG))]
6460 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6463 [(parallel [(set (reg:CC FLAGS_REG)
6464 (compare:CC (match_dup 1) (match_dup 2)))
6466 (minus:DWIH (match_dup 1) (match_dup 2)))])
6467 (parallel [(set (match_dup 3)
6471 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6473 (clobber (reg:CC FLAGS_REG))])]
6474 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6476 (define_insn "*sub<mode>_1"
6477 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6479 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6480 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6481 (clobber (reg:CC FLAGS_REG))]
6482 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6483 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6484 [(set_attr "type" "alu")
6485 (set_attr "mode" "<MODE>")])
6487 (define_insn "*subsi_1_zext"
6488 [(set (match_operand:DI 0 "register_operand" "=r")
6490 (minus:SI (match_operand:SI 1 "register_operand" "0")
6491 (match_operand:SI 2 "general_operand" "g"))))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494 "sub{l}\t{%2, %k0|%k0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "mode" "SI")])
6498 (define_insn "*subqi_1_slp"
6499 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6500 (minus:QI (match_dup 0)
6501 (match_operand:QI 1 "general_operand" "qn,qm")))
6502 (clobber (reg:CC FLAGS_REG))]
6503 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6505 "sub{b}\t{%1, %0|%0, %1}"
6506 [(set_attr "type" "alu1")
6507 (set_attr "mode" "QI")])
6509 (define_insn "*sub<mode>_2"
6510 [(set (reg FLAGS_REG)
6513 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6514 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6516 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6517 (minus:SWI (match_dup 1) (match_dup 2)))]
6518 "ix86_match_ccmode (insn, CCGOCmode)
6519 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6520 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "<MODE>")])
6524 (define_insn "*subsi_2_zext"
6525 [(set (reg FLAGS_REG)
6527 (minus:SI (match_operand:SI 1 "register_operand" "0")
6528 (match_operand:SI 2 "general_operand" "g"))
6530 (set (match_operand:DI 0 "register_operand" "=r")
6532 (minus:SI (match_dup 1)
6534 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6535 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6536 "sub{l}\t{%2, %k0|%k0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "mode" "SI")])
6540 (define_insn "*sub<mode>_3"
6541 [(set (reg FLAGS_REG)
6542 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6543 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6545 (minus:SWI (match_dup 1) (match_dup 2)))]
6546 "ix86_match_ccmode (insn, CCmode)
6547 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6548 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6549 [(set_attr "type" "alu")
6550 (set_attr "mode" "<MODE>")])
6552 (define_insn "*subsi_3_zext"
6553 [(set (reg FLAGS_REG)
6554 (compare (match_operand:SI 1 "register_operand" "0")
6555 (match_operand:SI 2 "general_operand" "g")))
6556 (set (match_operand:DI 0 "register_operand" "=r")
6558 (minus:SI (match_dup 1)
6560 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6561 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6562 "sub{l}\t{%2, %1|%1, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "mode" "SI")])
6566 ;; Add with carry and subtract with borrow
6568 (define_expand "<plusminus_insn><mode>3_carry"
6570 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6572 (match_operand:SWI 1 "nonimmediate_operand" "")
6573 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6574 [(match_operand 3 "flags_reg_operand" "")
6576 (match_operand:SWI 2 "<general_operand>" ""))))
6577 (clobber (reg:CC FLAGS_REG))])]
6578 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6580 (define_insn "*<plusminus_insn><mode>3_carry"
6581 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6583 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6585 (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6590 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "use_carry" "1")
6593 (set_attr "pent_pair" "pu")
6594 (set_attr "mode" "<MODE>")])
6596 (define_insn "*addsi3_carry_zext"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6599 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6600 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601 [(reg FLAGS_REG) (const_int 0)])
6602 (match_operand:SI 2 "general_operand" "g")))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6605 "adc{l}\t{%2, %k0|%k0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "use_carry" "1")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6611 (define_insn "*subsi3_carry_zext"
6612 [(set (match_operand:DI 0 "register_operand" "=r")
6614 (minus:SI (match_operand:SI 1 "register_operand" "0")
6615 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6616 [(reg FLAGS_REG) (const_int 0)])
6617 (match_operand:SI 2 "general_operand" "g")))))
6618 (clobber (reg:CC FLAGS_REG))]
6619 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6620 "sbb{l}\t{%2, %k0|%k0, %2}"
6621 [(set_attr "type" "alu")
6622 (set_attr "pent_pair" "pu")
6623 (set_attr "mode" "SI")])
6625 ;; Overflow setting add and subtract instructions
6627 (define_insn "*add<mode>3_cconly_overflow"
6628 [(set (reg:CCC FLAGS_REG)
6631 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6632 (match_operand:SWI 2 "<general_operand>" "<g>"))
6634 (clobber (match_scratch:SWI 0 "=<r>"))]
6635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6636 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "mode" "<MODE>")])
6640 (define_insn "*sub<mode>3_cconly_overflow"
6641 [(set (reg:CCC FLAGS_REG)
6644 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6645 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6648 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6649 [(set_attr "type" "icmp")
6650 (set_attr "mode" "<MODE>")])
6652 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6653 [(set (reg:CCC FLAGS_REG)
6656 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6657 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6659 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6660 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6661 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6662 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "mode" "<MODE>")])
6666 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6667 [(set (reg:CCC FLAGS_REG)
6670 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6671 (match_operand:SI 2 "general_operand" "g"))
6673 (set (match_operand:DI 0 "register_operand" "=r")
6674 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6675 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6676 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6677 [(set_attr "type" "alu")
6678 (set_attr "mode" "SI")])
6680 ;; The patterns that match these are at the end of this file.
6682 (define_expand "<plusminus_insn>xf3"
6683 [(set (match_operand:XF 0 "register_operand" "")
6685 (match_operand:XF 1 "register_operand" "")
6686 (match_operand:XF 2 "register_operand" "")))]
6689 (define_expand "<plusminus_insn><mode>3"
6690 [(set (match_operand:MODEF 0 "register_operand" "")
6692 (match_operand:MODEF 1 "register_operand" "")
6693 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6694 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6695 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6697 ;; Multiply instructions
6699 (define_expand "mul<mode>3"
6700 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6702 (match_operand:SWIM248 1 "register_operand" "")
6703 (match_operand:SWIM248 2 "<general_operand>" "")))
6704 (clobber (reg:CC FLAGS_REG))])])
6706 (define_expand "mulqi3"
6707 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6709 (match_operand:QI 1 "register_operand" "")
6710 (match_operand:QI 2 "nonimmediate_operand" "")))
6711 (clobber (reg:CC FLAGS_REG))])]
6712 "TARGET_QIMODE_MATH")
6715 ;; IMUL reg32/64, reg32/64, imm8 Direct
6716 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6717 ;; IMUL reg32/64, reg32/64, imm32 Direct
6718 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6719 ;; IMUL reg32/64, reg32/64 Direct
6720 ;; IMUL reg32/64, mem32/64 Direct
6722 ;; On BDVER1, all above IMULs use DirectPath
6724 (define_insn "*mul<mode>3_1"
6725 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6727 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6728 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6729 (clobber (reg:CC FLAGS_REG))]
6730 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6732 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6733 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6734 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6735 [(set_attr "type" "imul")
6736 (set_attr "prefix_0f" "0,0,1")
6737 (set (attr "athlon_decode")
6738 (cond [(eq_attr "cpu" "athlon")
6739 (const_string "vector")
6740 (eq_attr "alternative" "1")
6741 (const_string "vector")
6742 (and (eq_attr "alternative" "2")
6743 (match_operand 1 "memory_operand" ""))
6744 (const_string "vector")]
6745 (const_string "direct")))
6746 (set (attr "amdfam10_decode")
6747 (cond [(and (eq_attr "alternative" "0,1")
6748 (match_operand 1 "memory_operand" ""))
6749 (const_string "vector")]
6750 (const_string "direct")))
6751 (set_attr "bdver1_decode" "direct")
6752 (set_attr "mode" "<MODE>")])
6754 (define_insn "*mulsi3_1_zext"
6755 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6757 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6758 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6759 (clobber (reg:CC FLAGS_REG))]
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6764 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6765 imul{l}\t{%2, %k0|%k0, %2}"
6766 [(set_attr "type" "imul")
6767 (set_attr "prefix_0f" "0,0,1")
6768 (set (attr "athlon_decode")
6769 (cond [(eq_attr "cpu" "athlon")
6770 (const_string "vector")
6771 (eq_attr "alternative" "1")
6772 (const_string "vector")
6773 (and (eq_attr "alternative" "2")
6774 (match_operand 1 "memory_operand" ""))
6775 (const_string "vector")]
6776 (const_string "direct")))
6777 (set (attr "amdfam10_decode")
6778 (cond [(and (eq_attr "alternative" "0,1")
6779 (match_operand 1 "memory_operand" ""))
6780 (const_string "vector")]
6781 (const_string "direct")))
6782 (set_attr "bdver1_decode" "direct")
6783 (set_attr "mode" "SI")])
6786 ;; IMUL reg16, reg16, imm8 VectorPath
6787 ;; IMUL reg16, mem16, imm8 VectorPath
6788 ;; IMUL reg16, reg16, imm16 VectorPath
6789 ;; IMUL reg16, mem16, imm16 VectorPath
6790 ;; IMUL reg16, reg16 Direct
6791 ;; IMUL reg16, mem16 Direct
6793 ;; On BDVER1, all HI MULs use DoublePath
6795 (define_insn "*mulhi3_1"
6796 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6797 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6798 (match_operand:HI 2 "general_operand" "K,n,mr")))
6799 (clobber (reg:CC FLAGS_REG))]
6801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 imul{w}\t{%2, %1, %0|%0, %1, %2}
6804 imul{w}\t{%2, %1, %0|%0, %1, %2}
6805 imul{w}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "imul")
6807 (set_attr "prefix_0f" "0,0,1")
6808 (set (attr "athlon_decode")
6809 (cond [(eq_attr "cpu" "athlon")
6810 (const_string "vector")
6811 (eq_attr "alternative" "1,2")
6812 (const_string "vector")]
6813 (const_string "direct")))
6814 (set (attr "amdfam10_decode")
6815 (cond [(eq_attr "alternative" "0,1")
6816 (const_string "vector")]
6817 (const_string "direct")))
6818 (set_attr "bdver1_decode" "double")
6819 (set_attr "mode" "HI")])
6821 ;;On AMDFAM10 and BDVER1
6825 (define_insn "*mulqi3_1"
6826 [(set (match_operand:QI 0 "register_operand" "=a")
6827 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6828 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6829 (clobber (reg:CC FLAGS_REG))]
6831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6833 [(set_attr "type" "imul")
6834 (set_attr "length_immediate" "0")
6835 (set (attr "athlon_decode")
6836 (if_then_else (eq_attr "cpu" "athlon")
6837 (const_string "vector")
6838 (const_string "direct")))
6839 (set_attr "amdfam10_decode" "direct")
6840 (set_attr "bdver1_decode" "direct")
6841 (set_attr "mode" "QI")])
6843 (define_expand "<u>mul<mode><dwi>3"
6844 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6847 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6849 (match_operand:DWIH 2 "register_operand" ""))))
6850 (clobber (reg:CC FLAGS_REG))])])
6852 (define_expand "<u>mulqihi3"
6853 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6856 (match_operand:QI 1 "nonimmediate_operand" ""))
6858 (match_operand:QI 2 "register_operand" ""))))
6859 (clobber (reg:CC FLAGS_REG))])]
6860 "TARGET_QIMODE_MATH")
6862 (define_insn "*<u>mul<mode><dwi>3_1"
6863 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6866 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6868 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6869 (clobber (reg:CC FLAGS_REG))]
6870 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6871 "<sgnprefix>mul{<imodesuffix>}\t%2"
6872 [(set_attr "type" "imul")
6873 (set_attr "length_immediate" "0")
6874 (set (attr "athlon_decode")
6875 (if_then_else (eq_attr "cpu" "athlon")
6876 (const_string "vector")
6877 (const_string "double")))
6878 (set_attr "amdfam10_decode" "double")
6879 (set_attr "bdver1_decode" "direct")
6880 (set_attr "mode" "<MODE>")])
6882 (define_insn "*<u>mulqihi3_1"
6883 [(set (match_operand:HI 0 "register_operand" "=a")
6886 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6888 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6889 (clobber (reg:CC FLAGS_REG))]
6891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6892 "<sgnprefix>mul{b}\t%2"
6893 [(set_attr "type" "imul")
6894 (set_attr "length_immediate" "0")
6895 (set (attr "athlon_decode")
6896 (if_then_else (eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (const_string "direct")))
6899 (set_attr "amdfam10_decode" "direct")
6900 (set_attr "bdver1_decode" "direct")
6901 (set_attr "mode" "QI")])
6903 (define_expand "<s>mul<mode>3_highpart"
6904 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6909 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6911 (match_operand:SWI48 2 "register_operand" "")))
6913 (clobber (match_scratch:SWI48 3 ""))
6914 (clobber (reg:CC FLAGS_REG))])]
6916 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6918 (define_insn "*<s>muldi3_highpart_1"
6919 [(set (match_operand:DI 0 "register_operand" "=d")
6924 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6926 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6928 (clobber (match_scratch:DI 3 "=1"))
6929 (clobber (reg:CC FLAGS_REG))]
6931 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6932 "<sgnprefix>mul{q}\t%2"
6933 [(set_attr "type" "imul")
6934 (set_attr "length_immediate" "0")
6935 (set (attr "athlon_decode")
6936 (if_then_else (eq_attr "cpu" "athlon")
6937 (const_string "vector")
6938 (const_string "double")))
6939 (set_attr "amdfam10_decode" "double")
6940 (set_attr "bdver1_decode" "direct")
6941 (set_attr "mode" "DI")])
6943 (define_insn "*<s>mulsi3_highpart_1"
6944 [(set (match_operand:SI 0 "register_operand" "=d")
6949 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6951 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6953 (clobber (match_scratch:SI 3 "=1"))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6956 "<sgnprefix>mul{l}\t%2"
6957 [(set_attr "type" "imul")
6958 (set_attr "length_immediate" "0")
6959 (set (attr "athlon_decode")
6960 (if_then_else (eq_attr "cpu" "athlon")
6961 (const_string "vector")
6962 (const_string "double")))
6963 (set_attr "amdfam10_decode" "double")
6964 (set_attr "bdver1_decode" "direct")
6965 (set_attr "mode" "SI")])
6967 (define_insn "*<s>mulsi3_highpart_zext"
6968 [(set (match_operand:DI 0 "register_operand" "=d")
6969 (zero_extend:DI (truncate:SI
6971 (mult:DI (any_extend:DI
6972 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6974 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6976 (clobber (match_scratch:SI 3 "=1"))
6977 (clobber (reg:CC FLAGS_REG))]
6979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6980 "<sgnprefix>mul{l}\t%2"
6981 [(set_attr "type" "imul")
6982 (set_attr "length_immediate" "0")
6983 (set (attr "athlon_decode")
6984 (if_then_else (eq_attr "cpu" "athlon")
6985 (const_string "vector")
6986 (const_string "double")))
6987 (set_attr "amdfam10_decode" "double")
6988 (set_attr "bdver1_decode" "direct")
6989 (set_attr "mode" "SI")])
6991 ;; The patterns that match these are at the end of this file.
6993 (define_expand "mulxf3"
6994 [(set (match_operand:XF 0 "register_operand" "")
6995 (mult:XF (match_operand:XF 1 "register_operand" "")
6996 (match_operand:XF 2 "register_operand" "")))]
6999 (define_expand "mul<mode>3"
7000 [(set (match_operand:MODEF 0 "register_operand" "")
7001 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7002 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7003 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7004 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7006 ;; Divide instructions
7008 ;; The patterns that match these are at the end of this file.
7010 (define_expand "divxf3"
7011 [(set (match_operand:XF 0 "register_operand" "")
7012 (div:XF (match_operand:XF 1 "register_operand" "")
7013 (match_operand:XF 2 "register_operand" "")))]
7016 (define_expand "divdf3"
7017 [(set (match_operand:DF 0 "register_operand" "")
7018 (div:DF (match_operand:DF 1 "register_operand" "")
7019 (match_operand:DF 2 "nonimmediate_operand" "")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7021 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7023 (define_expand "divsf3"
7024 [(set (match_operand:SF 0 "register_operand" "")
7025 (div:SF (match_operand:SF 1 "register_operand" "")
7026 (match_operand:SF 2 "nonimmediate_operand" "")))]
7027 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7030 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7031 && flag_finite_math_only && !flag_trapping_math
7032 && flag_unsafe_math_optimizations)
7034 ix86_emit_swdivsf (operands[0], operands[1],
7035 operands[2], SFmode);
7040 ;; Divmod instructions.
7042 (define_expand "divmod<mode>4"
7043 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7045 (match_operand:SWIM248 1 "register_operand" "")
7046 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7047 (set (match_operand:SWIM248 3 "register_operand" "")
7048 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7049 (clobber (reg:CC FLAGS_REG))])])
7051 ;; Split with 8bit unsigned divide:
7052 ;; if (dividend an divisor are in [0-255])
7053 ;; use 8bit unsigned integer divide
7055 ;; use original integer divide
7057 [(set (match_operand:SWI48 0 "register_operand" "")
7058 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7059 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7060 (set (match_operand:SWI48 1 "register_operand" "")
7061 (mod:SWI48 (match_dup 2) (match_dup 3)))
7062 (clobber (reg:CC FLAGS_REG))]
7063 "TARGET_USE_8BIT_IDIV
7064 && TARGET_QIMODE_MATH
7065 && can_create_pseudo_p ()
7066 && !optimize_insn_for_size_p ()"
7068 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7070 (define_insn_and_split "divmod<mode>4_1"
7071 [(set (match_operand:SWI48 0 "register_operand" "=a")
7072 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7073 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7074 (set (match_operand:SWI48 1 "register_operand" "=&d")
7075 (mod:SWI48 (match_dup 2) (match_dup 3)))
7076 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7077 (clobber (reg:CC FLAGS_REG))]
7081 [(parallel [(set (match_dup 1)
7082 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7083 (clobber (reg:CC FLAGS_REG))])
7084 (parallel [(set (match_dup 0)
7085 (div:SWI48 (match_dup 2) (match_dup 3)))
7087 (mod:SWI48 (match_dup 2) (match_dup 3)))
7089 (clobber (reg:CC FLAGS_REG))])]
7091 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7093 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7094 operands[4] = operands[2];
7097 /* Avoid use of cltd in favor of a mov+shift. */
7098 emit_move_insn (operands[1], operands[2]);
7099 operands[4] = operands[1];
7102 [(set_attr "type" "multi")
7103 (set_attr "mode" "<MODE>")])
7105 (define_insn_and_split "*divmod<mode>4"
7106 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7107 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7108 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7109 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7110 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7111 (clobber (reg:CC FLAGS_REG))]
7115 [(parallel [(set (match_dup 1)
7116 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7117 (clobber (reg:CC FLAGS_REG))])
7118 (parallel [(set (match_dup 0)
7119 (div:SWIM248 (match_dup 2) (match_dup 3)))
7121 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7123 (clobber (reg:CC FLAGS_REG))])]
7125 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7127 if (<MODE>mode != HImode
7128 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7129 operands[4] = operands[2];
7132 /* Avoid use of cltd in favor of a mov+shift. */
7133 emit_move_insn (operands[1], operands[2]);
7134 operands[4] = operands[1];
7137 [(set_attr "type" "multi")
7138 (set_attr "mode" "<MODE>")])
7140 (define_insn "*divmod<mode>4_noext"
7141 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7142 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7143 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7144 (set (match_operand:SWIM248 1 "register_operand" "=d")
7145 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7146 (use (match_operand:SWIM248 4 "register_operand" "1"))
7147 (clobber (reg:CC FLAGS_REG))]
7149 "idiv{<imodesuffix>}\t%3"
7150 [(set_attr "type" "idiv")
7151 (set_attr "mode" "<MODE>")])
7153 (define_expand "divmodqi4"
7154 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7156 (match_operand:QI 1 "register_operand" "")
7157 (match_operand:QI 2 "nonimmediate_operand" "")))
7158 (set (match_operand:QI 3 "register_operand" "")
7159 (mod:QI (match_dup 1) (match_dup 2)))
7160 (clobber (reg:CC FLAGS_REG))])]
7161 "TARGET_QIMODE_MATH"
7166 tmp0 = gen_reg_rtx (HImode);
7167 tmp1 = gen_reg_rtx (HImode);
7169 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7171 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7172 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7174 /* Extract remainder from AH. */
7175 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7176 insn = emit_move_insn (operands[3], tmp1);
7178 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7179 set_unique_reg_note (insn, REG_EQUAL, mod);
7181 /* Extract quotient from AL. */
7182 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7184 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7185 set_unique_reg_note (insn, REG_EQUAL, div);
7190 ;; Divide AX by r/m8, with result stored in
7193 ;; Change div/mod to HImode and extend the second argument to HImode
7194 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7195 ;; combine may fail.
7196 (define_insn "divmodhiqi3"
7197 [(set (match_operand:HI 0 "register_operand" "=a")
7202 (mod:HI (match_operand:HI 1 "register_operand" "0")
7204 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7208 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "TARGET_QIMODE_MATH"
7212 [(set_attr "type" "idiv")
7213 (set_attr "mode" "QI")])
7215 (define_expand "udivmod<mode>4"
7216 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7218 (match_operand:SWIM248 1 "register_operand" "")
7219 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7220 (set (match_operand:SWIM248 3 "register_operand" "")
7221 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7222 (clobber (reg:CC FLAGS_REG))])])
7224 ;; Split with 8bit unsigned divide:
7225 ;; if (dividend an divisor are in [0-255])
7226 ;; use 8bit unsigned integer divide
7228 ;; use original integer divide
7230 [(set (match_operand:SWI48 0 "register_operand" "")
7231 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7232 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7233 (set (match_operand:SWI48 1 "register_operand" "")
7234 (umod:SWI48 (match_dup 2) (match_dup 3)))
7235 (clobber (reg:CC FLAGS_REG))]
7236 "TARGET_USE_8BIT_IDIV
7237 && TARGET_QIMODE_MATH
7238 && can_create_pseudo_p ()
7239 && !optimize_insn_for_size_p ()"
7241 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7243 (define_insn_and_split "udivmod<mode>4_1"
7244 [(set (match_operand:SWI48 0 "register_operand" "=a")
7245 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7246 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7247 (set (match_operand:SWI48 1 "register_operand" "=&d")
7248 (umod:SWI48 (match_dup 2) (match_dup 3)))
7249 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7250 (clobber (reg:CC FLAGS_REG))]
7254 [(set (match_dup 1) (const_int 0))
7255 (parallel [(set (match_dup 0)
7256 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7258 (umod:SWI48 (match_dup 2) (match_dup 3)))
7260 (clobber (reg:CC FLAGS_REG))])]
7262 [(set_attr "type" "multi")
7263 (set_attr "mode" "<MODE>")])
7265 (define_insn_and_split "*udivmod<mode>4"
7266 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7267 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7268 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7269 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7270 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7271 (clobber (reg:CC FLAGS_REG))]
7275 [(set (match_dup 1) (const_int 0))
7276 (parallel [(set (match_dup 0)
7277 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7279 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7281 (clobber (reg:CC FLAGS_REG))])]
7283 [(set_attr "type" "multi")
7284 (set_attr "mode" "<MODE>")])
7286 (define_insn "*udivmod<mode>4_noext"
7287 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7288 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7289 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7290 (set (match_operand:SWIM248 1 "register_operand" "=d")
7291 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7292 (use (match_operand:SWIM248 4 "register_operand" "1"))
7293 (clobber (reg:CC FLAGS_REG))]
7295 "div{<imodesuffix>}\t%3"
7296 [(set_attr "type" "idiv")
7297 (set_attr "mode" "<MODE>")])
7299 (define_expand "udivmodqi4"
7300 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7302 (match_operand:QI 1 "register_operand" "")
7303 (match_operand:QI 2 "nonimmediate_operand" "")))
7304 (set (match_operand:QI 3 "register_operand" "")
7305 (umod:QI (match_dup 1) (match_dup 2)))
7306 (clobber (reg:CC FLAGS_REG))])]
7307 "TARGET_QIMODE_MATH"
7312 tmp0 = gen_reg_rtx (HImode);
7313 tmp1 = gen_reg_rtx (HImode);
7315 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7317 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7318 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7320 /* Extract remainder from AH. */
7321 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7322 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7323 insn = emit_move_insn (operands[3], tmp1);
7325 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7326 set_unique_reg_note (insn, REG_EQUAL, mod);
7328 /* Extract quotient from AL. */
7329 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7331 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7332 set_unique_reg_note (insn, REG_EQUAL, div);
7337 (define_insn "udivmodhiqi3"
7338 [(set (match_operand:HI 0 "register_operand" "=a")
7343 (mod:HI (match_operand:HI 1 "register_operand" "0")
7345 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7349 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7350 (clobber (reg:CC FLAGS_REG))]
7351 "TARGET_QIMODE_MATH"
7353 [(set_attr "type" "idiv")
7354 (set_attr "mode" "QI")])
7356 ;; We cannot use div/idiv for double division, because it causes
7357 ;; "division by zero" on the overflow and that's not what we expect
7358 ;; from truncate. Because true (non truncating) double division is
7359 ;; never generated, we can't create this insn anyway.
7362 ; [(set (match_operand:SI 0 "register_operand" "=a")
7364 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7366 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7367 ; (set (match_operand:SI 3 "register_operand" "=d")
7369 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7370 ; (clobber (reg:CC FLAGS_REG))]
7372 ; "div{l}\t{%2, %0|%0, %2}"
7373 ; [(set_attr "type" "idiv")])
7375 ;;- Logical AND instructions
7377 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7378 ;; Note that this excludes ah.
7380 (define_expand "testsi_ccno_1"
7381 [(set (reg:CCNO FLAGS_REG)
7383 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7384 (match_operand:SI 1 "nonmemory_operand" ""))
7387 (define_expand "testqi_ccz_1"
7388 [(set (reg:CCZ FLAGS_REG)
7389 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7390 (match_operand:QI 1 "nonmemory_operand" ""))
7393 (define_expand "testdi_ccno_1"
7394 [(set (reg:CCNO FLAGS_REG)
7396 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7397 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7399 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7401 (define_insn "*testdi_1"
7402 [(set (reg FLAGS_REG)
7405 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7406 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7408 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7409 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7411 test{l}\t{%k1, %k0|%k0, %k1}
7412 test{l}\t{%k1, %k0|%k0, %k1}
7413 test{q}\t{%1, %0|%0, %1}
7414 test{q}\t{%1, %0|%0, %1}
7415 test{q}\t{%1, %0|%0, %1}"
7416 [(set_attr "type" "test")
7417 (set_attr "modrm" "0,1,0,1,1")
7418 (set_attr "mode" "SI,SI,DI,DI,DI")])
7420 (define_insn "*testqi_1_maybe_si"
7421 [(set (reg FLAGS_REG)
7424 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7425 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7427 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7428 && ix86_match_ccmode (insn,
7429 CONST_INT_P (operands[1])
7430 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7432 if (which_alternative == 3)
7434 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7435 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7436 return "test{l}\t{%1, %k0|%k0, %1}";
7438 return "test{b}\t{%1, %0|%0, %1}";
7440 [(set_attr "type" "test")
7441 (set_attr "modrm" "0,1,1,1")
7442 (set_attr "mode" "QI,QI,QI,SI")
7443 (set_attr "pent_pair" "uv,np,uv,np")])
7445 (define_insn "*test<mode>_1"
7446 [(set (reg FLAGS_REG)
7449 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7450 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7452 "ix86_match_ccmode (insn, CCNOmode)
7453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7454 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7455 [(set_attr "type" "test")
7456 (set_attr "modrm" "0,1,1")
7457 (set_attr "mode" "<MODE>")
7458 (set_attr "pent_pair" "uv,np,uv")])
7460 (define_expand "testqi_ext_ccno_0"
7461 [(set (reg:CCNO FLAGS_REG)
7465 (match_operand 0 "ext_register_operand" "")
7468 (match_operand 1 "const_int_operand" ""))
7471 (define_insn "*testqi_ext_0"
7472 [(set (reg FLAGS_REG)
7476 (match_operand 0 "ext_register_operand" "Q")
7479 (match_operand 1 "const_int_operand" "n"))
7481 "ix86_match_ccmode (insn, CCNOmode)"
7482 "test{b}\t{%1, %h0|%h0, %1}"
7483 [(set_attr "type" "test")
7484 (set_attr "mode" "QI")
7485 (set_attr "length_immediate" "1")
7486 (set_attr "modrm" "1")
7487 (set_attr "pent_pair" "np")])
7489 (define_insn "*testqi_ext_1_rex64"
7490 [(set (reg FLAGS_REG)
7494 (match_operand 0 "ext_register_operand" "Q")
7498 (match_operand:QI 1 "register_operand" "Q")))
7500 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7501 "test{b}\t{%1, %h0|%h0, %1}"
7502 [(set_attr "type" "test")
7503 (set_attr "mode" "QI")])
7505 (define_insn "*testqi_ext_1"
7506 [(set (reg FLAGS_REG)
7510 (match_operand 0 "ext_register_operand" "Q")
7514 (match_operand:QI 1 "general_operand" "Qm")))
7516 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7517 "test{b}\t{%1, %h0|%h0, %1}"
7518 [(set_attr "type" "test")
7519 (set_attr "mode" "QI")])
7521 (define_insn "*testqi_ext_2"
7522 [(set (reg FLAGS_REG)
7526 (match_operand 0 "ext_register_operand" "Q")
7530 (match_operand 1 "ext_register_operand" "Q")
7534 "ix86_match_ccmode (insn, CCNOmode)"
7535 "test{b}\t{%h1, %h0|%h0, %h1}"
7536 [(set_attr "type" "test")
7537 (set_attr "mode" "QI")])
7539 (define_insn "*testqi_ext_3_rex64"
7540 [(set (reg FLAGS_REG)
7541 (compare (zero_extract:DI
7542 (match_operand 0 "nonimmediate_operand" "rm")
7543 (match_operand:DI 1 "const_int_operand" "")
7544 (match_operand:DI 2 "const_int_operand" ""))
7547 && ix86_match_ccmode (insn, CCNOmode)
7548 && INTVAL (operands[1]) > 0
7549 && INTVAL (operands[2]) >= 0
7550 /* Ensure that resulting mask is zero or sign extended operand. */
7551 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7552 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7553 && INTVAL (operands[1]) > 32))
7554 && (GET_MODE (operands[0]) == SImode
7555 || GET_MODE (operands[0]) == DImode
7556 || GET_MODE (operands[0]) == HImode
7557 || GET_MODE (operands[0]) == QImode)"
7560 ;; Combine likes to form bit extractions for some tests. Humor it.
7561 (define_insn "*testqi_ext_3"
7562 [(set (reg FLAGS_REG)
7563 (compare (zero_extract:SI
7564 (match_operand 0 "nonimmediate_operand" "rm")
7565 (match_operand:SI 1 "const_int_operand" "")
7566 (match_operand:SI 2 "const_int_operand" ""))
7568 "ix86_match_ccmode (insn, CCNOmode)
7569 && INTVAL (operands[1]) > 0
7570 && INTVAL (operands[2]) >= 0
7571 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7572 && (GET_MODE (operands[0]) == SImode
7573 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7574 || GET_MODE (operands[0]) == HImode
7575 || GET_MODE (operands[0]) == QImode)"
7579 [(set (match_operand 0 "flags_reg_operand" "")
7580 (match_operator 1 "compare_operator"
7582 (match_operand 2 "nonimmediate_operand" "")
7583 (match_operand 3 "const_int_operand" "")
7584 (match_operand 4 "const_int_operand" ""))
7586 "ix86_match_ccmode (insn, CCNOmode)"
7587 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7589 rtx val = operands[2];
7590 HOST_WIDE_INT len = INTVAL (operands[3]);
7591 HOST_WIDE_INT pos = INTVAL (operands[4]);
7593 enum machine_mode mode, submode;
7595 mode = GET_MODE (val);
7598 /* ??? Combine likes to put non-volatile mem extractions in QImode
7599 no matter the size of the test. So find a mode that works. */
7600 if (! MEM_VOLATILE_P (val))
7602 mode = smallest_mode_for_size (pos + len, MODE_INT);
7603 val = adjust_address (val, mode, 0);
7606 else if (GET_CODE (val) == SUBREG
7607 && (submode = GET_MODE (SUBREG_REG (val)),
7608 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7609 && pos + len <= GET_MODE_BITSIZE (submode)
7610 && GET_MODE_CLASS (submode) == MODE_INT)
7612 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7614 val = SUBREG_REG (val);
7616 else if (mode == HImode && pos + len <= 8)
7618 /* Small HImode tests can be converted to QImode. */
7620 val = gen_lowpart (QImode, val);
7623 if (len == HOST_BITS_PER_WIDE_INT)
7626 mask = ((HOST_WIDE_INT)1 << len) - 1;
7629 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7632 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7633 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7634 ;; this is relatively important trick.
7635 ;; Do the conversion only post-reload to avoid limiting of the register class
7638 [(set (match_operand 0 "flags_reg_operand" "")
7639 (match_operator 1 "compare_operator"
7640 [(and (match_operand 2 "register_operand" "")
7641 (match_operand 3 "const_int_operand" ""))
7644 && QI_REG_P (operands[2])
7645 && GET_MODE (operands[2]) != QImode
7646 && ((ix86_match_ccmode (insn, CCZmode)
7647 && !(INTVAL (operands[3]) & ~(255 << 8)))
7648 || (ix86_match_ccmode (insn, CCNOmode)
7649 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7652 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7655 "operands[2] = gen_lowpart (SImode, operands[2]);
7656 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7659 [(set (match_operand 0 "flags_reg_operand" "")
7660 (match_operator 1 "compare_operator"
7661 [(and (match_operand 2 "nonimmediate_operand" "")
7662 (match_operand 3 "const_int_operand" ""))
7665 && GET_MODE (operands[2]) != QImode
7666 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7667 && ((ix86_match_ccmode (insn, CCZmode)
7668 && !(INTVAL (operands[3]) & ~255))
7669 || (ix86_match_ccmode (insn, CCNOmode)
7670 && !(INTVAL (operands[3]) & ~127)))"
7672 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7674 "operands[2] = gen_lowpart (QImode, operands[2]);
7675 operands[3] = gen_lowpart (QImode, operands[3]);")
7677 ;; %%% This used to optimize known byte-wide and operations to memory,
7678 ;; and sometimes to QImode registers. If this is considered useful,
7679 ;; it should be done with splitters.
7681 (define_expand "and<mode>3"
7682 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7683 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7684 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7686 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7688 (define_insn "*anddi_1"
7689 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7691 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7692 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7693 (clobber (reg:CC FLAGS_REG))]
7694 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7696 switch (get_attr_type (insn))
7700 enum machine_mode mode;
7702 gcc_assert (CONST_INT_P (operands[2]));
7703 if (INTVAL (operands[2]) == 0xff)
7707 gcc_assert (INTVAL (operands[2]) == 0xffff);
7711 operands[1] = gen_lowpart (mode, operands[1]);
7713 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7715 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7720 if (get_attr_mode (insn) == MODE_SI)
7721 return "and{l}\t{%k2, %k0|%k0, %k2}";
7723 return "and{q}\t{%2, %0|%0, %2}";
7726 [(set_attr "type" "alu,alu,alu,imovx")
7727 (set_attr "length_immediate" "*,*,*,0")
7728 (set (attr "prefix_rex")
7730 (and (eq_attr "type" "imovx")
7731 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7732 (match_operand 1 "ext_QIreg_operand" "")))
7734 (const_string "*")))
7735 (set_attr "mode" "SI,DI,DI,SI")])
7737 (define_insn "*andsi_1"
7738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7739 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7740 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7741 (clobber (reg:CC FLAGS_REG))]
7742 "ix86_binary_operator_ok (AND, SImode, operands)"
7744 switch (get_attr_type (insn))
7748 enum machine_mode mode;
7750 gcc_assert (CONST_INT_P (operands[2]));
7751 if (INTVAL (operands[2]) == 0xff)
7755 gcc_assert (INTVAL (operands[2]) == 0xffff);
7759 operands[1] = gen_lowpart (mode, operands[1]);
7761 return "movz{bl|x}\t{%1, %0|%0, %1}";
7763 return "movz{wl|x}\t{%1, %0|%0, %1}";
7767 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7768 return "and{l}\t{%2, %0|%0, %2}";
7771 [(set_attr "type" "alu,alu,imovx")
7772 (set (attr "prefix_rex")
7774 (and (eq_attr "type" "imovx")
7775 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7776 (match_operand 1 "ext_QIreg_operand" "")))
7778 (const_string "*")))
7779 (set_attr "length_immediate" "*,*,0")
7780 (set_attr "mode" "SI")])
7782 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7783 (define_insn "*andsi_1_zext"
7784 [(set (match_operand:DI 0 "register_operand" "=r")
7786 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7787 (match_operand:SI 2 "general_operand" "g"))))
7788 (clobber (reg:CC FLAGS_REG))]
7789 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7790 "and{l}\t{%2, %k0|%k0, %2}"
7791 [(set_attr "type" "alu")
7792 (set_attr "mode" "SI")])
7794 (define_insn "*andhi_1"
7795 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7796 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7797 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7798 (clobber (reg:CC FLAGS_REG))]
7799 "ix86_binary_operator_ok (AND, HImode, operands)"
7801 switch (get_attr_type (insn))
7804 gcc_assert (CONST_INT_P (operands[2]));
7805 gcc_assert (INTVAL (operands[2]) == 0xff);
7806 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7809 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7811 return "and{w}\t{%2, %0|%0, %2}";
7814 [(set_attr "type" "alu,alu,imovx")
7815 (set_attr "length_immediate" "*,*,0")
7816 (set (attr "prefix_rex")
7818 (and (eq_attr "type" "imovx")
7819 (match_operand 1 "ext_QIreg_operand" ""))
7821 (const_string "*")))
7822 (set_attr "mode" "HI,HI,SI")])
7824 ;; %%% Potential partial reg stall on alternative 2. What to do?
7825 (define_insn "*andqi_1"
7826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7827 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7828 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7829 (clobber (reg:CC FLAGS_REG))]
7830 "ix86_binary_operator_ok (AND, QImode, operands)"
7832 and{b}\t{%2, %0|%0, %2}
7833 and{b}\t{%2, %0|%0, %2}
7834 and{l}\t{%k2, %k0|%k0, %k2}"
7835 [(set_attr "type" "alu")
7836 (set_attr "mode" "QI,QI,SI")])
7838 (define_insn "*andqi_1_slp"
7839 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7840 (and:QI (match_dup 0)
7841 (match_operand:QI 1 "general_operand" "qn,qmn")))
7842 (clobber (reg:CC FLAGS_REG))]
7843 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7844 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7845 "and{b}\t{%1, %0|%0, %1}"
7846 [(set_attr "type" "alu1")
7847 (set_attr "mode" "QI")])
7850 [(set (match_operand 0 "register_operand" "")
7852 (const_int -65536)))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7855 || optimize_function_for_size_p (cfun)"
7856 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7857 "operands[1] = gen_lowpart (HImode, operands[0]);")
7860 [(set (match_operand 0 "ext_register_operand" "")
7863 (clobber (reg:CC FLAGS_REG))]
7864 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7865 && reload_completed"
7866 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7867 "operands[1] = gen_lowpart (QImode, operands[0]);")
7870 [(set (match_operand 0 "ext_register_operand" "")
7872 (const_int -65281)))
7873 (clobber (reg:CC FLAGS_REG))]
7874 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7875 && reload_completed"
7876 [(parallel [(set (zero_extract:SI (match_dup 0)
7880 (zero_extract:SI (match_dup 0)
7883 (zero_extract:SI (match_dup 0)
7886 (clobber (reg:CC FLAGS_REG))])]
7887 "operands[0] = gen_lowpart (SImode, operands[0]);")
7889 (define_insn "*anddi_2"
7890 [(set (reg FLAGS_REG)
7893 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7894 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7896 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7897 (and:DI (match_dup 1) (match_dup 2)))]
7898 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7899 && ix86_binary_operator_ok (AND, DImode, operands)"
7901 and{l}\t{%k2, %k0|%k0, %k2}
7902 and{q}\t{%2, %0|%0, %2}
7903 and{q}\t{%2, %0|%0, %2}"
7904 [(set_attr "type" "alu")
7905 (set_attr "mode" "SI,DI,DI")])
7907 (define_insn "*andqi_2_maybe_si"
7908 [(set (reg FLAGS_REG)
7910 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7911 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7913 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7914 (and:QI (match_dup 1) (match_dup 2)))]
7915 "ix86_binary_operator_ok (AND, QImode, operands)
7916 && ix86_match_ccmode (insn,
7917 CONST_INT_P (operands[2])
7918 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7920 if (which_alternative == 2)
7922 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7923 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7924 return "and{l}\t{%2, %k0|%k0, %2}";
7926 return "and{b}\t{%2, %0|%0, %2}";
7928 [(set_attr "type" "alu")
7929 (set_attr "mode" "QI,QI,SI")])
7931 (define_insn "*and<mode>_2"
7932 [(set (reg FLAGS_REG)
7933 (compare (and:SWI124
7934 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7935 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7937 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7938 (and:SWI124 (match_dup 1) (match_dup 2)))]
7939 "ix86_match_ccmode (insn, CCNOmode)
7940 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7941 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "<MODE>")])
7945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7946 (define_insn "*andsi_2_zext"
7947 [(set (reg FLAGS_REG)
7949 (match_operand:SI 1 "nonimmediate_operand" "%0")
7950 (match_operand:SI 2 "general_operand" "g"))
7952 (set (match_operand:DI 0 "register_operand" "=r")
7953 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7955 && ix86_binary_operator_ok (AND, SImode, operands)"
7956 "and{l}\t{%2, %k0|%k0, %2}"
7957 [(set_attr "type" "alu")
7958 (set_attr "mode" "SI")])
7960 (define_insn "*andqi_2_slp"
7961 [(set (reg FLAGS_REG)
7963 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7964 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7966 (set (strict_low_part (match_dup 0))
7967 (and:QI (match_dup 0) (match_dup 1)))]
7968 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7969 && ix86_match_ccmode (insn, CCNOmode)
7970 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7971 "and{b}\t{%1, %0|%0, %1}"
7972 [(set_attr "type" "alu1")
7973 (set_attr "mode" "QI")])
7975 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7976 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7977 ;; for a QImode operand, which of course failed.
7978 (define_insn "andqi_ext_0"
7979 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7984 (match_operand 1 "ext_register_operand" "0")
7987 (match_operand 2 "const_int_operand" "n")))
7988 (clobber (reg:CC FLAGS_REG))]
7990 "and{b}\t{%2, %h0|%h0, %2}"
7991 [(set_attr "type" "alu")
7992 (set_attr "length_immediate" "1")
7993 (set_attr "modrm" "1")
7994 (set_attr "mode" "QI")])
7996 ;; Generated by peephole translating test to and. This shows up
7997 ;; often in fp comparisons.
7998 (define_insn "*andqi_ext_0_cc"
7999 [(set (reg FLAGS_REG)
8003 (match_operand 1 "ext_register_operand" "0")
8006 (match_operand 2 "const_int_operand" "n"))
8008 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8017 "ix86_match_ccmode (insn, CCNOmode)"
8018 "and{b}\t{%2, %h0|%h0, %2}"
8019 [(set_attr "type" "alu")
8020 (set_attr "length_immediate" "1")
8021 (set_attr "modrm" "1")
8022 (set_attr "mode" "QI")])
8024 (define_insn "*andqi_ext_1_rex64"
8025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8030 (match_operand 1 "ext_register_operand" "0")
8034 (match_operand 2 "ext_register_operand" "Q"))))
8035 (clobber (reg:CC FLAGS_REG))]
8037 "and{b}\t{%2, %h0|%h0, %2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "length_immediate" "0")
8040 (set_attr "mode" "QI")])
8042 (define_insn "*andqi_ext_1"
8043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048 (match_operand 1 "ext_register_operand" "0")
8052 (match_operand:QI 2 "general_operand" "Qm"))))
8053 (clobber (reg:CC FLAGS_REG))]
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "0")
8058 (set_attr "mode" "QI")])
8060 (define_insn "*andqi_ext_2"
8061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8066 (match_operand 1 "ext_register_operand" "%0")
8070 (match_operand 2 "ext_register_operand" "Q")
8073 (clobber (reg:CC FLAGS_REG))]
8075 "and{b}\t{%h2, %h0|%h0, %h2}"
8076 [(set_attr "type" "alu")
8077 (set_attr "length_immediate" "0")
8078 (set_attr "mode" "QI")])
8080 ;; Convert wide AND instructions with immediate operand to shorter QImode
8081 ;; equivalents when possible.
8082 ;; Don't do the splitting with memory operands, since it introduces risk
8083 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8084 ;; for size, but that can (should?) be handled by generic code instead.
8086 [(set (match_operand 0 "register_operand" "")
8087 (and (match_operand 1 "register_operand" "")
8088 (match_operand 2 "const_int_operand" "")))
8089 (clobber (reg:CC FLAGS_REG))]
8091 && QI_REG_P (operands[0])
8092 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8093 && !(~INTVAL (operands[2]) & ~(255 << 8))
8094 && GET_MODE (operands[0]) != QImode"
8095 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8096 (and:SI (zero_extract:SI (match_dup 1)
8097 (const_int 8) (const_int 8))
8099 (clobber (reg:CC FLAGS_REG))])]
8100 "operands[0] = gen_lowpart (SImode, operands[0]);
8101 operands[1] = gen_lowpart (SImode, operands[1]);
8102 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8104 ;; Since AND can be encoded with sign extended immediate, this is only
8105 ;; profitable when 7th bit is not set.
8107 [(set (match_operand 0 "register_operand" "")
8108 (and (match_operand 1 "general_operand" "")
8109 (match_operand 2 "const_int_operand" "")))
8110 (clobber (reg:CC FLAGS_REG))]
8112 && ANY_QI_REG_P (operands[0])
8113 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8114 && !(~INTVAL (operands[2]) & ~255)
8115 && !(INTVAL (operands[2]) & 128)
8116 && GET_MODE (operands[0]) != QImode"
8117 [(parallel [(set (strict_low_part (match_dup 0))
8118 (and:QI (match_dup 1)
8120 (clobber (reg:CC FLAGS_REG))])]
8121 "operands[0] = gen_lowpart (QImode, operands[0]);
8122 operands[1] = gen_lowpart (QImode, operands[1]);
8123 operands[2] = gen_lowpart (QImode, operands[2]);")
8125 ;; Logical inclusive and exclusive OR instructions
8127 ;; %%% This used to optimize known byte-wide and operations to memory.
8128 ;; If this is considered useful, it should be done with splitters.
8130 (define_expand "<code><mode>3"
8131 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8132 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8133 (match_operand:SWIM 2 "<general_operand>" "")))]
8135 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8137 (define_insn "*<code><mode>_1"
8138 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8140 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8141 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8142 (clobber (reg:CC FLAGS_REG))]
8143 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8144 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "<MODE>")])
8148 ;; %%% Potential partial reg stall on alternative 2. What to do?
8149 (define_insn "*<code>qi_1"
8150 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8151 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8152 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8156 <logic>{b}\t{%2, %0|%0, %2}
8157 <logic>{b}\t{%2, %0|%0, %2}
8158 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8159 [(set_attr "type" "alu")
8160 (set_attr "mode" "QI,QI,SI")])
8162 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8163 (define_insn "*<code>si_1_zext"
8164 [(set (match_operand:DI 0 "register_operand" "=r")
8166 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8167 (match_operand:SI 2 "general_operand" "g"))))
8168 (clobber (reg:CC FLAGS_REG))]
8169 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8170 "<logic>{l}\t{%2, %k0|%k0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI")])
8174 (define_insn "*<code>si_1_zext_imm"
8175 [(set (match_operand:DI 0 "register_operand" "=r")
8177 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8178 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8181 "<logic>{l}\t{%2, %k0|%k0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "SI")])
8185 (define_insn "*<code>qi_1_slp"
8186 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8187 (any_or:QI (match_dup 0)
8188 (match_operand:QI 1 "general_operand" "qmn,qn")))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8191 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8192 "<logic>{b}\t{%1, %0|%0, %1}"
8193 [(set_attr "type" "alu1")
8194 (set_attr "mode" "QI")])
8196 (define_insn "*<code><mode>_2"
8197 [(set (reg FLAGS_REG)
8198 (compare (any_or:SWI
8199 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8200 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8202 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8203 (any_or:SWI (match_dup 1) (match_dup 2)))]
8204 "ix86_match_ccmode (insn, CCNOmode)
8205 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8206 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8207 [(set_attr "type" "alu")
8208 (set_attr "mode" "<MODE>")])
8210 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8211 ;; ??? Special case for immediate operand is missing - it is tricky.
8212 (define_insn "*<code>si_2_zext"
8213 [(set (reg FLAGS_REG)
8214 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8215 (match_operand:SI 2 "general_operand" "g"))
8217 (set (match_operand:DI 0 "register_operand" "=r")
8218 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8219 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8220 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8221 "<logic>{l}\t{%2, %k0|%k0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "SI")])
8225 (define_insn "*<code>si_2_zext_imm"
8226 [(set (reg FLAGS_REG)
8228 (match_operand:SI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8231 (set (match_operand:DI 0 "register_operand" "=r")
8232 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8233 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8234 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8235 "<logic>{l}\t{%2, %k0|%k0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "SI")])
8239 (define_insn "*<code>qi_2_slp"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8242 (match_operand:QI 1 "general_operand" "qmn,qn"))
8244 (set (strict_low_part (match_dup 0))
8245 (any_or:QI (match_dup 0) (match_dup 1)))]
8246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8247 && ix86_match_ccmode (insn, CCNOmode)
8248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8249 "<logic>{b}\t{%1, %0|%0, %1}"
8250 [(set_attr "type" "alu1")
8251 (set_attr "mode" "QI")])
8253 (define_insn "*<code><mode>_3"
8254 [(set (reg FLAGS_REG)
8255 (compare (any_or:SWI
8256 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8257 (match_operand:SWI 2 "<general_operand>" "<g>"))
8259 (clobber (match_scratch:SWI 0 "=<r>"))]
8260 "ix86_match_ccmode (insn, CCNOmode)
8261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "mode" "<MODE>")])
8266 (define_insn "*<code>qi_ext_0"
8267 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8272 (match_operand 1 "ext_register_operand" "0")
8275 (match_operand 2 "const_int_operand" "n")))
8276 (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" "1")
8281 (set_attr "modrm" "1")
8282 (set_attr "mode" "QI")])
8284 (define_insn "*<code>qi_ext_1_rex64"
8285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290 (match_operand 1 "ext_register_operand" "0")
8294 (match_operand 2 "ext_register_operand" "Q"))))
8295 (clobber (reg:CC FLAGS_REG))]
8297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8298 "<logic>{b}\t{%2, %h0|%h0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "length_immediate" "0")
8301 (set_attr "mode" "QI")])
8303 (define_insn "*<code>qi_ext_1"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309 (match_operand 1 "ext_register_operand" "0")
8313 (match_operand:QI 2 "general_operand" "Qm"))))
8314 (clobber (reg:CC FLAGS_REG))]
8316 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8317 "<logic>{b}\t{%2, %h0|%h0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "length_immediate" "0")
8320 (set_attr "mode" "QI")])
8322 (define_insn "*<code>qi_ext_2"
8323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8327 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8330 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8333 (clobber (reg:CC FLAGS_REG))]
8334 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8335 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "0")
8338 (set_attr "mode" "QI")])
8341 [(set (match_operand 0 "register_operand" "")
8342 (any_or (match_operand 1 "register_operand" "")
8343 (match_operand 2 "const_int_operand" "")))
8344 (clobber (reg:CC FLAGS_REG))]
8346 && QI_REG_P (operands[0])
8347 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8348 && !(INTVAL (operands[2]) & ~(255 << 8))
8349 && GET_MODE (operands[0]) != QImode"
8350 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8351 (any_or:SI (zero_extract:SI (match_dup 1)
8352 (const_int 8) (const_int 8))
8354 (clobber (reg:CC FLAGS_REG))])]
8355 "operands[0] = gen_lowpart (SImode, operands[0]);
8356 operands[1] = gen_lowpart (SImode, operands[1]);
8357 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8359 ;; Since OR can be encoded with sign extended immediate, this is only
8360 ;; profitable when 7th bit is set.
8362 [(set (match_operand 0 "register_operand" "")
8363 (any_or (match_operand 1 "general_operand" "")
8364 (match_operand 2 "const_int_operand" "")))
8365 (clobber (reg:CC FLAGS_REG))]
8367 && ANY_QI_REG_P (operands[0])
8368 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8369 && !(INTVAL (operands[2]) & ~255)
8370 && (INTVAL (operands[2]) & 128)
8371 && GET_MODE (operands[0]) != QImode"
8372 [(parallel [(set (strict_low_part (match_dup 0))
8373 (any_or:QI (match_dup 1)
8375 (clobber (reg:CC FLAGS_REG))])]
8376 "operands[0] = gen_lowpart (QImode, operands[0]);
8377 operands[1] = gen_lowpart (QImode, operands[1]);
8378 operands[2] = gen_lowpart (QImode, operands[2]);")
8380 (define_expand "xorqi_cc_ext_1"
8382 (set (reg:CCNO FLAGS_REG)
8386 (match_operand 1 "ext_register_operand" "")
8389 (match_operand:QI 2 "general_operand" ""))
8391 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8401 (define_insn "*xorqi_cc_ext_1_rex64"
8402 [(set (reg FLAGS_REG)
8406 (match_operand 1 "ext_register_operand" "0")
8409 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8411 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8421 "xor{b}\t{%2, %h0|%h0, %2}"
8422 [(set_attr "type" "alu")
8423 (set_attr "modrm" "1")
8424 (set_attr "mode" "QI")])
8426 (define_insn "*xorqi_cc_ext_1"
8427 [(set (reg FLAGS_REG)
8431 (match_operand 1 "ext_register_operand" "0")
8434 (match_operand:QI 2 "general_operand" "qmn"))
8436 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8445 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8446 "xor{b}\t{%2, %h0|%h0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "modrm" "1")
8449 (set_attr "mode" "QI")])
8451 ;; Negation instructions
8453 (define_expand "neg<mode>2"
8454 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8455 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8457 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8459 (define_insn_and_split "*neg<dwi>2_doubleword"
8460 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8461 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8462 (clobber (reg:CC FLAGS_REG))]
8463 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8467 [(set (reg:CCZ FLAGS_REG)
8468 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8469 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8472 (plus:DWIH (match_dup 3)
8473 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8475 (clobber (reg:CC FLAGS_REG))])
8478 (neg:DWIH (match_dup 2)))
8479 (clobber (reg:CC FLAGS_REG))])]
8480 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8482 (define_insn "*neg<mode>2_1"
8483 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8484 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8485 (clobber (reg:CC FLAGS_REG))]
8486 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8487 "neg{<imodesuffix>}\t%0"
8488 [(set_attr "type" "negnot")
8489 (set_attr "mode" "<MODE>")])
8491 ;; Combine is quite creative about this pattern.
8492 (define_insn "*negsi2_1_zext"
8493 [(set (match_operand:DI 0 "register_operand" "=r")
8495 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8498 (clobber (reg:CC FLAGS_REG))]
8499 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8501 [(set_attr "type" "negnot")
8502 (set_attr "mode" "SI")])
8504 ;; The problem with neg is that it does not perform (compare x 0),
8505 ;; it really performs (compare 0 x), which leaves us with the zero
8506 ;; flag being the only useful item.
8508 (define_insn "*neg<mode>2_cmpz"
8509 [(set (reg:CCZ FLAGS_REG)
8511 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8513 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8514 (neg:SWI (match_dup 1)))]
8515 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8516 "neg{<imodesuffix>}\t%0"
8517 [(set_attr "type" "negnot")
8518 (set_attr "mode" "<MODE>")])
8520 (define_insn "*negsi2_cmpz_zext"
8521 [(set (reg:CCZ FLAGS_REG)
8525 (match_operand:DI 1 "register_operand" "0")
8529 (set (match_operand:DI 0 "register_operand" "=r")
8530 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8533 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8535 [(set_attr "type" "negnot")
8536 (set_attr "mode" "SI")])
8538 ;; Changing of sign for FP values is doable using integer unit too.
8540 (define_expand "<code><mode>2"
8541 [(set (match_operand:X87MODEF 0 "register_operand" "")
8542 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8543 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8544 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8546 (define_insn "*absneg<mode>2_mixed"
8547 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8548 (match_operator:MODEF 3 "absneg_operator"
8549 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8550 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8555 (define_insn "*absneg<mode>2_sse"
8556 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8557 (match_operator:MODEF 3 "absneg_operator"
8558 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8559 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8560 (clobber (reg:CC FLAGS_REG))]
8561 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8564 (define_insn "*absneg<mode>2_i387"
8565 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8566 (match_operator:X87MODEF 3 "absneg_operator"
8567 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8568 (use (match_operand 2 "" ""))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8573 (define_expand "<code>tf2"
8574 [(set (match_operand:TF 0 "register_operand" "")
8575 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8577 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8579 (define_insn "*absnegtf2_sse"
8580 [(set (match_operand:TF 0 "register_operand" "=x,x")
8581 (match_operator:TF 3 "absneg_operator"
8582 [(match_operand:TF 1 "register_operand" "0,x")]))
8583 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8584 (clobber (reg:CC FLAGS_REG))]
8588 ;; Splitters for fp abs and neg.
8591 [(set (match_operand 0 "fp_register_operand" "")
8592 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8593 (use (match_operand 2 "" ""))
8594 (clobber (reg:CC FLAGS_REG))]
8596 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8599 [(set (match_operand 0 "register_operand" "")
8600 (match_operator 3 "absneg_operator"
8601 [(match_operand 1 "register_operand" "")]))
8602 (use (match_operand 2 "nonimmediate_operand" ""))
8603 (clobber (reg:CC FLAGS_REG))]
8604 "reload_completed && SSE_REG_P (operands[0])"
8605 [(set (match_dup 0) (match_dup 3))]
8607 enum machine_mode mode = GET_MODE (operands[0]);
8608 enum machine_mode vmode = GET_MODE (operands[2]);
8611 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8612 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8613 if (operands_match_p (operands[0], operands[2]))
8616 operands[1] = operands[2];
8619 if (GET_CODE (operands[3]) == ABS)
8620 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8622 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8627 [(set (match_operand:SF 0 "register_operand" "")
8628 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8629 (use (match_operand:V4SF 2 "" ""))
8630 (clobber (reg:CC FLAGS_REG))]
8632 [(parallel [(set (match_dup 0) (match_dup 1))
8633 (clobber (reg:CC FLAGS_REG))])]
8636 operands[0] = gen_lowpart (SImode, operands[0]);
8637 if (GET_CODE (operands[1]) == ABS)
8639 tmp = gen_int_mode (0x7fffffff, SImode);
8640 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8644 tmp = gen_int_mode (0x80000000, SImode);
8645 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8651 [(set (match_operand:DF 0 "register_operand" "")
8652 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8653 (use (match_operand 2 "" ""))
8654 (clobber (reg:CC FLAGS_REG))]
8656 [(parallel [(set (match_dup 0) (match_dup 1))
8657 (clobber (reg:CC FLAGS_REG))])]
8662 tmp = gen_lowpart (DImode, operands[0]);
8663 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8666 if (GET_CODE (operands[1]) == ABS)
8669 tmp = gen_rtx_NOT (DImode, tmp);
8673 operands[0] = gen_highpart (SImode, operands[0]);
8674 if (GET_CODE (operands[1]) == ABS)
8676 tmp = gen_int_mode (0x7fffffff, SImode);
8677 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8681 tmp = gen_int_mode (0x80000000, SImode);
8682 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8689 [(set (match_operand:XF 0 "register_operand" "")
8690 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8691 (use (match_operand 2 "" ""))
8692 (clobber (reg:CC FLAGS_REG))]
8694 [(parallel [(set (match_dup 0) (match_dup 1))
8695 (clobber (reg:CC FLAGS_REG))])]
8698 operands[0] = gen_rtx_REG (SImode,
8699 true_regnum (operands[0])
8700 + (TARGET_64BIT ? 1 : 2));
8701 if (GET_CODE (operands[1]) == ABS)
8703 tmp = GEN_INT (0x7fff);
8704 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8708 tmp = GEN_INT (0x8000);
8709 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8714 ;; Conditionalize these after reload. If they match before reload, we
8715 ;; lose the clobber and ability to use integer instructions.
8717 (define_insn "*<code><mode>2_1"
8718 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8719 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8721 && (reload_completed
8722 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8723 "f<absneg_mnemonic>"
8724 [(set_attr "type" "fsgn")
8725 (set_attr "mode" "<MODE>")])
8727 (define_insn "*<code>extendsfdf2"
8728 [(set (match_operand:DF 0 "register_operand" "=f")
8729 (absneg:DF (float_extend:DF
8730 (match_operand:SF 1 "register_operand" "0"))))]
8731 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8732 "f<absneg_mnemonic>"
8733 [(set_attr "type" "fsgn")
8734 (set_attr "mode" "DF")])
8736 (define_insn "*<code>extendsfxf2"
8737 [(set (match_operand:XF 0 "register_operand" "=f")
8738 (absneg:XF (float_extend:XF
8739 (match_operand:SF 1 "register_operand" "0"))))]
8741 "f<absneg_mnemonic>"
8742 [(set_attr "type" "fsgn")
8743 (set_attr "mode" "XF")])
8745 (define_insn "*<code>extenddfxf2"
8746 [(set (match_operand:XF 0 "register_operand" "=f")
8747 (absneg:XF (float_extend:XF
8748 (match_operand:DF 1 "register_operand" "0"))))]
8750 "f<absneg_mnemonic>"
8751 [(set_attr "type" "fsgn")
8752 (set_attr "mode" "XF")])
8754 ;; Copysign instructions
8756 (define_mode_iterator CSGNMODE [SF DF TF])
8757 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8759 (define_expand "copysign<mode>3"
8760 [(match_operand:CSGNMODE 0 "register_operand" "")
8761 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8762 (match_operand:CSGNMODE 2 "register_operand" "")]
8763 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8764 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8765 "ix86_expand_copysign (operands); DONE;")
8767 (define_insn_and_split "copysign<mode>3_const"
8768 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8770 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8771 (match_operand:CSGNMODE 2 "register_operand" "0")
8772 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8774 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8775 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8777 "&& reload_completed"
8779 "ix86_split_copysign_const (operands); DONE;")
8781 (define_insn "copysign<mode>3_var"
8782 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8784 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8785 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8786 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8787 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8789 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8790 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8791 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8795 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8797 [(match_operand:CSGNMODE 2 "register_operand" "")
8798 (match_operand:CSGNMODE 3 "register_operand" "")
8799 (match_operand:<CSGNVMODE> 4 "" "")
8800 (match_operand:<CSGNVMODE> 5 "" "")]
8802 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8803 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8804 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8805 && reload_completed"
8807 "ix86_split_copysign_var (operands); DONE;")
8809 ;; One complement instructions
8811 (define_expand "one_cmpl<mode>2"
8812 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8813 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8815 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8817 (define_insn "*one_cmpl<mode>2_1"
8818 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8819 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8820 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8821 "not{<imodesuffix>}\t%0"
8822 [(set_attr "type" "negnot")
8823 (set_attr "mode" "<MODE>")])
8825 ;; %%% Potential partial reg stall on alternative 1. What to do?
8826 (define_insn "*one_cmplqi2_1"
8827 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8828 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8829 "ix86_unary_operator_ok (NOT, QImode, operands)"
8833 [(set_attr "type" "negnot")
8834 (set_attr "mode" "QI,SI")])
8836 ;; ??? Currently never generated - xor is used instead.
8837 (define_insn "*one_cmplsi2_1_zext"
8838 [(set (match_operand:DI 0 "register_operand" "=r")
8840 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8841 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8843 [(set_attr "type" "negnot")
8844 (set_attr "mode" "SI")])
8846 (define_insn "*one_cmpl<mode>2_2"
8847 [(set (reg FLAGS_REG)
8848 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8850 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8851 (not:SWI (match_dup 1)))]
8852 "ix86_match_ccmode (insn, CCNOmode)
8853 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8855 [(set_attr "type" "alu1")
8856 (set_attr "mode" "<MODE>")])
8859 [(set (match_operand 0 "flags_reg_operand" "")
8860 (match_operator 2 "compare_operator"
8861 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8863 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8864 (not:SWI (match_dup 3)))]
8865 "ix86_match_ccmode (insn, CCNOmode)"
8866 [(parallel [(set (match_dup 0)
8867 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8870 (xor:SWI (match_dup 3) (const_int -1)))])])
8872 ;; ??? Currently never generated - xor is used instead.
8873 (define_insn "*one_cmplsi2_2_zext"
8874 [(set (reg FLAGS_REG)
8875 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8877 (set (match_operand:DI 0 "register_operand" "=r")
8878 (zero_extend:DI (not:SI (match_dup 1))))]
8879 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8880 && ix86_unary_operator_ok (NOT, SImode, operands)"
8882 [(set_attr "type" "alu1")
8883 (set_attr "mode" "SI")])
8886 [(set (match_operand 0 "flags_reg_operand" "")
8887 (match_operator 2 "compare_operator"
8888 [(not:SI (match_operand:SI 3 "register_operand" ""))
8890 (set (match_operand:DI 1 "register_operand" "")
8891 (zero_extend:DI (not:SI (match_dup 3))))]
8892 "ix86_match_ccmode (insn, CCNOmode)"
8893 [(parallel [(set (match_dup 0)
8894 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8897 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8899 ;; Shift instructions
8901 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8902 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8903 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8904 ;; from the assembler input.
8906 ;; This instruction shifts the target reg/mem as usual, but instead of
8907 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8908 ;; is a left shift double, bits are taken from the high order bits of
8909 ;; reg, else if the insn is a shift right double, bits are taken from the
8910 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8911 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8913 ;; Since sh[lr]d does not change the `reg' operand, that is done
8914 ;; separately, making all shifts emit pairs of shift double and normal
8915 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8916 ;; support a 63 bit shift, each shift where the count is in a reg expands
8917 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8919 ;; If the shift count is a constant, we need never emit more than one
8920 ;; shift pair, instead using moves and sign extension for counts greater
8923 (define_expand "ashl<mode>3"
8924 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8925 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8926 (match_operand:QI 2 "nonmemory_operand" "")))]
8928 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8930 (define_insn "*ashl<mode>3_doubleword"
8931 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8932 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8933 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8934 (clobber (reg:CC FLAGS_REG))]
8937 [(set_attr "type" "multi")])
8940 [(set (match_operand:DWI 0 "register_operand" "")
8941 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8942 (match_operand:QI 2 "nonmemory_operand" "")))
8943 (clobber (reg:CC FLAGS_REG))]
8944 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8946 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8948 ;; By default we don't ask for a scratch register, because when DWImode
8949 ;; values are manipulated, registers are already at a premium. But if
8950 ;; we have one handy, we won't turn it away.
8953 [(match_scratch:DWIH 3 "r")
8954 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8956 (match_operand:<DWI> 1 "nonmemory_operand" "")
8957 (match_operand:QI 2 "nonmemory_operand" "")))
8958 (clobber (reg:CC FLAGS_REG))])
8962 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8964 (define_insn "x86_64_shld"
8965 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8966 (ior:DI (ashift:DI (match_dup 0)
8967 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8968 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8969 (minus:QI (const_int 64) (match_dup 2)))))
8970 (clobber (reg:CC FLAGS_REG))]
8972 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8973 [(set_attr "type" "ishift")
8974 (set_attr "prefix_0f" "1")
8975 (set_attr "mode" "DI")
8976 (set_attr "athlon_decode" "vector")
8977 (set_attr "amdfam10_decode" "vector")
8978 (set_attr "bdver1_decode" "vector")])
8980 (define_insn "x86_shld"
8981 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8982 (ior:SI (ashift:SI (match_dup 0)
8983 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8984 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8985 (minus:QI (const_int 32) (match_dup 2)))))
8986 (clobber (reg:CC FLAGS_REG))]
8988 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8989 [(set_attr "type" "ishift")
8990 (set_attr "prefix_0f" "1")
8991 (set_attr "mode" "SI")
8992 (set_attr "pent_pair" "np")
8993 (set_attr "athlon_decode" "vector")
8994 (set_attr "amdfam10_decode" "vector")
8995 (set_attr "bdver1_decode" "vector")])
8997 (define_expand "x86_shift<mode>_adj_1"
8998 [(set (reg:CCZ FLAGS_REG)
8999 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9002 (set (match_operand:SWI48 0 "register_operand" "")
9003 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9004 (match_operand:SWI48 1 "register_operand" "")
9007 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9008 (match_operand:SWI48 3 "register_operand" "r")
9011 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9013 (define_expand "x86_shift<mode>_adj_2"
9014 [(use (match_operand:SWI48 0 "register_operand" ""))
9015 (use (match_operand:SWI48 1 "register_operand" ""))
9016 (use (match_operand:QI 2 "register_operand" ""))]
9019 rtx label = gen_label_rtx ();
9022 emit_insn (gen_testqi_ccz_1 (operands[2],
9023 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9025 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9026 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9027 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9028 gen_rtx_LABEL_REF (VOIDmode, label),
9030 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9031 JUMP_LABEL (tmp) = label;
9033 emit_move_insn (operands[0], operands[1]);
9034 ix86_expand_clear (operands[1]);
9037 LABEL_NUSES (label) = 1;
9042 ;; Avoid useless masking of count operand.
9043 (define_insn_and_split "*ashl<mode>3_mask"
9044 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9046 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9049 (match_operand:SI 2 "nonimmediate_operand" "c")
9050 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9051 (clobber (reg:CC FLAGS_REG))]
9052 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9053 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9054 == GET_MODE_BITSIZE (<MODE>mode)-1"
9057 [(parallel [(set (match_dup 0)
9058 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9059 (clobber (reg:CC FLAGS_REG))])]
9061 if (can_create_pseudo_p ())
9062 operands [2] = force_reg (SImode, operands[2]);
9064 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9066 [(set_attr "type" "ishift")
9067 (set_attr "mode" "<MODE>")])
9069 (define_insn "*ashl<mode>3_1"
9070 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9071 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9072 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9076 switch (get_attr_type (insn))
9082 gcc_assert (operands[2] == const1_rtx);
9083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9084 return "add{<imodesuffix>}\t%0, %0";
9087 if (operands[2] == const1_rtx
9088 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9089 return "sal{<imodesuffix>}\t%0";
9091 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9095 (cond [(eq_attr "alternative" "1")
9096 (const_string "lea")
9097 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9099 (match_operand 0 "register_operand" ""))
9100 (match_operand 2 "const1_operand" ""))
9101 (const_string "alu")
9103 (const_string "ishift")))
9104 (set (attr "length_immediate")
9106 (ior (eq_attr "type" "alu")
9107 (and (eq_attr "type" "ishift")
9108 (and (match_operand 2 "const1_operand" "")
9109 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9112 (const_string "*")))
9113 (set_attr "mode" "<MODE>")])
9115 (define_insn "*ashlsi3_1_zext"
9116 [(set (match_operand:DI 0 "register_operand" "=r,r")
9118 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9119 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9123 switch (get_attr_type (insn))
9129 gcc_assert (operands[2] == const1_rtx);
9130 return "add{l}\t%k0, %k0";
9133 if (operands[2] == const1_rtx
9134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9135 return "sal{l}\t%k0";
9137 return "sal{l}\t{%2, %k0|%k0, %2}";
9141 (cond [(eq_attr "alternative" "1")
9142 (const_string "lea")
9143 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9145 (match_operand 2 "const1_operand" ""))
9146 (const_string "alu")
9148 (const_string "ishift")))
9149 (set (attr "length_immediate")
9151 (ior (eq_attr "type" "alu")
9152 (and (eq_attr "type" "ishift")
9153 (and (match_operand 2 "const1_operand" "")
9154 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9157 (const_string "*")))
9158 (set_attr "mode" "SI")])
9160 (define_insn "*ashlhi3_1"
9161 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9162 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9163 (match_operand:QI 2 "nonmemory_operand" "cI")))
9164 (clobber (reg:CC FLAGS_REG))]
9165 "TARGET_PARTIAL_REG_STALL
9166 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9168 switch (get_attr_type (insn))
9171 gcc_assert (operands[2] == const1_rtx);
9172 return "add{w}\t%0, %0";
9175 if (operands[2] == const1_rtx
9176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9177 return "sal{w}\t%0";
9179 return "sal{w}\t{%2, %0|%0, %2}";
9183 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9185 (match_operand 0 "register_operand" ""))
9186 (match_operand 2 "const1_operand" ""))
9187 (const_string "alu")
9189 (const_string "ishift")))
9190 (set (attr "length_immediate")
9192 (ior (eq_attr "type" "alu")
9193 (and (eq_attr "type" "ishift")
9194 (and (match_operand 2 "const1_operand" "")
9195 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9198 (const_string "*")))
9199 (set_attr "mode" "HI")])
9201 (define_insn "*ashlhi3_1_lea"
9202 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9203 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9204 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "!TARGET_PARTIAL_REG_STALL
9207 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9209 switch (get_attr_type (insn))
9215 gcc_assert (operands[2] == const1_rtx);
9216 return "add{w}\t%0, %0";
9219 if (operands[2] == const1_rtx
9220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9221 return "sal{w}\t%0";
9223 return "sal{w}\t{%2, %0|%0, %2}";
9227 (cond [(eq_attr "alternative" "1")
9228 (const_string "lea")
9229 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9231 (match_operand 0 "register_operand" ""))
9232 (match_operand 2 "const1_operand" ""))
9233 (const_string "alu")
9235 (const_string "ishift")))
9236 (set (attr "length_immediate")
9238 (ior (eq_attr "type" "alu")
9239 (and (eq_attr "type" "ishift")
9240 (and (match_operand 2 "const1_operand" "")
9241 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9244 (const_string "*")))
9245 (set_attr "mode" "HI,SI")])
9247 (define_insn "*ashlqi3_1"
9248 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9249 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9250 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9251 (clobber (reg:CC FLAGS_REG))]
9252 "TARGET_PARTIAL_REG_STALL
9253 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9255 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9260 return "add{l}\t%k0, %k0";
9262 return "add{b}\t%0, %0";
9265 if (operands[2] == const1_rtx
9266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9268 if (get_attr_mode (insn) == MODE_SI)
9269 return "sal{l}\t%k0";
9271 return "sal{b}\t%0";
9275 if (get_attr_mode (insn) == MODE_SI)
9276 return "sal{l}\t{%2, %k0|%k0, %2}";
9278 return "sal{b}\t{%2, %0|%0, %2}";
9283 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9285 (match_operand 0 "register_operand" ""))
9286 (match_operand 2 "const1_operand" ""))
9287 (const_string "alu")
9289 (const_string "ishift")))
9290 (set (attr "length_immediate")
9292 (ior (eq_attr "type" "alu")
9293 (and (eq_attr "type" "ishift")
9294 (and (match_operand 2 "const1_operand" "")
9295 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9298 (const_string "*")))
9299 (set_attr "mode" "QI,SI")])
9301 ;; %%% Potential partial reg stall on alternative 2. What to do?
9302 (define_insn "*ashlqi3_1_lea"
9303 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9304 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9305 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9306 (clobber (reg:CC FLAGS_REG))]
9307 "!TARGET_PARTIAL_REG_STALL
9308 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9310 switch (get_attr_type (insn))
9316 gcc_assert (operands[2] == const1_rtx);
9317 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9318 return "add{l}\t%k0, %k0";
9320 return "add{b}\t%0, %0";
9323 if (operands[2] == const1_rtx
9324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9326 if (get_attr_mode (insn) == MODE_SI)
9327 return "sal{l}\t%k0";
9329 return "sal{b}\t%0";
9333 if (get_attr_mode (insn) == MODE_SI)
9334 return "sal{l}\t{%2, %k0|%k0, %2}";
9336 return "sal{b}\t{%2, %0|%0, %2}";
9341 (cond [(eq_attr "alternative" "2")
9342 (const_string "lea")
9343 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9345 (match_operand 0 "register_operand" ""))
9346 (match_operand 2 "const1_operand" ""))
9347 (const_string "alu")
9349 (const_string "ishift")))
9350 (set (attr "length_immediate")
9352 (ior (eq_attr "type" "alu")
9353 (and (eq_attr "type" "ishift")
9354 (and (match_operand 2 "const1_operand" "")
9355 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9358 (const_string "*")))
9359 (set_attr "mode" "QI,SI,SI")])
9361 (define_insn "*ashlqi3_1_slp"
9362 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9363 (ashift:QI (match_dup 0)
9364 (match_operand:QI 1 "nonmemory_operand" "cI")))
9365 (clobber (reg:CC FLAGS_REG))]
9366 "(optimize_function_for_size_p (cfun)
9367 || !TARGET_PARTIAL_FLAG_REG_STALL
9368 || (operands[1] == const1_rtx
9370 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9372 switch (get_attr_type (insn))
9375 gcc_assert (operands[1] == const1_rtx);
9376 return "add{b}\t%0, %0";
9379 if (operands[1] == const1_rtx
9380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9381 return "sal{b}\t%0";
9383 return "sal{b}\t{%1, %0|%0, %1}";
9387 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9389 (match_operand 0 "register_operand" ""))
9390 (match_operand 1 "const1_operand" ""))
9391 (const_string "alu")
9393 (const_string "ishift1")))
9394 (set (attr "length_immediate")
9396 (ior (eq_attr "type" "alu")
9397 (and (eq_attr "type" "ishift1")
9398 (and (match_operand 1 "const1_operand" "")
9399 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9402 (const_string "*")))
9403 (set_attr "mode" "QI")])
9405 ;; Convert lea to the lea pattern to avoid flags dependency.
9407 [(set (match_operand 0 "register_operand" "")
9408 (ashift (match_operand 1 "index_register_operand" "")
9409 (match_operand:QI 2 "const_int_operand" "")))
9410 (clobber (reg:CC FLAGS_REG))]
9412 && true_regnum (operands[0]) != true_regnum (operands[1])"
9416 enum machine_mode mode = GET_MODE (operands[0]);
9419 operands[1] = gen_lowpart (Pmode, operands[1]);
9420 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9422 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9424 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9425 operands[0] = gen_lowpart (SImode, operands[0]);
9427 if (TARGET_64BIT && mode != Pmode)
9428 pat = gen_rtx_SUBREG (SImode, pat, 0);
9430 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9434 ;; Convert lea to the lea pattern to avoid flags dependency.
9436 [(set (match_operand:DI 0 "register_operand" "")
9438 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9439 (match_operand:QI 2 "const_int_operand" ""))))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "TARGET_64BIT && reload_completed
9442 && true_regnum (operands[0]) != true_regnum (operands[1])"
9444 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9446 operands[1] = gen_lowpart (DImode, operands[1]);
9447 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9450 ;; This pattern can't accept a variable shift count, since shifts by
9451 ;; zero don't affect the flags. We assume that shifts by constant
9452 ;; zero are optimized away.
9453 (define_insn "*ashl<mode>3_cmp"
9454 [(set (reg FLAGS_REG)
9456 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9457 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9459 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9460 (ashift:SWI (match_dup 1) (match_dup 2)))]
9461 "(optimize_function_for_size_p (cfun)
9462 || !TARGET_PARTIAL_FLAG_REG_STALL
9463 || (operands[2] == const1_rtx
9465 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9466 && ix86_match_ccmode (insn, CCGOCmode)
9467 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9469 switch (get_attr_type (insn))
9472 gcc_assert (operands[2] == const1_rtx);
9473 return "add{<imodesuffix>}\t%0, %0";
9476 if (operands[2] == const1_rtx
9477 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9478 return "sal{<imodesuffix>}\t%0";
9480 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9484 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9486 (match_operand 0 "register_operand" ""))
9487 (match_operand 2 "const1_operand" ""))
9488 (const_string "alu")
9490 (const_string "ishift")))
9491 (set (attr "length_immediate")
9493 (ior (eq_attr "type" "alu")
9494 (and (eq_attr "type" "ishift")
9495 (and (match_operand 2 "const1_operand" "")
9496 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9499 (const_string "*")))
9500 (set_attr "mode" "<MODE>")])
9502 (define_insn "*ashlsi3_cmp_zext"
9503 [(set (reg FLAGS_REG)
9505 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9506 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9508 (set (match_operand:DI 0 "register_operand" "=r")
9509 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9511 && (optimize_function_for_size_p (cfun)
9512 || !TARGET_PARTIAL_FLAG_REG_STALL
9513 || (operands[2] == const1_rtx
9515 || TARGET_DOUBLE_WITH_ADD)))
9516 && ix86_match_ccmode (insn, CCGOCmode)
9517 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9519 switch (get_attr_type (insn))
9522 gcc_assert (operands[2] == const1_rtx);
9523 return "add{l}\t%k0, %k0";
9526 if (operands[2] == const1_rtx
9527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9528 return "sal{l}\t%k0";
9530 return "sal{l}\t{%2, %k0|%k0, %2}";
9534 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9536 (match_operand 2 "const1_operand" ""))
9537 (const_string "alu")
9539 (const_string "ishift")))
9540 (set (attr "length_immediate")
9542 (ior (eq_attr "type" "alu")
9543 (and (eq_attr "type" "ishift")
9544 (and (match_operand 2 "const1_operand" "")
9545 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9548 (const_string "*")))
9549 (set_attr "mode" "SI")])
9551 (define_insn "*ashl<mode>3_cconly"
9552 [(set (reg FLAGS_REG)
9554 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9555 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9557 (clobber (match_scratch:SWI 0 "=<r>"))]
9558 "(optimize_function_for_size_p (cfun)
9559 || !TARGET_PARTIAL_FLAG_REG_STALL
9560 || (operands[2] == const1_rtx
9562 || TARGET_DOUBLE_WITH_ADD)))
9563 && ix86_match_ccmode (insn, CCGOCmode)"
9565 switch (get_attr_type (insn))
9568 gcc_assert (operands[2] == const1_rtx);
9569 return "add{<imodesuffix>}\t%0, %0";
9572 if (operands[2] == const1_rtx
9573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9574 return "sal{<imodesuffix>}\t%0";
9576 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9580 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9582 (match_operand 0 "register_operand" ""))
9583 (match_operand 2 "const1_operand" ""))
9584 (const_string "alu")
9586 (const_string "ishift")))
9587 (set (attr "length_immediate")
9589 (ior (eq_attr "type" "alu")
9590 (and (eq_attr "type" "ishift")
9591 (and (match_operand 2 "const1_operand" "")
9592 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9595 (const_string "*")))
9596 (set_attr "mode" "<MODE>")])
9598 ;; See comment above `ashl<mode>3' about how this works.
9600 (define_expand "<shiftrt_insn><mode>3"
9601 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9602 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9603 (match_operand:QI 2 "nonmemory_operand" "")))]
9605 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9607 ;; Avoid useless masking of count operand.
9608 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9609 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9611 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9614 (match_operand:SI 2 "nonimmediate_operand" "c")
9615 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9618 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9619 == GET_MODE_BITSIZE (<MODE>mode)-1"
9622 [(parallel [(set (match_dup 0)
9623 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9624 (clobber (reg:CC FLAGS_REG))])]
9626 if (can_create_pseudo_p ())
9627 operands [2] = force_reg (SImode, operands[2]);
9629 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9631 [(set_attr "type" "ishift")
9632 (set_attr "mode" "<MODE>")])
9634 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9635 [(set (match_operand:DWI 0 "register_operand" "=r")
9636 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9637 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9638 (clobber (reg:CC FLAGS_REG))]
9641 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9643 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9644 [(set_attr "type" "multi")])
9646 ;; By default we don't ask for a scratch register, because when DWImode
9647 ;; values are manipulated, registers are already at a premium. But if
9648 ;; we have one handy, we won't turn it away.
9651 [(match_scratch:DWIH 3 "r")
9652 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9654 (match_operand:<DWI> 1 "register_operand" "")
9655 (match_operand:QI 2 "nonmemory_operand" "")))
9656 (clobber (reg:CC FLAGS_REG))])
9660 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9662 (define_insn "x86_64_shrd"
9663 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9664 (ior:DI (ashiftrt:DI (match_dup 0)
9665 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9666 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9667 (minus:QI (const_int 64) (match_dup 2)))))
9668 (clobber (reg:CC FLAGS_REG))]
9670 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9671 [(set_attr "type" "ishift")
9672 (set_attr "prefix_0f" "1")
9673 (set_attr "mode" "DI")
9674 (set_attr "athlon_decode" "vector")
9675 (set_attr "amdfam10_decode" "vector")
9676 (set_attr "bdver1_decode" "vector")])
9678 (define_insn "x86_shrd"
9679 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9680 (ior:SI (ashiftrt:SI (match_dup 0)
9681 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9682 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9683 (minus:QI (const_int 32) (match_dup 2)))))
9684 (clobber (reg:CC FLAGS_REG))]
9686 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9687 [(set_attr "type" "ishift")
9688 (set_attr "prefix_0f" "1")
9689 (set_attr "mode" "SI")
9690 (set_attr "pent_pair" "np")
9691 (set_attr "athlon_decode" "vector")
9692 (set_attr "amdfam10_decode" "vector")
9693 (set_attr "bdver1_decode" "vector")])
9695 (define_insn "ashrdi3_cvt"
9696 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9697 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9698 (match_operand:QI 2 "const_int_operand" "")))
9699 (clobber (reg:CC FLAGS_REG))]
9700 "TARGET_64BIT && INTVAL (operands[2]) == 63
9701 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9702 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9705 sar{q}\t{%2, %0|%0, %2}"
9706 [(set_attr "type" "imovx,ishift")
9707 (set_attr "prefix_0f" "0,*")
9708 (set_attr "length_immediate" "0,*")
9709 (set_attr "modrm" "0,1")
9710 (set_attr "mode" "DI")])
9712 (define_insn "ashrsi3_cvt"
9713 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9714 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9715 (match_operand:QI 2 "const_int_operand" "")))
9716 (clobber (reg:CC FLAGS_REG))]
9717 "INTVAL (operands[2]) == 31
9718 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9719 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9722 sar{l}\t{%2, %0|%0, %2}"
9723 [(set_attr "type" "imovx,ishift")
9724 (set_attr "prefix_0f" "0,*")
9725 (set_attr "length_immediate" "0,*")
9726 (set_attr "modrm" "0,1")
9727 (set_attr "mode" "SI")])
9729 (define_insn "*ashrsi3_cvt_zext"
9730 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9732 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9733 (match_operand:QI 2 "const_int_operand" ""))))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "TARGET_64BIT && INTVAL (operands[2]) == 31
9736 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9737 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9740 sar{l}\t{%2, %k0|%k0, %2}"
9741 [(set_attr "type" "imovx,ishift")
9742 (set_attr "prefix_0f" "0,*")
9743 (set_attr "length_immediate" "0,*")
9744 (set_attr "modrm" "0,1")
9745 (set_attr "mode" "SI")])
9747 (define_expand "x86_shift<mode>_adj_3"
9748 [(use (match_operand:SWI48 0 "register_operand" ""))
9749 (use (match_operand:SWI48 1 "register_operand" ""))
9750 (use (match_operand:QI 2 "register_operand" ""))]
9753 rtx label = gen_label_rtx ();
9756 emit_insn (gen_testqi_ccz_1 (operands[2],
9757 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9759 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9760 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9761 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9762 gen_rtx_LABEL_REF (VOIDmode, label),
9764 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9765 JUMP_LABEL (tmp) = label;
9767 emit_move_insn (operands[0], operands[1]);
9768 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9769 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9771 LABEL_NUSES (label) = 1;
9776 (define_insn "*<shiftrt_insn><mode>3_1"
9777 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9778 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9779 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9780 (clobber (reg:CC FLAGS_REG))]
9781 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9783 if (operands[2] == const1_rtx
9784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9785 return "<shiftrt>{<imodesuffix>}\t%0";
9787 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9789 [(set_attr "type" "ishift")
9790 (set (attr "length_immediate")
9792 (and (match_operand 2 "const1_operand" "")
9793 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9796 (const_string "*")))
9797 (set_attr "mode" "<MODE>")])
9799 (define_insn "*<shiftrt_insn>si3_1_zext"
9800 [(set (match_operand:DI 0 "register_operand" "=r")
9802 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9803 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9807 if (operands[2] == const1_rtx
9808 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9809 return "<shiftrt>{l}\t%k0";
9811 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9813 [(set_attr "type" "ishift")
9814 (set (attr "length_immediate")
9816 (and (match_operand 2 "const1_operand" "")
9817 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9820 (const_string "*")))
9821 (set_attr "mode" "SI")])
9823 (define_insn "*<shiftrt_insn>qi3_1_slp"
9824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9825 (any_shiftrt:QI (match_dup 0)
9826 (match_operand:QI 1 "nonmemory_operand" "cI")))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "(optimize_function_for_size_p (cfun)
9829 || !TARGET_PARTIAL_REG_STALL
9830 || (operands[1] == const1_rtx
9833 if (operands[1] == const1_rtx
9834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9835 return "<shiftrt>{b}\t%0";
9837 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9839 [(set_attr "type" "ishift1")
9840 (set (attr "length_immediate")
9842 (and (match_operand 1 "const1_operand" "")
9843 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9846 (const_string "*")))
9847 (set_attr "mode" "QI")])
9849 ;; This pattern can't accept a variable shift count, since shifts by
9850 ;; zero don't affect the flags. We assume that shifts by constant
9851 ;; zero are optimized away.
9852 (define_insn "*<shiftrt_insn><mode>3_cmp"
9853 [(set (reg FLAGS_REG)
9856 (match_operand:SWI 1 "nonimmediate_operand" "0")
9857 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9859 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9860 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9861 "(optimize_function_for_size_p (cfun)
9862 || !TARGET_PARTIAL_FLAG_REG_STALL
9863 || (operands[2] == const1_rtx
9865 && ix86_match_ccmode (insn, CCGOCmode)
9866 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9868 if (operands[2] == const1_rtx
9869 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9870 return "<shiftrt>{<imodesuffix>}\t%0";
9872 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9874 [(set_attr "type" "ishift")
9875 (set (attr "length_immediate")
9877 (and (match_operand 2 "const1_operand" "")
9878 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9881 (const_string "*")))
9882 (set_attr "mode" "<MODE>")])
9884 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9885 [(set (reg FLAGS_REG)
9887 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9888 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9890 (set (match_operand:DI 0 "register_operand" "=r")
9891 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9893 && (optimize_function_for_size_p (cfun)
9894 || !TARGET_PARTIAL_FLAG_REG_STALL
9895 || (operands[2] == const1_rtx
9897 && ix86_match_ccmode (insn, CCGOCmode)
9898 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9900 if (operands[2] == const1_rtx
9901 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9902 return "<shiftrt>{l}\t%k0";
9904 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9906 [(set_attr "type" "ishift")
9907 (set (attr "length_immediate")
9909 (and (match_operand 2 "const1_operand" "")
9910 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913 (const_string "*")))
9914 (set_attr "mode" "SI")])
9916 (define_insn "*<shiftrt_insn><mode>3_cconly"
9917 [(set (reg FLAGS_REG)
9920 (match_operand:SWI 1 "register_operand" "0")
9921 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9923 (clobber (match_scratch:SWI 0 "=<r>"))]
9924 "(optimize_function_for_size_p (cfun)
9925 || !TARGET_PARTIAL_FLAG_REG_STALL
9926 || (operands[2] == const1_rtx
9928 && ix86_match_ccmode (insn, CCGOCmode)"
9930 if (operands[2] == const1_rtx
9931 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9932 return "<shiftrt>{<imodesuffix>}\t%0";
9934 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9936 [(set_attr "type" "ishift")
9937 (set (attr "length_immediate")
9939 (and (match_operand 2 "const1_operand" "")
9940 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9943 (const_string "*")))
9944 (set_attr "mode" "<MODE>")])
9946 ;; Rotate instructions
9948 (define_expand "<rotate_insn>ti3"
9949 [(set (match_operand:TI 0 "register_operand" "")
9950 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9951 (match_operand:QI 2 "nonmemory_operand" "")))]
9954 if (const_1_to_63_operand (operands[2], VOIDmode))
9955 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9956 (operands[0], operands[1], operands[2]));
9963 (define_expand "<rotate_insn>di3"
9964 [(set (match_operand:DI 0 "shiftdi_operand" "")
9965 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9966 (match_operand:QI 2 "nonmemory_operand" "")))]
9970 ix86_expand_binary_operator (<CODE>, DImode, operands);
9971 else if (const_1_to_31_operand (operands[2], VOIDmode))
9972 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9973 (operands[0], operands[1], operands[2]));
9980 (define_expand "<rotate_insn><mode>3"
9981 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9982 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9983 (match_operand:QI 2 "nonmemory_operand" "")))]
9985 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9987 ;; Avoid useless masking of count operand.
9988 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9989 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9991 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9994 (match_operand:SI 2 "nonimmediate_operand" "c")
9995 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9996 (clobber (reg:CC FLAGS_REG))]
9997 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9998 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9999 == GET_MODE_BITSIZE (<MODE>mode)-1"
10002 [(parallel [(set (match_dup 0)
10003 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10004 (clobber (reg:CC FLAGS_REG))])]
10006 if (can_create_pseudo_p ())
10007 operands [2] = force_reg (SImode, operands[2]);
10009 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10011 [(set_attr "type" "rotate")
10012 (set_attr "mode" "<MODE>")])
10014 ;; Implement rotation using two double-precision
10015 ;; shift instructions and a scratch register.
10017 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10018 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10019 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10020 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10021 (clobber (reg:CC FLAGS_REG))
10022 (clobber (match_scratch:DWIH 3 "=&r"))]
10026 [(set (match_dup 3) (match_dup 4))
10028 [(set (match_dup 4)
10029 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10030 (lshiftrt:DWIH (match_dup 5)
10031 (minus:QI (match_dup 6) (match_dup 2)))))
10032 (clobber (reg:CC FLAGS_REG))])
10034 [(set (match_dup 5)
10035 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10036 (lshiftrt:DWIH (match_dup 3)
10037 (minus:QI (match_dup 6) (match_dup 2)))))
10038 (clobber (reg:CC FLAGS_REG))])]
10040 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10042 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10045 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10046 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10047 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10048 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10049 (clobber (reg:CC FLAGS_REG))
10050 (clobber (match_scratch:DWIH 3 "=&r"))]
10054 [(set (match_dup 3) (match_dup 4))
10056 [(set (match_dup 4)
10057 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10058 (ashift:DWIH (match_dup 5)
10059 (minus:QI (match_dup 6) (match_dup 2)))))
10060 (clobber (reg:CC FLAGS_REG))])
10062 [(set (match_dup 5)
10063 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10064 (ashift:DWIH (match_dup 3)
10065 (minus:QI (match_dup 6) (match_dup 2)))))
10066 (clobber (reg:CC FLAGS_REG))])]
10068 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10070 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10073 (define_insn "*<rotate_insn><mode>3_1"
10074 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10075 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10076 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10077 (clobber (reg:CC FLAGS_REG))]
10078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10080 if (operands[2] == const1_rtx
10081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10082 return "<rotate>{<imodesuffix>}\t%0";
10084 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10086 [(set_attr "type" "rotate")
10087 (set (attr "length_immediate")
10089 (and (match_operand 2 "const1_operand" "")
10090 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10093 (const_string "*")))
10094 (set_attr "mode" "<MODE>")])
10096 (define_insn "*<rotate_insn>si3_1_zext"
10097 [(set (match_operand:DI 0 "register_operand" "=r")
10099 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10100 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10101 (clobber (reg:CC FLAGS_REG))]
10102 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10104 if (operands[2] == const1_rtx
10105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10106 return "<rotate>{l}\t%k0";
10108 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10110 [(set_attr "type" "rotate")
10111 (set (attr "length_immediate")
10113 (and (match_operand 2 "const1_operand" "")
10114 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117 (const_string "*")))
10118 (set_attr "mode" "SI")])
10120 (define_insn "*<rotate_insn>qi3_1_slp"
10121 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10122 (any_rotate:QI (match_dup 0)
10123 (match_operand:QI 1 "nonmemory_operand" "cI")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "(optimize_function_for_size_p (cfun)
10126 || !TARGET_PARTIAL_REG_STALL
10127 || (operands[1] == const1_rtx
10128 && TARGET_SHIFT1))"
10130 if (operands[1] == const1_rtx
10131 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10132 return "<rotate>{b}\t%0";
10134 return "<rotate>{b}\t{%1, %0|%0, %1}";
10136 [(set_attr "type" "rotate1")
10137 (set (attr "length_immediate")
10139 (and (match_operand 1 "const1_operand" "")
10140 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10143 (const_string "*")))
10144 (set_attr "mode" "QI")])
10147 [(set (match_operand:HI 0 "register_operand" "")
10148 (any_rotate:HI (match_dup 0) (const_int 8)))
10149 (clobber (reg:CC FLAGS_REG))]
10151 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10152 [(parallel [(set (strict_low_part (match_dup 0))
10153 (bswap:HI (match_dup 0)))
10154 (clobber (reg:CC FLAGS_REG))])])
10156 ;; Bit set / bit test instructions
10158 (define_expand "extv"
10159 [(set (match_operand:SI 0 "register_operand" "")
10160 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10161 (match_operand:SI 2 "const8_operand" "")
10162 (match_operand:SI 3 "const8_operand" "")))]
10165 /* Handle extractions from %ah et al. */
10166 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10169 /* From mips.md: extract_bit_field doesn't verify that our source
10170 matches the predicate, so check it again here. */
10171 if (! ext_register_operand (operands[1], VOIDmode))
10175 (define_expand "extzv"
10176 [(set (match_operand:SI 0 "register_operand" "")
10177 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10178 (match_operand:SI 2 "const8_operand" "")
10179 (match_operand:SI 3 "const8_operand" "")))]
10182 /* Handle extractions from %ah et al. */
10183 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10186 /* From mips.md: extract_bit_field doesn't verify that our source
10187 matches the predicate, so check it again here. */
10188 if (! ext_register_operand (operands[1], VOIDmode))
10192 (define_expand "insv"
10193 [(set (zero_extract (match_operand 0 "register_operand" "")
10194 (match_operand 1 "const_int_operand" "")
10195 (match_operand 2 "const_int_operand" ""))
10196 (match_operand 3 "register_operand" ""))]
10199 rtx (*gen_mov_insv_1) (rtx, rtx);
10201 if (ix86_expand_pinsr (operands))
10204 /* Handle insertions to %ah et al. */
10205 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10208 /* From mips.md: insert_bit_field doesn't verify that our source
10209 matches the predicate, so check it again here. */
10210 if (! ext_register_operand (operands[0], VOIDmode))
10213 gen_mov_insv_1 = (TARGET_64BIT
10214 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10216 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10220 ;; %%% bts, btr, btc, bt.
10221 ;; In general these instructions are *slow* when applied to memory,
10222 ;; since they enforce atomic operation. When applied to registers,
10223 ;; it depends on the cpu implementation. They're never faster than
10224 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10225 ;; no point. But in 64-bit, we can't hold the relevant immediates
10226 ;; within the instruction itself, so operating on bits in the high
10227 ;; 32-bits of a register becomes easier.
10229 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10230 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10231 ;; negdf respectively, so they can never be disabled entirely.
10233 (define_insn "*btsq"
10234 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10236 (match_operand:DI 1 "const_0_to_63_operand" ""))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10240 "bts{q}\t{%1, %0|%0, %1}"
10241 [(set_attr "type" "alu1")
10242 (set_attr "prefix_0f" "1")
10243 (set_attr "mode" "DI")])
10245 (define_insn "*btrq"
10246 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10248 (match_operand:DI 1 "const_0_to_63_operand" ""))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10252 "btr{q}\t{%1, %0|%0, %1}"
10253 [(set_attr "type" "alu1")
10254 (set_attr "prefix_0f" "1")
10255 (set_attr "mode" "DI")])
10257 (define_insn "*btcq"
10258 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10260 (match_operand:DI 1 "const_0_to_63_operand" ""))
10261 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10264 "btc{q}\t{%1, %0|%0, %1}"
10265 [(set_attr "type" "alu1")
10266 (set_attr "prefix_0f" "1")
10267 (set_attr "mode" "DI")])
10269 ;; Allow Nocona to avoid these instructions if a register is available.
10272 [(match_scratch:DI 2 "r")
10273 (parallel [(set (zero_extract:DI
10274 (match_operand:DI 0 "register_operand" "")
10276 (match_operand:DI 1 "const_0_to_63_operand" ""))
10278 (clobber (reg:CC FLAGS_REG))])]
10279 "TARGET_64BIT && !TARGET_USE_BT"
10282 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10285 if (HOST_BITS_PER_WIDE_INT >= 64)
10286 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10287 else if (i < HOST_BITS_PER_WIDE_INT)
10288 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10290 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10292 op1 = immed_double_const (lo, hi, DImode);
10295 emit_move_insn (operands[2], op1);
10299 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10304 [(match_scratch:DI 2 "r")
10305 (parallel [(set (zero_extract:DI
10306 (match_operand:DI 0 "register_operand" "")
10308 (match_operand:DI 1 "const_0_to_63_operand" ""))
10310 (clobber (reg:CC FLAGS_REG))])]
10311 "TARGET_64BIT && !TARGET_USE_BT"
10314 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10317 if (HOST_BITS_PER_WIDE_INT >= 64)
10318 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10319 else if (i < HOST_BITS_PER_WIDE_INT)
10320 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10322 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10324 op1 = immed_double_const (~lo, ~hi, DImode);
10327 emit_move_insn (operands[2], op1);
10331 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10336 [(match_scratch:DI 2 "r")
10337 (parallel [(set (zero_extract:DI
10338 (match_operand:DI 0 "register_operand" "")
10340 (match_operand:DI 1 "const_0_to_63_operand" ""))
10341 (not:DI (zero_extract:DI
10342 (match_dup 0) (const_int 1) (match_dup 1))))
10343 (clobber (reg:CC FLAGS_REG))])]
10344 "TARGET_64BIT && !TARGET_USE_BT"
10347 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10350 if (HOST_BITS_PER_WIDE_INT >= 64)
10351 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10352 else if (i < HOST_BITS_PER_WIDE_INT)
10353 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10355 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10357 op1 = immed_double_const (lo, hi, DImode);
10360 emit_move_insn (operands[2], op1);
10364 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10368 (define_insn "*bt<mode>"
10369 [(set (reg:CCC FLAGS_REG)
10371 (zero_extract:SWI48
10372 (match_operand:SWI48 0 "register_operand" "r")
10374 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10376 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10377 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10378 [(set_attr "type" "alu1")
10379 (set_attr "prefix_0f" "1")
10380 (set_attr "mode" "<MODE>")])
10382 ;; Store-flag instructions.
10384 ;; For all sCOND expanders, also expand the compare or test insn that
10385 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10387 (define_insn_and_split "*setcc_di_1"
10388 [(set (match_operand:DI 0 "register_operand" "=q")
10389 (match_operator:DI 1 "ix86_comparison_operator"
10390 [(reg FLAGS_REG) (const_int 0)]))]
10391 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10393 "&& reload_completed"
10394 [(set (match_dup 2) (match_dup 1))
10395 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10397 PUT_MODE (operands[1], QImode);
10398 operands[2] = gen_lowpart (QImode, operands[0]);
10401 (define_insn_and_split "*setcc_si_1_and"
10402 [(set (match_operand:SI 0 "register_operand" "=q")
10403 (match_operator:SI 1 "ix86_comparison_operator"
10404 [(reg FLAGS_REG) (const_int 0)]))
10405 (clobber (reg:CC FLAGS_REG))]
10406 "!TARGET_PARTIAL_REG_STALL
10407 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10409 "&& reload_completed"
10410 [(set (match_dup 2) (match_dup 1))
10411 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10412 (clobber (reg:CC FLAGS_REG))])]
10414 PUT_MODE (operands[1], QImode);
10415 operands[2] = gen_lowpart (QImode, operands[0]);
10418 (define_insn_and_split "*setcc_si_1_movzbl"
10419 [(set (match_operand:SI 0 "register_operand" "=q")
10420 (match_operator:SI 1 "ix86_comparison_operator"
10421 [(reg FLAGS_REG) (const_int 0)]))]
10422 "!TARGET_PARTIAL_REG_STALL
10423 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10425 "&& reload_completed"
10426 [(set (match_dup 2) (match_dup 1))
10427 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10429 PUT_MODE (operands[1], QImode);
10430 operands[2] = gen_lowpart (QImode, operands[0]);
10433 (define_insn "*setcc_qi"
10434 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10435 (match_operator:QI 1 "ix86_comparison_operator"
10436 [(reg FLAGS_REG) (const_int 0)]))]
10439 [(set_attr "type" "setcc")
10440 (set_attr "mode" "QI")])
10442 (define_insn "*setcc_qi_slp"
10443 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10444 (match_operator:QI 1 "ix86_comparison_operator"
10445 [(reg FLAGS_REG) (const_int 0)]))]
10448 [(set_attr "type" "setcc")
10449 (set_attr "mode" "QI")])
10451 ;; In general it is not safe to assume too much about CCmode registers,
10452 ;; so simplify-rtx stops when it sees a second one. Under certain
10453 ;; conditions this is safe on x86, so help combine not create
10460 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10461 (ne:QI (match_operator 1 "ix86_comparison_operator"
10462 [(reg FLAGS_REG) (const_int 0)])
10465 [(set (match_dup 0) (match_dup 1))]
10466 "PUT_MODE (operands[1], QImode);")
10469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10470 (ne:QI (match_operator 1 "ix86_comparison_operator"
10471 [(reg FLAGS_REG) (const_int 0)])
10474 [(set (match_dup 0) (match_dup 1))]
10475 "PUT_MODE (operands[1], QImode);")
10478 [(set (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))
10498 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10499 (eq:QI (match_operator 1 "ix86_comparison_operator"
10500 [(reg FLAGS_REG) (const_int 0)])
10503 [(set (match_dup 0) (match_dup 1))]
10505 rtx new_op1 = copy_rtx (operands[1]);
10506 operands[1] = new_op1;
10507 PUT_MODE (new_op1, QImode);
10508 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10509 GET_MODE (XEXP (new_op1, 0))));
10511 /* Make sure that (a) the CCmode we have for the flags is strong
10512 enough for the reversed compare or (b) we have a valid FP compare. */
10513 if (! ix86_comparison_operator (new_op1, VOIDmode))
10517 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10518 ;; subsequent logical operations are used to imitate conditional moves.
10519 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10522 (define_insn "setcc_<mode>_sse"
10523 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10524 (match_operator:MODEF 3 "sse_comparison_operator"
10525 [(match_operand:MODEF 1 "register_operand" "0,x")
10526 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10527 "SSE_FLOAT_MODE_P (<MODE>mode)"
10529 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10530 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10531 [(set_attr "isa" "noavx,avx")
10532 (set_attr "type" "ssecmp")
10533 (set_attr "length_immediate" "1")
10534 (set_attr "prefix" "orig,vex")
10535 (set_attr "mode" "<MODE>")])
10537 ;; Basic conditional jump instructions.
10538 ;; We ignore the overflow flag for signed branch instructions.
10540 (define_insn "*jcc_1"
10542 (if_then_else (match_operator 1 "ix86_comparison_operator"
10543 [(reg FLAGS_REG) (const_int 0)])
10544 (label_ref (match_operand 0 "" ""))
10548 [(set_attr "type" "ibr")
10549 (set_attr "modrm" "0")
10550 (set (attr "length")
10551 (if_then_else (and (ge (minus (match_dup 0) (pc))
10553 (lt (minus (match_dup 0) (pc))
10558 (define_insn "*jcc_2"
10560 (if_then_else (match_operator 1 "ix86_comparison_operator"
10561 [(reg FLAGS_REG) (const_int 0)])
10563 (label_ref (match_operand 0 "" ""))))]
10566 [(set_attr "type" "ibr")
10567 (set_attr "modrm" "0")
10568 (set (attr "length")
10569 (if_then_else (and (ge (minus (match_dup 0) (pc))
10571 (lt (minus (match_dup 0) (pc))
10576 ;; In general it is not safe to assume too much about CCmode registers,
10577 ;; so simplify-rtx stops when it sees a second one. Under certain
10578 ;; conditions this is safe on x86, so help combine not create
10586 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10587 [(reg FLAGS_REG) (const_int 0)])
10589 (label_ref (match_operand 1 "" ""))
10593 (if_then_else (match_dup 0)
10594 (label_ref (match_dup 1))
10596 "PUT_MODE (operands[0], VOIDmode);")
10600 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10601 [(reg FLAGS_REG) (const_int 0)])
10603 (label_ref (match_operand 1 "" ""))
10607 (if_then_else (match_dup 0)
10608 (label_ref (match_dup 1))
10611 rtx new_op0 = copy_rtx (operands[0]);
10612 operands[0] = new_op0;
10613 PUT_MODE (new_op0, VOIDmode);
10614 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10615 GET_MODE (XEXP (new_op0, 0))));
10617 /* Make sure that (a) the CCmode we have for the flags is strong
10618 enough for the reversed compare or (b) we have a valid FP compare. */
10619 if (! ix86_comparison_operator (new_op0, VOIDmode))
10623 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10624 ;; pass generates from shift insn with QImode operand. Actually, the mode
10625 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10626 ;; appropriate modulo of the bit offset value.
10628 (define_insn_and_split "*jcc_bt<mode>"
10630 (if_then_else (match_operator 0 "bt_comparison_operator"
10631 [(zero_extract:SWI48
10632 (match_operand:SWI48 1 "register_operand" "r")
10635 (match_operand:QI 2 "register_operand" "r")))
10637 (label_ref (match_operand 3 "" ""))
10639 (clobber (reg:CC FLAGS_REG))]
10640 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10643 [(set (reg:CCC FLAGS_REG)
10645 (zero_extract:SWI48
10651 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10652 (label_ref (match_dup 3))
10655 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10657 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10660 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10661 ;; also for DImode, this is what combine produces.
10662 (define_insn_and_split "*jcc_bt<mode>_mask"
10664 (if_then_else (match_operator 0 "bt_comparison_operator"
10665 [(zero_extract:SWI48
10666 (match_operand:SWI48 1 "register_operand" "r")
10669 (match_operand:SI 2 "register_operand" "r")
10670 (match_operand:SI 3 "const_int_operand" "n")))])
10671 (label_ref (match_operand 4 "" ""))
10673 (clobber (reg:CC FLAGS_REG))]
10674 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10675 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10676 == GET_MODE_BITSIZE (<MODE>mode)-1"
10679 [(set (reg:CCC FLAGS_REG)
10681 (zero_extract:SWI48
10687 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688 (label_ref (match_dup 4))
10691 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10693 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10696 (define_insn_and_split "*jcc_btsi_1"
10698 (if_then_else (match_operator 0 "bt_comparison_operator"
10701 (match_operand:SI 1 "register_operand" "r")
10702 (match_operand:QI 2 "register_operand" "r"))
10705 (label_ref (match_operand 3 "" ""))
10707 (clobber (reg:CC FLAGS_REG))]
10708 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10711 [(set (reg:CCC FLAGS_REG)
10719 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10720 (label_ref (match_dup 3))
10723 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10725 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10728 ;; avoid useless masking of bit offset operand
10729 (define_insn_and_split "*jcc_btsi_mask_1"
10732 (match_operator 0 "bt_comparison_operator"
10735 (match_operand:SI 1 "register_operand" "r")
10738 (match_operand:SI 2 "register_operand" "r")
10739 (match_operand:SI 3 "const_int_operand" "n")) 0))
10742 (label_ref (match_operand 4 "" ""))
10744 (clobber (reg:CC FLAGS_REG))]
10745 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10746 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10749 [(set (reg:CCC FLAGS_REG)
10757 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10758 (label_ref (match_dup 4))
10760 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10762 ;; Define combination compare-and-branch fp compare instructions to help
10765 (define_insn "*fp_jcc_1_387"
10767 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10768 [(match_operand 1 "register_operand" "f")
10769 (match_operand 2 "nonimmediate_operand" "fm")])
10770 (label_ref (match_operand 3 "" ""))
10772 (clobber (reg:CCFP FPSR_REG))
10773 (clobber (reg:CCFP FLAGS_REG))
10774 (clobber (match_scratch:HI 4 "=a"))]
10776 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10777 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10778 && SELECT_CC_MODE (GET_CODE (operands[0]),
10779 operands[1], operands[2]) == CCFPmode
10783 (define_insn "*fp_jcc_1r_387"
10785 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10786 [(match_operand 1 "register_operand" "f")
10787 (match_operand 2 "nonimmediate_operand" "fm")])
10789 (label_ref (match_operand 3 "" ""))))
10790 (clobber (reg:CCFP FPSR_REG))
10791 (clobber (reg:CCFP FLAGS_REG))
10792 (clobber (match_scratch:HI 4 "=a"))]
10794 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10795 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10796 && SELECT_CC_MODE (GET_CODE (operands[0]),
10797 operands[1], operands[2]) == CCFPmode
10801 (define_insn "*fp_jcc_2_387"
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "register_operand" "f")])
10806 (label_ref (match_operand 3 "" ""))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10811 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10816 (define_insn "*fp_jcc_2r_387"
10818 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819 [(match_operand 1 "register_operand" "f")
10820 (match_operand 2 "register_operand" "f")])
10822 (label_ref (match_operand 3 "" ""))))
10823 (clobber (reg:CCFP FPSR_REG))
10824 (clobber (reg:CCFP FLAGS_REG))
10825 (clobber (match_scratch:HI 4 "=a"))]
10826 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10831 (define_insn "*fp_jcc_3_387"
10833 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10834 [(match_operand 1 "register_operand" "f")
10835 (match_operand 2 "const0_operand" "")])
10836 (label_ref (match_operand 3 "" ""))
10838 (clobber (reg:CCFP FPSR_REG))
10839 (clobber (reg:CCFP FLAGS_REG))
10840 (clobber (match_scratch:HI 4 "=a"))]
10841 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10842 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10843 && SELECT_CC_MODE (GET_CODE (operands[0]),
10844 operands[1], operands[2]) == CCFPmode
10850 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10851 [(match_operand 1 "register_operand" "")
10852 (match_operand 2 "nonimmediate_operand" "")])
10853 (match_operand 3 "" "")
10854 (match_operand 4 "" "")))
10855 (clobber (reg:CCFP FPSR_REG))
10856 (clobber (reg:CCFP FLAGS_REG))]
10860 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10861 operands[3], operands[4], NULL_RTX, NULL_RTX);
10867 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10868 [(match_operand 1 "register_operand" "")
10869 (match_operand 2 "general_operand" "")])
10870 (match_operand 3 "" "")
10871 (match_operand 4 "" "")))
10872 (clobber (reg:CCFP FPSR_REG))
10873 (clobber (reg:CCFP FLAGS_REG))
10874 (clobber (match_scratch:HI 5 "=a"))]
10878 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10879 operands[3], operands[4], operands[5], NULL_RTX);
10883 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10884 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10885 ;; with a precedence over other operators and is always put in the first
10886 ;; place. Swap condition and operands to match ficom instruction.
10888 (define_insn "*fp_jcc_4_<mode>_387"
10891 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10892 [(match_operator 1 "float_operator"
10893 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10894 (match_operand 3 "register_operand" "f,f")])
10895 (label_ref (match_operand 4 "" ""))
10897 (clobber (reg:CCFP FPSR_REG))
10898 (clobber (reg:CCFP FLAGS_REG))
10899 (clobber (match_scratch:HI 5 "=a,a"))]
10900 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10901 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10902 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10903 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10910 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10911 [(match_operator 1 "float_operator"
10912 [(match_operand:SWI24 2 "memory_operand" "")])
10913 (match_operand 3 "register_operand" "")])
10914 (match_operand 4 "" "")
10915 (match_operand 5 "" "")))
10916 (clobber (reg:CCFP FPSR_REG))
10917 (clobber (reg:CCFP FLAGS_REG))
10918 (clobber (match_scratch:HI 6 "=a"))]
10922 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10924 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10925 operands[3], operands[7],
10926 operands[4], operands[5], operands[6], NULL_RTX);
10930 ;; %%% Kill this when reload knows how to do it.
10934 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10935 [(match_operator 1 "float_operator"
10936 [(match_operand:SWI24 2 "register_operand" "")])
10937 (match_operand 3 "register_operand" "")])
10938 (match_operand 4 "" "")
10939 (match_operand 5 "" "")))
10940 (clobber (reg:CCFP FPSR_REG))
10941 (clobber (reg:CCFP FLAGS_REG))
10942 (clobber (match_scratch:HI 6 "=a"))]
10946 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10947 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10949 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10950 operands[3], operands[7],
10951 operands[4], operands[5], operands[6], operands[2]);
10955 ;; Unconditional and other jump instructions
10957 (define_insn "jump"
10959 (label_ref (match_operand 0 "" "")))]
10962 [(set_attr "type" "ibr")
10963 (set (attr "length")
10964 (if_then_else (and (ge (minus (match_dup 0) (pc))
10966 (lt (minus (match_dup 0) (pc))
10970 (set_attr "modrm" "0")])
10972 (define_expand "indirect_jump"
10973 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10977 (define_insn "*indirect_jump"
10978 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10981 [(set_attr "type" "ibr")
10982 (set_attr "length_immediate" "0")])
10984 (define_expand "tablejump"
10985 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10986 (use (label_ref (match_operand 1 "" "")))])]
10989 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10990 relative. Convert the relative address to an absolute address. */
10994 enum rtx_code code;
10996 /* We can't use @GOTOFF for text labels on VxWorks;
10997 see gotoff_operand. */
10998 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11002 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11004 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11008 op1 = pic_offset_table_rtx;
11013 op0 = pic_offset_table_rtx;
11017 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11022 (define_insn "*tablejump_1"
11023 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11024 (use (label_ref (match_operand 1 "" "")))]
11027 [(set_attr "type" "ibr")
11028 (set_attr "length_immediate" "0")])
11030 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11033 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11034 (set (match_operand:QI 1 "register_operand" "")
11035 (match_operator:QI 2 "ix86_comparison_operator"
11036 [(reg FLAGS_REG) (const_int 0)]))
11037 (set (match_operand 3 "q_regs_operand" "")
11038 (zero_extend (match_dup 1)))]
11039 "(peep2_reg_dead_p (3, operands[1])
11040 || operands_match_p (operands[1], operands[3]))
11041 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11042 [(set (match_dup 4) (match_dup 0))
11043 (set (strict_low_part (match_dup 5))
11046 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11047 operands[5] = gen_lowpart (QImode, operands[3]);
11048 ix86_expand_clear (operands[3]);
11051 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11054 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11055 (set (match_operand:QI 1 "register_operand" "")
11056 (match_operator:QI 2 "ix86_comparison_operator"
11057 [(reg FLAGS_REG) (const_int 0)]))
11058 (parallel [(set (match_operand 3 "q_regs_operand" "")
11059 (zero_extend (match_dup 1)))
11060 (clobber (reg:CC FLAGS_REG))])]
11061 "(peep2_reg_dead_p (3, operands[1])
11062 || operands_match_p (operands[1], operands[3]))
11063 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11064 [(set (match_dup 4) (match_dup 0))
11065 (set (strict_low_part (match_dup 5))
11068 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11069 operands[5] = gen_lowpart (QImode, operands[3]);
11070 ix86_expand_clear (operands[3]);
11073 ;; Call instructions.
11075 ;; The predicates normally associated with named expanders are not properly
11076 ;; checked for calls. This is a bug in the generic code, but it isn't that
11077 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11079 ;; P6 processors will jump to the address after the decrement when %esp
11080 ;; is used as a call operand, so they will execute return address as a code.
11081 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11083 ;; Register constraint for call instruction.
11084 (define_mode_attr c [(SI "l") (DI "r")])
11086 ;; Call subroutine returning no value.
11088 (define_expand "call"
11089 [(call (match_operand:QI 0 "" "")
11090 (match_operand 1 "" ""))
11091 (use (match_operand 2 "" ""))]
11094 ix86_expand_call (NULL, operands[0], operands[1],
11095 operands[2], NULL, false);
11099 (define_expand "sibcall"
11100 [(call (match_operand:QI 0 "" "")
11101 (match_operand 1 "" ""))
11102 (use (match_operand 2 "" ""))]
11105 ix86_expand_call (NULL, operands[0], operands[1],
11106 operands[2], NULL, true);
11110 (define_insn_and_split "*call_vzeroupper"
11111 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11112 (match_operand 1 "" ""))
11113 (unspec [(match_operand 2 "const_int_operand" "")]
11114 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11115 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11117 "&& reload_completed"
11119 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11120 [(set_attr "type" "call")])
11122 (define_insn "*call"
11123 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11124 (match_operand 1 "" ""))]
11125 "!SIBLING_CALL_P (insn)"
11126 "* return ix86_output_call_insn (insn, operands[0]);"
11127 [(set_attr "type" "call")])
11129 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11131 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11132 (match_operand 1 "" ""))
11133 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11134 (clobber (reg:TI XMM6_REG))
11135 (clobber (reg:TI XMM7_REG))
11136 (clobber (reg:TI XMM8_REG))
11137 (clobber (reg:TI XMM9_REG))
11138 (clobber (reg:TI XMM10_REG))
11139 (clobber (reg:TI XMM11_REG))
11140 (clobber (reg:TI XMM12_REG))
11141 (clobber (reg:TI XMM13_REG))
11142 (clobber (reg:TI XMM14_REG))
11143 (clobber (reg:TI XMM15_REG))
11144 (clobber (reg:DI SI_REG))
11145 (clobber (reg:DI DI_REG))])
11146 (unspec [(match_operand 2 "const_int_operand" "")]
11147 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11148 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11150 "&& reload_completed"
11152 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11153 [(set_attr "type" "call")])
11155 (define_insn "*call_rex64_ms_sysv"
11156 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11157 (match_operand 1 "" ""))
11158 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11159 (clobber (reg:TI XMM6_REG))
11160 (clobber (reg:TI XMM7_REG))
11161 (clobber (reg:TI XMM8_REG))
11162 (clobber (reg:TI XMM9_REG))
11163 (clobber (reg:TI XMM10_REG))
11164 (clobber (reg:TI XMM11_REG))
11165 (clobber (reg:TI XMM12_REG))
11166 (clobber (reg:TI XMM13_REG))
11167 (clobber (reg:TI XMM14_REG))
11168 (clobber (reg:TI XMM15_REG))
11169 (clobber (reg:DI SI_REG))
11170 (clobber (reg:DI DI_REG))]
11171 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11172 "* return ix86_output_call_insn (insn, operands[0]);"
11173 [(set_attr "type" "call")])
11175 (define_insn_and_split "*sibcall_vzeroupper"
11176 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11177 (match_operand 1 "" ""))
11178 (unspec [(match_operand 2 "const_int_operand" "")]
11179 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11180 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11182 "&& reload_completed"
11184 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11185 [(set_attr "type" "call")])
11187 (define_insn "*sibcall"
11188 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11189 (match_operand 1 "" ""))]
11190 "SIBLING_CALL_P (insn)"
11191 "* return ix86_output_call_insn (insn, operands[0]);"
11192 [(set_attr "type" "call")])
11194 (define_expand "call_pop"
11195 [(parallel [(call (match_operand:QI 0 "" "")
11196 (match_operand:SI 1 "" ""))
11197 (set (reg:SI SP_REG)
11198 (plus:SI (reg:SI SP_REG)
11199 (match_operand:SI 3 "" "")))])]
11202 ix86_expand_call (NULL, operands[0], operands[1],
11203 operands[2], operands[3], false);
11207 (define_insn_and_split "*call_pop_vzeroupper"
11209 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11210 (match_operand:SI 1 "" ""))
11211 (set (reg:SI SP_REG)
11212 (plus:SI (reg:SI SP_REG)
11213 (match_operand:SI 2 "immediate_operand" "i")))])
11214 (unspec [(match_operand 3 "const_int_operand" "")]
11215 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11216 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11218 "&& reload_completed"
11220 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11221 [(set_attr "type" "call")])
11223 (define_insn "*call_pop"
11224 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11225 (match_operand 1 "" ""))
11226 (set (reg:SI SP_REG)
11227 (plus:SI (reg:SI SP_REG)
11228 (match_operand:SI 2 "immediate_operand" "i")))]
11229 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11230 "* return ix86_output_call_insn (insn, operands[0]);"
11231 [(set_attr "type" "call")])
11233 (define_insn_and_split "*sibcall_pop_vzeroupper"
11235 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11236 (match_operand 1 "" ""))
11237 (set (reg:SI SP_REG)
11238 (plus:SI (reg:SI SP_REG)
11239 (match_operand:SI 2 "immediate_operand" "i")))])
11240 (unspec [(match_operand 3 "const_int_operand" "")]
11241 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11242 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11244 "&& reload_completed"
11246 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11247 [(set_attr "type" "call")])
11249 (define_insn "*sibcall_pop"
11250 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11251 (match_operand 1 "" ""))
11252 (set (reg:SI SP_REG)
11253 (plus:SI (reg:SI SP_REG)
11254 (match_operand:SI 2 "immediate_operand" "i")))]
11255 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11256 "* return ix86_output_call_insn (insn, operands[0]);"
11257 [(set_attr "type" "call")])
11259 ;; Call subroutine, returning value in operand 0
11261 (define_expand "call_value"
11262 [(set (match_operand 0 "" "")
11263 (call (match_operand:QI 1 "" "")
11264 (match_operand 2 "" "")))
11265 (use (match_operand 3 "" ""))]
11268 ix86_expand_call (operands[0], operands[1], operands[2],
11269 operands[3], NULL, false);
11273 (define_expand "sibcall_value"
11274 [(set (match_operand 0 "" "")
11275 (call (match_operand:QI 1 "" "")
11276 (match_operand 2 "" "")))
11277 (use (match_operand 3 "" ""))]
11280 ix86_expand_call (operands[0], operands[1], operands[2],
11281 operands[3], NULL, true);
11285 (define_insn_and_split "*call_value_vzeroupper"
11286 [(set (match_operand 0 "" "")
11287 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11288 (match_operand 2 "" "")))
11289 (unspec [(match_operand 3 "const_int_operand" "")]
11290 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11291 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11293 "&& reload_completed"
11295 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11296 [(set_attr "type" "callv")])
11298 (define_insn "*call_value"
11299 [(set (match_operand 0 "" "")
11300 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11301 (match_operand 2 "" "")))]
11302 "!SIBLING_CALL_P (insn)"
11303 "* return ix86_output_call_insn (insn, operands[1]);"
11304 [(set_attr "type" "callv")])
11306 (define_insn_and_split "*sibcall_value_vzeroupper"
11307 [(set (match_operand 0 "" "")
11308 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11309 (match_operand 2 "" "")))
11310 (unspec [(match_operand 3 "const_int_operand" "")]
11311 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11312 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11314 "&& reload_completed"
11316 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11317 [(set_attr "type" "callv")])
11319 (define_insn "*sibcall_value"
11320 [(set (match_operand 0 "" "")
11321 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11322 (match_operand 2 "" "")))]
11323 "SIBLING_CALL_P (insn)"
11324 "* return ix86_output_call_insn (insn, operands[1]);"
11325 [(set_attr "type" "callv")])
11327 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11329 [(set (match_operand 0 "" "")
11330 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11331 (match_operand 2 "" "")))
11332 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11333 (clobber (reg:TI XMM6_REG))
11334 (clobber (reg:TI XMM7_REG))
11335 (clobber (reg:TI XMM8_REG))
11336 (clobber (reg:TI XMM9_REG))
11337 (clobber (reg:TI XMM10_REG))
11338 (clobber (reg:TI XMM11_REG))
11339 (clobber (reg:TI XMM12_REG))
11340 (clobber (reg:TI XMM13_REG))
11341 (clobber (reg:TI XMM14_REG))
11342 (clobber (reg:TI XMM15_REG))
11343 (clobber (reg:DI SI_REG))
11344 (clobber (reg:DI DI_REG))])
11345 (unspec [(match_operand 3 "const_int_operand" "")]
11346 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11347 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11349 "&& reload_completed"
11351 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11352 [(set_attr "type" "callv")])
11354 (define_insn "*call_value_rex64_ms_sysv"
11355 [(set (match_operand 0 "" "")
11356 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11357 (match_operand 2 "" "")))
11358 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11359 (clobber (reg:TI XMM6_REG))
11360 (clobber (reg:TI XMM7_REG))
11361 (clobber (reg:TI XMM8_REG))
11362 (clobber (reg:TI XMM9_REG))
11363 (clobber (reg:TI XMM10_REG))
11364 (clobber (reg:TI XMM11_REG))
11365 (clobber (reg:TI XMM12_REG))
11366 (clobber (reg:TI XMM13_REG))
11367 (clobber (reg:TI XMM14_REG))
11368 (clobber (reg:TI XMM15_REG))
11369 (clobber (reg:DI SI_REG))
11370 (clobber (reg:DI DI_REG))]
11371 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11372 "* return ix86_output_call_insn (insn, operands[1]);"
11373 [(set_attr "type" "callv")])
11375 (define_expand "call_value_pop"
11376 [(parallel [(set (match_operand 0 "" "")
11377 (call (match_operand:QI 1 "" "")
11378 (match_operand:SI 2 "" "")))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 4 "" "")))])]
11384 ix86_expand_call (operands[0], operands[1], operands[2],
11385 operands[3], operands[4], false);
11389 (define_insn_and_split "*call_value_pop_vzeroupper"
11391 [(set (match_operand 0 "" "")
11392 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11393 (match_operand 2 "" "")))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 3 "immediate_operand" "i")))])
11397 (unspec [(match_operand 4 "const_int_operand" "")]
11398 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11401 "&& reload_completed"
11403 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11404 [(set_attr "type" "callv")])
11406 (define_insn "*call_value_pop"
11407 [(set (match_operand 0 "" "")
11408 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11409 (match_operand 2 "" "")))
11410 (set (reg:SI SP_REG)
11411 (plus:SI (reg:SI SP_REG)
11412 (match_operand:SI 3 "immediate_operand" "i")))]
11413 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11414 "* return ix86_output_call_insn (insn, operands[1]);"
11415 [(set_attr "type" "callv")])
11417 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11419 [(set (match_operand 0 "" "")
11420 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11421 (match_operand 2 "" "")))
11422 (set (reg:SI SP_REG)
11423 (plus:SI (reg:SI SP_REG)
11424 (match_operand:SI 3 "immediate_operand" "i")))])
11425 (unspec [(match_operand 4 "const_int_operand" "")]
11426 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11427 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11429 "&& reload_completed"
11431 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11432 [(set_attr "type" "callv")])
11434 (define_insn "*sibcall_value_pop"
11435 [(set (match_operand 0 "" "")
11436 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11437 (match_operand 2 "" "")))
11438 (set (reg:SI SP_REG)
11439 (plus:SI (reg:SI SP_REG)
11440 (match_operand:SI 3 "immediate_operand" "i")))]
11441 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11442 "* return ix86_output_call_insn (insn, operands[1]);"
11443 [(set_attr "type" "callv")])
11445 ;; Call subroutine returning any type.
11447 (define_expand "untyped_call"
11448 [(parallel [(call (match_operand 0 "" "")
11450 (match_operand 1 "" "")
11451 (match_operand 2 "" "")])]
11456 /* In order to give reg-stack an easier job in validating two
11457 coprocessor registers as containing a possible return value,
11458 simply pretend the untyped call returns a complex long double
11461 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11462 and should have the default ABI. */
11464 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11465 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11466 operands[0], const0_rtx,
11467 GEN_INT ((TARGET_64BIT
11468 ? (ix86_abi == SYSV_ABI
11469 ? X86_64_SSE_REGPARM_MAX
11470 : X86_64_MS_SSE_REGPARM_MAX)
11471 : X86_32_SSE_REGPARM_MAX)
11475 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11477 rtx set = XVECEXP (operands[2], 0, i);
11478 emit_move_insn (SET_DEST (set), SET_SRC (set));
11481 /* The optimizer does not know that the call sets the function value
11482 registers we stored in the result block. We avoid problems by
11483 claiming that all hard registers are used and clobbered at this
11485 emit_insn (gen_blockage ());
11490 ;; Prologue and epilogue instructions
11492 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11493 ;; all of memory. This blocks insns from being moved across this point.
11495 (define_insn "blockage"
11496 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11499 [(set_attr "length" "0")])
11501 ;; Do not schedule instructions accessing memory across this point.
11503 (define_expand "memory_blockage"
11504 [(set (match_dup 0)
11505 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11508 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11509 MEM_VOLATILE_P (operands[0]) = 1;
11512 (define_insn "*memory_blockage"
11513 [(set (match_operand:BLK 0 "" "")
11514 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11517 [(set_attr "length" "0")])
11519 ;; As USE insns aren't meaningful after reload, this is used instead
11520 ;; to prevent deleting instructions setting registers for PIC code
11521 (define_insn "prologue_use"
11522 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11525 [(set_attr "length" "0")])
11527 ;; Insn emitted into the body of a function to return from a function.
11528 ;; This is only done if the function's epilogue is known to be simple.
11529 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11531 (define_expand "return"
11533 "ix86_can_use_return_insn_p ()"
11535 if (crtl->args.pops_args)
11537 rtx popc = GEN_INT (crtl->args.pops_args);
11538 emit_jump_insn (gen_return_pop_internal (popc));
11543 (define_insn "return_internal"
11547 [(set_attr "length" "1")
11548 (set_attr "atom_unit" "jeu")
11549 (set_attr "length_immediate" "0")
11550 (set_attr "modrm" "0")])
11552 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11553 ;; instruction Athlon and K8 have.
11555 (define_insn "return_internal_long"
11557 (unspec [(const_int 0)] UNSPEC_REP)]
11560 [(set_attr "length" "2")
11561 (set_attr "atom_unit" "jeu")
11562 (set_attr "length_immediate" "0")
11563 (set_attr "prefix_rep" "1")
11564 (set_attr "modrm" "0")])
11566 (define_insn "return_pop_internal"
11568 (use (match_operand:SI 0 "const_int_operand" ""))]
11571 [(set_attr "length" "3")
11572 (set_attr "atom_unit" "jeu")
11573 (set_attr "length_immediate" "2")
11574 (set_attr "modrm" "0")])
11576 (define_insn "return_indirect_internal"
11578 (use (match_operand:SI 0 "register_operand" "r"))]
11581 [(set_attr "type" "ibr")
11582 (set_attr "length_immediate" "0")])
11588 [(set_attr "length" "1")
11589 (set_attr "length_immediate" "0")
11590 (set_attr "modrm" "0")])
11592 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11593 (define_insn "nops"
11594 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11598 int num = INTVAL (operands[0]);
11600 gcc_assert (num >= 1 && num <= 8);
11603 fputs ("\tnop\n", asm_out_file);
11607 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11608 (set_attr "length_immediate" "0")
11609 (set_attr "modrm" "0")])
11611 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11612 ;; branch prediction penalty for the third jump in a 16-byte
11616 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11619 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11620 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11622 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11623 The align insn is used to avoid 3 jump instructions in the row to improve
11624 branch prediction and the benefits hardly outweigh the cost of extra 8
11625 nops on the average inserted by full alignment pseudo operation. */
11629 [(set_attr "length" "16")])
11631 (define_expand "prologue"
11634 "ix86_expand_prologue (); DONE;")
11636 (define_insn "set_got"
11637 [(set (match_operand:SI 0 "register_operand" "=r")
11638 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11639 (clobber (reg:CC FLAGS_REG))]
11641 "* return output_set_got (operands[0], NULL_RTX);"
11642 [(set_attr "type" "multi")
11643 (set_attr "length" "12")])
11645 (define_insn "set_got_labelled"
11646 [(set (match_operand:SI 0 "register_operand" "=r")
11647 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11649 (clobber (reg:CC FLAGS_REG))]
11651 "* return output_set_got (operands[0], operands[1]);"
11652 [(set_attr "type" "multi")
11653 (set_attr "length" "12")])
11655 (define_insn "set_got_rex64"
11656 [(set (match_operand:DI 0 "register_operand" "=r")
11657 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11659 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11660 [(set_attr "type" "lea")
11661 (set_attr "length_address" "4")
11662 (set_attr "mode" "DI")])
11664 (define_insn "set_rip_rex64"
11665 [(set (match_operand:DI 0 "register_operand" "=r")
11666 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11668 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11669 [(set_attr "type" "lea")
11670 (set_attr "length_address" "4")
11671 (set_attr "mode" "DI")])
11673 (define_insn "set_got_offset_rex64"
11674 [(set (match_operand:DI 0 "register_operand" "=r")
11676 [(label_ref (match_operand 1 "" ""))]
11677 UNSPEC_SET_GOT_OFFSET))]
11679 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11680 [(set_attr "type" "imov")
11681 (set_attr "length_immediate" "0")
11682 (set_attr "length_address" "8")
11683 (set_attr "mode" "DI")])
11685 (define_expand "epilogue"
11688 "ix86_expand_epilogue (1); DONE;")
11690 (define_expand "sibcall_epilogue"
11693 "ix86_expand_epilogue (0); DONE;")
11695 (define_expand "eh_return"
11696 [(use (match_operand 0 "register_operand" ""))]
11699 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11701 /* Tricky bit: we write the address of the handler to which we will
11702 be returning into someone else's stack frame, one word below the
11703 stack address we wish to restore. */
11704 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11705 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11706 tmp = gen_rtx_MEM (Pmode, tmp);
11707 emit_move_insn (tmp, ra);
11709 emit_jump_insn (gen_eh_return_internal ());
11714 (define_insn_and_split "eh_return_internal"
11718 "epilogue_completed"
11720 "ix86_expand_epilogue (2); DONE;")
11722 (define_insn "leave"
11723 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11724 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11725 (clobber (mem:BLK (scratch)))]
11728 [(set_attr "type" "leave")])
11730 (define_insn "leave_rex64"
11731 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11732 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11733 (clobber (mem:BLK (scratch)))]
11736 [(set_attr "type" "leave")])
11738 ;; Handle -fsplit-stack.
11740 (define_expand "split_stack_prologue"
11744 ix86_expand_split_stack_prologue ();
11748 ;; In order to support the call/return predictor, we use a return
11749 ;; instruction which the middle-end doesn't see.
11750 (define_insn "split_stack_return"
11751 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11752 UNSPECV_SPLIT_STACK_RETURN)]
11755 if (operands[0] == const0_rtx)
11760 [(set_attr "atom_unit" "jeu")
11761 (set_attr "modrm" "0")
11762 (set (attr "length")
11763 (if_then_else (match_operand:SI 0 "const0_operand" "")
11766 (set (attr "length_immediate")
11767 (if_then_else (match_operand:SI 0 "const0_operand" "")
11771 ;; If there are operand 0 bytes available on the stack, jump to
11774 (define_expand "split_stack_space_check"
11775 [(set (pc) (if_then_else
11776 (ltu (minus (reg SP_REG)
11777 (match_operand 0 "register_operand" ""))
11778 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11779 (label_ref (match_operand 1 "" ""))
11783 rtx reg, size, limit;
11785 reg = gen_reg_rtx (Pmode);
11786 size = force_reg (Pmode, operands[0]);
11787 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11788 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11789 UNSPEC_STACK_CHECK);
11790 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11791 ix86_expand_branch (GEU, reg, limit, operands[1]);
11796 ;; Bit manipulation instructions.
11798 (define_expand "ffs<mode>2"
11799 [(set (match_dup 2) (const_int -1))
11800 (parallel [(set (reg:CCZ FLAGS_REG)
11802 (match_operand:SWI48 1 "nonimmediate_operand" "")
11804 (set (match_operand:SWI48 0 "register_operand" "")
11805 (ctz:SWI48 (match_dup 1)))])
11806 (set (match_dup 0) (if_then_else:SWI48
11807 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11810 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11811 (clobber (reg:CC FLAGS_REG))])]
11814 if (<MODE>mode == SImode && !TARGET_CMOVE)
11816 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11819 operands[2] = gen_reg_rtx (<MODE>mode);
11822 (define_insn_and_split "ffssi2_no_cmove"
11823 [(set (match_operand:SI 0 "register_operand" "=r")
11824 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11825 (clobber (match_scratch:SI 2 "=&q"))
11826 (clobber (reg:CC FLAGS_REG))]
11829 "&& reload_completed"
11830 [(parallel [(set (reg:CCZ FLAGS_REG)
11831 (compare:CCZ (match_dup 1) (const_int 0)))
11832 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11833 (set (strict_low_part (match_dup 3))
11834 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11835 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11836 (clobber (reg:CC FLAGS_REG))])
11837 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11838 (clobber (reg:CC FLAGS_REG))])
11839 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11840 (clobber (reg:CC FLAGS_REG))])]
11842 operands[3] = gen_lowpart (QImode, operands[2]);
11843 ix86_expand_clear (operands[2]);
11846 (define_insn "*ffs<mode>_1"
11847 [(set (reg:CCZ FLAGS_REG)
11848 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11850 (set (match_operand:SWI48 0 "register_operand" "=r")
11851 (ctz:SWI48 (match_dup 1)))]
11853 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11854 [(set_attr "type" "alu1")
11855 (set_attr "prefix_0f" "1")
11856 (set_attr "mode" "<MODE>")])
11858 (define_insn "ctz<mode>2"
11859 [(set (match_operand:SWI248 0 "register_operand" "=r")
11860 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11861 (clobber (reg:CC FLAGS_REG))]
11865 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11867 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11869 [(set_attr "type" "alu1")
11870 (set_attr "prefix_0f" "1")
11871 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11872 (set_attr "mode" "<MODE>")])
11874 (define_expand "clz<mode>2"
11876 [(set (match_operand:SWI248 0 "register_operand" "")
11879 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11880 (clobber (reg:CC FLAGS_REG))])
11882 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11883 (clobber (reg:CC FLAGS_REG))])]
11888 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11891 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11894 (define_insn "clz<mode>2_abm"
11895 [(set (match_operand:SWI248 0 "register_operand" "=r")
11896 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "TARGET_ABM || TARGET_BMI"
11899 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11900 [(set_attr "prefix_rep" "1")
11901 (set_attr "type" "bitmanip")
11902 (set_attr "mode" "<MODE>")])
11904 ;; BMI instructions.
11905 (define_insn "*bmi_andn_<mode>"
11906 [(set (match_operand:SWI48 0 "register_operand" "=r")
11909 (match_operand:SWI48 1 "register_operand" "r"))
11910 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11911 (clobber (reg:CC FLAGS_REG))]
11913 "andn\t{%2, %1, %0|%0, %1, %2}"
11914 [(set_attr "type" "bitmanip")
11915 (set_attr "mode" "<MODE>")])
11917 (define_insn "bmi_bextr_<mode>"
11918 [(set (match_operand:SWI48 0 "register_operand" "=r")
11919 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11920 (match_operand:SWI48 2 "register_operand" "r")]
11922 (clobber (reg:CC FLAGS_REG))]
11924 "bextr\t{%2, %1, %0|%0, %1, %2}"
11925 [(set_attr "type" "bitmanip")
11926 (set_attr "mode" "<MODE>")])
11928 (define_insn "*bmi_blsi_<mode>"
11929 [(set (match_operand:SWI48 0 "register_operand" "=r")
11932 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11934 (clobber (reg:CC FLAGS_REG))]
11936 "blsi\t{%1, %0|%0, %1}"
11937 [(set_attr "type" "bitmanip")
11938 (set_attr "mode" "<MODE>")])
11940 (define_insn "*bmi_blsmsk_<mode>"
11941 [(set (match_operand:SWI48 0 "register_operand" "=r")
11944 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11947 (clobber (reg:CC FLAGS_REG))]
11949 "blsmsk\t{%1, %0|%0, %1}"
11950 [(set_attr "type" "bitmanip")
11951 (set_attr "mode" "<MODE>")])
11953 (define_insn "*bmi_blsr_<mode>"
11954 [(set (match_operand:SWI48 0 "register_operand" "=r")
11957 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11960 (clobber (reg:CC FLAGS_REG))]
11962 "blsr\t{%1, %0|%0, %1}"
11963 [(set_attr "type" "bitmanip")
11964 (set_attr "mode" "<MODE>")])
11966 ;; TBM instructions.
11967 (define_insn "tbm_bextri_<mode>"
11968 [(set (match_operand:SWI48 0 "register_operand" "=r")
11969 (zero_extract:SWI48
11970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11971 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11972 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11973 (clobber (reg:CC FLAGS_REG))]
11976 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11977 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11979 [(set_attr "type" "bitmanip")
11980 (set_attr "mode" "<MODE>")])
11982 (define_insn "*tbm_blcfill_<mode>"
11983 [(set (match_operand:SWI48 0 "register_operand" "=r")
11986 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11989 (clobber (reg:CC FLAGS_REG))]
11991 "blcfill\t{%1, %0|%0, %1}"
11992 [(set_attr "type" "bitmanip")
11993 (set_attr "mode" "<MODE>")])
11995 (define_insn "*tbm_blci_<mode>"
11996 [(set (match_operand:SWI48 0 "register_operand" "=r")
12000 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12003 (clobber (reg:CC FLAGS_REG))]
12005 "blci\t{%1, %0|%0, %1}"
12006 [(set_attr "type" "bitmanip")
12007 (set_attr "mode" "<MODE>")])
12009 (define_insn "*tbm_blcic_<mode>"
12010 [(set (match_operand:SWI48 0 "register_operand" "=r")
12013 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12017 (clobber (reg:CC FLAGS_REG))]
12019 "blcic\t{%1, %0|%0, %1}"
12020 [(set_attr "type" "bitmanip")
12021 (set_attr "mode" "<MODE>")])
12023 (define_insn "*tbm_blcmsk_<mode>"
12024 [(set (match_operand:SWI48 0 "register_operand" "=r")
12027 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12030 (clobber (reg:CC FLAGS_REG))]
12032 "blcmsk\t{%1, %0|%0, %1}"
12033 [(set_attr "type" "bitmanip")
12034 (set_attr "mode" "<MODE>")])
12036 (define_insn "*tbm_blcs_<mode>"
12037 [(set (match_operand:SWI48 0 "register_operand" "=r")
12040 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12043 (clobber (reg:CC FLAGS_REG))]
12045 "blcs\t{%1, %0|%0, %1}"
12046 [(set_attr "type" "bitmanip")
12047 (set_attr "mode" "<MODE>")])
12049 (define_insn "*tbm_blsfill_<mode>"
12050 [(set (match_operand:SWI48 0 "register_operand" "=r")
12053 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12056 (clobber (reg:CC FLAGS_REG))]
12058 "blsfill\t{%1, %0|%0, %1}"
12059 [(set_attr "type" "bitmanip")
12060 (set_attr "mode" "<MODE>")])
12062 (define_insn "*tbm_blsic_<mode>"
12063 [(set (match_operand:SWI48 0 "register_operand" "=r")
12066 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12070 (clobber (reg:CC FLAGS_REG))]
12072 "blsic\t{%1, %0|%0, %1}"
12073 [(set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 (define_insn "*tbm_t1mskc_<mode>"
12077 [(set (match_operand:SWI48 0 "register_operand" "=r")
12080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084 (clobber (reg:CC FLAGS_REG))]
12086 "t1mskc\t{%1, %0|%0, %1}"
12087 [(set_attr "type" "bitmanip")
12088 (set_attr "mode" "<MODE>")])
12090 (define_insn "*tbm_tzmsk_<mode>"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12094 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12098 (clobber (reg:CC FLAGS_REG))]
12100 "tzmsk\t{%1, %0|%0, %1}"
12101 [(set_attr "type" "bitmanip")
12102 (set_attr "mode" "<MODE>")])
12104 (define_insn "bsr_rex64"
12105 [(set (match_operand:DI 0 "register_operand" "=r")
12106 (minus:DI (const_int 63)
12107 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12108 (clobber (reg:CC FLAGS_REG))]
12110 "bsr{q}\t{%1, %0|%0, %1}"
12111 [(set_attr "type" "alu1")
12112 (set_attr "prefix_0f" "1")
12113 (set_attr "mode" "DI")])
12116 [(set (match_operand:SI 0 "register_operand" "=r")
12117 (minus:SI (const_int 31)
12118 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12119 (clobber (reg:CC FLAGS_REG))]
12121 "bsr{l}\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "alu1")
12123 (set_attr "prefix_0f" "1")
12124 (set_attr "mode" "SI")])
12126 (define_insn "*bsrhi"
12127 [(set (match_operand:HI 0 "register_operand" "=r")
12128 (minus:HI (const_int 15)
12129 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12130 (clobber (reg:CC FLAGS_REG))]
12132 "bsr{w}\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "alu1")
12134 (set_attr "prefix_0f" "1")
12135 (set_attr "mode" "HI")])
12137 (define_insn "popcount<mode>2"
12138 [(set (match_operand:SWI248 0 "register_operand" "=r")
12140 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12141 (clobber (reg:CC FLAGS_REG))]
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 "*popcount<mode>2_cmp"
12155 [(set (reg FLAGS_REG)
12158 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12160 (set (match_operand:SWI248 0 "register_operand" "=r")
12161 (popcount:SWI248 (match_dup 1)))]
12162 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12165 return "popcnt\t{%1, %0|%0, %1}";
12167 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12170 [(set_attr "prefix_rep" "1")
12171 (set_attr "type" "bitmanip")
12172 (set_attr "mode" "<MODE>")])
12174 (define_insn "*popcountsi2_cmp_zext"
12175 [(set (reg FLAGS_REG)
12177 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12179 (set (match_operand:DI 0 "register_operand" "=r")
12180 (zero_extend:DI(popcount:SI (match_dup 1))))]
12181 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12184 return "popcnt\t{%1, %0|%0, %1}";
12186 return "popcnt{l}\t{%1, %0|%0, %1}";
12189 [(set_attr "prefix_rep" "1")
12190 (set_attr "type" "bitmanip")
12191 (set_attr "mode" "SI")])
12193 (define_expand "bswap<mode>2"
12194 [(set (match_operand:SWI48 0 "register_operand" "")
12195 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12198 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12200 rtx x = operands[0];
12202 emit_move_insn (x, operands[1]);
12203 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12204 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12205 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12210 (define_insn "*bswap<mode>2_movbe"
12211 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12212 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12214 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12217 movbe\t{%1, %0|%0, %1}
12218 movbe\t{%1, %0|%0, %1}"
12219 [(set_attr "type" "bitmanip,imov,imov")
12220 (set_attr "modrm" "0,1,1")
12221 (set_attr "prefix_0f" "*,1,1")
12222 (set_attr "prefix_extra" "*,1,1")
12223 (set_attr "mode" "<MODE>")])
12225 (define_insn "*bswap<mode>2_1"
12226 [(set (match_operand:SWI48 0 "register_operand" "=r")
12227 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12230 [(set_attr "type" "bitmanip")
12231 (set_attr "modrm" "0")
12232 (set_attr "mode" "<MODE>")])
12234 (define_insn "*bswaphi_lowpart_1"
12235 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12236 (bswap:HI (match_dup 0)))
12237 (clobber (reg:CC FLAGS_REG))]
12238 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12240 xchg{b}\t{%h0, %b0|%b0, %h0}
12241 rol{w}\t{$8, %0|%0, 8}"
12242 [(set_attr "length" "2,4")
12243 (set_attr "mode" "QI,HI")])
12245 (define_insn "bswaphi_lowpart"
12246 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12247 (bswap:HI (match_dup 0)))
12248 (clobber (reg:CC FLAGS_REG))]
12250 "rol{w}\t{$8, %0|%0, 8}"
12251 [(set_attr "length" "4")
12252 (set_attr "mode" "HI")])
12254 (define_expand "paritydi2"
12255 [(set (match_operand:DI 0 "register_operand" "")
12256 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12259 rtx scratch = gen_reg_rtx (QImode);
12262 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12263 NULL_RTX, operands[1]));
12265 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12266 gen_rtx_REG (CCmode, FLAGS_REG),
12268 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12271 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12274 rtx tmp = gen_reg_rtx (SImode);
12276 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12277 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12282 (define_expand "paritysi2"
12283 [(set (match_operand:SI 0 "register_operand" "")
12284 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12287 rtx scratch = gen_reg_rtx (QImode);
12290 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12292 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12293 gen_rtx_REG (CCmode, FLAGS_REG),
12295 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12297 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12301 (define_insn_and_split "paritydi2_cmp"
12302 [(set (reg:CC FLAGS_REG)
12303 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12305 (clobber (match_scratch:DI 0 "=r"))
12306 (clobber (match_scratch:SI 1 "=&r"))
12307 (clobber (match_scratch:HI 2 "=Q"))]
12310 "&& reload_completed"
12312 [(set (match_dup 1)
12313 (xor:SI (match_dup 1) (match_dup 4)))
12314 (clobber (reg:CC FLAGS_REG))])
12316 [(set (reg:CC FLAGS_REG)
12317 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12318 (clobber (match_dup 1))
12319 (clobber (match_dup 2))])]
12321 operands[4] = gen_lowpart (SImode, operands[3]);
12325 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12326 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12329 operands[1] = gen_highpart (SImode, operands[3]);
12332 (define_insn_and_split "paritysi2_cmp"
12333 [(set (reg:CC FLAGS_REG)
12334 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12336 (clobber (match_scratch:SI 0 "=r"))
12337 (clobber (match_scratch:HI 1 "=&Q"))]
12340 "&& reload_completed"
12342 [(set (match_dup 1)
12343 (xor:HI (match_dup 1) (match_dup 3)))
12344 (clobber (reg:CC FLAGS_REG))])
12346 [(set (reg:CC FLAGS_REG)
12347 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12348 (clobber (match_dup 1))])]
12350 operands[3] = gen_lowpart (HImode, operands[2]);
12352 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12353 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12356 (define_insn "*parityhi2_cmp"
12357 [(set (reg:CC FLAGS_REG)
12358 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12360 (clobber (match_scratch:HI 0 "=Q"))]
12362 "xor{b}\t{%h0, %b0|%b0, %h0}"
12363 [(set_attr "length" "2")
12364 (set_attr "mode" "HI")])
12366 ;; Thread-local storage patterns for ELF.
12368 ;; Note that these code sequences must appear exactly as shown
12369 ;; in order to allow linker relaxation.
12371 (define_insn "*tls_global_dynamic_32_gnu"
12372 [(set (match_operand:SI 0 "register_operand" "=a")
12374 [(match_operand:SI 1 "register_operand" "b")
12375 (match_operand:SI 2 "tls_symbolic_operand" "")
12376 (match_operand:SI 3 "constant_call_address_operand" "z")]
12378 (clobber (match_scratch:SI 4 "=d"))
12379 (clobber (match_scratch:SI 5 "=c"))
12380 (clobber (reg:CC FLAGS_REG))]
12381 "!TARGET_64BIT && TARGET_GNU_TLS"
12384 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12385 if (TARGET_SUN_TLS)
12386 #ifdef HAVE_AS_IX86_TLSGDPLT
12387 return "call\t%a2@tlsgdplt";
12389 return "call\t%p3@plt";
12391 return "call\t%P3";
12393 [(set_attr "type" "multi")
12394 (set_attr "length" "12")])
12396 (define_expand "tls_global_dynamic_32"
12398 [(set (match_operand:SI 0 "register_operand" "")
12399 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12400 (match_operand:SI 1 "tls_symbolic_operand" "")
12401 (match_operand:SI 3 "constant_call_address_operand" "")]
12403 (clobber (match_scratch:SI 4 ""))
12404 (clobber (match_scratch:SI 5 ""))
12405 (clobber (reg:CC FLAGS_REG))])])
12407 (define_insn "*tls_global_dynamic_64"
12408 [(set (match_operand:DI 0 "register_operand" "=a")
12410 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12411 (match_operand:DI 3 "" "")))
12412 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12416 fputs (ASM_BYTE "0x66\n", asm_out_file);
12418 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12419 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12420 fputs ("\trex64\n", asm_out_file);
12421 if (TARGET_SUN_TLS)
12422 return "call\t%p2@plt";
12423 return "call\t%P2";
12425 [(set_attr "type" "multi")
12426 (set_attr "length" "16")])
12428 (define_expand "tls_global_dynamic_64"
12430 [(set (match_operand:DI 0 "register_operand" "")
12432 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12434 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12437 (define_insn "*tls_local_dynamic_base_32_gnu"
12438 [(set (match_operand:SI 0 "register_operand" "=a")
12440 [(match_operand:SI 1 "register_operand" "b")
12441 (match_operand:SI 2 "constant_call_address_operand" "z")]
12442 UNSPEC_TLS_LD_BASE))
12443 (clobber (match_scratch:SI 3 "=d"))
12444 (clobber (match_scratch:SI 4 "=c"))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "!TARGET_64BIT && TARGET_GNU_TLS"
12449 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12450 if (TARGET_SUN_TLS)
12451 #ifdef HAVE_AS_IX86_TLSLDMPLT
12452 return "call\t%&@tlsldmplt";
12454 return "call\t%p2@plt";
12456 return "call\t%P2";
12458 [(set_attr "type" "multi")
12459 (set_attr "length" "11")])
12461 (define_expand "tls_local_dynamic_base_32"
12463 [(set (match_operand:SI 0 "register_operand" "")
12465 [(match_operand:SI 1 "register_operand" "")
12466 (match_operand:SI 2 "constant_call_address_operand" "")]
12467 UNSPEC_TLS_LD_BASE))
12468 (clobber (match_scratch:SI 3 ""))
12469 (clobber (match_scratch:SI 4 ""))
12470 (clobber (reg:CC FLAGS_REG))])])
12472 (define_insn "*tls_local_dynamic_base_64"
12473 [(set (match_operand:DI 0 "register_operand" "=a")
12475 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12476 (match_operand:DI 2 "" "")))
12477 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12481 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12482 if (TARGET_SUN_TLS)
12483 return "call\t%p1@plt";
12484 return "call\t%P1";
12486 [(set_attr "type" "multi")
12487 (set_attr "length" "12")])
12489 (define_expand "tls_local_dynamic_base_64"
12491 [(set (match_operand:DI 0 "register_operand" "")
12493 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12495 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12497 ;; Local dynamic of a single variable is a lose. Show combine how
12498 ;; to convert that back to global dynamic.
12500 (define_insn_and_split "*tls_local_dynamic_32_once"
12501 [(set (match_operand:SI 0 "register_operand" "=a")
12503 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12504 (match_operand:SI 2 "constant_call_address_operand" "z")]
12505 UNSPEC_TLS_LD_BASE)
12506 (const:SI (unspec:SI
12507 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12509 (clobber (match_scratch:SI 4 "=d"))
12510 (clobber (match_scratch:SI 5 "=c"))
12511 (clobber (reg:CC FLAGS_REG))]
12516 [(set (match_dup 0)
12517 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12519 (clobber (match_dup 4))
12520 (clobber (match_dup 5))
12521 (clobber (reg:CC FLAGS_REG))])])
12523 ;; Segment register for the thread base ptr load
12524 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12526 ;; Load and add the thread base pointer from %<tp_seg>:0.
12527 (define_insn "*load_tp_<mode>"
12528 [(set (match_operand:P 0 "register_operand" "=r")
12529 (unspec:P [(const_int 0)] UNSPEC_TP))]
12531 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12532 [(set_attr "type" "imov")
12533 (set_attr "modrm" "0")
12534 (set_attr "length" "7")
12535 (set_attr "memory" "load")
12536 (set_attr "imm_disp" "false")])
12538 (define_insn "*add_tp_<mode>"
12539 [(set (match_operand:P 0 "register_operand" "=r")
12540 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12541 (match_operand:P 1 "register_operand" "0")))
12542 (clobber (reg:CC FLAGS_REG))]
12544 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12545 [(set_attr "type" "alu")
12546 (set_attr "modrm" "0")
12547 (set_attr "length" "7")
12548 (set_attr "memory" "load")
12549 (set_attr "imm_disp" "false")])
12551 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12552 ;; %rax as destination of the initial executable code sequence.
12553 (define_insn "tls_initial_exec_64_sun"
12554 [(set (match_operand:DI 0 "register_operand" "=a")
12556 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12557 UNSPEC_TLS_IE_SUN))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_64BIT && TARGET_SUN_TLS"
12562 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12563 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12565 [(set_attr "type" "multi")])
12567 ;; GNU2 TLS patterns can be split.
12569 (define_expand "tls_dynamic_gnu2_32"
12570 [(set (match_dup 3)
12571 (plus:SI (match_operand:SI 2 "register_operand" "")
12573 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12576 [(set (match_operand:SI 0 "register_operand" "")
12577 (unspec:SI [(match_dup 1) (match_dup 3)
12578 (match_dup 2) (reg:SI SP_REG)]
12580 (clobber (reg:CC FLAGS_REG))])]
12581 "!TARGET_64BIT && TARGET_GNU2_TLS"
12583 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12584 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12587 (define_insn "*tls_dynamic_lea_32"
12588 [(set (match_operand:SI 0 "register_operand" "=r")
12589 (plus:SI (match_operand:SI 1 "register_operand" "b")
12591 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12592 UNSPEC_TLSDESC))))]
12593 "!TARGET_64BIT && TARGET_GNU2_TLS"
12594 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12595 [(set_attr "type" "lea")
12596 (set_attr "mode" "SI")
12597 (set_attr "length" "6")
12598 (set_attr "length_address" "4")])
12600 (define_insn "*tls_dynamic_call_32"
12601 [(set (match_operand:SI 0 "register_operand" "=a")
12602 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12603 (match_operand:SI 2 "register_operand" "0")
12604 ;; we have to make sure %ebx still points to the GOT
12605 (match_operand:SI 3 "register_operand" "b")
12608 (clobber (reg:CC FLAGS_REG))]
12609 "!TARGET_64BIT && TARGET_GNU2_TLS"
12610 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12611 [(set_attr "type" "call")
12612 (set_attr "length" "2")
12613 (set_attr "length_address" "0")])
12615 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12616 [(set (match_operand:SI 0 "register_operand" "=&a")
12618 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12619 (match_operand:SI 4 "" "")
12620 (match_operand:SI 2 "register_operand" "b")
12623 (const:SI (unspec:SI
12624 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12626 (clobber (reg:CC FLAGS_REG))]
12627 "!TARGET_64BIT && TARGET_GNU2_TLS"
12630 [(set (match_dup 0) (match_dup 5))]
12632 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12633 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12636 (define_expand "tls_dynamic_gnu2_64"
12637 [(set (match_dup 2)
12638 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12641 [(set (match_operand:DI 0 "register_operand" "")
12642 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12644 (clobber (reg:CC FLAGS_REG))])]
12645 "TARGET_64BIT && TARGET_GNU2_TLS"
12647 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12648 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12651 (define_insn "*tls_dynamic_lea_64"
12652 [(set (match_operand:DI 0 "register_operand" "=r")
12653 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12655 "TARGET_64BIT && TARGET_GNU2_TLS"
12656 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12657 [(set_attr "type" "lea")
12658 (set_attr "mode" "DI")
12659 (set_attr "length" "7")
12660 (set_attr "length_address" "4")])
12662 (define_insn "*tls_dynamic_call_64"
12663 [(set (match_operand:DI 0 "register_operand" "=a")
12664 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12665 (match_operand:DI 2 "register_operand" "0")
12668 (clobber (reg:CC FLAGS_REG))]
12669 "TARGET_64BIT && TARGET_GNU2_TLS"
12670 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12671 [(set_attr "type" "call")
12672 (set_attr "length" "2")
12673 (set_attr "length_address" "0")])
12675 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12676 [(set (match_operand:DI 0 "register_operand" "=&a")
12678 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12679 (match_operand:DI 3 "" "")
12682 (const:DI (unspec:DI
12683 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12685 (clobber (reg:CC FLAGS_REG))]
12686 "TARGET_64BIT && TARGET_GNU2_TLS"
12689 [(set (match_dup 0) (match_dup 4))]
12691 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12692 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12695 ;; These patterns match the binary 387 instructions for addM3, subM3,
12696 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12697 ;; SFmode. The first is the normal insn, the second the same insn but
12698 ;; with one operand a conversion, and the third the same insn but with
12699 ;; the other operand a conversion. The conversion may be SFmode or
12700 ;; SImode if the target mode DFmode, but only SImode if the target mode
12703 ;; Gcc is slightly more smart about handling normal two address instructions
12704 ;; so use special patterns for add and mull.
12706 (define_insn "*fop_<mode>_comm_mixed"
12707 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12708 (match_operator:MODEF 3 "binary_fp_operator"
12709 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12710 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12712 && COMMUTATIVE_ARITH_P (operands[3])
12713 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12714 "* return output_387_binary_op (insn, operands);"
12715 [(set (attr "type")
12716 (if_then_else (eq_attr "alternative" "1,2")
12717 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12718 (const_string "ssemul")
12719 (const_string "sseadd"))
12720 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12721 (const_string "fmul")
12722 (const_string "fop"))))
12723 (set_attr "isa" "base,noavx,avx")
12724 (set_attr "prefix" "orig,orig,vex")
12725 (set_attr "mode" "<MODE>")])
12727 (define_insn "*fop_<mode>_comm_sse"
12728 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12729 (match_operator:MODEF 3 "binary_fp_operator"
12730 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12731 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12732 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12733 && COMMUTATIVE_ARITH_P (operands[3])
12734 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12735 "* return output_387_binary_op (insn, operands);"
12736 [(set (attr "type")
12737 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12738 (const_string "ssemul")
12739 (const_string "sseadd")))
12740 (set_attr "isa" "noavx,avx")
12741 (set_attr "prefix" "orig,vex")
12742 (set_attr "mode" "<MODE>")])
12744 (define_insn "*fop_<mode>_comm_i387"
12745 [(set (match_operand:MODEF 0 "register_operand" "=f")
12746 (match_operator:MODEF 3 "binary_fp_operator"
12747 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12748 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12749 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12750 && COMMUTATIVE_ARITH_P (operands[3])
12751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12752 "* return output_387_binary_op (insn, operands);"
12753 [(set (attr "type")
12754 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12755 (const_string "fmul")
12756 (const_string "fop")))
12757 (set_attr "mode" "<MODE>")])
12759 (define_insn "*fop_<mode>_1_mixed"
12760 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12761 (match_operator:MODEF 3 "binary_fp_operator"
12762 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12763 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12764 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12765 && !COMMUTATIVE_ARITH_P (operands[3])
12766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12767 "* return output_387_binary_op (insn, operands);"
12768 [(set (attr "type")
12769 (cond [(and (eq_attr "alternative" "2,3")
12770 (match_operand:MODEF 3 "mult_operator" ""))
12771 (const_string "ssemul")
12772 (and (eq_attr "alternative" "2,3")
12773 (match_operand:MODEF 3 "div_operator" ""))
12774 (const_string "ssediv")
12775 (eq_attr "alternative" "2,3")
12776 (const_string "sseadd")
12777 (match_operand:MODEF 3 "mult_operator" "")
12778 (const_string "fmul")
12779 (match_operand:MODEF 3 "div_operator" "")
12780 (const_string "fdiv")
12782 (const_string "fop")))
12783 (set_attr "isa" "base,base,noavx,avx")
12784 (set_attr "prefix" "orig,orig,orig,vex")
12785 (set_attr "mode" "<MODE>")])
12787 (define_insn "*rcpsf2_sse"
12788 [(set (match_operand:SF 0 "register_operand" "=x")
12789 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12792 "%vrcpss\t{%1, %d0|%d0, %1}"
12793 [(set_attr "type" "sse")
12794 (set_attr "atom_sse_attr" "rcp")
12795 (set_attr "prefix" "maybe_vex")
12796 (set_attr "mode" "SF")])
12798 (define_insn "*fop_<mode>_1_sse"
12799 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12800 (match_operator:MODEF 3 "binary_fp_operator"
12801 [(match_operand:MODEF 1 "register_operand" "0,x")
12802 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12803 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12804 && !COMMUTATIVE_ARITH_P (operands[3])"
12805 "* return output_387_binary_op (insn, operands);"
12806 [(set (attr "type")
12807 (cond [(match_operand:MODEF 3 "mult_operator" "")
12808 (const_string "ssemul")
12809 (match_operand:MODEF 3 "div_operator" "")
12810 (const_string "ssediv")
12812 (const_string "sseadd")))
12813 (set_attr "isa" "noavx,avx")
12814 (set_attr "prefix" "orig,vex")
12815 (set_attr "mode" "<MODE>")])
12817 ;; This pattern is not fully shadowed by the pattern above.
12818 (define_insn "*fop_<mode>_1_i387"
12819 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12820 (match_operator:MODEF 3 "binary_fp_operator"
12821 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12822 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12823 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12824 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12825 && !COMMUTATIVE_ARITH_P (operands[3])
12826 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12827 "* return 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 "mode" "<MODE>")])
12837 ;; ??? Add SSE splitters for these!
12838 (define_insn "*fop_<MODEF:mode>_2_i387"
12839 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12840 (match_operator:MODEF 3 "binary_fp_operator"
12842 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12843 (match_operand:MODEF 2 "register_operand" "0,0")]))]
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" "<SWI24:MODE>")])
12858 (define_insn "*fop_<MODEF:mode>_3_i387"
12859 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12860 (match_operator:MODEF 3 "binary_fp_operator"
12861 [(match_operand:MODEF 1 "register_operand" "0,0")
12863 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12864 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12865 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12866 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12867 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12868 [(set (attr "type")
12869 (cond [(match_operand:MODEF 3 "mult_operator" "")
12870 (const_string "fmul")
12871 (match_operand:MODEF 3 "div_operator" "")
12872 (const_string "fdiv")
12874 (const_string "fop")))
12875 (set_attr "fp_int_src" "true")
12876 (set_attr "mode" "<MODE>")])
12878 (define_insn "*fop_df_4_i387"
12879 [(set (match_operand:DF 0 "register_operand" "=f,f")
12880 (match_operator:DF 3 "binary_fp_operator"
12882 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12883 (match_operand:DF 2 "register_operand" "0,f")]))]
12884 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12885 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12887 "* return output_387_binary_op (insn, operands);"
12888 [(set (attr "type")
12889 (cond [(match_operand:DF 3 "mult_operator" "")
12890 (const_string "fmul")
12891 (match_operand:DF 3 "div_operator" "")
12892 (const_string "fdiv")
12894 (const_string "fop")))
12895 (set_attr "mode" "SF")])
12897 (define_insn "*fop_df_5_i387"
12898 [(set (match_operand:DF 0 "register_operand" "=f,f")
12899 (match_operator:DF 3 "binary_fp_operator"
12900 [(match_operand:DF 1 "register_operand" "0,f")
12902 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12903 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12904 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12905 "* return output_387_binary_op (insn, operands);"
12906 [(set (attr "type")
12907 (cond [(match_operand:DF 3 "mult_operator" "")
12908 (const_string "fmul")
12909 (match_operand:DF 3 "div_operator" "")
12910 (const_string "fdiv")
12912 (const_string "fop")))
12913 (set_attr "mode" "SF")])
12915 (define_insn "*fop_df_6_i387"
12916 [(set (match_operand:DF 0 "register_operand" "=f,f")
12917 (match_operator:DF 3 "binary_fp_operator"
12919 (match_operand:SF 1 "register_operand" "0,f"))
12921 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12922 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12923 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12924 "* return output_387_binary_op (insn, operands);"
12925 [(set (attr "type")
12926 (cond [(match_operand:DF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (match_operand:DF 3 "div_operator" "")
12929 (const_string "fdiv")
12931 (const_string "fop")))
12932 (set_attr "mode" "SF")])
12934 (define_insn "*fop_xf_comm_i387"
12935 [(set (match_operand:XF 0 "register_operand" "=f")
12936 (match_operator:XF 3 "binary_fp_operator"
12937 [(match_operand:XF 1 "register_operand" "%0")
12938 (match_operand:XF 2 "register_operand" "f")]))]
12940 && COMMUTATIVE_ARITH_P (operands[3])"
12941 "* return output_387_binary_op (insn, operands);"
12942 [(set (attr "type")
12943 (if_then_else (match_operand:XF 3 "mult_operator" "")
12944 (const_string "fmul")
12945 (const_string "fop")))
12946 (set_attr "mode" "XF")])
12948 (define_insn "*fop_xf_1_i387"
12949 [(set (match_operand:XF 0 "register_operand" "=f,f")
12950 (match_operator:XF 3 "binary_fp_operator"
12951 [(match_operand:XF 1 "register_operand" "0,f")
12952 (match_operand:XF 2 "register_operand" "f,0")]))]
12954 && !COMMUTATIVE_ARITH_P (operands[3])"
12955 "* return output_387_binary_op (insn, operands);"
12956 [(set (attr "type")
12957 (cond [(match_operand:XF 3 "mult_operator" "")
12958 (const_string "fmul")
12959 (match_operand:XF 3 "div_operator" "")
12960 (const_string "fdiv")
12962 (const_string "fop")))
12963 (set_attr "mode" "XF")])
12965 (define_insn "*fop_xf_2_i387"
12966 [(set (match_operand:XF 0 "register_operand" "=f,f")
12967 (match_operator:XF 3 "binary_fp_operator"
12969 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12970 (match_operand:XF 2 "register_operand" "0,0")]))]
12971 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12972 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12973 [(set (attr "type")
12974 (cond [(match_operand:XF 3 "mult_operator" "")
12975 (const_string "fmul")
12976 (match_operand:XF 3 "div_operator" "")
12977 (const_string "fdiv")
12979 (const_string "fop")))
12980 (set_attr "fp_int_src" "true")
12981 (set_attr "mode" "<MODE>")])
12983 (define_insn "*fop_xf_3_i387"
12984 [(set (match_operand:XF 0 "register_operand" "=f,f")
12985 (match_operator:XF 3 "binary_fp_operator"
12986 [(match_operand:XF 1 "register_operand" "0,0")
12988 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12989 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12990 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12991 [(set (attr "type")
12992 (cond [(match_operand:XF 3 "mult_operator" "")
12993 (const_string "fmul")
12994 (match_operand:XF 3 "div_operator" "")
12995 (const_string "fdiv")
12997 (const_string "fop")))
12998 (set_attr "fp_int_src" "true")
12999 (set_attr "mode" "<MODE>")])
13001 (define_insn "*fop_xf_4_i387"
13002 [(set (match_operand:XF 0 "register_operand" "=f,f")
13003 (match_operator:XF 3 "binary_fp_operator"
13005 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13006 (match_operand:XF 2 "register_operand" "0,f")]))]
13008 "* return output_387_binary_op (insn, operands);"
13009 [(set (attr "type")
13010 (cond [(match_operand:XF 3 "mult_operator" "")
13011 (const_string "fmul")
13012 (match_operand:XF 3 "div_operator" "")
13013 (const_string "fdiv")
13015 (const_string "fop")))
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*fop_xf_5_i387"
13019 [(set (match_operand:XF 0 "register_operand" "=f,f")
13020 (match_operator:XF 3 "binary_fp_operator"
13021 [(match_operand:XF 1 "register_operand" "0,f")
13023 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13025 "* return output_387_binary_op (insn, operands);"
13026 [(set (attr "type")
13027 (cond [(match_operand:XF 3 "mult_operator" "")
13028 (const_string "fmul")
13029 (match_operand:XF 3 "div_operator" "")
13030 (const_string "fdiv")
13032 (const_string "fop")))
13033 (set_attr "mode" "<MODE>")])
13035 (define_insn "*fop_xf_6_i387"
13036 [(set (match_operand:XF 0 "register_operand" "=f,f")
13037 (match_operator:XF 3 "binary_fp_operator"
13039 (match_operand:MODEF 1 "register_operand" "0,f"))
13041 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13043 "* return output_387_binary_op (insn, operands);"
13044 [(set (attr "type")
13045 (cond [(match_operand:XF 3 "mult_operator" "")
13046 (const_string "fmul")
13047 (match_operand:XF 3 "div_operator" "")
13048 (const_string "fdiv")
13050 (const_string "fop")))
13051 (set_attr "mode" "<MODE>")])
13054 [(set (match_operand 0 "register_operand" "")
13055 (match_operator 3 "binary_fp_operator"
13056 [(float (match_operand:SWI24 1 "register_operand" ""))
13057 (match_operand 2 "register_operand" "")]))]
13059 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13060 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13063 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13064 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13065 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13066 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13067 GET_MODE (operands[3]),
13070 ix86_free_from_memory (GET_MODE (operands[1]));
13075 [(set (match_operand 0 "register_operand" "")
13076 (match_operator 3 "binary_fp_operator"
13077 [(match_operand 1 "register_operand" "")
13078 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13080 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13081 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13084 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13085 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13086 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13087 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13088 GET_MODE (operands[3]),
13091 ix86_free_from_memory (GET_MODE (operands[2]));
13095 ;; FPU special functions.
13097 ;; This pattern implements a no-op XFmode truncation for
13098 ;; all fancy i386 XFmode math functions.
13100 (define_insn "truncxf<mode>2_i387_noop_unspec"
13101 [(set (match_operand:MODEF 0 "register_operand" "=f")
13102 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13103 UNSPEC_TRUNC_NOOP))]
13104 "TARGET_USE_FANCY_MATH_387"
13105 "* return output_387_reg_move (insn, operands);"
13106 [(set_attr "type" "fmov")
13107 (set_attr "mode" "<MODE>")])
13109 (define_insn "sqrtxf2"
13110 [(set (match_operand:XF 0 "register_operand" "=f")
13111 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13112 "TARGET_USE_FANCY_MATH_387"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")
13116 (set_attr "athlon_decode" "direct")
13117 (set_attr "amdfam10_decode" "direct")
13118 (set_attr "bdver1_decode" "direct")])
13120 (define_insn "sqrt_extend<mode>xf2_i387"
13121 [(set (match_operand:XF 0 "register_operand" "=f")
13124 (match_operand:MODEF 1 "register_operand" "0"))))]
13125 "TARGET_USE_FANCY_MATH_387"
13127 [(set_attr "type" "fpspc")
13128 (set_attr "mode" "XF")
13129 (set_attr "athlon_decode" "direct")
13130 (set_attr "amdfam10_decode" "direct")
13131 (set_attr "bdver1_decode" "direct")])
13133 (define_insn "*rsqrtsf2_sse"
13134 [(set (match_operand:SF 0 "register_operand" "=x")
13135 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13138 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13139 [(set_attr "type" "sse")
13140 (set_attr "atom_sse_attr" "rcp")
13141 (set_attr "prefix" "maybe_vex")
13142 (set_attr "mode" "SF")])
13144 (define_expand "rsqrtsf2"
13145 [(set (match_operand:SF 0 "register_operand" "")
13146 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13150 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13154 (define_insn "*sqrt<mode>2_sse"
13155 [(set (match_operand:MODEF 0 "register_operand" "=x")
13157 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13158 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13159 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13160 [(set_attr "type" "sse")
13161 (set_attr "atom_sse_attr" "sqrt")
13162 (set_attr "prefix" "maybe_vex")
13163 (set_attr "mode" "<MODE>")
13164 (set_attr "athlon_decode" "*")
13165 (set_attr "amdfam10_decode" "*")
13166 (set_attr "bdver1_decode" "*")])
13168 (define_expand "sqrt<mode>2"
13169 [(set (match_operand:MODEF 0 "register_operand" "")
13171 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13172 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13173 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13175 if (<MODE>mode == SFmode
13176 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13177 && flag_finite_math_only && !flag_trapping_math
13178 && flag_unsafe_math_optimizations)
13180 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13184 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13186 rtx op0 = gen_reg_rtx (XFmode);
13187 rtx op1 = force_reg (<MODE>mode, operands[1]);
13189 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13190 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13195 (define_insn "fpremxf4_i387"
13196 [(set (match_operand:XF 0 "register_operand" "=f")
13197 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13198 (match_operand:XF 3 "register_operand" "1")]
13200 (set (match_operand:XF 1 "register_operand" "=u")
13201 (unspec:XF [(match_dup 2) (match_dup 3)]
13203 (set (reg:CCFP FPSR_REG)
13204 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13206 "TARGET_USE_FANCY_MATH_387"
13208 [(set_attr "type" "fpspc")
13209 (set_attr "mode" "XF")])
13211 (define_expand "fmodxf3"
13212 [(use (match_operand:XF 0 "register_operand" ""))
13213 (use (match_operand:XF 1 "general_operand" ""))
13214 (use (match_operand:XF 2 "general_operand" ""))]
13215 "TARGET_USE_FANCY_MATH_387"
13217 rtx label = gen_label_rtx ();
13219 rtx op1 = gen_reg_rtx (XFmode);
13220 rtx op2 = gen_reg_rtx (XFmode);
13222 emit_move_insn (op2, operands[2]);
13223 emit_move_insn (op1, operands[1]);
13225 emit_label (label);
13226 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13227 ix86_emit_fp_unordered_jump (label);
13228 LABEL_NUSES (label) = 1;
13230 emit_move_insn (operands[0], op1);
13234 (define_expand "fmod<mode>3"
13235 [(use (match_operand:MODEF 0 "register_operand" ""))
13236 (use (match_operand:MODEF 1 "general_operand" ""))
13237 (use (match_operand:MODEF 2 "general_operand" ""))]
13238 "TARGET_USE_FANCY_MATH_387"
13240 rtx (*gen_truncxf) (rtx, rtx);
13242 rtx label = gen_label_rtx ();
13244 rtx op1 = gen_reg_rtx (XFmode);
13245 rtx op2 = gen_reg_rtx (XFmode);
13247 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13248 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13250 emit_label (label);
13251 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13252 ix86_emit_fp_unordered_jump (label);
13253 LABEL_NUSES (label) = 1;
13255 /* Truncate the result properly for strict SSE math. */
13256 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13257 && !TARGET_MIX_SSE_I387)
13258 gen_truncxf = gen_truncxf<mode>2;
13260 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13262 emit_insn (gen_truncxf (operands[0], op1));
13266 (define_insn "fprem1xf4_i387"
13267 [(set (match_operand:XF 0 "register_operand" "=f")
13268 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13269 (match_operand:XF 3 "register_operand" "1")]
13271 (set (match_operand:XF 1 "register_operand" "=u")
13272 (unspec:XF [(match_dup 2) (match_dup 3)]
13274 (set (reg:CCFP FPSR_REG)
13275 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13277 "TARGET_USE_FANCY_MATH_387"
13279 [(set_attr "type" "fpspc")
13280 (set_attr "mode" "XF")])
13282 (define_expand "remainderxf3"
13283 [(use (match_operand:XF 0 "register_operand" ""))
13284 (use (match_operand:XF 1 "general_operand" ""))
13285 (use (match_operand:XF 2 "general_operand" ""))]
13286 "TARGET_USE_FANCY_MATH_387"
13288 rtx label = gen_label_rtx ();
13290 rtx op1 = gen_reg_rtx (XFmode);
13291 rtx op2 = gen_reg_rtx (XFmode);
13293 emit_move_insn (op2, operands[2]);
13294 emit_move_insn (op1, operands[1]);
13296 emit_label (label);
13297 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13298 ix86_emit_fp_unordered_jump (label);
13299 LABEL_NUSES (label) = 1;
13301 emit_move_insn (operands[0], op1);
13305 (define_expand "remainder<mode>3"
13306 [(use (match_operand:MODEF 0 "register_operand" ""))
13307 (use (match_operand:MODEF 1 "general_operand" ""))
13308 (use (match_operand:MODEF 2 "general_operand" ""))]
13309 "TARGET_USE_FANCY_MATH_387"
13311 rtx (*gen_truncxf) (rtx, rtx);
13313 rtx label = gen_label_rtx ();
13315 rtx op1 = gen_reg_rtx (XFmode);
13316 rtx op2 = gen_reg_rtx (XFmode);
13318 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13319 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13321 emit_label (label);
13323 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13324 ix86_emit_fp_unordered_jump (label);
13325 LABEL_NUSES (label) = 1;
13327 /* Truncate the result properly for strict SSE math. */
13328 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13329 && !TARGET_MIX_SSE_I387)
13330 gen_truncxf = gen_truncxf<mode>2;
13332 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13334 emit_insn (gen_truncxf (operands[0], op1));
13338 (define_insn "*sinxf2_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13341 "TARGET_USE_FANCY_MATH_387
13342 && flag_unsafe_math_optimizations"
13344 [(set_attr "type" "fpspc")
13345 (set_attr "mode" "XF")])
13347 (define_insn "*sin_extend<mode>xf2_i387"
13348 [(set (match_operand:XF 0 "register_operand" "=f")
13349 (unspec:XF [(float_extend:XF
13350 (match_operand:MODEF 1 "register_operand" "0"))]
13352 "TARGET_USE_FANCY_MATH_387
13353 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13354 || TARGET_MIX_SSE_I387)
13355 && flag_unsafe_math_optimizations"
13357 [(set_attr "type" "fpspc")
13358 (set_attr "mode" "XF")])
13360 (define_insn "*cosxf2_i387"
13361 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13366 [(set_attr "type" "fpspc")
13367 (set_attr "mode" "XF")])
13369 (define_insn "*cos_extend<mode>xf2_i387"
13370 [(set (match_operand:XF 0 "register_operand" "=f")
13371 (unspec:XF [(float_extend:XF
13372 (match_operand:MODEF 1 "register_operand" "0"))]
13374 "TARGET_USE_FANCY_MATH_387
13375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13376 || TARGET_MIX_SSE_I387)
13377 && flag_unsafe_math_optimizations"
13379 [(set_attr "type" "fpspc")
13380 (set_attr "mode" "XF")])
13382 ;; When sincos pattern is defined, sin and cos builtin functions will be
13383 ;; expanded to sincos pattern with one of its outputs left unused.
13384 ;; CSE pass will figure out if two sincos patterns can be combined,
13385 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13386 ;; depending on the unused output.
13388 (define_insn "sincosxf3"
13389 [(set (match_operand:XF 0 "register_operand" "=f")
13390 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13391 UNSPEC_SINCOS_COS))
13392 (set (match_operand:XF 1 "register_operand" "=u")
13393 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13394 "TARGET_USE_FANCY_MATH_387
13395 && flag_unsafe_math_optimizations"
13397 [(set_attr "type" "fpspc")
13398 (set_attr "mode" "XF")])
13401 [(set (match_operand:XF 0 "register_operand" "")
13402 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13403 UNSPEC_SINCOS_COS))
13404 (set (match_operand:XF 1 "register_operand" "")
13405 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13406 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13407 && can_create_pseudo_p ()"
13408 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13411 [(set (match_operand:XF 0 "register_operand" "")
13412 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13413 UNSPEC_SINCOS_COS))
13414 (set (match_operand:XF 1 "register_operand" "")
13415 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13416 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13417 && can_create_pseudo_p ()"
13418 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13420 (define_insn "sincos_extend<mode>xf3_i387"
13421 [(set (match_operand:XF 0 "register_operand" "=f")
13422 (unspec:XF [(float_extend:XF
13423 (match_operand:MODEF 2 "register_operand" "0"))]
13424 UNSPEC_SINCOS_COS))
13425 (set (match_operand:XF 1 "register_operand" "=u")
13426 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13427 "TARGET_USE_FANCY_MATH_387
13428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13429 || TARGET_MIX_SSE_I387)
13430 && flag_unsafe_math_optimizations"
13432 [(set_attr "type" "fpspc")
13433 (set_attr "mode" "XF")])
13436 [(set (match_operand:XF 0 "register_operand" "")
13437 (unspec:XF [(float_extend:XF
13438 (match_operand:MODEF 2 "register_operand" ""))]
13439 UNSPEC_SINCOS_COS))
13440 (set (match_operand:XF 1 "register_operand" "")
13441 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13442 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13443 && can_create_pseudo_p ()"
13444 [(set (match_dup 1)
13445 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13448 [(set (match_operand:XF 0 "register_operand" "")
13449 (unspec:XF [(float_extend:XF
13450 (match_operand:MODEF 2 "register_operand" ""))]
13451 UNSPEC_SINCOS_COS))
13452 (set (match_operand:XF 1 "register_operand" "")
13453 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13454 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13455 && can_create_pseudo_p ()"
13456 [(set (match_dup 0)
13457 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13459 (define_expand "sincos<mode>3"
13460 [(use (match_operand:MODEF 0 "register_operand" ""))
13461 (use (match_operand:MODEF 1 "register_operand" ""))
13462 (use (match_operand:MODEF 2 "register_operand" ""))]
13463 "TARGET_USE_FANCY_MATH_387
13464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13465 || TARGET_MIX_SSE_I387)
13466 && flag_unsafe_math_optimizations"
13468 rtx op0 = gen_reg_rtx (XFmode);
13469 rtx op1 = gen_reg_rtx (XFmode);
13471 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13473 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13477 (define_insn "fptanxf4_i387"
13478 [(set (match_operand:XF 0 "register_operand" "=f")
13479 (match_operand:XF 3 "const_double_operand" "F"))
13480 (set (match_operand:XF 1 "register_operand" "=u")
13481 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13483 "TARGET_USE_FANCY_MATH_387
13484 && flag_unsafe_math_optimizations
13485 && standard_80387_constant_p (operands[3]) == 2"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13490 (define_insn "fptan_extend<mode>xf4_i387"
13491 [(set (match_operand:MODEF 0 "register_operand" "=f")
13492 (match_operand:MODEF 3 "const_double_operand" "F"))
13493 (set (match_operand:XF 1 "register_operand" "=u")
13494 (unspec:XF [(float_extend:XF
13495 (match_operand:MODEF 2 "register_operand" "0"))]
13497 "TARGET_USE_FANCY_MATH_387
13498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13499 || TARGET_MIX_SSE_I387)
13500 && flag_unsafe_math_optimizations
13501 && standard_80387_constant_p (operands[3]) == 2"
13503 [(set_attr "type" "fpspc")
13504 (set_attr "mode" "XF")])
13506 (define_expand "tanxf2"
13507 [(use (match_operand:XF 0 "register_operand" ""))
13508 (use (match_operand:XF 1 "register_operand" ""))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && flag_unsafe_math_optimizations"
13512 rtx one = gen_reg_rtx (XFmode);
13513 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13515 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13519 (define_expand "tan<mode>2"
13520 [(use (match_operand:MODEF 0 "register_operand" ""))
13521 (use (match_operand:MODEF 1 "register_operand" ""))]
13522 "TARGET_USE_FANCY_MATH_387
13523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13524 || TARGET_MIX_SSE_I387)
13525 && flag_unsafe_math_optimizations"
13527 rtx op0 = gen_reg_rtx (XFmode);
13529 rtx one = gen_reg_rtx (<MODE>mode);
13530 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13532 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13533 operands[1], op2));
13534 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13538 (define_insn "*fpatanxf3_i387"
13539 [(set (match_operand:XF 0 "register_operand" "=f")
13540 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13541 (match_operand:XF 2 "register_operand" "u")]
13543 (clobber (match_scratch:XF 3 "=2"))]
13544 "TARGET_USE_FANCY_MATH_387
13545 && flag_unsafe_math_optimizations"
13547 [(set_attr "type" "fpspc")
13548 (set_attr "mode" "XF")])
13550 (define_insn "fpatan_extend<mode>xf3_i387"
13551 [(set (match_operand:XF 0 "register_operand" "=f")
13552 (unspec:XF [(float_extend:XF
13553 (match_operand:MODEF 1 "register_operand" "0"))
13555 (match_operand:MODEF 2 "register_operand" "u"))]
13557 (clobber (match_scratch:XF 3 "=2"))]
13558 "TARGET_USE_FANCY_MATH_387
13559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13560 || TARGET_MIX_SSE_I387)
13561 && flag_unsafe_math_optimizations"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_expand "atan2xf3"
13567 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13568 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13569 (match_operand:XF 1 "register_operand" "")]
13571 (clobber (match_scratch:XF 3 ""))])]
13572 "TARGET_USE_FANCY_MATH_387
13573 && flag_unsafe_math_optimizations")
13575 (define_expand "atan2<mode>3"
13576 [(use (match_operand:MODEF 0 "register_operand" ""))
13577 (use (match_operand:MODEF 1 "register_operand" ""))
13578 (use (match_operand:MODEF 2 "register_operand" ""))]
13579 "TARGET_USE_FANCY_MATH_387
13580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13581 || TARGET_MIX_SSE_I387)
13582 && flag_unsafe_math_optimizations"
13584 rtx op0 = gen_reg_rtx (XFmode);
13586 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13591 (define_expand "atanxf2"
13592 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13593 (unspec:XF [(match_dup 2)
13594 (match_operand:XF 1 "register_operand" "")]
13596 (clobber (match_scratch:XF 3 ""))])]
13597 "TARGET_USE_FANCY_MATH_387
13598 && flag_unsafe_math_optimizations"
13600 operands[2] = gen_reg_rtx (XFmode);
13601 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13604 (define_expand "atan<mode>2"
13605 [(use (match_operand:MODEF 0 "register_operand" ""))
13606 (use (match_operand:MODEF 1 "register_operand" ""))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13609 || TARGET_MIX_SSE_I387)
13610 && flag_unsafe_math_optimizations"
13612 rtx op0 = gen_reg_rtx (XFmode);
13614 rtx op2 = gen_reg_rtx (<MODE>mode);
13615 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13617 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13618 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13622 (define_expand "asinxf2"
13623 [(set (match_dup 2)
13624 (mult:XF (match_operand:XF 1 "register_operand" "")
13626 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13627 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13628 (parallel [(set (match_operand:XF 0 "register_operand" "")
13629 (unspec:XF [(match_dup 5) (match_dup 1)]
13631 (clobber (match_scratch:XF 6 ""))])]
13632 "TARGET_USE_FANCY_MATH_387
13633 && flag_unsafe_math_optimizations"
13637 if (optimize_insn_for_size_p ())
13640 for (i = 2; i < 6; i++)
13641 operands[i] = gen_reg_rtx (XFmode);
13643 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13646 (define_expand "asin<mode>2"
13647 [(use (match_operand:MODEF 0 "register_operand" ""))
13648 (use (match_operand:MODEF 1 "general_operand" ""))]
13649 "TARGET_USE_FANCY_MATH_387
13650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13651 || TARGET_MIX_SSE_I387)
13652 && flag_unsafe_math_optimizations"
13654 rtx op0 = gen_reg_rtx (XFmode);
13655 rtx op1 = gen_reg_rtx (XFmode);
13657 if (optimize_insn_for_size_p ())
13660 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13661 emit_insn (gen_asinxf2 (op0, op1));
13662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13666 (define_expand "acosxf2"
13667 [(set (match_dup 2)
13668 (mult:XF (match_operand:XF 1 "register_operand" "")
13670 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13671 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13672 (parallel [(set (match_operand:XF 0 "register_operand" "")
13673 (unspec:XF [(match_dup 1) (match_dup 5)]
13675 (clobber (match_scratch:XF 6 ""))])]
13676 "TARGET_USE_FANCY_MATH_387
13677 && flag_unsafe_math_optimizations"
13681 if (optimize_insn_for_size_p ())
13684 for (i = 2; i < 6; i++)
13685 operands[i] = gen_reg_rtx (XFmode);
13687 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13690 (define_expand "acos<mode>2"
13691 [(use (match_operand:MODEF 0 "register_operand" ""))
13692 (use (match_operand:MODEF 1 "general_operand" ""))]
13693 "TARGET_USE_FANCY_MATH_387
13694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13695 || TARGET_MIX_SSE_I387)
13696 && flag_unsafe_math_optimizations"
13698 rtx op0 = gen_reg_rtx (XFmode);
13699 rtx op1 = gen_reg_rtx (XFmode);
13701 if (optimize_insn_for_size_p ())
13704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13705 emit_insn (gen_acosxf2 (op0, op1));
13706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13710 (define_insn "fyl2xxf3_i387"
13711 [(set (match_operand:XF 0 "register_operand" "=f")
13712 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13713 (match_operand:XF 2 "register_operand" "u")]
13715 (clobber (match_scratch:XF 3 "=2"))]
13716 "TARGET_USE_FANCY_MATH_387
13717 && flag_unsafe_math_optimizations"
13719 [(set_attr "type" "fpspc")
13720 (set_attr "mode" "XF")])
13722 (define_insn "fyl2x_extend<mode>xf3_i387"
13723 [(set (match_operand:XF 0 "register_operand" "=f")
13724 (unspec:XF [(float_extend:XF
13725 (match_operand:MODEF 1 "register_operand" "0"))
13726 (match_operand:XF 2 "register_operand" "u")]
13728 (clobber (match_scratch:XF 3 "=2"))]
13729 "TARGET_USE_FANCY_MATH_387
13730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13731 || TARGET_MIX_SSE_I387)
13732 && flag_unsafe_math_optimizations"
13734 [(set_attr "type" "fpspc")
13735 (set_attr "mode" "XF")])
13737 (define_expand "logxf2"
13738 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13739 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13740 (match_dup 2)] UNSPEC_FYL2X))
13741 (clobber (match_scratch:XF 3 ""))])]
13742 "TARGET_USE_FANCY_MATH_387
13743 && flag_unsafe_math_optimizations"
13745 operands[2] = gen_reg_rtx (XFmode);
13746 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13749 (define_expand "log<mode>2"
13750 [(use (match_operand:MODEF 0 "register_operand" ""))
13751 (use (match_operand:MODEF 1 "register_operand" ""))]
13752 "TARGET_USE_FANCY_MATH_387
13753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13754 || TARGET_MIX_SSE_I387)
13755 && flag_unsafe_math_optimizations"
13757 rtx op0 = gen_reg_rtx (XFmode);
13759 rtx op2 = gen_reg_rtx (XFmode);
13760 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13762 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13763 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13767 (define_expand "log10xf2"
13768 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13769 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13770 (match_dup 2)] UNSPEC_FYL2X))
13771 (clobber (match_scratch:XF 3 ""))])]
13772 "TARGET_USE_FANCY_MATH_387
13773 && flag_unsafe_math_optimizations"
13775 operands[2] = gen_reg_rtx (XFmode);
13776 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13779 (define_expand "log10<mode>2"
13780 [(use (match_operand:MODEF 0 "register_operand" ""))
13781 (use (match_operand:MODEF 1 "register_operand" ""))]
13782 "TARGET_USE_FANCY_MATH_387
13783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784 || TARGET_MIX_SSE_I387)
13785 && flag_unsafe_math_optimizations"
13787 rtx op0 = gen_reg_rtx (XFmode);
13789 rtx op2 = gen_reg_rtx (XFmode);
13790 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13792 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13793 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13797 (define_expand "log2xf2"
13798 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13799 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13800 (match_dup 2)] UNSPEC_FYL2X))
13801 (clobber (match_scratch:XF 3 ""))])]
13802 "TARGET_USE_FANCY_MATH_387
13803 && flag_unsafe_math_optimizations"
13805 operands[2] = gen_reg_rtx (XFmode);
13806 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13809 (define_expand "log2<mode>2"
13810 [(use (match_operand:MODEF 0 "register_operand" ""))
13811 (use (match_operand:MODEF 1 "register_operand" ""))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13814 || TARGET_MIX_SSE_I387)
13815 && flag_unsafe_math_optimizations"
13817 rtx op0 = gen_reg_rtx (XFmode);
13819 rtx op2 = gen_reg_rtx (XFmode);
13820 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13822 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13823 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13827 (define_insn "fyl2xp1xf3_i387"
13828 [(set (match_operand:XF 0 "register_operand" "=f")
13829 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13830 (match_operand:XF 2 "register_operand" "u")]
13832 (clobber (match_scratch:XF 3 "=2"))]
13833 "TARGET_USE_FANCY_MATH_387
13834 && flag_unsafe_math_optimizations"
13836 [(set_attr "type" "fpspc")
13837 (set_attr "mode" "XF")])
13839 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13840 [(set (match_operand:XF 0 "register_operand" "=f")
13841 (unspec:XF [(float_extend:XF
13842 (match_operand:MODEF 1 "register_operand" "0"))
13843 (match_operand:XF 2 "register_operand" "u")]
13845 (clobber (match_scratch:XF 3 "=2"))]
13846 "TARGET_USE_FANCY_MATH_387
13847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13848 || TARGET_MIX_SSE_I387)
13849 && flag_unsafe_math_optimizations"
13851 [(set_attr "type" "fpspc")
13852 (set_attr "mode" "XF")])
13854 (define_expand "log1pxf2"
13855 [(use (match_operand:XF 0 "register_operand" ""))
13856 (use (match_operand:XF 1 "register_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && flag_unsafe_math_optimizations"
13860 if (optimize_insn_for_size_p ())
13863 ix86_emit_i387_log1p (operands[0], operands[1]);
13867 (define_expand "log1p<mode>2"
13868 [(use (match_operand:MODEF 0 "register_operand" ""))
13869 (use (match_operand:MODEF 1 "register_operand" ""))]
13870 "TARGET_USE_FANCY_MATH_387
13871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13872 || TARGET_MIX_SSE_I387)
13873 && flag_unsafe_math_optimizations"
13877 if (optimize_insn_for_size_p ())
13880 op0 = gen_reg_rtx (XFmode);
13882 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13884 ix86_emit_i387_log1p (op0, operands[1]);
13885 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13889 (define_insn "fxtractxf3_i387"
13890 [(set (match_operand:XF 0 "register_operand" "=f")
13891 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13892 UNSPEC_XTRACT_FRACT))
13893 (set (match_operand:XF 1 "register_operand" "=u")
13894 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13898 [(set_attr "type" "fpspc")
13899 (set_attr "mode" "XF")])
13901 (define_insn "fxtract_extend<mode>xf3_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (unspec:XF [(float_extend:XF
13904 (match_operand:MODEF 2 "register_operand" "0"))]
13905 UNSPEC_XTRACT_FRACT))
13906 (set (match_operand:XF 1 "register_operand" "=u")
13907 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13908 "TARGET_USE_FANCY_MATH_387
13909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910 || TARGET_MIX_SSE_I387)
13911 && flag_unsafe_math_optimizations"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13916 (define_expand "logbxf2"
13917 [(parallel [(set (match_dup 2)
13918 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13919 UNSPEC_XTRACT_FRACT))
13920 (set (match_operand:XF 0 "register_operand" "")
13921 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13922 "TARGET_USE_FANCY_MATH_387
13923 && flag_unsafe_math_optimizations"
13924 "operands[2] = gen_reg_rtx (XFmode);")
13926 (define_expand "logb<mode>2"
13927 [(use (match_operand:MODEF 0 "register_operand" ""))
13928 (use (match_operand:MODEF 1 "register_operand" ""))]
13929 "TARGET_USE_FANCY_MATH_387
13930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13931 || TARGET_MIX_SSE_I387)
13932 && flag_unsafe_math_optimizations"
13934 rtx op0 = gen_reg_rtx (XFmode);
13935 rtx op1 = gen_reg_rtx (XFmode);
13937 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13942 (define_expand "ilogbxf2"
13943 [(use (match_operand:SI 0 "register_operand" ""))
13944 (use (match_operand:XF 1 "register_operand" ""))]
13945 "TARGET_USE_FANCY_MATH_387
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 op0 = gen_reg_rtx (XFmode);
13954 op1 = gen_reg_rtx (XFmode);
13956 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13957 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13961 (define_expand "ilogb<mode>2"
13962 [(use (match_operand:SI 0 "register_operand" ""))
13963 (use (match_operand:MODEF 1 "register_operand" ""))]
13964 "TARGET_USE_FANCY_MATH_387
13965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13966 || TARGET_MIX_SSE_I387)
13967 && flag_unsafe_math_optimizations"
13971 if (optimize_insn_for_size_p ())
13974 op0 = gen_reg_rtx (XFmode);
13975 op1 = gen_reg_rtx (XFmode);
13977 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13978 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13982 (define_insn "*f2xm1xf2_i387"
13983 [(set (match_operand:XF 0 "register_operand" "=f")
13984 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13986 "TARGET_USE_FANCY_MATH_387
13987 && flag_unsafe_math_optimizations"
13989 [(set_attr "type" "fpspc")
13990 (set_attr "mode" "XF")])
13992 (define_insn "*fscalexf4_i387"
13993 [(set (match_operand:XF 0 "register_operand" "=f")
13994 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13995 (match_operand:XF 3 "register_operand" "1")]
13996 UNSPEC_FSCALE_FRACT))
13997 (set (match_operand:XF 1 "register_operand" "=u")
13998 (unspec:XF [(match_dup 2) (match_dup 3)]
13999 UNSPEC_FSCALE_EXP))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_expand "expNcorexf3"
14007 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14008 (match_operand:XF 2 "register_operand" "")))
14009 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14010 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14011 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14012 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14013 (parallel [(set (match_operand:XF 0 "register_operand" "")
14014 (unspec:XF [(match_dup 8) (match_dup 4)]
14015 UNSPEC_FSCALE_FRACT))
14017 (unspec:XF [(match_dup 8) (match_dup 4)]
14018 UNSPEC_FSCALE_EXP))])]
14019 "TARGET_USE_FANCY_MATH_387
14020 && flag_unsafe_math_optimizations"
14024 if (optimize_insn_for_size_p ())
14027 for (i = 3; i < 10; i++)
14028 operands[i] = gen_reg_rtx (XFmode);
14030 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14033 (define_expand "expxf2"
14034 [(use (match_operand:XF 0 "register_operand" ""))
14035 (use (match_operand:XF 1 "register_operand" ""))]
14036 "TARGET_USE_FANCY_MATH_387
14037 && flag_unsafe_math_optimizations"
14041 if (optimize_insn_for_size_p ())
14044 op2 = gen_reg_rtx (XFmode);
14045 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14047 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14051 (define_expand "exp<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand" ""))
14053 (use (match_operand:MODEF 1 "general_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14061 if (optimize_insn_for_size_p ())
14064 op0 = gen_reg_rtx (XFmode);
14065 op1 = gen_reg_rtx (XFmode);
14067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14068 emit_insn (gen_expxf2 (op0, op1));
14069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073 (define_expand "exp10xf2"
14074 [(use (match_operand:XF 0 "register_operand" ""))
14075 (use (match_operand:XF 1 "register_operand" ""))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14081 if (optimize_insn_for_size_p ())
14084 op2 = gen_reg_rtx (XFmode);
14085 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14087 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14091 (define_expand "exp10<mode>2"
14092 [(use (match_operand:MODEF 0 "register_operand" ""))
14093 (use (match_operand:MODEF 1 "general_operand" ""))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14101 if (optimize_insn_for_size_p ())
14104 op0 = gen_reg_rtx (XFmode);
14105 op1 = gen_reg_rtx (XFmode);
14107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14108 emit_insn (gen_exp10xf2 (op0, op1));
14109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113 (define_expand "exp2xf2"
14114 [(use (match_operand:XF 0 "register_operand" ""))
14115 (use (match_operand:XF 1 "register_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && flag_unsafe_math_optimizations"
14121 if (optimize_insn_for_size_p ())
14124 op2 = gen_reg_rtx (XFmode);
14125 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14127 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14131 (define_expand "exp2<mode>2"
14132 [(use (match_operand:MODEF 0 "register_operand" ""))
14133 (use (match_operand:MODEF 1 "general_operand" ""))]
14134 "TARGET_USE_FANCY_MATH_387
14135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14136 || TARGET_MIX_SSE_I387)
14137 && flag_unsafe_math_optimizations"
14141 if (optimize_insn_for_size_p ())
14144 op0 = gen_reg_rtx (XFmode);
14145 op1 = gen_reg_rtx (XFmode);
14147 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14148 emit_insn (gen_exp2xf2 (op0, op1));
14149 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14153 (define_expand "expm1xf2"
14154 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14156 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14157 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14158 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14159 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14160 (parallel [(set (match_dup 7)
14161 (unspec:XF [(match_dup 6) (match_dup 4)]
14162 UNSPEC_FSCALE_FRACT))
14164 (unspec:XF [(match_dup 6) (match_dup 4)]
14165 UNSPEC_FSCALE_EXP))])
14166 (parallel [(set (match_dup 10)
14167 (unspec:XF [(match_dup 9) (match_dup 8)]
14168 UNSPEC_FSCALE_FRACT))
14169 (set (match_dup 11)
14170 (unspec:XF [(match_dup 9) (match_dup 8)]
14171 UNSPEC_FSCALE_EXP))])
14172 (set (match_dup 12) (minus:XF (match_dup 10)
14173 (float_extend:XF (match_dup 13))))
14174 (set (match_operand:XF 0 "register_operand" "")
14175 (plus:XF (match_dup 12) (match_dup 7)))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && flag_unsafe_math_optimizations"
14181 if (optimize_insn_for_size_p ())
14184 for (i = 2; i < 13; i++)
14185 operands[i] = gen_reg_rtx (XFmode);
14188 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14190 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14193 (define_expand "expm1<mode>2"
14194 [(use (match_operand:MODEF 0 "register_operand" ""))
14195 (use (match_operand:MODEF 1 "general_operand" ""))]
14196 "TARGET_USE_FANCY_MATH_387
14197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14198 || TARGET_MIX_SSE_I387)
14199 && flag_unsafe_math_optimizations"
14203 if (optimize_insn_for_size_p ())
14206 op0 = gen_reg_rtx (XFmode);
14207 op1 = gen_reg_rtx (XFmode);
14209 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14210 emit_insn (gen_expm1xf2 (op0, op1));
14211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14215 (define_expand "ldexpxf3"
14216 [(set (match_dup 3)
14217 (float:XF (match_operand:SI 2 "register_operand" "")))
14218 (parallel [(set (match_operand:XF 0 " register_operand" "")
14219 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14221 UNSPEC_FSCALE_FRACT))
14223 (unspec:XF [(match_dup 1) (match_dup 3)]
14224 UNSPEC_FSCALE_EXP))])]
14225 "TARGET_USE_FANCY_MATH_387
14226 && flag_unsafe_math_optimizations"
14228 if (optimize_insn_for_size_p ())
14231 operands[3] = gen_reg_rtx (XFmode);
14232 operands[4] = gen_reg_rtx (XFmode);
14235 (define_expand "ldexp<mode>3"
14236 [(use (match_operand:MODEF 0 "register_operand" ""))
14237 (use (match_operand:MODEF 1 "general_operand" ""))
14238 (use (match_operand:SI 2 "register_operand" ""))]
14239 "TARGET_USE_FANCY_MATH_387
14240 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14241 || TARGET_MIX_SSE_I387)
14242 && flag_unsafe_math_optimizations"
14246 if (optimize_insn_for_size_p ())
14249 op0 = gen_reg_rtx (XFmode);
14250 op1 = gen_reg_rtx (XFmode);
14252 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14253 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14254 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14258 (define_expand "scalbxf3"
14259 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14260 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14261 (match_operand:XF 2 "register_operand" "")]
14262 UNSPEC_FSCALE_FRACT))
14264 (unspec:XF [(match_dup 1) (match_dup 2)]
14265 UNSPEC_FSCALE_EXP))])]
14266 "TARGET_USE_FANCY_MATH_387
14267 && flag_unsafe_math_optimizations"
14269 if (optimize_insn_for_size_p ())
14272 operands[3] = gen_reg_rtx (XFmode);
14275 (define_expand "scalb<mode>3"
14276 [(use (match_operand:MODEF 0 "register_operand" ""))
14277 (use (match_operand:MODEF 1 "general_operand" ""))
14278 (use (match_operand:MODEF 2 "general_operand" ""))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14281 || TARGET_MIX_SSE_I387)
14282 && flag_unsafe_math_optimizations"
14286 if (optimize_insn_for_size_p ())
14289 op0 = gen_reg_rtx (XFmode);
14290 op1 = gen_reg_rtx (XFmode);
14291 op2 = gen_reg_rtx (XFmode);
14293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14294 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14295 emit_insn (gen_scalbxf3 (op0, op1, op2));
14296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14300 (define_expand "significandxf2"
14301 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14302 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14303 UNSPEC_XTRACT_FRACT))
14305 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14306 "TARGET_USE_FANCY_MATH_387
14307 && flag_unsafe_math_optimizations"
14308 "operands[2] = gen_reg_rtx (XFmode);")
14310 (define_expand "significand<mode>2"
14311 [(use (match_operand:MODEF 0 "register_operand" ""))
14312 (use (match_operand:MODEF 1 "register_operand" ""))]
14313 "TARGET_USE_FANCY_MATH_387
14314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315 || TARGET_MIX_SSE_I387)
14316 && flag_unsafe_math_optimizations"
14318 rtx op0 = gen_reg_rtx (XFmode);
14319 rtx op1 = gen_reg_rtx (XFmode);
14321 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14327 (define_insn "sse4_1_round<mode>2"
14328 [(set (match_operand:MODEF 0 "register_operand" "=x")
14329 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14330 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14333 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14334 [(set_attr "type" "ssecvt")
14335 (set_attr "prefix_extra" "1")
14336 (set_attr "prefix" "maybe_vex")
14337 (set_attr "mode" "<MODE>")])
14339 (define_insn "rintxf2"
14340 [(set (match_operand:XF 0 "register_operand" "=f")
14341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14343 "TARGET_USE_FANCY_MATH_387
14344 && flag_unsafe_math_optimizations"
14346 [(set_attr "type" "fpspc")
14347 (set_attr "mode" "XF")])
14349 (define_expand "rint<mode>2"
14350 [(use (match_operand:MODEF 0 "register_operand" ""))
14351 (use (match_operand:MODEF 1 "register_operand" ""))]
14352 "(TARGET_USE_FANCY_MATH_387
14353 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14354 || TARGET_MIX_SSE_I387)
14355 && flag_unsafe_math_optimizations)
14356 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14357 && !flag_trapping_math)"
14359 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14360 && !flag_trapping_math)
14362 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14365 emit_insn (gen_sse4_1_round<mode>2
14366 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14368 ix86_expand_rint (operand0, operand1);
14372 rtx op0 = gen_reg_rtx (XFmode);
14373 rtx op1 = gen_reg_rtx (XFmode);
14375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14376 emit_insn (gen_rintxf2 (op0, op1));
14378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14383 (define_expand "round<mode>2"
14384 [(match_operand:MODEF 0 "register_operand" "")
14385 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14386 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14387 && !flag_trapping_math && !flag_rounding_math"
14389 if (optimize_insn_for_size_p ())
14391 if (TARGET_64BIT || (<MODE>mode != DFmode))
14392 ix86_expand_round (operand0, operand1);
14394 ix86_expand_rounddf_32 (operand0, operand1);
14398 (define_insn_and_split "*fistdi2_1"
14399 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14400 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14402 "TARGET_USE_FANCY_MATH_387
14403 && can_create_pseudo_p ()"
14408 if (memory_operand (operands[0], VOIDmode))
14409 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14412 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14413 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14418 [(set_attr "type" "fpspc")
14419 (set_attr "mode" "DI")])
14421 (define_insn "fistdi2"
14422 [(set (match_operand:DI 0 "memory_operand" "=m")
14423 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14425 (clobber (match_scratch:XF 2 "=&1f"))]
14426 "TARGET_USE_FANCY_MATH_387"
14427 "* return output_fix_trunc (insn, operands, false);"
14428 [(set_attr "type" "fpspc")
14429 (set_attr "mode" "DI")])
14431 (define_insn "fistdi2_with_temp"
14432 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14433 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14435 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14436 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14437 "TARGET_USE_FANCY_MATH_387"
14439 [(set_attr "type" "fpspc")
14440 (set_attr "mode" "DI")])
14443 [(set (match_operand:DI 0 "register_operand" "")
14444 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14446 (clobber (match_operand:DI 2 "memory_operand" ""))
14447 (clobber (match_scratch 3 ""))]
14449 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14450 (clobber (match_dup 3))])
14451 (set (match_dup 0) (match_dup 2))])
14454 [(set (match_operand:DI 0 "memory_operand" "")
14455 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14457 (clobber (match_operand:DI 2 "memory_operand" ""))
14458 (clobber (match_scratch 3 ""))]
14460 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14461 (clobber (match_dup 3))])])
14463 (define_insn_and_split "*fist<mode>2_1"
14464 [(set (match_operand:SWI24 0 "register_operand" "")
14465 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14467 "TARGET_USE_FANCY_MATH_387
14468 && can_create_pseudo_p ()"
14473 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14474 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "<MODE>")])
14481 (define_insn "fist<mode>2"
14482 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14483 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14485 "TARGET_USE_FANCY_MATH_387"
14486 "* return output_fix_trunc (insn, operands, false);"
14487 [(set_attr "type" "fpspc")
14488 (set_attr "mode" "<MODE>")])
14490 (define_insn "fist<mode>2_with_temp"
14491 [(set (match_operand:SWI24 0 "register_operand" "=r")
14492 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14494 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14495 "TARGET_USE_FANCY_MATH_387"
14497 [(set_attr "type" "fpspc")
14498 (set_attr "mode" "<MODE>")])
14501 [(set (match_operand:SWI24 0 "register_operand" "")
14502 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14504 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14506 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14507 (set (match_dup 0) (match_dup 2))])
14510 [(set (match_operand:SWI24 0 "memory_operand" "")
14511 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14513 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14515 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14517 (define_expand "lrintxf<mode>2"
14518 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14519 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14521 "TARGET_USE_FANCY_MATH_387")
14523 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14524 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14525 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14526 UNSPEC_FIX_NOTRUNC))]
14527 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14528 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14530 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14531 [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14532 (match_operand:MODEF 1 "register_operand" "")]
14533 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14534 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14535 && !flag_trapping_math && !flag_rounding_math"
14537 if (optimize_insn_for_size_p ())
14539 ix86_expand_lround (operand0, operand1);
14543 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14544 (define_insn_and_split "frndintxf2_floor"
14545 [(set (match_operand:XF 0 "register_operand" "")
14546 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14547 UNSPEC_FRNDINT_FLOOR))
14548 (clobber (reg:CC FLAGS_REG))]
14549 "TARGET_USE_FANCY_MATH_387
14550 && flag_unsafe_math_optimizations
14551 && can_create_pseudo_p ()"
14556 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14558 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14559 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14561 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14562 operands[2], operands[3]));
14565 [(set_attr "type" "frndint")
14566 (set_attr "i387_cw" "floor")
14567 (set_attr "mode" "XF")])
14569 (define_insn "frndintxf2_floor_i387"
14570 [(set (match_operand:XF 0 "register_operand" "=f")
14571 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14572 UNSPEC_FRNDINT_FLOOR))
14573 (use (match_operand:HI 2 "memory_operand" "m"))
14574 (use (match_operand:HI 3 "memory_operand" "m"))]
14575 "TARGET_USE_FANCY_MATH_387
14576 && flag_unsafe_math_optimizations"
14577 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14578 [(set_attr "type" "frndint")
14579 (set_attr "i387_cw" "floor")
14580 (set_attr "mode" "XF")])
14582 (define_expand "floorxf2"
14583 [(use (match_operand:XF 0 "register_operand" ""))
14584 (use (match_operand:XF 1 "register_operand" ""))]
14585 "TARGET_USE_FANCY_MATH_387
14586 && flag_unsafe_math_optimizations"
14588 if (optimize_insn_for_size_p ())
14590 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14594 (define_expand "floor<mode>2"
14595 [(use (match_operand:MODEF 0 "register_operand" ""))
14596 (use (match_operand:MODEF 1 "register_operand" ""))]
14597 "(TARGET_USE_FANCY_MATH_387
14598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14599 || TARGET_MIX_SSE_I387)
14600 && flag_unsafe_math_optimizations)
14601 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14602 && !flag_trapping_math)"
14604 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14605 && !flag_trapping_math
14606 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14608 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14611 emit_insn (gen_sse4_1_round<mode>2
14612 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14613 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14614 ix86_expand_floorceil (operand0, operand1, true);
14616 ix86_expand_floorceildf_32 (operand0, operand1, true);
14622 if (optimize_insn_for_size_p ())
14625 op0 = gen_reg_rtx (XFmode);
14626 op1 = gen_reg_rtx (XFmode);
14627 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14628 emit_insn (gen_frndintxf2_floor (op0, op1));
14630 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14635 (define_insn_and_split "*fist<mode>2_floor_1"
14636 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14637 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14638 UNSPEC_FIST_FLOOR))
14639 (clobber (reg:CC FLAGS_REG))]
14640 "TARGET_USE_FANCY_MATH_387
14641 && flag_unsafe_math_optimizations
14642 && can_create_pseudo_p ()"
14647 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14649 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14650 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14651 if (memory_operand (operands[0], VOIDmode))
14652 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14653 operands[2], operands[3]));
14656 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14657 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14658 operands[2], operands[3],
14663 [(set_attr "type" "fistp")
14664 (set_attr "i387_cw" "floor")
14665 (set_attr "mode" "<MODE>")])
14667 (define_insn "fistdi2_floor"
14668 [(set (match_operand:DI 0 "memory_operand" "=m")
14669 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14670 UNSPEC_FIST_FLOOR))
14671 (use (match_operand:HI 2 "memory_operand" "m"))
14672 (use (match_operand:HI 3 "memory_operand" "m"))
14673 (clobber (match_scratch:XF 4 "=&1f"))]
14674 "TARGET_USE_FANCY_MATH_387
14675 && flag_unsafe_math_optimizations"
14676 "* return output_fix_trunc (insn, operands, false);"
14677 [(set_attr "type" "fistp")
14678 (set_attr "i387_cw" "floor")
14679 (set_attr "mode" "DI")])
14681 (define_insn "fistdi2_floor_with_temp"
14682 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14683 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14684 UNSPEC_FIST_FLOOR))
14685 (use (match_operand:HI 2 "memory_operand" "m,m"))
14686 (use (match_operand:HI 3 "memory_operand" "m,m"))
14687 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14688 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && flag_unsafe_math_optimizations"
14692 [(set_attr "type" "fistp")
14693 (set_attr "i387_cw" "floor")
14694 (set_attr "mode" "DI")])
14697 [(set (match_operand:DI 0 "register_operand" "")
14698 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14699 UNSPEC_FIST_FLOOR))
14700 (use (match_operand:HI 2 "memory_operand" ""))
14701 (use (match_operand:HI 3 "memory_operand" ""))
14702 (clobber (match_operand:DI 4 "memory_operand" ""))
14703 (clobber (match_scratch 5 ""))]
14705 [(parallel [(set (match_dup 4)
14706 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14707 (use (match_dup 2))
14708 (use (match_dup 3))
14709 (clobber (match_dup 5))])
14710 (set (match_dup 0) (match_dup 4))])
14713 [(set (match_operand:DI 0 "memory_operand" "")
14714 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14715 UNSPEC_FIST_FLOOR))
14716 (use (match_operand:HI 2 "memory_operand" ""))
14717 (use (match_operand:HI 3 "memory_operand" ""))
14718 (clobber (match_operand:DI 4 "memory_operand" ""))
14719 (clobber (match_scratch 5 ""))]
14721 [(parallel [(set (match_dup 0)
14722 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14723 (use (match_dup 2))
14724 (use (match_dup 3))
14725 (clobber (match_dup 5))])])
14727 (define_insn "fist<mode>2_floor"
14728 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14729 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14730 UNSPEC_FIST_FLOOR))
14731 (use (match_operand:HI 2 "memory_operand" "m"))
14732 (use (match_operand:HI 3 "memory_operand" "m"))]
14733 "TARGET_USE_FANCY_MATH_387
14734 && flag_unsafe_math_optimizations"
14735 "* return output_fix_trunc (insn, operands, false);"
14736 [(set_attr "type" "fistp")
14737 (set_attr "i387_cw" "floor")
14738 (set_attr "mode" "<MODE>")])
14740 (define_insn "fist<mode>2_floor_with_temp"
14741 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14742 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14743 UNSPEC_FIST_FLOOR))
14744 (use (match_operand:HI 2 "memory_operand" "m,m"))
14745 (use (match_operand:HI 3 "memory_operand" "m,m"))
14746 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14747 "TARGET_USE_FANCY_MATH_387
14748 && flag_unsafe_math_optimizations"
14750 [(set_attr "type" "fistp")
14751 (set_attr "i387_cw" "floor")
14752 (set_attr "mode" "<MODE>")])
14755 [(set (match_operand:SWI24 0 "register_operand" "")
14756 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14757 UNSPEC_FIST_FLOOR))
14758 (use (match_operand:HI 2 "memory_operand" ""))
14759 (use (match_operand:HI 3 "memory_operand" ""))
14760 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14762 [(parallel [(set (match_dup 4)
14763 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14764 (use (match_dup 2))
14765 (use (match_dup 3))])
14766 (set (match_dup 0) (match_dup 4))])
14769 [(set (match_operand:SWI24 0 "memory_operand" "")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14771 UNSPEC_FIST_FLOOR))
14772 (use (match_operand:HI 2 "memory_operand" ""))
14773 (use (match_operand:HI 3 "memory_operand" ""))
14774 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14776 [(parallel [(set (match_dup 0)
14777 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14778 (use (match_dup 2))
14779 (use (match_dup 3))])])
14781 (define_expand "lfloorxf<mode>2"
14782 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14783 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14784 UNSPEC_FIST_FLOOR))
14785 (clobber (reg:CC FLAGS_REG))])]
14786 "TARGET_USE_FANCY_MATH_387
14787 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14788 && flag_unsafe_math_optimizations")
14790 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14791 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14792 (match_operand:MODEF 1 "register_operand" "")]
14793 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14794 && !flag_trapping_math"
14796 if (TARGET_64BIT && optimize_insn_for_size_p ())
14798 ix86_expand_lfloorceil (operand0, operand1, true);
14802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14803 (define_insn_and_split "frndintxf2_ceil"
14804 [(set (match_operand:XF 0 "register_operand" "")
14805 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14806 UNSPEC_FRNDINT_CEIL))
14807 (clobber (reg:CC FLAGS_REG))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations
14810 && can_create_pseudo_p ()"
14815 ix86_optimize_mode_switching[I387_CEIL] = 1;
14817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14820 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14821 operands[2], operands[3]));
14824 [(set_attr "type" "frndint")
14825 (set_attr "i387_cw" "ceil")
14826 (set_attr "mode" "XF")])
14828 (define_insn "frndintxf2_ceil_i387"
14829 [(set (match_operand:XF 0 "register_operand" "=f")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14831 UNSPEC_FRNDINT_CEIL))
14832 (use (match_operand:HI 2 "memory_operand" "m"))
14833 (use (match_operand:HI 3 "memory_operand" "m"))]
14834 "TARGET_USE_FANCY_MATH_387
14835 && flag_unsafe_math_optimizations"
14836 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14837 [(set_attr "type" "frndint")
14838 (set_attr "i387_cw" "ceil")
14839 (set_attr "mode" "XF")])
14841 (define_expand "ceilxf2"
14842 [(use (match_operand:XF 0 "register_operand" ""))
14843 (use (match_operand:XF 1 "register_operand" ""))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && flag_unsafe_math_optimizations"
14847 if (optimize_insn_for_size_p ())
14849 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14853 (define_expand "ceil<mode>2"
14854 [(use (match_operand:MODEF 0 "register_operand" ""))
14855 (use (match_operand:MODEF 1 "register_operand" ""))]
14856 "(TARGET_USE_FANCY_MATH_387
14857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations)
14860 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14861 && !flag_trapping_math)"
14863 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14864 && !flag_trapping_math
14865 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14868 emit_insn (gen_sse4_1_round<mode>2
14869 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14870 else if (optimize_insn_for_size_p ())
14872 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14873 ix86_expand_floorceil (operand0, operand1, false);
14875 ix86_expand_floorceildf_32 (operand0, operand1, false);
14881 if (optimize_insn_for_size_p ())
14884 op0 = gen_reg_rtx (XFmode);
14885 op1 = gen_reg_rtx (XFmode);
14886 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14887 emit_insn (gen_frndintxf2_ceil (op0, op1));
14889 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14894 (define_insn_and_split "*fist<mode>2_ceil_1"
14895 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14896 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14898 (clobber (reg:CC FLAGS_REG))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && flag_unsafe_math_optimizations
14901 && can_create_pseudo_p ()"
14906 ix86_optimize_mode_switching[I387_CEIL] = 1;
14908 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14909 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14910 if (memory_operand (operands[0], VOIDmode))
14911 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14912 operands[2], operands[3]));
14915 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14916 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14917 operands[2], operands[3],
14922 [(set_attr "type" "fistp")
14923 (set_attr "i387_cw" "ceil")
14924 (set_attr "mode" "<MODE>")])
14926 (define_insn "fistdi2_ceil"
14927 [(set (match_operand:DI 0 "memory_operand" "=m")
14928 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14930 (use (match_operand:HI 2 "memory_operand" "m"))
14931 (use (match_operand:HI 3 "memory_operand" "m"))
14932 (clobber (match_scratch:XF 4 "=&1f"))]
14933 "TARGET_USE_FANCY_MATH_387
14934 && flag_unsafe_math_optimizations"
14935 "* return output_fix_trunc (insn, operands, false);"
14936 [(set_attr "type" "fistp")
14937 (set_attr "i387_cw" "ceil")
14938 (set_attr "mode" "DI")])
14940 (define_insn "fistdi2_ceil_with_temp"
14941 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14942 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14944 (use (match_operand:HI 2 "memory_operand" "m,m"))
14945 (use (match_operand:HI 3 "memory_operand" "m,m"))
14946 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14947 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14948 "TARGET_USE_FANCY_MATH_387
14949 && flag_unsafe_math_optimizations"
14951 [(set_attr "type" "fistp")
14952 (set_attr "i387_cw" "ceil")
14953 (set_attr "mode" "DI")])
14956 [(set (match_operand:DI 0 "register_operand" "")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14959 (use (match_operand:HI 2 "memory_operand" ""))
14960 (use (match_operand:HI 3 "memory_operand" ""))
14961 (clobber (match_operand:DI 4 "memory_operand" ""))
14962 (clobber (match_scratch 5 ""))]
14964 [(parallel [(set (match_dup 4)
14965 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14966 (use (match_dup 2))
14967 (use (match_dup 3))
14968 (clobber (match_dup 5))])
14969 (set (match_dup 0) (match_dup 4))])
14972 [(set (match_operand:DI 0 "memory_operand" "")
14973 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14975 (use (match_operand:HI 2 "memory_operand" ""))
14976 (use (match_operand:HI 3 "memory_operand" ""))
14977 (clobber (match_operand:DI 4 "memory_operand" ""))
14978 (clobber (match_scratch 5 ""))]
14980 [(parallel [(set (match_dup 0)
14981 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14982 (use (match_dup 2))
14983 (use (match_dup 3))
14984 (clobber (match_dup 5))])])
14986 (define_insn "fist<mode>2_ceil"
14987 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14988 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14990 (use (match_operand:HI 2 "memory_operand" "m"))
14991 (use (match_operand:HI 3 "memory_operand" "m"))]
14992 "TARGET_USE_FANCY_MATH_387
14993 && flag_unsafe_math_optimizations"
14994 "* return output_fix_trunc (insn, operands, false);"
14995 [(set_attr "type" "fistp")
14996 (set_attr "i387_cw" "ceil")
14997 (set_attr "mode" "<MODE>")])
14999 (define_insn "fist<mode>2_ceil_with_temp"
15000 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15001 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15003 (use (match_operand:HI 2 "memory_operand" "m,m"))
15004 (use (match_operand:HI 3 "memory_operand" "m,m"))
15005 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15006 "TARGET_USE_FANCY_MATH_387
15007 && flag_unsafe_math_optimizations"
15009 [(set_attr "type" "fistp")
15010 (set_attr "i387_cw" "ceil")
15011 (set_attr "mode" "<MODE>")])
15014 [(set (match_operand:SWI24 0 "register_operand" "")
15015 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15017 (use (match_operand:HI 2 "memory_operand" ""))
15018 (use (match_operand:HI 3 "memory_operand" ""))
15019 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15021 [(parallel [(set (match_dup 4)
15022 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15023 (use (match_dup 2))
15024 (use (match_dup 3))])
15025 (set (match_dup 0) (match_dup 4))])
15028 [(set (match_operand:SWI24 0 "memory_operand" "")
15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15031 (use (match_operand:HI 2 "memory_operand" ""))
15032 (use (match_operand:HI 3 "memory_operand" ""))
15033 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15035 [(parallel [(set (match_dup 0)
15036 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15037 (use (match_dup 2))
15038 (use (match_dup 3))])])
15040 (define_expand "lceilxf<mode>2"
15041 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15042 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15044 (clobber (reg:CC FLAGS_REG))])]
15045 "TARGET_USE_FANCY_MATH_387
15046 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15047 && flag_unsafe_math_optimizations")
15049 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15050 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15051 (match_operand:MODEF 1 "register_operand" "")]
15052 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15053 && !flag_trapping_math"
15055 ix86_expand_lfloorceil (operand0, operand1, false);
15059 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15060 (define_insn_and_split "frndintxf2_trunc"
15061 [(set (match_operand:XF 0 "register_operand" "")
15062 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15063 UNSPEC_FRNDINT_TRUNC))
15064 (clobber (reg:CC FLAGS_REG))]
15065 "TARGET_USE_FANCY_MATH_387
15066 && flag_unsafe_math_optimizations
15067 && can_create_pseudo_p ()"
15072 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15074 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15075 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15077 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15078 operands[2], operands[3]));
15081 [(set_attr "type" "frndint")
15082 (set_attr "i387_cw" "trunc")
15083 (set_attr "mode" "XF")])
15085 (define_insn "frndintxf2_trunc_i387"
15086 [(set (match_operand:XF 0 "register_operand" "=f")
15087 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15088 UNSPEC_FRNDINT_TRUNC))
15089 (use (match_operand:HI 2 "memory_operand" "m"))
15090 (use (match_operand:HI 3 "memory_operand" "m"))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && flag_unsafe_math_optimizations"
15093 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15094 [(set_attr "type" "frndint")
15095 (set_attr "i387_cw" "trunc")
15096 (set_attr "mode" "XF")])
15098 (define_expand "btruncxf2"
15099 [(use (match_operand:XF 0 "register_operand" ""))
15100 (use (match_operand:XF 1 "register_operand" ""))]
15101 "TARGET_USE_FANCY_MATH_387
15102 && flag_unsafe_math_optimizations"
15104 if (optimize_insn_for_size_p ())
15106 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15110 (define_expand "btrunc<mode>2"
15111 [(use (match_operand:MODEF 0 "register_operand" ""))
15112 (use (match_operand:MODEF 1 "register_operand" ""))]
15113 "(TARGET_USE_FANCY_MATH_387
15114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15115 || TARGET_MIX_SSE_I387)
15116 && flag_unsafe_math_optimizations)
15117 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15118 && !flag_trapping_math)"
15120 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15121 && !flag_trapping_math
15122 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15125 emit_insn (gen_sse4_1_round<mode>2
15126 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15127 else if (optimize_insn_for_size_p ())
15129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15130 ix86_expand_trunc (operand0, operand1);
15132 ix86_expand_truncdf_32 (operand0, operand1);
15138 if (optimize_insn_for_size_p ())
15141 op0 = gen_reg_rtx (XFmode);
15142 op1 = gen_reg_rtx (XFmode);
15143 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15144 emit_insn (gen_frndintxf2_trunc (op0, op1));
15146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15151 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15152 (define_insn_and_split "frndintxf2_mask_pm"
15153 [(set (match_operand:XF 0 "register_operand" "")
15154 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15155 UNSPEC_FRNDINT_MASK_PM))
15156 (clobber (reg:CC FLAGS_REG))]
15157 "TARGET_USE_FANCY_MATH_387
15158 && flag_unsafe_math_optimizations
15159 && can_create_pseudo_p ()"
15164 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15166 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15167 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15169 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15170 operands[2], operands[3]));
15173 [(set_attr "type" "frndint")
15174 (set_attr "i387_cw" "mask_pm")
15175 (set_attr "mode" "XF")])
15177 (define_insn "frndintxf2_mask_pm_i387"
15178 [(set (match_operand:XF 0 "register_operand" "=f")
15179 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15180 UNSPEC_FRNDINT_MASK_PM))
15181 (use (match_operand:HI 2 "memory_operand" "m"))
15182 (use (match_operand:HI 3 "memory_operand" "m"))]
15183 "TARGET_USE_FANCY_MATH_387
15184 && flag_unsafe_math_optimizations"
15185 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15186 [(set_attr "type" "frndint")
15187 (set_attr "i387_cw" "mask_pm")
15188 (set_attr "mode" "XF")])
15190 (define_expand "nearbyintxf2"
15191 [(use (match_operand:XF 0 "register_operand" ""))
15192 (use (match_operand:XF 1 "register_operand" ""))]
15193 "TARGET_USE_FANCY_MATH_387
15194 && flag_unsafe_math_optimizations"
15196 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15200 (define_expand "nearbyint<mode>2"
15201 [(use (match_operand:MODEF 0 "register_operand" ""))
15202 (use (match_operand:MODEF 1 "register_operand" ""))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15205 || TARGET_MIX_SSE_I387)
15206 && flag_unsafe_math_optimizations"
15208 rtx op0 = gen_reg_rtx (XFmode);
15209 rtx op1 = gen_reg_rtx (XFmode);
15211 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15212 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15214 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15218 (define_insn "fxam<mode>2_i387"
15219 [(set (match_operand:HI 0 "register_operand" "=a")
15221 [(match_operand:X87MODEF 1 "register_operand" "f")]
15223 "TARGET_USE_FANCY_MATH_387"
15224 "fxam\n\tfnstsw\t%0"
15225 [(set_attr "type" "multi")
15226 (set_attr "length" "4")
15227 (set_attr "unit" "i387")
15228 (set_attr "mode" "<MODE>")])
15230 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15231 [(set (match_operand:HI 0 "register_operand" "")
15233 [(match_operand:MODEF 1 "memory_operand" "")]
15235 "TARGET_USE_FANCY_MATH_387
15236 && can_create_pseudo_p ()"
15239 [(set (match_dup 2)(match_dup 1))
15241 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15243 operands[2] = gen_reg_rtx (<MODE>mode);
15245 MEM_VOLATILE_P (operands[1]) = 1;
15247 [(set_attr "type" "multi")
15248 (set_attr "unit" "i387")
15249 (set_attr "mode" "<MODE>")])
15251 (define_expand "isinfxf2"
15252 [(use (match_operand:SI 0 "register_operand" ""))
15253 (use (match_operand:XF 1 "register_operand" ""))]
15254 "TARGET_USE_FANCY_MATH_387
15255 && TARGET_C99_FUNCTIONS"
15257 rtx mask = GEN_INT (0x45);
15258 rtx val = GEN_INT (0x05);
15262 rtx scratch = gen_reg_rtx (HImode);
15263 rtx res = gen_reg_rtx (QImode);
15265 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15267 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15268 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15269 cond = gen_rtx_fmt_ee (EQ, QImode,
15270 gen_rtx_REG (CCmode, FLAGS_REG),
15272 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15273 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15277 (define_expand "isinf<mode>2"
15278 [(use (match_operand:SI 0 "register_operand" ""))
15279 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && TARGET_C99_FUNCTIONS
15282 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15284 rtx mask = GEN_INT (0x45);
15285 rtx val = GEN_INT (0x05);
15289 rtx scratch = gen_reg_rtx (HImode);
15290 rtx res = gen_reg_rtx (QImode);
15292 /* Remove excess precision by forcing value through memory. */
15293 if (memory_operand (operands[1], VOIDmode))
15294 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15297 enum ix86_stack_slot slot = (virtuals_instantiated
15300 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15302 emit_move_insn (temp, operands[1]);
15303 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15306 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15307 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15308 cond = gen_rtx_fmt_ee (EQ, QImode,
15309 gen_rtx_REG (CCmode, FLAGS_REG),
15311 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15312 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15316 (define_expand "signbitxf2"
15317 [(use (match_operand:SI 0 "register_operand" ""))
15318 (use (match_operand:XF 1 "register_operand" ""))]
15319 "TARGET_USE_FANCY_MATH_387"
15321 rtx scratch = gen_reg_rtx (HImode);
15323 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15324 emit_insn (gen_andsi3 (operands[0],
15325 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15329 (define_insn "movmsk_df"
15330 [(set (match_operand:SI 0 "register_operand" "=r")
15332 [(match_operand:DF 1 "register_operand" "x")]
15334 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15335 "%vmovmskpd\t{%1, %0|%0, %1}"
15336 [(set_attr "type" "ssemov")
15337 (set_attr "prefix" "maybe_vex")
15338 (set_attr "mode" "DF")])
15340 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15341 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15342 (define_expand "signbitdf2"
15343 [(use (match_operand:SI 0 "register_operand" ""))
15344 (use (match_operand:DF 1 "register_operand" ""))]
15345 "TARGET_USE_FANCY_MATH_387
15346 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15348 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15350 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15351 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15355 rtx scratch = gen_reg_rtx (HImode);
15357 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15358 emit_insn (gen_andsi3 (operands[0],
15359 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15364 (define_expand "signbitsf2"
15365 [(use (match_operand:SI 0 "register_operand" ""))
15366 (use (match_operand:SF 1 "register_operand" ""))]
15367 "TARGET_USE_FANCY_MATH_387
15368 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15370 rtx scratch = gen_reg_rtx (HImode);
15372 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15373 emit_insn (gen_andsi3 (operands[0],
15374 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15378 ;; Block operation instructions
15381 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15384 [(set_attr "length" "1")
15385 (set_attr "length_immediate" "0")
15386 (set_attr "modrm" "0")])
15388 (define_expand "movmem<mode>"
15389 [(use (match_operand:BLK 0 "memory_operand" ""))
15390 (use (match_operand:BLK 1 "memory_operand" ""))
15391 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15392 (use (match_operand:SWI48 3 "const_int_operand" ""))
15393 (use (match_operand:SI 4 "const_int_operand" ""))
15394 (use (match_operand:SI 5 "const_int_operand" ""))]
15397 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15398 operands[4], operands[5]))
15404 ;; Most CPUs don't like single string operations
15405 ;; Handle this case here to simplify previous expander.
15407 (define_expand "strmov"
15408 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15409 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15410 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15411 (clobber (reg:CC FLAGS_REG))])
15412 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15413 (clobber (reg:CC FLAGS_REG))])]
15416 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15418 /* If .md ever supports :P for Pmode, these can be directly
15419 in the pattern above. */
15420 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15421 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15423 /* Can't use this if the user has appropriated esi or edi. */
15424 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15425 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15427 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15428 operands[2], operands[3],
15429 operands[5], operands[6]));
15433 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15436 (define_expand "strmov_singleop"
15437 [(parallel [(set (match_operand 1 "memory_operand" "")
15438 (match_operand 3 "memory_operand" ""))
15439 (set (match_operand 0 "register_operand" "")
15440 (match_operand 4 "" ""))
15441 (set (match_operand 2 "register_operand" "")
15442 (match_operand 5 "" ""))])]
15444 "ix86_current_function_needs_cld = 1;")
15446 (define_insn "*strmovdi_rex_1"
15447 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15448 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15449 (set (match_operand:DI 0 "register_operand" "=D")
15450 (plus:DI (match_dup 2)
15452 (set (match_operand:DI 1 "register_operand" "=S")
15453 (plus:DI (match_dup 3)
15457 [(set_attr "type" "str")
15458 (set_attr "memory" "both")
15459 (set_attr "mode" "DI")])
15461 (define_insn "*strmovsi_1"
15462 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15463 (mem:SI (match_operand:P 3 "register_operand" "1")))
15464 (set (match_operand:P 0 "register_operand" "=D")
15465 (plus:P (match_dup 2)
15467 (set (match_operand:P 1 "register_operand" "=S")
15468 (plus:P (match_dup 3)
15472 [(set_attr "type" "str")
15473 (set_attr "memory" "both")
15474 (set_attr "mode" "SI")])
15476 (define_insn "*strmovhi_1"
15477 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15478 (mem:HI (match_operand:P 3 "register_operand" "1")))
15479 (set (match_operand:P 0 "register_operand" "=D")
15480 (plus:P (match_dup 2)
15482 (set (match_operand:P 1 "register_operand" "=S")
15483 (plus:P (match_dup 3)
15487 [(set_attr "type" "str")
15488 (set_attr "memory" "both")
15489 (set_attr "mode" "HI")])
15491 (define_insn "*strmovqi_1"
15492 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15493 (mem:QI (match_operand:P 3 "register_operand" "1")))
15494 (set (match_operand:P 0 "register_operand" "=D")
15495 (plus:P (match_dup 2)
15497 (set (match_operand:P 1 "register_operand" "=S")
15498 (plus:P (match_dup 3)
15502 [(set_attr "type" "str")
15503 (set_attr "memory" "both")
15504 (set (attr "prefix_rex")
15506 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15508 (const_string "*")))
15509 (set_attr "mode" "QI")])
15511 (define_expand "rep_mov"
15512 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15513 (set (match_operand 0 "register_operand" "")
15514 (match_operand 5 "" ""))
15515 (set (match_operand 2 "register_operand" "")
15516 (match_operand 6 "" ""))
15517 (set (match_operand 1 "memory_operand" "")
15518 (match_operand 3 "memory_operand" ""))
15519 (use (match_dup 4))])]
15521 "ix86_current_function_needs_cld = 1;")
15523 (define_insn "*rep_movdi_rex64"
15524 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15525 (set (match_operand:DI 0 "register_operand" "=D")
15526 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15528 (match_operand:DI 3 "register_operand" "0")))
15529 (set (match_operand:DI 1 "register_operand" "=S")
15530 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15531 (match_operand:DI 4 "register_operand" "1")))
15532 (set (mem:BLK (match_dup 3))
15533 (mem:BLK (match_dup 4)))
15534 (use (match_dup 5))]
15537 [(set_attr "type" "str")
15538 (set_attr "prefix_rep" "1")
15539 (set_attr "memory" "both")
15540 (set_attr "mode" "DI")])
15542 (define_insn "*rep_movsi"
15543 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15544 (set (match_operand:P 0 "register_operand" "=D")
15545 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15547 (match_operand:P 3 "register_operand" "0")))
15548 (set (match_operand:P 1 "register_operand" "=S")
15549 (plus:P (ashift:P (match_dup 5) (const_int 2))
15550 (match_operand:P 4 "register_operand" "1")))
15551 (set (mem:BLK (match_dup 3))
15552 (mem:BLK (match_dup 4)))
15553 (use (match_dup 5))]
15555 "rep{%;} movs{l|d}"
15556 [(set_attr "type" "str")
15557 (set_attr "prefix_rep" "1")
15558 (set_attr "memory" "both")
15559 (set_attr "mode" "SI")])
15561 (define_insn "*rep_movqi"
15562 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15563 (set (match_operand:P 0 "register_operand" "=D")
15564 (plus:P (match_operand:P 3 "register_operand" "0")
15565 (match_operand:P 5 "register_operand" "2")))
15566 (set (match_operand:P 1 "register_operand" "=S")
15567 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15568 (set (mem:BLK (match_dup 3))
15569 (mem:BLK (match_dup 4)))
15570 (use (match_dup 5))]
15573 [(set_attr "type" "str")
15574 (set_attr "prefix_rep" "1")
15575 (set_attr "memory" "both")
15576 (set_attr "mode" "QI")])
15578 (define_expand "setmem<mode>"
15579 [(use (match_operand:BLK 0 "memory_operand" ""))
15580 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15581 (use (match_operand:QI 2 "nonmemory_operand" ""))
15582 (use (match_operand 3 "const_int_operand" ""))
15583 (use (match_operand:SI 4 "const_int_operand" ""))
15584 (use (match_operand:SI 5 "const_int_operand" ""))]
15587 if (ix86_expand_setmem (operands[0], operands[1],
15588 operands[2], operands[3],
15589 operands[4], operands[5]))
15595 ;; Most CPUs don't like single string operations
15596 ;; Handle this case here to simplify previous expander.
15598 (define_expand "strset"
15599 [(set (match_operand 1 "memory_operand" "")
15600 (match_operand 2 "register_operand" ""))
15601 (parallel [(set (match_operand 0 "register_operand" "")
15603 (clobber (reg:CC FLAGS_REG))])]
15606 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15607 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15609 /* If .md ever supports :P for Pmode, this can be directly
15610 in the pattern above. */
15611 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15612 GEN_INT (GET_MODE_SIZE (GET_MODE
15614 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15616 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15622 (define_expand "strset_singleop"
15623 [(parallel [(set (match_operand 1 "memory_operand" "")
15624 (match_operand 2 "register_operand" ""))
15625 (set (match_operand 0 "register_operand" "")
15626 (match_operand 3 "" ""))])]
15628 "ix86_current_function_needs_cld = 1;")
15630 (define_insn "*strsetdi_rex_1"
15631 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15632 (match_operand:DI 2 "register_operand" "a"))
15633 (set (match_operand:DI 0 "register_operand" "=D")
15634 (plus:DI (match_dup 1)
15638 [(set_attr "type" "str")
15639 (set_attr "memory" "store")
15640 (set_attr "mode" "DI")])
15642 (define_insn "*strsetsi_1"
15643 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15644 (match_operand:SI 2 "register_operand" "a"))
15645 (set (match_operand:P 0 "register_operand" "=D")
15646 (plus:P (match_dup 1)
15650 [(set_attr "type" "str")
15651 (set_attr "memory" "store")
15652 (set_attr "mode" "SI")])
15654 (define_insn "*strsethi_1"
15655 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15656 (match_operand:HI 2 "register_operand" "a"))
15657 (set (match_operand:P 0 "register_operand" "=D")
15658 (plus:P (match_dup 1)
15662 [(set_attr "type" "str")
15663 (set_attr "memory" "store")
15664 (set_attr "mode" "HI")])
15666 (define_insn "*strsetqi_1"
15667 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15668 (match_operand:QI 2 "register_operand" "a"))
15669 (set (match_operand:P 0 "register_operand" "=D")
15670 (plus:P (match_dup 1)
15674 [(set_attr "type" "str")
15675 (set_attr "memory" "store")
15676 (set (attr "prefix_rex")
15678 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15680 (const_string "*")))
15681 (set_attr "mode" "QI")])
15683 (define_expand "rep_stos"
15684 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15685 (set (match_operand 0 "register_operand" "")
15686 (match_operand 4 "" ""))
15687 (set (match_operand 2 "memory_operand" "") (const_int 0))
15688 (use (match_operand 3 "register_operand" ""))
15689 (use (match_dup 1))])]
15691 "ix86_current_function_needs_cld = 1;")
15693 (define_insn "*rep_stosdi_rex64"
15694 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15695 (set (match_operand:DI 0 "register_operand" "=D")
15696 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15698 (match_operand:DI 3 "register_operand" "0")))
15699 (set (mem:BLK (match_dup 3))
15701 (use (match_operand:DI 2 "register_operand" "a"))
15702 (use (match_dup 4))]
15705 [(set_attr "type" "str")
15706 (set_attr "prefix_rep" "1")
15707 (set_attr "memory" "store")
15708 (set_attr "mode" "DI")])
15710 (define_insn "*rep_stossi"
15711 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15712 (set (match_operand:P 0 "register_operand" "=D")
15713 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15715 (match_operand:P 3 "register_operand" "0")))
15716 (set (mem:BLK (match_dup 3))
15718 (use (match_operand:SI 2 "register_operand" "a"))
15719 (use (match_dup 4))]
15721 "rep{%;} stos{l|d}"
15722 [(set_attr "type" "str")
15723 (set_attr "prefix_rep" "1")
15724 (set_attr "memory" "store")
15725 (set_attr "mode" "SI")])
15727 (define_insn "*rep_stosqi"
15728 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15729 (set (match_operand:P 0 "register_operand" "=D")
15730 (plus:P (match_operand:P 3 "register_operand" "0")
15731 (match_operand:P 4 "register_operand" "1")))
15732 (set (mem:BLK (match_dup 3))
15734 (use (match_operand:QI 2 "register_operand" "a"))
15735 (use (match_dup 4))]
15738 [(set_attr "type" "str")
15739 (set_attr "prefix_rep" "1")
15740 (set_attr "memory" "store")
15741 (set (attr "prefix_rex")
15743 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15745 (const_string "*")))
15746 (set_attr "mode" "QI")])
15748 (define_expand "cmpstrnsi"
15749 [(set (match_operand:SI 0 "register_operand" "")
15750 (compare:SI (match_operand:BLK 1 "general_operand" "")
15751 (match_operand:BLK 2 "general_operand" "")))
15752 (use (match_operand 3 "general_operand" ""))
15753 (use (match_operand 4 "immediate_operand" ""))]
15756 rtx addr1, addr2, out, outlow, count, countreg, align;
15758 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15761 /* Can't use this if the user has appropriated esi or edi. */
15762 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15767 out = gen_reg_rtx (SImode);
15769 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15770 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15771 if (addr1 != XEXP (operands[1], 0))
15772 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15773 if (addr2 != XEXP (operands[2], 0))
15774 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15776 count = operands[3];
15777 countreg = ix86_zero_extend_to_Pmode (count);
15779 /* %%% Iff we are testing strict equality, we can use known alignment
15780 to good advantage. This may be possible with combine, particularly
15781 once cc0 is dead. */
15782 align = operands[4];
15784 if (CONST_INT_P (count))
15786 if (INTVAL (count) == 0)
15788 emit_move_insn (operands[0], const0_rtx);
15791 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15792 operands[1], operands[2]));
15796 rtx (*gen_cmp) (rtx, rtx);
15798 gen_cmp = (TARGET_64BIT
15799 ? gen_cmpdi_1 : gen_cmpsi_1);
15801 emit_insn (gen_cmp (countreg, countreg));
15802 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15803 operands[1], operands[2]));
15806 outlow = gen_lowpart (QImode, out);
15807 emit_insn (gen_cmpintqi (outlow));
15808 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15810 if (operands[0] != out)
15811 emit_move_insn (operands[0], out);
15816 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15818 (define_expand "cmpintqi"
15819 [(set (match_dup 1)
15820 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15822 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15823 (parallel [(set (match_operand:QI 0 "register_operand" "")
15824 (minus:QI (match_dup 1)
15826 (clobber (reg:CC FLAGS_REG))])]
15829 operands[1] = gen_reg_rtx (QImode);
15830 operands[2] = gen_reg_rtx (QImode);
15833 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15834 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15836 (define_expand "cmpstrnqi_nz_1"
15837 [(parallel [(set (reg:CC FLAGS_REG)
15838 (compare:CC (match_operand 4 "memory_operand" "")
15839 (match_operand 5 "memory_operand" "")))
15840 (use (match_operand 2 "register_operand" ""))
15841 (use (match_operand:SI 3 "immediate_operand" ""))
15842 (clobber (match_operand 0 "register_operand" ""))
15843 (clobber (match_operand 1 "register_operand" ""))
15844 (clobber (match_dup 2))])]
15846 "ix86_current_function_needs_cld = 1;")
15848 (define_insn "*cmpstrnqi_nz_1"
15849 [(set (reg:CC FLAGS_REG)
15850 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15851 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15852 (use (match_operand:P 6 "register_operand" "2"))
15853 (use (match_operand:SI 3 "immediate_operand" "i"))
15854 (clobber (match_operand:P 0 "register_operand" "=S"))
15855 (clobber (match_operand:P 1 "register_operand" "=D"))
15856 (clobber (match_operand:P 2 "register_operand" "=c"))]
15859 [(set_attr "type" "str")
15860 (set_attr "mode" "QI")
15861 (set (attr "prefix_rex")
15863 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15865 (const_string "*")))
15866 (set_attr "prefix_rep" "1")])
15868 ;; The same, but the count is not known to not be zero.
15870 (define_expand "cmpstrnqi_1"
15871 [(parallel [(set (reg:CC FLAGS_REG)
15872 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15874 (compare:CC (match_operand 4 "memory_operand" "")
15875 (match_operand 5 "memory_operand" ""))
15877 (use (match_operand:SI 3 "immediate_operand" ""))
15878 (use (reg:CC FLAGS_REG))
15879 (clobber (match_operand 0 "register_operand" ""))
15880 (clobber (match_operand 1 "register_operand" ""))
15881 (clobber (match_dup 2))])]
15883 "ix86_current_function_needs_cld = 1;")
15885 (define_insn "*cmpstrnqi_1"
15886 [(set (reg:CC FLAGS_REG)
15887 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15889 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15890 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15892 (use (match_operand:SI 3 "immediate_operand" "i"))
15893 (use (reg:CC FLAGS_REG))
15894 (clobber (match_operand:P 0 "register_operand" "=S"))
15895 (clobber (match_operand:P 1 "register_operand" "=D"))
15896 (clobber (match_operand:P 2 "register_operand" "=c"))]
15899 [(set_attr "type" "str")
15900 (set_attr "mode" "QI")
15901 (set (attr "prefix_rex")
15903 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15905 (const_string "*")))
15906 (set_attr "prefix_rep" "1")])
15908 (define_expand "strlen<mode>"
15909 [(set (match_operand:SWI48x 0 "register_operand" "")
15910 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15911 (match_operand:QI 2 "immediate_operand" "")
15912 (match_operand 3 "immediate_operand" "")]
15916 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15922 (define_expand "strlenqi_1"
15923 [(parallel [(set (match_operand 0 "register_operand" "")
15924 (match_operand 2 "" ""))
15925 (clobber (match_operand 1 "register_operand" ""))
15926 (clobber (reg:CC FLAGS_REG))])]
15928 "ix86_current_function_needs_cld = 1;")
15930 (define_insn "*strlenqi_1"
15931 [(set (match_operand:P 0 "register_operand" "=&c")
15932 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15933 (match_operand:QI 2 "register_operand" "a")
15934 (match_operand:P 3 "immediate_operand" "i")
15935 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15936 (clobber (match_operand:P 1 "register_operand" "=D"))
15937 (clobber (reg:CC FLAGS_REG))]
15940 [(set_attr "type" "str")
15941 (set_attr "mode" "QI")
15942 (set (attr "prefix_rex")
15944 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15946 (const_string "*")))
15947 (set_attr "prefix_rep" "1")])
15949 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15950 ;; handled in combine, but it is not currently up to the task.
15951 ;; When used for their truth value, the cmpstrn* expanders generate
15960 ;; The intermediate three instructions are unnecessary.
15962 ;; This one handles cmpstrn*_nz_1...
15965 (set (reg:CC FLAGS_REG)
15966 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15967 (mem:BLK (match_operand 5 "register_operand" ""))))
15968 (use (match_operand 6 "register_operand" ""))
15969 (use (match_operand:SI 3 "immediate_operand" ""))
15970 (clobber (match_operand 0 "register_operand" ""))
15971 (clobber (match_operand 1 "register_operand" ""))
15972 (clobber (match_operand 2 "register_operand" ""))])
15973 (set (match_operand:QI 7 "register_operand" "")
15974 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15975 (set (match_operand:QI 8 "register_operand" "")
15976 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15977 (set (reg FLAGS_REG)
15978 (compare (match_dup 7) (match_dup 8)))
15980 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15982 (set (reg:CC FLAGS_REG)
15983 (compare:CC (mem:BLK (match_dup 4))
15984 (mem:BLK (match_dup 5))))
15985 (use (match_dup 6))
15986 (use (match_dup 3))
15987 (clobber (match_dup 0))
15988 (clobber (match_dup 1))
15989 (clobber (match_dup 2))])])
15991 ;; ...and this one handles cmpstrn*_1.
15994 (set (reg:CC FLAGS_REG)
15995 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15997 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15998 (mem:BLK (match_operand 5 "register_operand" "")))
16000 (use (match_operand:SI 3 "immediate_operand" ""))
16001 (use (reg:CC FLAGS_REG))
16002 (clobber (match_operand 0 "register_operand" ""))
16003 (clobber (match_operand 1 "register_operand" ""))
16004 (clobber (match_operand 2 "register_operand" ""))])
16005 (set (match_operand:QI 7 "register_operand" "")
16006 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16007 (set (match_operand:QI 8 "register_operand" "")
16008 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16009 (set (reg FLAGS_REG)
16010 (compare (match_dup 7) (match_dup 8)))
16012 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16014 (set (reg:CC FLAGS_REG)
16015 (if_then_else:CC (ne (match_dup 6)
16017 (compare:CC (mem:BLK (match_dup 4))
16018 (mem:BLK (match_dup 5)))
16020 (use (match_dup 3))
16021 (use (reg:CC FLAGS_REG))
16022 (clobber (match_dup 0))
16023 (clobber (match_dup 1))
16024 (clobber (match_dup 2))])])
16026 ;; Conditional move instructions.
16028 (define_expand "mov<mode>cc"
16029 [(set (match_operand:SWIM 0 "register_operand" "")
16030 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16031 (match_operand:SWIM 2 "general_operand" "")
16032 (match_operand:SWIM 3 "general_operand" "")))]
16034 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16036 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16037 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16038 ;; So just document what we're doing explicitly.
16040 (define_expand "x86_mov<mode>cc_0_m1"
16042 [(set (match_operand:SWI48 0 "register_operand" "")
16043 (if_then_else:SWI48
16044 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16045 [(match_operand 1 "flags_reg_operand" "")
16049 (clobber (reg:CC FLAGS_REG))])])
16051 (define_insn "*x86_mov<mode>cc_0_m1"
16052 [(set (match_operand:SWI48 0 "register_operand" "=r")
16053 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16054 [(reg FLAGS_REG) (const_int 0)])
16057 (clobber (reg:CC FLAGS_REG))]
16059 "sbb{<imodesuffix>}\t%0, %0"
16060 ; Since we don't have the proper number of operands for an alu insn,
16061 ; fill in all the blanks.
16062 [(set_attr "type" "alu")
16063 (set_attr "use_carry" "1")
16064 (set_attr "pent_pair" "pu")
16065 (set_attr "memory" "none")
16066 (set_attr "imm_disp" "false")
16067 (set_attr "mode" "<MODE>")
16068 (set_attr "length_immediate" "0")])
16070 (define_insn "*x86_mov<mode>cc_0_m1_se"
16071 [(set (match_operand:SWI48 0 "register_operand" "=r")
16072 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16073 [(reg FLAGS_REG) (const_int 0)])
16076 (clobber (reg:CC FLAGS_REG))]
16078 "sbb{<imodesuffix>}\t%0, %0"
16079 [(set_attr "type" "alu")
16080 (set_attr "use_carry" "1")
16081 (set_attr "pent_pair" "pu")
16082 (set_attr "memory" "none")
16083 (set_attr "imm_disp" "false")
16084 (set_attr "mode" "<MODE>")
16085 (set_attr "length_immediate" "0")])
16087 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16088 [(set (match_operand:SWI48 0 "register_operand" "=r")
16089 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16090 [(reg FLAGS_REG) (const_int 0)])))]
16092 "sbb{<imodesuffix>}\t%0, %0"
16093 [(set_attr "type" "alu")
16094 (set_attr "use_carry" "1")
16095 (set_attr "pent_pair" "pu")
16096 (set_attr "memory" "none")
16097 (set_attr "imm_disp" "false")
16098 (set_attr "mode" "<MODE>")
16099 (set_attr "length_immediate" "0")])
16101 (define_insn "*mov<mode>cc_noc"
16102 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16103 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16104 [(reg FLAGS_REG) (const_int 0)])
16105 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16106 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16107 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16109 cmov%O2%C1\t{%2, %0|%0, %2}
16110 cmov%O2%c1\t{%3, %0|%0, %3}"
16111 [(set_attr "type" "icmov")
16112 (set_attr "mode" "<MODE>")])
16114 (define_insn_and_split "*movqicc_noc"
16115 [(set (match_operand:QI 0 "register_operand" "=r,r")
16116 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16117 [(match_operand 4 "flags_reg_operand" "")
16119 (match_operand:QI 2 "register_operand" "r,0")
16120 (match_operand:QI 3 "register_operand" "0,r")))]
16121 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16123 "&& reload_completed"
16124 [(set (match_dup 0)
16125 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16128 "operands[0] = gen_lowpart (SImode, operands[0]);
16129 operands[2] = gen_lowpart (SImode, operands[2]);
16130 operands[3] = gen_lowpart (SImode, operands[3]);"
16131 [(set_attr "type" "icmov")
16132 (set_attr "mode" "SI")])
16134 (define_expand "mov<mode>cc"
16135 [(set (match_operand:X87MODEF 0 "register_operand" "")
16136 (if_then_else:X87MODEF
16137 (match_operand 1 "ix86_fp_comparison_operator" "")
16138 (match_operand:X87MODEF 2 "register_operand" "")
16139 (match_operand:X87MODEF 3 "register_operand" "")))]
16140 "(TARGET_80387 && TARGET_CMOVE)
16141 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16142 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16144 (define_insn "*movxfcc_1"
16145 [(set (match_operand:XF 0 "register_operand" "=f,f")
16146 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16147 [(reg FLAGS_REG) (const_int 0)])
16148 (match_operand:XF 2 "register_operand" "f,0")
16149 (match_operand:XF 3 "register_operand" "0,f")))]
16150 "TARGET_80387 && TARGET_CMOVE"
16152 fcmov%F1\t{%2, %0|%0, %2}
16153 fcmov%f1\t{%3, %0|%0, %3}"
16154 [(set_attr "type" "fcmov")
16155 (set_attr "mode" "XF")])
16157 (define_insn "*movdfcc_1_rex64"
16158 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16159 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16160 [(reg FLAGS_REG) (const_int 0)])
16161 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16162 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16163 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16164 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16166 fcmov%F1\t{%2, %0|%0, %2}
16167 fcmov%f1\t{%3, %0|%0, %3}
16168 cmov%O2%C1\t{%2, %0|%0, %2}
16169 cmov%O2%c1\t{%3, %0|%0, %3}"
16170 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16171 (set_attr "mode" "DF,DF,DI,DI")])
16173 (define_insn "*movdfcc_1"
16174 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16175 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16176 [(reg FLAGS_REG) (const_int 0)])
16177 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16178 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16179 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16180 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16182 fcmov%F1\t{%2, %0|%0, %2}
16183 fcmov%f1\t{%3, %0|%0, %3}
16186 [(set_attr "type" "fcmov,fcmov,multi,multi")
16187 (set_attr "mode" "DF,DF,DI,DI")])
16190 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16191 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16192 [(match_operand 4 "flags_reg_operand" "")
16194 (match_operand:DF 2 "nonimmediate_operand" "")
16195 (match_operand:DF 3 "nonimmediate_operand" "")))]
16196 "!TARGET_64BIT && reload_completed"
16197 [(set (match_dup 2)
16198 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16202 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16206 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16207 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16210 (define_insn "*movsfcc_1_387"
16211 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16212 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16213 [(reg FLAGS_REG) (const_int 0)])
16214 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16215 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16216 "TARGET_80387 && TARGET_CMOVE
16217 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16219 fcmov%F1\t{%2, %0|%0, %2}
16220 fcmov%f1\t{%3, %0|%0, %3}
16221 cmov%O2%C1\t{%2, %0|%0, %2}
16222 cmov%O2%c1\t{%3, %0|%0, %3}"
16223 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16224 (set_attr "mode" "SF,SF,SI,SI")])
16226 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16227 ;; the scalar versions to have only XMM registers as operands.
16229 ;; XOP conditional move
16230 (define_insn "*xop_pcmov_<mode>"
16231 [(set (match_operand:MODEF 0 "register_operand" "=x")
16232 (if_then_else:MODEF
16233 (match_operand:MODEF 1 "register_operand" "x")
16234 (match_operand:MODEF 2 "register_operand" "x")
16235 (match_operand:MODEF 3 "register_operand" "x")))]
16237 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16238 [(set_attr "type" "sse4arg")])
16240 ;; These versions of the min/max patterns are intentionally ignorant of
16241 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16242 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16243 ;; are undefined in this condition, we're certain this is correct.
16245 (define_insn "<code><mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16248 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16250 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16253 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16254 [(set_attr "isa" "noavx,avx")
16255 (set_attr "prefix" "orig,vex")
16256 (set_attr "type" "sseadd")
16257 (set_attr "mode" "<MODE>")])
16259 ;; These versions of the min/max patterns implement exactly the operations
16260 ;; min = (op1 < op2 ? op1 : op2)
16261 ;; max = (!(op1 < op2) ? op1 : op2)
16262 ;; Their operands are not commutative, and thus they may be used in the
16263 ;; presence of -0.0 and NaN.
16265 (define_insn "*ieee_smin<mode>3"
16266 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16268 [(match_operand:MODEF 1 "register_operand" "0,x")
16269 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16271 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16273 min<ssemodesuffix>\t{%2, %0|%0, %2}
16274 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16275 [(set_attr "isa" "noavx,avx")
16276 (set_attr "prefix" "orig,vex")
16277 (set_attr "type" "sseadd")
16278 (set_attr "mode" "<MODE>")])
16280 (define_insn "*ieee_smax<mode>3"
16281 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16283 [(match_operand:MODEF 1 "register_operand" "0,x")
16284 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16286 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16288 max<ssemodesuffix>\t{%2, %0|%0, %2}
16289 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16290 [(set_attr "isa" "noavx,avx")
16291 (set_attr "prefix" "orig,vex")
16292 (set_attr "type" "sseadd")
16293 (set_attr "mode" "<MODE>")])
16295 ;; Make two stack loads independent:
16297 ;; fld %st(0) -> fld bb
16298 ;; fmul bb fmul %st(1), %st
16300 ;; Actually we only match the last two instructions for simplicity.
16302 [(set (match_operand 0 "fp_register_operand" "")
16303 (match_operand 1 "fp_register_operand" ""))
16305 (match_operator 2 "binary_fp_operator"
16307 (match_operand 3 "memory_operand" "")]))]
16308 "REGNO (operands[0]) != REGNO (operands[1])"
16309 [(set (match_dup 0) (match_dup 3))
16310 (set (match_dup 0) (match_dup 4))]
16312 ;; The % modifier is not operational anymore in peephole2's, so we have to
16313 ;; swap the operands manually in the case of addition and multiplication.
16314 "if (COMMUTATIVE_ARITH_P (operands[2]))
16315 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16316 GET_MODE (operands[2]),
16317 operands[0], operands[1]);
16319 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16320 GET_MODE (operands[2]),
16321 operands[1], operands[0]);")
16323 ;; Conditional addition patterns
16324 (define_expand "add<mode>cc"
16325 [(match_operand:SWI 0 "register_operand" "")
16326 (match_operand 1 "ordered_comparison_operator" "")
16327 (match_operand:SWI 2 "register_operand" "")
16328 (match_operand:SWI 3 "const_int_operand" "")]
16330 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16332 ;; Misc patterns (?)
16334 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16335 ;; Otherwise there will be nothing to keep
16337 ;; [(set (reg ebp) (reg esp))]
16338 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16339 ;; (clobber (eflags)]
16340 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16342 ;; in proper program order.
16344 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16345 [(set (match_operand:P 0 "register_operand" "=r,r")
16346 (plus:P (match_operand:P 1 "register_operand" "0,r")
16347 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16348 (clobber (reg:CC FLAGS_REG))
16349 (clobber (mem:BLK (scratch)))]
16352 switch (get_attr_type (insn))
16355 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16359 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16360 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16362 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16365 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16366 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16369 [(set (attr "type")
16370 (cond [(and (eq_attr "alternative" "0")
16371 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16372 (const_string "alu")
16373 (match_operand:<MODE> 2 "const0_operand" "")
16374 (const_string "imov")
16376 (const_string "lea")))
16377 (set (attr "length_immediate")
16378 (cond [(eq_attr "type" "imov")
16380 (and (eq_attr "type" "alu")
16381 (match_operand 2 "const128_operand" ""))
16384 (const_string "*")))
16385 (set_attr "mode" "<MODE>")])
16387 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16388 [(set (match_operand:P 0 "register_operand" "=r")
16389 (minus:P (match_operand:P 1 "register_operand" "0")
16390 (match_operand:P 2 "register_operand" "r")))
16391 (clobber (reg:CC FLAGS_REG))
16392 (clobber (mem:BLK (scratch)))]
16394 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16395 [(set_attr "type" "alu")
16396 (set_attr "mode" "<MODE>")])
16398 (define_insn "allocate_stack_worker_probe_<mode>"
16399 [(set (match_operand:P 0 "register_operand" "=a")
16400 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16401 UNSPECV_STACK_PROBE))
16402 (clobber (reg:CC FLAGS_REG))]
16403 "ix86_target_stack_probe ()"
16404 "call\t___chkstk_ms"
16405 [(set_attr "type" "multi")
16406 (set_attr "length" "5")])
16408 (define_expand "allocate_stack"
16409 [(match_operand 0 "register_operand" "")
16410 (match_operand 1 "general_operand" "")]
16411 "ix86_target_stack_probe ()"
16415 #ifndef CHECK_STACK_LIMIT
16416 #define CHECK_STACK_LIMIT 0
16419 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16420 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16422 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16423 stack_pointer_rtx, 0, OPTAB_DIRECT);
16424 if (x != stack_pointer_rtx)
16425 emit_move_insn (stack_pointer_rtx, x);
16429 x = copy_to_mode_reg (Pmode, operands[1]);
16431 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16433 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16434 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16435 stack_pointer_rtx, 0, OPTAB_DIRECT);
16436 if (x != stack_pointer_rtx)
16437 emit_move_insn (stack_pointer_rtx, x);
16440 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16444 ;; Use IOR for stack probes, this is shorter.
16445 (define_expand "probe_stack"
16446 [(match_operand 0 "memory_operand" "")]
16449 rtx (*gen_ior3) (rtx, rtx, rtx);
16451 gen_ior3 = (GET_MODE (operands[0]) == DImode
16452 ? gen_iordi3 : gen_iorsi3);
16454 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16458 (define_insn "adjust_stack_and_probe<mode>"
16459 [(set (match_operand:P 0 "register_operand" "=r")
16460 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16461 UNSPECV_PROBE_STACK_RANGE))
16462 (set (reg:P SP_REG)
16463 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16464 (clobber (reg:CC FLAGS_REG))
16465 (clobber (mem:BLK (scratch)))]
16467 "* return output_adjust_stack_and_probe (operands[0]);"
16468 [(set_attr "type" "multi")])
16470 (define_insn "probe_stack_range<mode>"
16471 [(set (match_operand:P 0 "register_operand" "=r")
16472 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16473 (match_operand:P 2 "const_int_operand" "n")]
16474 UNSPECV_PROBE_STACK_RANGE))
16475 (clobber (reg:CC FLAGS_REG))]
16477 "* return output_probe_stack_range (operands[0], operands[2]);"
16478 [(set_attr "type" "multi")])
16480 (define_expand "builtin_setjmp_receiver"
16481 [(label_ref (match_operand 0 "" ""))]
16482 "!TARGET_64BIT && flag_pic"
16488 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16489 rtx label_rtx = gen_label_rtx ();
16490 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16491 xops[0] = xops[1] = picreg;
16492 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16493 ix86_expand_binary_operator (MINUS, SImode, xops);
16497 emit_insn (gen_set_got (pic_offset_table_rtx));
16501 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16504 [(set (match_operand 0 "register_operand" "")
16505 (match_operator 3 "promotable_binary_operator"
16506 [(match_operand 1 "register_operand" "")
16507 (match_operand 2 "aligned_operand" "")]))
16508 (clobber (reg:CC FLAGS_REG))]
16509 "! TARGET_PARTIAL_REG_STALL && reload_completed
16510 && ((GET_MODE (operands[0]) == HImode
16511 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16512 /* ??? next two lines just !satisfies_constraint_K (...) */
16513 || !CONST_INT_P (operands[2])
16514 || satisfies_constraint_K (operands[2])))
16515 || (GET_MODE (operands[0]) == QImode
16516 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16517 [(parallel [(set (match_dup 0)
16518 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16519 (clobber (reg:CC FLAGS_REG))])]
16520 "operands[0] = gen_lowpart (SImode, operands[0]);
16521 operands[1] = gen_lowpart (SImode, operands[1]);
16522 if (GET_CODE (operands[3]) != ASHIFT)
16523 operands[2] = gen_lowpart (SImode, operands[2]);
16524 PUT_MODE (operands[3], SImode);")
16526 ; Promote the QImode tests, as i386 has encoding of the AND
16527 ; instruction with 32-bit sign-extended immediate and thus the
16528 ; instruction size is unchanged, except in the %eax case for
16529 ; which it is increased by one byte, hence the ! optimize_size.
16531 [(set (match_operand 0 "flags_reg_operand" "")
16532 (match_operator 2 "compare_operator"
16533 [(and (match_operand 3 "aligned_operand" "")
16534 (match_operand 4 "const_int_operand" ""))
16536 (set (match_operand 1 "register_operand" "")
16537 (and (match_dup 3) (match_dup 4)))]
16538 "! TARGET_PARTIAL_REG_STALL && reload_completed
16539 && optimize_insn_for_speed_p ()
16540 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16541 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16542 /* Ensure that the operand will remain sign-extended immediate. */
16543 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16544 [(parallel [(set (match_dup 0)
16545 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16548 (and:SI (match_dup 3) (match_dup 4)))])]
16551 = gen_int_mode (INTVAL (operands[4])
16552 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16553 operands[1] = gen_lowpart (SImode, operands[1]);
16554 operands[3] = gen_lowpart (SImode, operands[3]);
16557 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16558 ; the TEST instruction with 32-bit sign-extended immediate and thus
16559 ; the instruction size would at least double, which is not what we
16560 ; want even with ! optimize_size.
16562 [(set (match_operand 0 "flags_reg_operand" "")
16563 (match_operator 1 "compare_operator"
16564 [(and (match_operand:HI 2 "aligned_operand" "")
16565 (match_operand:HI 3 "const_int_operand" ""))
16567 "! TARGET_PARTIAL_REG_STALL && reload_completed
16568 && ! TARGET_FAST_PREFIX
16569 && optimize_insn_for_speed_p ()
16570 /* Ensure that the operand will remain sign-extended immediate. */
16571 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16572 [(set (match_dup 0)
16573 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16577 = gen_int_mode (INTVAL (operands[3])
16578 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16579 operands[2] = gen_lowpart (SImode, operands[2]);
16583 [(set (match_operand 0 "register_operand" "")
16584 (neg (match_operand 1 "register_operand" "")))
16585 (clobber (reg:CC FLAGS_REG))]
16586 "! TARGET_PARTIAL_REG_STALL && reload_completed
16587 && (GET_MODE (operands[0]) == HImode
16588 || (GET_MODE (operands[0]) == QImode
16589 && (TARGET_PROMOTE_QImode
16590 || optimize_insn_for_size_p ())))"
16591 [(parallel [(set (match_dup 0)
16592 (neg:SI (match_dup 1)))
16593 (clobber (reg:CC FLAGS_REG))])]
16594 "operands[0] = gen_lowpart (SImode, operands[0]);
16595 operands[1] = gen_lowpart (SImode, operands[1]);")
16598 [(set (match_operand 0 "register_operand" "")
16599 (not (match_operand 1 "register_operand" "")))]
16600 "! TARGET_PARTIAL_REG_STALL && reload_completed
16601 && (GET_MODE (operands[0]) == HImode
16602 || (GET_MODE (operands[0]) == QImode
16603 && (TARGET_PROMOTE_QImode
16604 || optimize_insn_for_size_p ())))"
16605 [(set (match_dup 0)
16606 (not:SI (match_dup 1)))]
16607 "operands[0] = gen_lowpart (SImode, operands[0]);
16608 operands[1] = gen_lowpart (SImode, operands[1]);")
16611 [(set (match_operand 0 "register_operand" "")
16612 (if_then_else (match_operator 1 "ordered_comparison_operator"
16613 [(reg FLAGS_REG) (const_int 0)])
16614 (match_operand 2 "register_operand" "")
16615 (match_operand 3 "register_operand" "")))]
16616 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16617 && (GET_MODE (operands[0]) == HImode
16618 || (GET_MODE (operands[0]) == QImode
16619 && (TARGET_PROMOTE_QImode
16620 || optimize_insn_for_size_p ())))"
16621 [(set (match_dup 0)
16622 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16623 "operands[0] = gen_lowpart (SImode, operands[0]);
16624 operands[2] = gen_lowpart (SImode, operands[2]);
16625 operands[3] = gen_lowpart (SImode, operands[3]);")
16627 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16628 ;; transform a complex memory operation into two memory to register operations.
16630 ;; Don't push memory operands
16632 [(set (match_operand:SWI 0 "push_operand" "")
16633 (match_operand:SWI 1 "memory_operand" ""))
16634 (match_scratch:SWI 2 "<r>")]
16635 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16636 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16637 [(set (match_dup 2) (match_dup 1))
16638 (set (match_dup 0) (match_dup 2))])
16640 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16643 [(set (match_operand:SF 0 "push_operand" "")
16644 (match_operand:SF 1 "memory_operand" ""))
16645 (match_scratch:SF 2 "r")]
16646 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16647 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16648 [(set (match_dup 2) (match_dup 1))
16649 (set (match_dup 0) (match_dup 2))])
16651 ;; Don't move an immediate directly to memory when the instruction
16654 [(match_scratch:SWI124 1 "<r>")
16655 (set (match_operand:SWI124 0 "memory_operand" "")
16657 "optimize_insn_for_speed_p ()
16658 && !TARGET_USE_MOV0
16659 && TARGET_SPLIT_LONG_MOVES
16660 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16661 && peep2_regno_dead_p (0, FLAGS_REG)"
16662 [(parallel [(set (match_dup 2) (const_int 0))
16663 (clobber (reg:CC FLAGS_REG))])
16664 (set (match_dup 0) (match_dup 1))]
16665 "operands[2] = gen_lowpart (SImode, operands[1]);")
16668 [(match_scratch:SWI124 2 "<r>")
16669 (set (match_operand:SWI124 0 "memory_operand" "")
16670 (match_operand:SWI124 1 "immediate_operand" ""))]
16671 "optimize_insn_for_speed_p ()
16672 && TARGET_SPLIT_LONG_MOVES
16673 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16674 [(set (match_dup 2) (match_dup 1))
16675 (set (match_dup 0) (match_dup 2))])
16677 ;; Don't compare memory with zero, load and use a test instead.
16679 [(set (match_operand 0 "flags_reg_operand" "")
16680 (match_operator 1 "compare_operator"
16681 [(match_operand:SI 2 "memory_operand" "")
16683 (match_scratch:SI 3 "r")]
16684 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16685 [(set (match_dup 3) (match_dup 2))
16686 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16688 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16689 ;; Don't split NOTs with a displacement operand, because resulting XOR
16690 ;; will not be pairable anyway.
16692 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16693 ;; represented using a modRM byte. The XOR replacement is long decoded,
16694 ;; so this split helps here as well.
16696 ;; Note: Can't do this as a regular split because we can't get proper
16697 ;; lifetime information then.
16700 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16701 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16702 "optimize_insn_for_speed_p ()
16703 && ((TARGET_NOT_UNPAIRABLE
16704 && (!MEM_P (operands[0])
16705 || !memory_displacement_operand (operands[0], <MODE>mode)))
16706 || (TARGET_NOT_VECTORMODE
16707 && long_memory_operand (operands[0], <MODE>mode)))
16708 && peep2_regno_dead_p (0, FLAGS_REG)"
16709 [(parallel [(set (match_dup 0)
16710 (xor:SWI124 (match_dup 1) (const_int -1)))
16711 (clobber (reg:CC FLAGS_REG))])])
16713 ;; Non pairable "test imm, reg" instructions can be translated to
16714 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16715 ;; byte opcode instead of two, have a short form for byte operands),
16716 ;; so do it for other CPUs as well. Given that the value was dead,
16717 ;; this should not create any new dependencies. Pass on the sub-word
16718 ;; versions if we're concerned about partial register stalls.
16721 [(set (match_operand 0 "flags_reg_operand" "")
16722 (match_operator 1 "compare_operator"
16723 [(and:SI (match_operand:SI 2 "register_operand" "")
16724 (match_operand:SI 3 "immediate_operand" ""))
16726 "ix86_match_ccmode (insn, CCNOmode)
16727 && (true_regnum (operands[2]) != AX_REG
16728 || satisfies_constraint_K (operands[3]))
16729 && peep2_reg_dead_p (1, operands[2])"
16731 [(set (match_dup 0)
16732 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16735 (and:SI (match_dup 2) (match_dup 3)))])])
16737 ;; We don't need to handle HImode case, because it will be promoted to SImode
16738 ;; on ! TARGET_PARTIAL_REG_STALL
16741 [(set (match_operand 0 "flags_reg_operand" "")
16742 (match_operator 1 "compare_operator"
16743 [(and:QI (match_operand:QI 2 "register_operand" "")
16744 (match_operand:QI 3 "immediate_operand" ""))
16746 "! TARGET_PARTIAL_REG_STALL
16747 && ix86_match_ccmode (insn, CCNOmode)
16748 && true_regnum (operands[2]) != AX_REG
16749 && peep2_reg_dead_p (1, operands[2])"
16751 [(set (match_dup 0)
16752 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16755 (and:QI (match_dup 2) (match_dup 3)))])])
16758 [(set (match_operand 0 "flags_reg_operand" "")
16759 (match_operator 1 "compare_operator"
16762 (match_operand 2 "ext_register_operand" "")
16765 (match_operand 3 "const_int_operand" ""))
16767 "! TARGET_PARTIAL_REG_STALL
16768 && ix86_match_ccmode (insn, CCNOmode)
16769 && true_regnum (operands[2]) != AX_REG
16770 && peep2_reg_dead_p (1, operands[2])"
16771 [(parallel [(set (match_dup 0)
16780 (set (zero_extract:SI (match_dup 2)
16788 (match_dup 3)))])])
16790 ;; Don't do logical operations with memory inputs.
16792 [(match_scratch:SI 2 "r")
16793 (parallel [(set (match_operand:SI 0 "register_operand" "")
16794 (match_operator:SI 3 "arith_or_logical_operator"
16796 (match_operand:SI 1 "memory_operand" "")]))
16797 (clobber (reg:CC FLAGS_REG))])]
16798 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16799 [(set (match_dup 2) (match_dup 1))
16800 (parallel [(set (match_dup 0)
16801 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16802 (clobber (reg:CC FLAGS_REG))])])
16805 [(match_scratch:SI 2 "r")
16806 (parallel [(set (match_operand:SI 0 "register_operand" "")
16807 (match_operator:SI 3 "arith_or_logical_operator"
16808 [(match_operand:SI 1 "memory_operand" "")
16810 (clobber (reg:CC FLAGS_REG))])]
16811 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16812 [(set (match_dup 2) (match_dup 1))
16813 (parallel [(set (match_dup 0)
16814 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16815 (clobber (reg:CC FLAGS_REG))])])
16817 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16818 ;; refers to the destination of the load!
16821 [(set (match_operand:SI 0 "register_operand" "")
16822 (match_operand:SI 1 "register_operand" ""))
16823 (parallel [(set (match_dup 0)
16824 (match_operator:SI 3 "commutative_operator"
16826 (match_operand:SI 2 "memory_operand" "")]))
16827 (clobber (reg:CC FLAGS_REG))])]
16828 "REGNO (operands[0]) != REGNO (operands[1])
16829 && GENERAL_REGNO_P (REGNO (operands[0]))
16830 && GENERAL_REGNO_P (REGNO (operands[1]))"
16831 [(set (match_dup 0) (match_dup 4))
16832 (parallel [(set (match_dup 0)
16833 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16834 (clobber (reg:CC FLAGS_REG))])]
16835 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16838 [(set (match_operand 0 "register_operand" "")
16839 (match_operand 1 "register_operand" ""))
16841 (match_operator 3 "commutative_operator"
16843 (match_operand 2 "memory_operand" "")]))]
16844 "REGNO (operands[0]) != REGNO (operands[1])
16845 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16846 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16847 [(set (match_dup 0) (match_dup 2))
16849 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16851 ; Don't do logical operations with memory outputs
16853 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16854 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16855 ; the same decoder scheduling characteristics as the original.
16858 [(match_scratch:SI 2 "r")
16859 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16860 (match_operator:SI 3 "arith_or_logical_operator"
16862 (match_operand:SI 1 "nonmemory_operand" "")]))
16863 (clobber (reg:CC FLAGS_REG))])]
16864 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16865 /* Do not split stack checking probes. */
16866 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16867 [(set (match_dup 2) (match_dup 0))
16868 (parallel [(set (match_dup 2)
16869 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16870 (clobber (reg:CC FLAGS_REG))])
16871 (set (match_dup 0) (match_dup 2))])
16874 [(match_scratch:SI 2 "r")
16875 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16876 (match_operator:SI 3 "arith_or_logical_operator"
16877 [(match_operand:SI 1 "nonmemory_operand" "")
16879 (clobber (reg:CC FLAGS_REG))])]
16880 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16881 /* Do not split stack checking probes. */
16882 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16883 [(set (match_dup 2) (match_dup 0))
16884 (parallel [(set (match_dup 2)
16885 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16886 (clobber (reg:CC FLAGS_REG))])
16887 (set (match_dup 0) (match_dup 2))])
16889 ;; Attempt to use arith or logical operations with memory outputs with
16890 ;; setting of flags.
16892 [(set (match_operand:SWI 0 "register_operand" "")
16893 (match_operand:SWI 1 "memory_operand" ""))
16894 (parallel [(set (match_dup 0)
16895 (match_operator:SWI 3 "plusminuslogic_operator"
16897 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16898 (clobber (reg:CC FLAGS_REG))])
16899 (set (match_dup 1) (match_dup 0))
16900 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16901 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16902 && peep2_reg_dead_p (4, operands[0])
16903 && !reg_overlap_mentioned_p (operands[0], operands[1])
16904 && ix86_match_ccmode (peep2_next_insn (3),
16905 (GET_CODE (operands[3]) == PLUS
16906 || GET_CODE (operands[3]) == MINUS)
16907 ? CCGOCmode : CCNOmode)"
16908 [(parallel [(set (match_dup 4) (match_dup 5))
16909 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16910 (match_dup 2)]))])]
16911 "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16912 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16913 copy_rtx (operands[1]),
16914 copy_rtx (operands[2]));
16915 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16916 operands[5], const0_rtx);")
16919 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16920 (match_operator:SWI 2 "plusminuslogic_operator"
16922 (match_operand:SWI 1 "memory_operand" "")]))
16923 (clobber (reg:CC FLAGS_REG))])
16924 (set (match_dup 1) (match_dup 0))
16925 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16926 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16927 && GET_CODE (operands[2]) != MINUS
16928 && peep2_reg_dead_p (3, operands[0])
16929 && !reg_overlap_mentioned_p (operands[0], operands[1])
16930 && ix86_match_ccmode (peep2_next_insn (2),
16931 GET_CODE (operands[2]) == PLUS
16932 ? CCGOCmode : CCNOmode)"
16933 [(parallel [(set (match_dup 3) (match_dup 4))
16934 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16935 (match_dup 0)]))])]
16936 "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16937 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16938 copy_rtx (operands[1]),
16939 copy_rtx (operands[0]));
16940 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16941 operands[4], const0_rtx);")
16944 [(set (match_operand:SWI12 0 "register_operand" "")
16945 (match_operand:SWI12 1 "memory_operand" ""))
16946 (parallel [(set (match_operand:SI 4 "register_operand" "")
16947 (match_operator:SI 3 "plusminuslogic_operator"
16949 (match_operand:SI 2 "nonmemory_operand" "")]))
16950 (clobber (reg:CC FLAGS_REG))])
16951 (set (match_dup 1) (match_dup 0))
16952 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16953 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16954 && REG_P (operands[0]) && REG_P (operands[4])
16955 && REGNO (operands[0]) == REGNO (operands[4])
16956 && peep2_reg_dead_p (4, operands[0])
16957 && !reg_overlap_mentioned_p (operands[0], operands[1])
16958 && ix86_match_ccmode (peep2_next_insn (3),
16959 (GET_CODE (operands[3]) == PLUS
16960 || GET_CODE (operands[3]) == MINUS)
16961 ? CCGOCmode : CCNOmode)"
16962 [(parallel [(set (match_dup 4) (match_dup 5))
16963 (set (match_dup 1) (match_dup 6))])]
16964 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16965 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16966 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16967 copy_rtx (operands[1]), operands[2]);
16968 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16969 operands[5], const0_rtx);
16970 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16971 copy_rtx (operands[1]),
16972 copy_rtx (operands[2]));")
16974 ;; Attempt to always use XOR for zeroing registers.
16976 [(set (match_operand 0 "register_operand" "")
16977 (match_operand 1 "const0_operand" ""))]
16978 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16979 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16980 && GENERAL_REG_P (operands[0])
16981 && peep2_regno_dead_p (0, FLAGS_REG)"
16982 [(parallel [(set (match_dup 0) (const_int 0))
16983 (clobber (reg:CC FLAGS_REG))])]
16984 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16987 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16989 "(GET_MODE (operands[0]) == QImode
16990 || GET_MODE (operands[0]) == HImode)
16991 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16992 && peep2_regno_dead_p (0, FLAGS_REG)"
16993 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16994 (clobber (reg:CC FLAGS_REG))])])
16996 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16998 [(set (match_operand:SWI248 0 "register_operand" "")
17000 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17001 && peep2_regno_dead_p (0, FLAGS_REG)"
17002 [(parallel [(set (match_dup 0) (const_int -1))
17003 (clobber (reg:CC FLAGS_REG))])]
17005 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17006 operands[0] = gen_lowpart (SImode, operands[0]);
17009 ;; Attempt to convert simple lea to add/shift.
17010 ;; These can be created by move expanders.
17013 [(set (match_operand:SWI48 0 "register_operand" "")
17014 (plus:SWI48 (match_dup 0)
17015 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17016 "peep2_regno_dead_p (0, FLAGS_REG)"
17017 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17018 (clobber (reg:CC FLAGS_REG))])])
17021 [(set (match_operand:SI 0 "register_operand" "")
17022 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17023 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17025 && peep2_regno_dead_p (0, FLAGS_REG)
17026 && REGNO (operands[0]) == REGNO (operands[1])"
17027 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17028 (clobber (reg:CC FLAGS_REG))])]
17029 "operands[2] = gen_lowpart (SImode, operands[2]);")
17032 [(set (match_operand:SWI48 0 "register_operand" "")
17033 (mult:SWI48 (match_dup 0)
17034 (match_operand:SWI48 1 "const_int_operand" "")))]
17035 "exact_log2 (INTVAL (operands[1])) >= 0
17036 && peep2_regno_dead_p (0, FLAGS_REG)"
17037 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17038 (clobber (reg:CC FLAGS_REG))])]
17039 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17042 [(set (match_operand:SI 0 "register_operand" "")
17043 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17044 (match_operand:DI 2 "const_int_operand" "")) 0))]
17046 && exact_log2 (INTVAL (operands[2])) >= 0
17047 && REGNO (operands[0]) == REGNO (operands[1])
17048 && peep2_regno_dead_p (0, FLAGS_REG)"
17049 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17050 (clobber (reg:CC FLAGS_REG))])]
17051 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17053 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17054 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17055 ;; On many CPUs it is also faster, since special hardware to avoid esp
17056 ;; dependencies is present.
17058 ;; While some of these conversions may be done using splitters, we use
17059 ;; peepholes in order to allow combine_stack_adjustments pass to see
17060 ;; nonobfuscated RTL.
17062 ;; Convert prologue esp subtractions to push.
17063 ;; We need register to push. In order to keep verify_flow_info happy we have
17065 ;; - use scratch and clobber it in order to avoid dependencies
17066 ;; - use already live register
17067 ;; We can't use the second way right now, since there is no reliable way how to
17068 ;; verify that given register is live. First choice will also most likely in
17069 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17070 ;; call clobbered registers are dead. We may want to use base pointer as an
17071 ;; alternative when no register is available later.
17074 [(match_scratch:P 1 "r")
17075 (parallel [(set (reg:P SP_REG)
17076 (plus:P (reg:P SP_REG)
17077 (match_operand:P 0 "const_int_operand" "")))
17078 (clobber (reg:CC FLAGS_REG))
17079 (clobber (mem:BLK (scratch)))])]
17080 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17081 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17082 [(clobber (match_dup 1))
17083 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17084 (clobber (mem:BLK (scratch)))])])
17087 [(match_scratch:P 1 "r")
17088 (parallel [(set (reg:P SP_REG)
17089 (plus:P (reg:P SP_REG)
17090 (match_operand:P 0 "const_int_operand" "")))
17091 (clobber (reg:CC FLAGS_REG))
17092 (clobber (mem:BLK (scratch)))])]
17093 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17094 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17095 [(clobber (match_dup 1))
17096 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17097 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17098 (clobber (mem:BLK (scratch)))])])
17100 ;; Convert esp subtractions to push.
17102 [(match_scratch:P 1 "r")
17103 (parallel [(set (reg:P SP_REG)
17104 (plus:P (reg:P SP_REG)
17105 (match_operand:P 0 "const_int_operand" "")))
17106 (clobber (reg:CC FLAGS_REG))])]
17107 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17108 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17109 [(clobber (match_dup 1))
17110 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17113 [(match_scratch:P 1 "r")
17114 (parallel [(set (reg:P SP_REG)
17115 (plus:P (reg:P SP_REG)
17116 (match_operand:P 0 "const_int_operand" "")))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17119 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17120 [(clobber (match_dup 1))
17121 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17122 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17124 ;; Convert epilogue deallocator to pop.
17126 [(match_scratch:P 1 "r")
17127 (parallel [(set (reg:P SP_REG)
17128 (plus:P (reg:P SP_REG)
17129 (match_operand:P 0 "const_int_operand" "")))
17130 (clobber (reg:CC FLAGS_REG))
17131 (clobber (mem:BLK (scratch)))])]
17132 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17133 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17134 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17135 (clobber (mem:BLK (scratch)))])])
17137 ;; Two pops case is tricky, since pop causes dependency
17138 ;; on destination register. We use two registers if available.
17140 [(match_scratch:P 1 "r")
17141 (match_scratch:P 2 "r")
17142 (parallel [(set (reg:P SP_REG)
17143 (plus:P (reg:P SP_REG)
17144 (match_operand:P 0 "const_int_operand" "")))
17145 (clobber (reg:CC FLAGS_REG))
17146 (clobber (mem:BLK (scratch)))])]
17147 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17148 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17149 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17150 (clobber (mem:BLK (scratch)))])
17151 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17154 [(match_scratch:P 1 "r")
17155 (parallel [(set (reg:P SP_REG)
17156 (plus:P (reg:P SP_REG)
17157 (match_operand:P 0 "const_int_operand" "")))
17158 (clobber (reg:CC FLAGS_REG))
17159 (clobber (mem:BLK (scratch)))])]
17160 "optimize_insn_for_size_p ()
17161 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17162 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17163 (clobber (mem:BLK (scratch)))])
17164 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17166 ;; Convert esp additions to pop.
17168 [(match_scratch:P 1 "r")
17169 (parallel [(set (reg:P SP_REG)
17170 (plus:P (reg:P SP_REG)
17171 (match_operand:P 0 "const_int_operand" "")))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17174 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17176 ;; Two pops case is tricky, since pop causes dependency
17177 ;; on destination register. We use two registers if available.
17179 [(match_scratch:P 1 "r")
17180 (match_scratch:P 2 "r")
17181 (parallel [(set (reg:P SP_REG)
17182 (plus:P (reg:P SP_REG)
17183 (match_operand:P 0 "const_int_operand" "")))
17184 (clobber (reg:CC FLAGS_REG))])]
17185 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17186 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17187 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17190 [(match_scratch:P 1 "r")
17191 (parallel [(set (reg:P SP_REG)
17192 (plus:P (reg:P SP_REG)
17193 (match_operand:P 0 "const_int_operand" "")))
17194 (clobber (reg:CC FLAGS_REG))])]
17195 "optimize_insn_for_size_p ()
17196 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17197 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17198 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17200 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17201 ;; required and register dies. Similarly for 128 to -128.
17203 [(set (match_operand 0 "flags_reg_operand" "")
17204 (match_operator 1 "compare_operator"
17205 [(match_operand 2 "register_operand" "")
17206 (match_operand 3 "const_int_operand" "")]))]
17207 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17208 && incdec_operand (operands[3], GET_MODE (operands[3])))
17209 || (!TARGET_FUSE_CMP_AND_BRANCH
17210 && INTVAL (operands[3]) == 128))
17211 && ix86_match_ccmode (insn, CCGCmode)
17212 && peep2_reg_dead_p (1, operands[2])"
17213 [(parallel [(set (match_dup 0)
17214 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17215 (clobber (match_dup 2))])])
17217 ;; Convert imul by three, five and nine into lea
17220 [(set (match_operand:SWI48 0 "register_operand" "")
17221 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17222 (match_operand:SWI48 2 "const_int_operand" "")))
17223 (clobber (reg:CC FLAGS_REG))])]
17224 "INTVAL (operands[2]) == 3
17225 || INTVAL (operands[2]) == 5
17226 || INTVAL (operands[2]) == 9"
17227 [(set (match_dup 0)
17228 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17230 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17234 [(set (match_operand:SWI48 0 "register_operand" "")
17235 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17236 (match_operand:SWI48 2 "const_int_operand" "")))
17237 (clobber (reg:CC FLAGS_REG))])]
17238 "optimize_insn_for_speed_p ()
17239 && (INTVAL (operands[2]) == 3
17240 || INTVAL (operands[2]) == 5
17241 || INTVAL (operands[2]) == 9)"
17242 [(set (match_dup 0) (match_dup 1))
17244 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17246 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17248 ;; imul $32bit_imm, mem, reg is vector decoded, while
17249 ;; imul $32bit_imm, reg, reg is direct decoded.
17251 [(match_scratch:SWI48 3 "r")
17252 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17253 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17254 (match_operand:SWI48 2 "immediate_operand" "")))
17255 (clobber (reg:CC FLAGS_REG))])]
17256 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17257 && !satisfies_constraint_K (operands[2])"
17258 [(set (match_dup 3) (match_dup 1))
17259 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17260 (clobber (reg:CC FLAGS_REG))])])
17263 [(match_scratch:SI 3 "r")
17264 (parallel [(set (match_operand:DI 0 "register_operand" "")
17266 (mult:SI (match_operand:SI 1 "memory_operand" "")
17267 (match_operand:SI 2 "immediate_operand" ""))))
17268 (clobber (reg:CC FLAGS_REG))])]
17270 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17271 && !satisfies_constraint_K (operands[2])"
17272 [(set (match_dup 3) (match_dup 1))
17273 (parallel [(set (match_dup 0)
17274 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17275 (clobber (reg:CC FLAGS_REG))])])
17277 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17278 ;; Convert it into imul reg, reg
17279 ;; It would be better to force assembler to encode instruction using long
17280 ;; immediate, but there is apparently no way to do so.
17282 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17284 (match_operand:SWI248 1 "nonimmediate_operand" "")
17285 (match_operand:SWI248 2 "const_int_operand" "")))
17286 (clobber (reg:CC FLAGS_REG))])
17287 (match_scratch:SWI248 3 "r")]
17288 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17289 && satisfies_constraint_K (operands[2])"
17290 [(set (match_dup 3) (match_dup 2))
17291 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17292 (clobber (reg:CC FLAGS_REG))])]
17294 if (!rtx_equal_p (operands[0], operands[1]))
17295 emit_move_insn (operands[0], operands[1]);
17298 ;; After splitting up read-modify operations, array accesses with memory
17299 ;; operands might end up in form:
17301 ;; movl 4(%esp), %edx
17303 ;; instead of pre-splitting:
17305 ;; addl 4(%esp), %eax
17307 ;; movl 4(%esp), %edx
17308 ;; leal (%edx,%eax,4), %eax
17311 [(match_scratch:P 5 "r")
17312 (parallel [(set (match_operand 0 "register_operand" "")
17313 (ashift (match_operand 1 "register_operand" "")
17314 (match_operand 2 "const_int_operand" "")))
17315 (clobber (reg:CC FLAGS_REG))])
17316 (parallel [(set (match_operand 3 "register_operand" "")
17317 (plus (match_dup 0)
17318 (match_operand 4 "x86_64_general_operand" "")))
17319 (clobber (reg:CC FLAGS_REG))])]
17320 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17321 /* Validate MODE for lea. */
17322 && ((!TARGET_PARTIAL_REG_STALL
17323 && (GET_MODE (operands[0]) == QImode
17324 || GET_MODE (operands[0]) == HImode))
17325 || GET_MODE (operands[0]) == SImode
17326 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17327 && (rtx_equal_p (operands[0], operands[3])
17328 || peep2_reg_dead_p (2, operands[0]))
17329 /* We reorder load and the shift. */
17330 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17331 [(set (match_dup 5) (match_dup 4))
17332 (set (match_dup 0) (match_dup 1))]
17334 enum machine_mode op1mode = GET_MODE (operands[1]);
17335 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17336 int scale = 1 << INTVAL (operands[2]);
17337 rtx index = gen_lowpart (Pmode, operands[1]);
17338 rtx base = gen_lowpart (Pmode, operands[5]);
17339 rtx dest = gen_lowpart (mode, operands[3]);
17341 operands[1] = gen_rtx_PLUS (Pmode, base,
17342 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17343 operands[5] = base;
17345 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17346 if (op1mode != Pmode)
17347 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17348 operands[0] = dest;
17351 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17352 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17353 ;; caught for use by garbage collectors and the like. Using an insn that
17354 ;; maps to SIGILL makes it more likely the program will rightfully die.
17355 ;; Keeping with tradition, "6" is in honor of #UD.
17356 (define_insn "trap"
17357 [(trap_if (const_int 1) (const_int 6))]
17359 { return ASM_SHORT "0x0b0f"; }
17360 [(set_attr "length" "2")])
17362 (define_expand "prefetch"
17363 [(prefetch (match_operand 0 "address_operand" "")
17364 (match_operand:SI 1 "const_int_operand" "")
17365 (match_operand:SI 2 "const_int_operand" ""))]
17366 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17368 int rw = INTVAL (operands[1]);
17369 int locality = INTVAL (operands[2]);
17371 gcc_assert (rw == 0 || rw == 1);
17372 gcc_assert (locality >= 0 && locality <= 3);
17373 gcc_assert (GET_MODE (operands[0]) == Pmode
17374 || GET_MODE (operands[0]) == VOIDmode);
17376 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17377 supported by SSE counterpart or the SSE prefetch is not available
17378 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17380 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17381 operands[2] = GEN_INT (3);
17383 operands[1] = const0_rtx;
17386 (define_insn "*prefetch_sse_<mode>"
17387 [(prefetch (match_operand:P 0 "address_operand" "p")
17389 (match_operand:SI 1 "const_int_operand" ""))]
17390 "TARGET_PREFETCH_SSE"
17392 static const char * const patterns[4] = {
17393 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17396 int locality = INTVAL (operands[1]);
17397 gcc_assert (locality >= 0 && locality <= 3);
17399 return patterns[locality];
17401 [(set_attr "type" "sse")
17402 (set_attr "atom_sse_attr" "prefetch")
17403 (set (attr "length_address")
17404 (symbol_ref "memory_address_length (operands[0])"))
17405 (set_attr "memory" "none")])
17407 (define_insn "*prefetch_3dnow_<mode>"
17408 [(prefetch (match_operand:P 0 "address_operand" "p")
17409 (match_operand:SI 1 "const_int_operand" "n")
17413 if (INTVAL (operands[1]) == 0)
17414 return "prefetch\t%a0";
17416 return "prefetchw\t%a0";
17418 [(set_attr "type" "mmx")
17419 (set (attr "length_address")
17420 (symbol_ref "memory_address_length (operands[0])"))
17421 (set_attr "memory" "none")])
17423 (define_expand "stack_protect_set"
17424 [(match_operand 0 "memory_operand" "")
17425 (match_operand 1 "memory_operand" "")]
17428 rtx (*insn)(rtx, rtx);
17430 #ifdef TARGET_THREAD_SSP_OFFSET
17431 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17432 insn = (TARGET_64BIT
17433 ? gen_stack_tls_protect_set_di
17434 : gen_stack_tls_protect_set_si);
17436 insn = (TARGET_64BIT
17437 ? gen_stack_protect_set_di
17438 : gen_stack_protect_set_si);
17441 emit_insn (insn (operands[0], operands[1]));
17445 (define_insn "stack_protect_set_<mode>"
17446 [(set (match_operand:P 0 "memory_operand" "=m")
17447 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17448 (set (match_scratch:P 2 "=&r") (const_int 0))
17449 (clobber (reg:CC FLAGS_REG))]
17451 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17452 [(set_attr "type" "multi")])
17454 (define_insn "stack_tls_protect_set_<mode>"
17455 [(set (match_operand:P 0 "memory_operand" "=m")
17456 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17457 UNSPEC_SP_TLS_SET))
17458 (set (match_scratch:P 2 "=&r") (const_int 0))
17459 (clobber (reg:CC FLAGS_REG))]
17461 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17462 [(set_attr "type" "multi")])
17464 (define_expand "stack_protect_test"
17465 [(match_operand 0 "memory_operand" "")
17466 (match_operand 1 "memory_operand" "")
17467 (match_operand 2 "" "")]
17470 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17472 rtx (*insn)(rtx, rtx, rtx);
17474 #ifdef TARGET_THREAD_SSP_OFFSET
17475 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17476 insn = (TARGET_64BIT
17477 ? gen_stack_tls_protect_test_di
17478 : gen_stack_tls_protect_test_si);
17480 insn = (TARGET_64BIT
17481 ? gen_stack_protect_test_di
17482 : gen_stack_protect_test_si);
17485 emit_insn (insn (flags, operands[0], operands[1]));
17487 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17488 flags, const0_rtx, operands[2]));
17492 (define_insn "stack_protect_test_<mode>"
17493 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17494 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17495 (match_operand:P 2 "memory_operand" "m")]
17497 (clobber (match_scratch:P 3 "=&r"))]
17499 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17500 [(set_attr "type" "multi")])
17502 (define_insn "stack_tls_protect_test_<mode>"
17503 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17504 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17505 (match_operand:P 2 "const_int_operand" "i")]
17506 UNSPEC_SP_TLS_TEST))
17507 (clobber (match_scratch:P 3 "=r"))]
17509 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17510 [(set_attr "type" "multi")])
17512 (define_insn "sse4_2_crc32<mode>"
17513 [(set (match_operand:SI 0 "register_operand" "=r")
17515 [(match_operand:SI 1 "register_operand" "0")
17516 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17518 "TARGET_SSE4_2 || TARGET_CRC32"
17519 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17520 [(set_attr "type" "sselog1")
17521 (set_attr "prefix_rep" "1")
17522 (set_attr "prefix_extra" "1")
17523 (set (attr "prefix_data16")
17524 (if_then_else (match_operand:HI 2 "" "")
17526 (const_string "*")))
17527 (set (attr "prefix_rex")
17528 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17530 (const_string "*")))
17531 (set_attr "mode" "SI")])
17533 (define_insn "sse4_2_crc32di"
17534 [(set (match_operand:DI 0 "register_operand" "=r")
17536 [(match_operand:DI 1 "register_operand" "0")
17537 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17539 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17540 "crc32{q}\t{%2, %0|%0, %2}"
17541 [(set_attr "type" "sselog1")
17542 (set_attr "prefix_rep" "1")
17543 (set_attr "prefix_extra" "1")
17544 (set_attr "mode" "DI")])
17546 (define_expand "rdpmc"
17547 [(match_operand:DI 0 "register_operand" "")
17548 (match_operand:SI 1 "register_operand" "")]
17551 rtx reg = gen_reg_rtx (DImode);
17554 /* Force operand 1 into ECX. */
17555 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17556 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17557 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17562 rtvec vec = rtvec_alloc (2);
17563 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17564 rtx upper = gen_reg_rtx (DImode);
17565 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17566 gen_rtvec (1, const0_rtx),
17568 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17569 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17571 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17572 NULL, 1, OPTAB_DIRECT);
17573 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17577 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17578 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17582 (define_insn "*rdpmc"
17583 [(set (match_operand:DI 0 "register_operand" "=A")
17584 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17588 [(set_attr "type" "other")
17589 (set_attr "length" "2")])
17591 (define_insn "*rdpmc_rex64"
17592 [(set (match_operand:DI 0 "register_operand" "=a")
17593 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17595 (set (match_operand:DI 1 "register_operand" "=d")
17596 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17599 [(set_attr "type" "other")
17600 (set_attr "length" "2")])
17602 (define_expand "rdtsc"
17603 [(set (match_operand:DI 0 "register_operand" "")
17604 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17609 rtvec vec = rtvec_alloc (2);
17610 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17611 rtx upper = gen_reg_rtx (DImode);
17612 rtx lower = gen_reg_rtx (DImode);
17613 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17614 gen_rtvec (1, const0_rtx),
17616 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17617 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17619 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17620 NULL, 1, OPTAB_DIRECT);
17621 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17623 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17628 (define_insn "*rdtsc"
17629 [(set (match_operand:DI 0 "register_operand" "=A")
17630 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17633 [(set_attr "type" "other")
17634 (set_attr "length" "2")])
17636 (define_insn "*rdtsc_rex64"
17637 [(set (match_operand:DI 0 "register_operand" "=a")
17638 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17639 (set (match_operand:DI 1 "register_operand" "=d")
17640 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17643 [(set_attr "type" "other")
17644 (set_attr "length" "2")])
17646 (define_expand "rdtscp"
17647 [(match_operand:DI 0 "register_operand" "")
17648 (match_operand:SI 1 "memory_operand" "")]
17651 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17652 gen_rtvec (1, const0_rtx),
17654 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17655 gen_rtvec (1, const0_rtx),
17657 rtx reg = gen_reg_rtx (DImode);
17658 rtx tmp = gen_reg_rtx (SImode);
17662 rtvec vec = rtvec_alloc (3);
17663 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17664 rtx upper = gen_reg_rtx (DImode);
17665 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17666 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17667 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17669 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17670 NULL, 1, OPTAB_DIRECT);
17671 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17676 rtvec vec = rtvec_alloc (2);
17677 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17678 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17679 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17683 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17687 (define_insn "*rdtscp"
17688 [(set (match_operand:DI 0 "register_operand" "=A")
17689 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17690 (set (match_operand:SI 1 "register_operand" "=c")
17691 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17694 [(set_attr "type" "other")
17695 (set_attr "length" "3")])
17697 (define_insn "*rdtscp_rex64"
17698 [(set (match_operand:DI 0 "register_operand" "=a")
17699 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17700 (set (match_operand:DI 1 "register_operand" "=d")
17701 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17702 (set (match_operand:SI 2 "register_operand" "=c")
17703 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17706 [(set_attr "type" "other")
17707 (set_attr "length" "3")])
17709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17711 ;; LWP instructions
17713 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17715 (define_expand "lwp_llwpcb"
17716 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17717 UNSPECV_LLWP_INTRINSIC)]
17720 (define_insn "*lwp_llwpcb<mode>1"
17721 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17722 UNSPECV_LLWP_INTRINSIC)]
17725 [(set_attr "type" "lwp")
17726 (set_attr "mode" "<MODE>")
17727 (set_attr "length" "5")])
17729 (define_expand "lwp_slwpcb"
17730 [(set (match_operand 0 "register_operand" "=r")
17731 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17736 insn = (TARGET_64BIT
17738 : gen_lwp_slwpcbsi);
17740 emit_insn (insn (operands[0]));
17744 (define_insn "lwp_slwpcb<mode>"
17745 [(set (match_operand:P 0 "register_operand" "=r")
17746 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17749 [(set_attr "type" "lwp")
17750 (set_attr "mode" "<MODE>")
17751 (set_attr "length" "5")])
17753 (define_expand "lwp_lwpval<mode>3"
17754 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17755 (match_operand:SI 2 "nonimmediate_operand" "rm")
17756 (match_operand:SI 3 "const_int_operand" "i")]
17757 UNSPECV_LWPVAL_INTRINSIC)]
17759 "/* Avoid unused variable warning. */
17762 (define_insn "*lwp_lwpval<mode>3_1"
17763 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17764 (match_operand:SI 1 "nonimmediate_operand" "rm")
17765 (match_operand:SI 2 "const_int_operand" "i")]
17766 UNSPECV_LWPVAL_INTRINSIC)]
17768 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17769 [(set_attr "type" "lwp")
17770 (set_attr "mode" "<MODE>")
17771 (set (attr "length")
17772 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17774 (define_expand "lwp_lwpins<mode>3"
17775 [(set (reg:CCC FLAGS_REG)
17776 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17777 (match_operand:SI 2 "nonimmediate_operand" "rm")
17778 (match_operand:SI 3 "const_int_operand" "i")]
17779 UNSPECV_LWPINS_INTRINSIC))
17780 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17781 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17784 (define_insn "*lwp_lwpins<mode>3_1"
17785 [(set (reg:CCC FLAGS_REG)
17786 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17787 (match_operand:SI 1 "nonimmediate_operand" "rm")
17788 (match_operand:SI 2 "const_int_operand" "i")]
17789 UNSPECV_LWPINS_INTRINSIC))]
17791 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17792 [(set_attr "type" "lwp")
17793 (set_attr "mode" "<MODE>")
17794 (set (attr "length")
17795 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17797 (define_insn "rdfsbase<mode>"
17798 [(set (match_operand:SWI48 0 "register_operand" "=r")
17799 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17800 "TARGET_64BIT && TARGET_FSGSBASE"
17802 [(set_attr "type" "other")
17803 (set_attr "prefix_extra" "2")])
17805 (define_insn "rdgsbase<mode>"
17806 [(set (match_operand:SWI48 0 "register_operand" "=r")
17807 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17808 "TARGET_64BIT && TARGET_FSGSBASE"
17810 [(set_attr "type" "other")
17811 (set_attr "prefix_extra" "2")])
17813 (define_insn "wrfsbase<mode>"
17814 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17816 "TARGET_64BIT && TARGET_FSGSBASE"
17818 [(set_attr "type" "other")
17819 (set_attr "prefix_extra" "2")])
17821 (define_insn "wrgsbase<mode>"
17822 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17824 "TARGET_64BIT && TARGET_FSGSBASE"
17826 [(set_attr "type" "other")
17827 (set_attr "prefix_extra" "2")])
17829 (define_insn "rdrand<mode>_1"
17830 [(set (match_operand:SWI248 0 "register_operand" "=r")
17831 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17832 (set (reg:CCC FLAGS_REG)
17833 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17836 [(set_attr "type" "other")
17837 (set_attr "prefix_extra" "1")])
17839 (define_expand "pause"
17840 [(set (match_dup 0)
17841 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17844 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17845 MEM_VOLATILE_P (operands[0]) = 1;
17848 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17849 ;; They have the same encoding.
17850 (define_insn "*pause"
17851 [(set (match_operand:BLK 0 "" "")
17852 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17855 [(set_attr "length" "2")
17856 (set_attr "memory" "unknown")])
17860 (include "sync.md")